| 224 | return !out.empty(); |
| 225 | } |
| 226 | |
| 227 | static bool parse_float_list(const char * text, std::vector<double> & out) { |
| 228 | out.clear(); |
| 229 | if (!text || !*text) return false; |
| 230 | const char * p = text; |
| 231 | while (*p) { |
| 232 | char * end = nullptr; |
| 233 | double v = std::strtod(p, &end); |
| 234 | if (end == p || v <= 0.0) return false; |
| 235 | out.push_back(v); |
| 236 | if (*end == '\0') break; |
| 237 | if (*end != ',') return false; |
| 238 | p = end + 1; |
| 239 | } |
| 240 | return !out.empty(); |
| 241 | } |
| 242 | |
| 243 | // ─── Draft IPC — extracted to src/qwen35/draft_ipc.{h,cpp} ── |