24#if !defined(DIMVAL_WITH_NLOHMANN_JSON)
25#if __has_include(<nlohmann/json.hpp>)
26#define DIMVAL_WITH_NLOHMANN_JSON 1
28#define DIMVAL_WITH_NLOHMANN_JSON 0
32#if DIMVAL_WITH_NLOHMANN_JSON
39#include <nlohmann/json.hpp>
41#include <commons/json.hpp>
47template <UnitLike U, NumericValue T>
48inline void to_json(::nlohmann::json& j,
const UnitValue<U, T>& v) {
49 constexpr auto d = U::descriptor();
50 j = ::nlohmann::json{{
"u", d.id}, {
"v", v.v}};
53template <UnitLike U, NumericValue T>
54inline void from_json(const ::nlohmann::json& j, UnitValue<U, T>& v) {
55 constexpr auto d = U::descriptor();
56 const auto id = j.at(
"u").get<std::string>();
58 throw ::nlohmann::detail::other_error::create(
60 std::string{
"dimval: unit mismatch: expected '"} + std::string{d.id} +
"', got '" +
id +
64 v.v = j.at(
"v").get<T>();
67template <MeasureLike M, NumericValue T>
68inline void to_json(::nlohmann::json& j,
const MeasureValue<M, T>& v) {
69 constexpr auto md = M::descriptor();
70 using unit_t = M::base_unit_t;
71 constexpr auto ud = unit_t::descriptor();
72 j = ::nlohmann::json{{
"m", md.id}, {
"u", ud.id}, {
"v", v.v}};
75template <MeasureLike M, NumericValue T>
76inline void from_json(const ::nlohmann::json& j, MeasureValue<M, T>& v) {
77 constexpr auto md = M::descriptor();
78 using unit_t = M::base_unit_t;
79 constexpr auto ud = unit_t::descriptor();
80 const auto mid = j.at(
"m").get<std::string>();
82 throw ::nlohmann::detail::other_error::create(
84 std::string{
"dimval: measure mismatch: expected '"} + std::string{md.id} +
"', got '" +
88 if (
const auto it = j.find(
"u"); it != j.end()) {
89 const auto uid = it->get<std::string>();
91 throw ::nlohmann::detail::other_error::create(
93 std::string{
"dimval: unit mismatch: expected '"} + std::string{ud.id} +
"', got '" +
98 v.v = j.at(
"v").get<T>();
101template <UnitLike U, NumericValue T>
102inline void to_json(::nlohmann::json& j,
const UnitRangeValue<U, T>& r) {
103 constexpr auto d = U::descriptor();
104 j = ::nlohmann::json{
108 {
"mi", r.inclusion().lower == Bound::Inclusive},
109 {
"xi", r.inclusion().upper == Bound::Inclusive},
113template <UnitLike U, NumericValue T>
114inline void from_json(const ::nlohmann::json& j, UnitRangeValue<U, T>& r) {
115 constexpr auto d = U::descriptor();
116 const auto id = j.at(
"u").get<std::string>();
118 throw ::nlohmann::detail::other_error::create(
120 std::string{
"dimval: unit mismatch: expected '"} + std::string{d.id} +
"', got '" +
id +
124 const auto lo = j.at(
"min").get<T>();
125 const auto hi = j.at(
"max").get<T>();
127 j.value(
"mi",
true) ? Bound::Inclusive : Bound::Exclusive,
128 j.value(
"xi",
true) ? Bound::Inclusive : Bound::Exclusive,
130 auto built = UnitRangeValue<U, T>::make(UnitValue<U, T>{lo}, UnitValue<U, T>{hi}, inc);
132 throw ::nlohmann::detail::other_error::create(
133 502, std::string{
"dimval: invalid range: "} + built.error().message, &j);
138template <MeasureLike M, NumericValue T>
139inline void to_json(::nlohmann::json& j,
const MeasureRangeValue<M, T>& r) {
140 constexpr auto md = M::descriptor();
141 using unit_t = M::base_unit_t;
142 constexpr auto ud = unit_t::descriptor();
143 j = ::nlohmann::json{
148 {
"mi", r.inclusion().lower == Bound::Inclusive},
149 {
"xi", r.inclusion().upper == Bound::Inclusive},
153template <MeasureLike M, NumericValue T>
154inline void from_json(const ::nlohmann::json& j, MeasureRangeValue<M, T>& r) {
155 constexpr auto md = M::descriptor();
156 using unit_t = M::base_unit_t;
157 constexpr auto ud = unit_t::descriptor();
158 const auto mid = j.at(
"m").get<std::string>();
160 throw ::nlohmann::detail::other_error::create(
162 std::string{
"dimval: measure mismatch: expected '"} + std::string{md.id} +
"', got '" +
166 if (
const auto it = j.find(
"u"); it != j.end()) {
167 const auto uid = it->get<std::string>();
169 throw ::nlohmann::detail::other_error::create(
171 std::string{
"dimval: unit mismatch: expected '"} + std::string{ud.id} +
"', got '" +
176 const auto lo = j.at(
"min").get<T>();
177 const auto hi = j.at(
"max").get<T>();
179 j.value(
"mi",
true) ? Bound::Inclusive : Bound::Exclusive,
180 j.value(
"xi",
true) ? Bound::Inclusive : Bound::Exclusive,
182 auto built = MeasureRangeValue<M, T>::make(MeasureValue<M, T>{lo}, MeasureValue<M, T>{hi}, inc);
184 throw ::nlohmann::detail::other_error::create(
185 502, std::string{
"dimval: invalid range: "} + built.error().message, &j);
190inline void to_json(::nlohmann::json& j,
const UnitDescriptor& d) {
191 j = ::nlohmann::json{
193 {
"symbol", d.symbol},
194 {
"short_name", d.short_name},
195 {
"long_name", d.long_name},
197 {
"factor", d.factor},
198 {
"offset", d.offset},
199 {
"formatter", d.formatter},
200 {
"default_precision", d.default_precision},
203 j[
"icon"] = d.icon ? ::nlohmann::json(*d.icon) : ::nlohmann::json(nullptr);
204 j[
"color"] = d.color ? ::nlohmann::json(*d.color) : ::nlohmann::json(nullptr);
207inline void to_json(::nlohmann::json& j,
const MeasureDescriptor& d) {
208 j = ::nlohmann::json{
210 {
"base_unit_id", d.base_unit_id},
212 {
"formatter", d.formatter},
213 {
"default_precision", d.default_precision},
216 j[
"icon"] = d.icon ? ::nlohmann::json(*d.icon) : ::nlohmann::json(nullptr);
217 j[
"color"] = d.color ? ::nlohmann::json(*d.color) : ::nlohmann::json(nullptr);
MeasureValue<M,T>: a UnitValue tagged with an additional semantic measure.
UnitRangeValue and MeasureRangeValue — closed/open intervals of dimensional values.
Concepts and helper accessors that drive the static side of dimval.
UnitValue<U,T>: a strongly-typed value carrying a compile-time unit tag.