#pragma once #include #include #include #include namespace jvalidate::constraint { /** * @brief A constraint on the Int and Double types, asserting that the given * arg is less than the stored value. Equality is accepted or rejected based * on exclusive being true or not. * Unlike other constraint types, numeric constraints are trivial and thus * are implemented directly in the constraint object. * * https://json-schema.org/draft/2020-12/json-schema-validation#section-6.2.2 * https://json-schema.org/draft/2020-12/json-schema-validation#section-6.2.3 */ struct MaximumConstraint { double value; bool exclusive; bool operator()(double arg) const { return exclusive ? arg < value : arg <= value; } }; /** * @brief A constraint on the Int and Double types, asserting that the given * arg is greater than the stored value. Equality is accepted or rejected based * on exclusive being true or not. * Unlike other constraint types, numeric constraints are trivial and thus * are implemented directly in the constraint object. * * https://json-schema.org/draft/2020-12/json-schema-validation#section-6.2.4 * https://json-schema.org/draft/2020-12/json-schema-validation#section-6.2.5 */ struct MinimumConstraint { double value; bool exclusive; bool operator()(double arg) const { return exclusive ? arg > value : arg >= value; } }; /** * @brief A constraint on the Int and Double types, asserting that the given * arg is a multiple of the stored value. * Unlike other constraint types, numeric constraints are trivial and thus * are implemented directly in the constraint object. * * https://json-schema.org/draft/2020-12/json-schema-validation#section-6.2.1 */ struct MultipleOfConstraint { double value; bool operator()(double arg) const { if (std::fabs(std::remainder(arg, value)) <= std::numeric_limits::epsilon()) { return true; } double const div = arg / value; return std::isfinite(div) && detail::is_json_integer(div); } }; }