139 std::vector<ParameterMetadata<double>> double_params_;
140 std::vector<ParameterMetadata<int>> int_params_;
141 std::string model_name_ =
"Model";
153 double_params_.push_back(
meta);
160 int_params_.push_back(
meta);
176 for (
const auto &
meta : double_params_) {
181 for (
const auto &
meta : int_params_) {
192 static json get_by_path(
const json &
j,
const std::string &
path) {
193 if (
path.find(
'.') == std::string::npos) {
194 return j.contains(
path) ?
j.at(
path) : json(
nullptr);
203 return json(
nullptr);
205 current = ¤t->at(key);
206 if (dot == std::string::npos)
break;
212 static bool has_by_path(
const json &j,
const std::string &path) {
213 if (path.find(
'.') == std::string::npos) {
214 return j.contains(path);
216 const json *current = &j;
218 while (start < path.size()) {
219 size_t dot = path.find(
'.', start);
220 std::string key = (dot == std::string::npos) ? path.substr(start)
221 : path.substr(start, dot - start);
222 if (!current->is_object() || !current->contains(key)) {
225 current = ¤t->at(key);
226 if (dot == std::string::npos)
break;
232 static bool is_finite_number(
const json &v) {
233 if (!v.is_number())
return false;
234 double x = v.get<
double>();
235 return std::isfinite(x);
241 void validate_parameter(
const json &config,
const ParameterMetadata<double> &meta,
242 ValidationResult &result)
const {
244 bool exists = has_by_path(config, meta.name);
245 json val = exists ? get_by_path(config, meta.name) : json(nullptr);
248 if (meta.required && !meta.default_value) {
249 std::ostringstream err;
250 err <<
"Required parameter '" << meta.name <<
"' is missing\n"
251 <<
" " << meta.format_info();
252 result.errors.push_back(err.str());
254 }
else if (meta.default_value) {
256 std::ostringstream val_str;
257 val_str << *meta.default_value <<
" (default)";
258 result.validated_params[meta.name] = val_str.str();
267 if (!val.is_number()) {
268 std::ostringstream err;
269 err <<
"Parameter '" << meta.name <<
"' has wrong type\n"
270 <<
" Expected: number\n"
271 <<
" Got: " << val.type_name() <<
"\n"
272 <<
" Value: " << val.dump() <<
"\n"
273 <<
" " << meta.format_info();
274 result.errors.push_back(err.str());
279 double value = val.get<
double>();
280 if (!std::isfinite(value)) {
281 std::ostringstream err;
282 err <<
"Parameter '" << meta.name <<
"' is not finite (NaN/Inf)\n"
283 <<
" " << meta.format_info();
284 result.errors.push_back(err.str());
287 if (
auto error = meta.validate(value)) {
288 std::ostringstream err;
289 err << *error <<
"\n"
290 <<
" " << meta.format_info();
291 result.errors.push_back(err.str());
294 std::ostringstream val_str;
296 if (meta.min_value && meta.max_value) {
297 val_str <<
" [range: " << *meta.min_value <<
", " << *meta.max_value <<
"]";
299 result.validated_params[meta.name] = val_str.str();
306 void validate_parameter(
const json &config,
const ParameterMetadata<int> &meta,
307 ValidationResult &result)
const {
309 bool exists = has_by_path(config, meta.name);
310 json val = exists ? get_by_path(config, meta.name) : json(nullptr);
313 if (meta.required && !meta.default_value) {
314 std::ostringstream err;
315 err <<
"Required parameter '" << meta.name <<
"' is missing\n"
316 <<
" " << meta.format_info();
317 result.errors.push_back(err.str());
319 }
else if (meta.default_value) {
321 std::ostringstream val_str;
322 val_str << *meta.default_value <<
" (default)";
323 result.validated_params[meta.name] = val_str.str();
332 if (!val.is_number_integer()) {
333 std::ostringstream err;
334 err <<
"Parameter '" << meta.name <<
"' has wrong type\n"
335 <<
" Expected: integer\n"
336 <<
" Got: " << val.type_name() <<
"\n"
337 <<
" Value: " << val.dump() <<
"\n"
338 <<
" " << meta.format_info();
339 result.errors.push_back(err.str());
344 int value = val.get<
int>();
345 if (
auto error = meta.validate(value)) {
346 std::ostringstream err;
347 err << *error <<
"\n"
348 <<
" " << meta.format_info();
349 result.errors.push_back(err.str());
352 std::ostringstream val_str;
354 if (meta.min_value && meta.max_value) {
355 val_str <<
" [range: " << *meta.min_value <<
", " << *meta.max_value <<
"]";
357 result.validated_params[meta.name] = val_str.str();