211 template<
typename To>
212 [[nodiscard]]
friend constexpr auto promote_if(datum
const& lhs, datum
const& rhs)
noexcept
219 r.set(
get<To>(lhs),
static_cast<To
>(rhs));
222 r.set(
static_cast<To
>(lhs),
get<To>(rhs));
228 constexpr ~datum() noexcept
235 if (
other.is_pointer()) {
240 constexpr datum(datum&&
other) noexcept : _tag(
other._tag), _value(
other._value)
242 other._tag = tag_type::monostate;
243 other._value._long_long = 0;
246 constexpr datum() noexcept : _tag(tag_type::monostate), _value(0) {}
247 constexpr explicit datum(std::monostate) noexcept : _tag(tag_type::monostate), _value(0) {}
248 constexpr explicit datum(nullptr_t) noexcept : _tag(tag_type::null), _value(0) {}
249 constexpr explicit datum(
continue_type) noexcept : _tag(tag_type::flow_continue), _value(0) {}
250 constexpr explicit datum(
break_type) noexcept : _tag(tag_type::flow_break), _value(0) {}
251 constexpr explicit datum(
bool value) noexcept : _tag(tag_type::boolean), _value(value) {}
252 constexpr explicit datum(std::floating_point
auto value) noexcept :
257 constexpr explicit datum(numeric_integral
auto value) noexcept :
262 constexpr explicit datum(std::chrono::year_month_day value) noexcept : _tag(tag_type::year_month_day), _value(value) {}
263 explicit datum(std::string value) noexcept : _tag(tag_type::string), _value(
new std::string{
std::move(value)}) {}
264 explicit datum(std::string_view value) noexcept : _tag(tag_type::string), _value(
new std::string{value}) {}
265 explicit datum(
char const* value) noexcept : _tag(tag_type::string), _value(
new std::string{value}) {}
266 explicit datum(vector_type value) noexcept : _tag(tag_type::vector), _value(
new vector_type{
std::move(value)}) {}
267 explicit datum(map_type value) noexcept : _tag(tag_type::map), _value(
new map_type{
std::move(value)}) {}
268 explicit datum(bstring value) noexcept : _tag(tag_type::bstring), _value(
new bstring{
std::move(value)}) {}
270 template<
typename... Args>
271 [[nodiscard]]
static datum make_vector(Args
const&... args)
noexcept
273 return datum{vector_type{datum{args}...}};
276 template<
typename Key,
typename Value,
typename... Args>
277 static void populate_map(map_type& r, Key
const& key, Value
const& value, Args
const&... args)
noexcept
279 r.insert(std::pair<datum, datum>{datum{key}, datum{value}});
280 if constexpr (
sizeof...(Args) > 0) {
281 populate_map(r, args...);
285 template<
typename... Args>
286 [[nodiscard]]
static datum make_map(Args
const&... args)
noexcept
288 static_assert(
sizeof...(Args) % 2 == 0,
"Expect key value pairs for the arguments of make_map()");
291 if constexpr (
sizeof...(Args) > 0) {
292 populate_map(r, args...);
297 [[nodiscard]]
static datum make_break() noexcept
302 [[nodiscard]]
static datum make_continue() noexcept
307 constexpr datum& operator=(datum
const&
other)
noexcept
309 hi_return_on_self_assignment(
other);
313 _value =
other._value;
314 if (
other.is_pointer()) {
320 constexpr datum& operator=(datum&&
other)
noexcept
327 constexpr datum& operator=(std::floating_point
auto value)
noexcept(
sizeof(value) <= 4)
330 _tag = tag_type::floating_point;
331 _value =
static_cast<double>(value);
335 constexpr datum& operator=(numeric_integral
auto value)
noexcept(
sizeof(value) <= 4)
338 _tag = tag_type::integral;
339 _value =
static_cast<long long>(value);
343 constexpr datum& operator=(
bool value)
noexcept
346 _tag = tag_type::boolean;
351 constexpr datum& operator=(std::chrono::year_month_day value)
noexcept
354 _tag = tag_type::year_month_day;
359 constexpr datum& operator=(std::monostate)
noexcept
362 _tag = tag_type::monostate;
367 constexpr datum& operator=(nullptr_t)
noexcept
370 _tag = tag_type::null;
375 datum& operator=(std::string value)
noexcept
378 _tag = tag_type::string;
379 _value =
new std::string{
std::move(value)};
383 datum& operator=(
char const* value)
noexcept
386 _tag = tag_type::string;
387 _value =
new std::string{value};
391 datum& operator=(std::string_view value)
noexcept
394 _tag = tag_type::string;
395 _value =
new std::string{value};
399 datum& operator=(vector_type value)
noexcept
402 _tag = tag_type::vector;
403 _value =
new vector_type{
std::move(value)};
407 datum& operator=(map_type value)
noexcept
410 _tag = tag_type::map;
415 datum& operator=(bstring value)
noexcept
418 _tag = tag_type::bstring;
423 constexpr explicit operator bool() const noexcept
426 case tag_type::floating_point:
428 case tag_type::boolean:
430 case tag_type::integral:
432 case tag_type::year_month_day:
434 case tag_type::string:
436 case tag_type::vector:
440 case tag_type::bstring:
447 [[nodiscard]]
constexpr bool empty()
const
450 case tag_type::string:
452 case tag_type::vector:
456 case tag_type::bstring:
459 throw std::domain_error(std::format(
"Type {} can not be checked for empty", repr(*
this)));
463 template<std::
floating_po
int T>
464 constexpr explicit operator T()
const
467 case tag_type::floating_point:
469 case tag_type::integral:
471 case tag_type::boolean:
474 throw std::domain_error(std::format(
"Can't convert {} to floating point", repr(*
this)));
478 template<numeric_
integral T>
479 constexpr explicit operator T()
const
486 throw std::overflow_error(
"double to integral");
488 return round_cast<T>(r);
492 throw std::overflow_error(
"long long to integral");
500 throw std::domain_error(std::format(
"Can't convert {} to an integral", repr(*
this)));
504 constexpr explicit operator std::chrono::year_month_day()
const
509 throw std::domain_error(std::format(
"Can't convert {} to an std::chrono::year_month_day", repr(*
this)));
513 explicit operator std::string() const noexcept
516 case tag_type::monostate:
518 case tag_type::floating_point:
519 return hi::to_string(_value._double);
520 case tag_type::integral:
522 case tag_type::boolean:
523 return _value._bool ?
"true" :
"false";
524 case tag_type::year_month_day:
525 return std::format(
"{:%Y-%m-%d}", _value._year_month_day);
528 case tag_type::flow_break:
530 case tag_type::flow_continue:
532 case tag_type::string:
533 return *_value._string;
534 case tag_type::vector:
536 auto r = std::string{
"["};
537 for (
auto const& item : *_value._vector) {
546 auto r = std::string{
"{"};
547 for (
auto const& item : *_value._map) {
548 r += repr(item.first);
550 r += repr(item.second);
556 case tag_type::bstring:
557 return base64::encode(*_value._bstring);
563 explicit operator std::string_view()
const
566 return std::string_view{*s};
568 throw std::domain_error(std::format(
"Can't convert {} to an std::string_view", repr(*
this)));
572 explicit operator vector_type()
const
577 throw std::domain_error(std::format(
"Can't convert {} to an vector", repr(*
this)));
581 explicit operator map_type()
const
586 throw std::domain_error(std::format(
"Can't convert {} to an map", repr(*
this)));
590 explicit operator bstring()
const
593 if (_tag != tag_type::bstring) {
594 throw std::domain_error(std::format(
"Can't convert {} to an bstring", repr(*
this)));
599 [[nodiscard]]
constexpr char const* type_name() const noexcept
602 case tag_type::floating_point:
604 case tag_type::integral:
606 case tag_type::boolean:
608 case tag_type::year_month_day:
610 case tag_type::string:
612 case tag_type::vector:
616 case tag_type::bstring:
627 return _tag == tag_type::monostate;
633 [[nodiscard]]
constexpr bool is_break() const noexcept
635 return _tag == tag_type::flow_break;
643 return _tag == tag_type::flow_continue;
649 case tag_type::floating_point:
651 case tag_type::integral:
653 case tag_type::boolean:
655 case tag_type::year_month_day:
661 return std::hash<uint32_t>{}(r);
663 case tag_type::string:
664 return std::hash<std::string>{}(*_value._string);
665 case tag_type::vector:
668 for (
auto const& v : *_value._vector) {
669 r = hash_mix(r, v.hash());
676 for (
auto const& kv : *_value._map) {
677 r = hash_mix(r, kv.first.hash(), kv.second.hash());
681 case tag_type::bstring:
682 return std::hash<bstring>{}(*_value._bstring);
688 [[nodiscard]]
constexpr std::size_t size()
const
699 throw std::domain_error(std::format(
"Can not evaluate {}.size()", repr(*
this)));
703 [[nodiscard]]
constexpr friend std::size_t size(datum
const& rhs)
708 [[nodiscard]]
constexpr datum
const& back()
const
712 throw std::domain_error(std::format(
"Empty vector {}.back()", repr(*
this)));
716 throw std::domain_error(std::format(
"Can not evaluate {}.back()", repr(*
this)));
720 [[nodiscard]]
constexpr datum& back()
724 throw std::domain_error(std::format(
"Empty vector {}.back()", repr(*
this)));
728 throw std::domain_error(std::format(
"Can not evaluate {}.back()", repr(*
this)));
732 [[nodiscard]]
constexpr datum
const& front()
const
736 throw std::domain_error(std::format(
"Empty vector {}.front()", repr(*
this)));
740 throw std::domain_error(std::format(
"Can not evaluate {}.front()", repr(*
this)));
744 [[nodiscard]]
constexpr datum& front()
748 throw std::domain_error(std::format(
"Empty vector {}.front()", repr(*
this)));
752 throw std::domain_error(std::format(
"Can not evaluate {}.front()", repr(*
this)));
756 [[nodiscard]]
constexpr auto cbegin()
const
761 throw std::domain_error(std::format(
"Can not evaluate {}.cbegin()", repr(*
this)));
765 [[nodiscard]]
constexpr auto begin()
const
770 throw std::domain_error(std::format(
"Can not evaluate {}.begin()", repr(*
this)));
774 [[nodiscard]]
constexpr auto begin()
779 throw std::domain_error(std::format(
"Can not evaluate {}.begin()", repr(*
this)));
783 [[nodiscard]]
constexpr auto cend()
const
788 throw std::domain_error(std::format(
"Can not evaluate {}.cend()", repr(*
this)));
792 [[nodiscard]]
constexpr auto end()
const
797 throw std::domain_error(std::format(
"Can not evaluate {}.end()", repr(*
this)));
801 [[nodiscard]]
constexpr auto end()
806 throw std::domain_error(std::format(
"Can not evaluate {}.end()", repr(*
this)));
812 [[nodiscard]] vector_type
keys()
const
815 auto r = vector_type{};
816 r.reserve(m->size());
817 for (
auto const& kv : *m) {
818 r.push_back(kv.first);
831 auto r = vector_type{};
832 r.reserve(m->size());
833 for (
auto const& kv : *m) {
834 r.push_back(kv.second);
838 throw std::domain_error(std::format(
"Can not evaluate {}.values()", repr(*
this)));
844 [[nodiscard]] vector_type
items()
const
847 auto r = vector_type{};
848 r.reserve(m->size());
850 for (
auto const& item : *m) {
851 r.push_back(make_vector(item.first, item.second));
855 throw std::domain_error(std::format(
"Can not evaluate {}.items()", repr(*
this)));
859 constexpr void push_back(
datum const& rhs)
861 if (
auto* v = get_if<vector_type>(*
this)) {
862 return v->push_back(rhs);
864 throw std::domain_error(std::format(
"Can not evaluate {}.push_back({})", repr(*
this), repr(rhs)));
868 constexpr void push_back(datum&& rhs)
873 throw std::domain_error(std::format(
"Can not evaluate {}.push_back({})", repr(*
this), repr(rhs)));
877 template<
typename Arg>
878 constexpr void push_back(Arg&& arg)
883 constexpr void pop_back()
887 throw std::domain_error(std::format(
"Empty vector {}.pop_back()", repr(*
this)));
889 return v->pop_back();
891 throw std::domain_error(std::format(
"Can not evaluate {}.pop_back()", repr(*
this)));
895 [[nodiscard]]
constexpr bool contains(datum
const& rhs)
const
898 return m->contains(rhs);
900 throw std::domain_error(std::format(
"Can not evaluate {}.contains({})", repr(*
this), repr(rhs)));
904 template<
typename Arg>
905 [[nodiscard]]
constexpr bool contains(Arg
const& arg)
const
907 return contains(datum{arg});
910 [[nodiscard]] std::vector<datum*> find(jsonpath
const& path)
noexcept
912 auto r = std::vector<datum*>{};
913 find(path.cbegin(), path.cend(), r);
917 [[nodiscard]] std::vector<datum const*> find(jsonpath
const& path)
const noexcept
919 auto tmp = std::vector<datum*>{};
920 const_cast<datum*
>(
this)->find(path.cbegin(), path.cend(), tmp);
921 auto r = std::vector<datum const*>{};
936 return to_bool(
remove(path.cbegin(), path.cend()));
946 hi_axiom(path.is_singular());
947 return find_one(path.cbegin(), path.cend(),
false);
957 hi_axiom(path.is_singular());
958 return find_one(path.cbegin(), path.cend(),
true);
968 hi_axiom(path.is_singular());
969 return const_cast<datum*
>(
this)->
find_one(path.cbegin(), path.cend(),
false);
972 [[nodiscard]]
datum const& operator[](
datum const& rhs)
const
979 index = ssize(v) + index;
981 if (index < 0 or index >= ssize(v)) {
989 auto const it = m.find(rhs);
991 throw std::overflow_error(std::format(
"Key {} not found in map", repr(rhs)));
997 throw std::domain_error(std::format(
"Can not evaluate {}[{}]", repr(*
this), repr(rhs)));
1001 [[nodiscard]]
constexpr datum& operator[](datum
const& rhs)
1008 index = ssize(v) + index;
1010 if (index < 0 or index >= ssize(v)) {
1011 throw std::overflow_error(std::format(
"Index {} beyond bounds of vector", repr(rhs)));
1021 throw std::domain_error(std::format(
"Can not evaluate {}[{}]", repr(*
this), repr(rhs)));
1025 [[nodiscard]]
constexpr datum
const& operator[](
auto const& rhs)
const
1027 return (*
this)[datum{rhs}];
1030 [[nodiscard]]
constexpr datum& operator[](
auto const& rhs)
1032 return (*
this)[datum{rhs}];
1035 [[nodiscard]]
constexpr datum& operator++()
1038 ++_value._long_long;
1041 throw std::domain_error(std::format(
"Can not evaluate ++{}", repr(*
this)));
1045 [[nodiscard]]
constexpr datum& operator--()
1048 --_value._long_long;
1051 throw std::domain_error(std::format(
"Can not evaluate --{}", repr(*
this)));
1055 [[nodiscard]]
constexpr datum operator++(
int)
1059 _value._long_long++;
1062 throw std::domain_error(std::format(
"Can not evaluate {}++", repr(*
this)));
1065 [[nodiscard]]
constexpr datum operator--(
int)
1069 _value._long_long--;
1072 throw std::domain_error(std::format(
"Can not evaluate {}--", repr(*
this)));
1076 constexpr datum& operator+=(
auto const& rhs)
1082 return (*
this) = (*this) + rhs;
1086#define X(op, inner_op) \
1087 constexpr datum& operator op(auto const& rhs) \
1089 return (*this) = (*this)inner_op rhs; \
1103 [[nodiscard]]
friend constexpr bool operator==(datum
const& lhs, datum
const& rhs)
noexcept
1106 return doubles.lhs() == doubles.rhs();
1109 return long_longs.lhs() == long_longs.rhs();
1112 return bools.lhs() == bools.rhs();
1115 return ymds.lhs() == ymds.rhs();
1118 return strings.lhs() == strings.rhs();
1121 return vectors.lhs() == vectors.rhs();
1124 return maps.lhs() == maps.rhs();
1127 return lhs._tag == rhs._tag;
1157 [[nodiscard]]
friend constexpr std::partial_ordering operator<=>(datum
const& lhs, datum
const& rhs)
noexcept
1160 return doubles.lhs() <=> doubles.rhs();
1163 return long_longs.lhs() <=> long_longs.rhs();
1166 return bools.lhs() <=> bools.rhs();
1169 return year_month_days.lhs() <=> year_month_days.rhs();
1172 return strings.lhs() <=> strings.rhs();
1175 return vectors.lhs() <=> vectors.rhs();
1178 return maps.lhs() <=> maps.rhs();
1181 return bstrings.lhs() <=> bstrings.rhs();
1184 return lhs._tag <=> rhs._tag;
1198 [[nodiscard]]
friend constexpr datum operator-(datum
const& rhs)
1201 return datum{-*rhs_double};
1204 return datum{-*rhs_long_long};
1207 throw std::domain_error(std::format(
"Can not evaluate -{}", repr(rhs)));
1220 [[nodiscard]]
friend constexpr datum operator~(datum
const& rhs)
1223 return datum{~*rhs_long_long};
1226 throw std::domain_error(std::format(
"Can not evaluate ~{}", repr(rhs)));
1244 [[nodiscard]]
friend constexpr datum operator+(datum
const& lhs, datum
const& rhs)
1247 return datum{doubles.lhs() + doubles.rhs()};
1250 return datum{long_longs.lhs() + long_longs.rhs()};
1253 return datum{strings.lhs() + strings.rhs()};
1256 auto r = vectors.lhs();
1257 r.insert(r.end(), vectors.rhs().begin(), vectors.rhs().end());
1261 throw std::domain_error(std::format(
"Can not evaluate {} '+' {}", repr(lhs), repr(rhs)));
1276 [[nodiscard]]
friend constexpr datum operator-(datum
const& lhs, datum
const& rhs)
1279 return datum{doubles.lhs() - doubles.rhs()};
1282 return datum{long_longs.lhs() - long_longs.rhs()};
1285 throw std::domain_error(std::format(
"Can not evaluate {} '-' {}", repr(lhs), repr(rhs)));
1300 [[nodiscard]]
friend constexpr datum
operator*(datum
const& lhs, datum
const& rhs)
1303 return datum{doubles.lhs() * doubles.rhs()};
1306 return datum{long_longs.lhs() * long_longs.rhs()};
1309 throw std::domain_error(std::format(
"Can not evaluate {} '*' {}", repr(lhs), repr(rhs)));
1324 [[nodiscard]]
friend constexpr datum operator/(datum
const& lhs, datum
const& rhs)
1327 if (doubles.rhs() == 0) {
1328 throw std::domain_error(std::format(
"Divide by zero {} '/' {}", repr(lhs), repr(rhs)));
1330 return datum{doubles.lhs() / doubles.rhs()};
1333 if (long_longs.rhs() == 0) {
1334 throw std::domain_error(std::format(
"Divide by zero {} '/' {}", repr(lhs), repr(rhs)));
1336 return datum{long_longs.lhs() / long_longs.rhs()};
1339 throw std::domain_error(std::format(
"Can not evaluate {} '/' {}", repr(lhs), repr(rhs)));
1354 [[nodiscard]]
friend constexpr datum operator%(datum
const& lhs, datum
const& rhs)
1357 if (long_longs.rhs() == 0) {
1358 throw std::domain_error(std::format(
"Divide by zero {} '%' {}", repr(lhs), repr(rhs)));
1360 return datum{long_longs.lhs() % long_longs.rhs()};
1363 throw std::domain_error(std::format(
"Can not evaluate {} '%' {}", repr(lhs), repr(rhs)));
1377 [[nodiscard]]
friend constexpr datum
pow(datum
const& lhs, datum
const& rhs)
1380 return datum{
pow(doubles.lhs(), doubles.rhs())};
1383 return datum{
pow(long_longs.lhs(), long_longs.rhs())};
1386 throw std::domain_error(std::format(
"Can not evaluate pow({}, {})", repr(lhs), repr(rhs)));
1400 [[nodiscard]]
friend constexpr datum operator&(datum
const& lhs, datum
const& rhs)
1403 return datum{long_longs.lhs() & long_longs.rhs()};
1406 return datum{bools.lhs() and bools.rhs()};
1409 throw std::domain_error(std::format(
"Can not evaluate {} '&' {}", repr(lhs), repr(rhs)));
1423 [[nodiscard]]
friend constexpr datum operator|(datum
const& lhs, datum
const& rhs)
1426 return datum{long_longs.lhs() | long_longs.rhs()};
1429 return datum{bools.lhs() or bools.rhs()};
1432 throw std::domain_error(std::format(
"Can not evaluate {} '|' {}", repr(lhs), repr(rhs)));
1446 [[nodiscard]]
friend constexpr datum operator^(datum
const& lhs, datum
const& rhs)
1449 return datum{long_longs.lhs() ^ long_longs.rhs()};
1452 return datum{bools.lhs() != bools.rhs()};
1455 throw std::domain_error(std::format(
"Can not evaluate {} '^' {}", repr(lhs), repr(rhs)));
1471 [[nodiscard]]
friend constexpr datum operator<<(datum
const& lhs, datum
const& rhs)
1474 if (long_longs.rhs() < 0 or long_longs.rhs() > (
sizeof(
long long) * CHAR_BIT - 1)) {
1475 throw std::domain_error(std::format(
"Invalid shift count {} '<<' {}", repr(lhs), repr(rhs)));
1477 return datum{long_longs.lhs() << long_longs.rhs()};
1480 throw std::domain_error(std::format(
"Can not evaluate {} '<<' {}", repr(lhs), repr(rhs)));
1495 [[nodiscard]]
friend constexpr datum operator>>(datum
const& lhs, datum
const& rhs)
1498 if (long_longs.rhs() < 0 or long_longs.rhs() > (
sizeof(
long long) * CHAR_BIT - 1)) {
1499 throw std::domain_error(std::format(
"Invalid shift count {} '>>' {}", repr(lhs), repr(rhs)));
1501 return datum{long_longs.lhs() >> long_longs.rhs()};
1504 throw std::domain_error(std::format(
"Can not evaluate {} '>>' {}", repr(lhs), repr(rhs)));
1508 friend std::ostream& operator<<(std::ostream& lhs, datum
const& rhs)
1514 template<typename RHS> \
1515 [[nodiscard]] friend constexpr auto operator op(datum const& lhs, RHS&& rhs) \
1516 requires( requires { datum{std::forward<RHS>(rhs)}; } and not std::same_as<std::remove_cvref_t<RHS>, datum>) \
1518 return lhs op datum{std::forward<RHS>(rhs)}; \
1520 template<typename LHS> \
1521 [[nodiscard]] friend constexpr auto operator op(LHS&& lhs, datum const& rhs) \
1522 requires( requires { datum{std::forward<LHS>(lhs)}; } and not std::same_as<std::remove_cvref_t<LHS>, datum>) \
1524 return datum{std::forward<LHS>(lhs)} op rhs; \
1543 [[nodiscard]]
friend std::string repr(datum
const& rhs)
noexcept
1546 case tag_type::monostate:
1548 case tag_type::floating_point:
1549 return std::format(
"{:.1f}", rhs._value._double);
1550 case tag_type::integral:
1551 return std::format(
"{}", rhs._value._long_long);
1552 case tag_type::boolean:
1553 return rhs._value._bool ?
"true" :
"false";
1554 case tag_type::year_month_day:
1555 return std::format(
"{:%Y-%m-%d}", rhs._value._year_month_day);
1556 case tag_type::null:
1558 case tag_type::flow_break:
1560 case tag_type::flow_continue:
1562 case tag_type::string:
1563 return std::format(
"\"{}\"", *rhs._value._string);
1564 case tag_type::vector:
1566 auto r = std::string{
"["};
1567 for (
auto const& item : *rhs._value._vector) {
1576 auto r = std::string{
"{"};
1577 for (
auto const& item : *rhs._value._map) {
1578 r += repr(item.first);
1580 r += repr(item.second);
1586 case tag_type::bstring:
1587 return base64::encode(*rhs._value._bstring);
1606 template<
typename T>
1609 if constexpr (std::is_same_v<T, double>) {
1610 return rhs._tag == tag_type::floating_point;
1611 }
else if constexpr (std::is_same_v<T, long long>) {
1612 return rhs._tag == tag_type::integral;
1613 }
else if constexpr (std::is_same_v<T, bool>) {
1614 return rhs._tag == tag_type::boolean;
1615 }
else if constexpr (std::is_same_v<T, std::chrono::year_month_day>) {
1616 return rhs._tag == tag_type::year_month_day;
1617 }
else if constexpr (std::is_same_v<T, nullptr_t>) {
1618 return rhs._tag == tag_type::null;
1619 }
else if constexpr (std::is_same_v<T, std::monostate>) {
1620 return rhs._tag == tag_type::monostate;
1621 }
else if constexpr (std::is_same_v<T, break_type>) {
1622 return rhs._tag == tag_type::flow_break;
1623 }
else if constexpr (std::is_same_v<T, continue_type>) {
1624 return rhs._tag == tag_type::flow_continue;
1625 }
else if constexpr (std::is_same_v<T, std::string>) {
1626 return rhs._tag == tag_type::string;
1627 }
else if constexpr (std::is_same_v<T, vector_type>) {
1628 return rhs._tag == tag_type::vector;
1629 }
else if constexpr (std::is_same_v<T, map_type>) {
1630 return rhs._tag == tag_type::map;
1631 }
else if constexpr (std::is_same_v<T, bstring>) {
1632 return rhs._tag == tag_type::bstring;
1634 hi_static_no_default();
1647 template<
typename To>
1648 [[nodiscard]]
friend constexpr bool promotable_to(
datum const& rhs)
noexcept
1650 if constexpr (std::is_same_v<To, double>) {
1652 }
else if constexpr (std::is_same_v<To, long long>) {
1667 template<
typename T>
1668 [[nodiscard]]
friend constexpr T
const&
get(datum
const& rhs)
noexcept
1671 if constexpr (std::is_same_v<T, double>) {
1672 return rhs._value._double;
1673 }
else if constexpr (std::is_same_v<T, long long>) {
1674 return rhs._value._long_long;
1675 }
else if constexpr (std::is_same_v<T, bool>) {
1676 return rhs._value._bool;
1677 }
else if constexpr (std::is_same_v<T, std::chrono::year_month_day>) {
1678 return rhs._value._year_month_day;
1679 }
else if constexpr (std::is_same_v<T, std::string>) {
1680 return *rhs._value._string;
1681 }
else if constexpr (std::is_same_v<T, vector_type>) {
1682 return *rhs._value._vector;
1683 }
else if constexpr (std::is_same_v<T, map_type>) {
1684 return *rhs._value._map;
1685 }
else if constexpr (std::is_same_v<T, bstring>) {
1686 return *rhs._value._bstring;
1688 hi_static_no_default();
1700 template<
typename T>
1701 [[nodiscard]]
friend constexpr T&
get(datum& rhs)
noexcept
1704 if constexpr (std::is_same_v<T, double>) {
1705 return rhs._value._double;
1706 }
else if constexpr (std::is_same_v<T, long long>) {
1707 return rhs._value._long_long;
1708 }
else if constexpr (std::is_same_v<T, bool>) {
1709 return rhs._value._bool;
1710 }
else if constexpr (std::is_same_v<T, std::chrono::year_month_day>) {
1711 return rhs._value._year_month_day;
1712 }
else if constexpr (std::is_same_v<T, std::string>) {
1713 return *rhs._value._string;
1714 }
else if constexpr (std::is_same_v<T, vector_type>) {
1715 return *rhs._value._vector;
1716 }
else if constexpr (std::is_same_v<T, map_type>) {
1717 return *rhs._value._map;
1718 }
else if constexpr (std::is_same_v<T, bstring>) {
1719 return *rhs._value._bstring;
1721 hi_static_no_default();
1733 template<
typename T>
1734 [[nodiscard]]
friend constexpr T*
get_if(datum& rhs)
noexcept
1751 template<
typename T>
1752 [[nodiscard]]
friend constexpr T
const*
get_if(datum
const& rhs)
noexcept
1770 template<
typename T>
1773 if (
auto* value = rhs.find_one(path)) {
1793 template<
typename T>
1794 [[nodiscard]]
friend T
const*
get_if(datum
const& rhs,
jsonpath const& path)
noexcept
1796 if (
auto* value =
const_cast<datum&
>(rhs).
find_one(path)) {
1808 enum class tag_type :
signed char {
1826 tag_type _tag = tag_type::monostate;
1829 long long _long_long;
1831 std::chrono::year_month_day _year_month_day;
1833 vector_type* _vector;
1837 constexpr value_type(numeric_integral
auto value) noexcept : _long_long(
narrow_cast<long long>(value)) {}
1838 constexpr value_type(std::floating_point
auto value) noexcept : _double(
narrow_cast<double>(value)) {}
1839 constexpr value_type(
bool value) noexcept : _bool(value) {}
1840 constexpr value_type(std::chrono::year_month_day value) noexcept : _year_month_day(value) {}
1841 constexpr value_type(std::string* value) noexcept : _string(value) {}
1842 constexpr value_type(vector_type* value) noexcept : _vector(value) {}
1843 constexpr value_type(map_type* value) noexcept : _map(value) {}
1844 constexpr value_type(bstring* value) noexcept : _bstring(value) {}
1849 [[nodiscard]]
constexpr bool is_scalar() const noexcept
1851 return std::to_underlying(_tag) >= 0;
1854 [[nodiscard]]
constexpr bool is_pointer() const noexcept
1856 return std::to_underlying(_tag) < 0;
1859 hi_no_inline
void copy_pointer(datum
const&
other)
noexcept
1861 hi_axiom(
other.is_pointer());
1862 switch (
other._tag) {
1863 case tag_type::string:
1864 _value._string =
new std::string{*
other._value._string};
1866 case tag_type::vector:
1867 _value._vector =
new vector_type{*
other._value._vector};
1870 _value._map =
new map_type{*
other._value._map};
1872 case tag_type::bstring:
1873 _value._bstring =
new bstring{*
other._value._bstring};
1880 hi_no_inline
void _delete_pointer() noexcept
1882 hi_axiom(is_pointer());
1884 case tag_type::string:
1885 delete _value._string;
1887 case tag_type::vector:
1888 delete _value._vector;
1893 case tag_type::bstring:
1894 delete _value._bstring;
1901 constexpr void delete_pointer() noexcept
1908 void find_wildcard(jsonpath::const_iterator it, jsonpath::const_iterator it_end, std::vector<datum*>& r)
noexcept
1911 for (
auto& item : *vector) {
1912 item.find(it + 1, it_end, r);
1916 for (
auto& item : *map) {
1917 item.second.find(it + 1, it_end, r);
1922 void find_descend(jsonpath::const_iterator it, jsonpath::const_iterator it_end, std::vector<datum*>& r)
noexcept
1924 this->find(it + 1, it_end, r);
1927 for (
auto& item : *vector) {
1928 item.find(it, it_end, r);
1932 for (
auto& item : *map) {
1933 item.second.find(it, it_end, r);
1939 jsonpath::indices
const& indices,
1940 jsonpath::const_iterator it,
1941 jsonpath::const_iterator it_end,
1942 std::vector<datum*>& r)
noexcept
1945 for (
auto const index : indices.filter(ssize(*vector))) {
1946 (*vector)[index].find(it + 1, it_end, r);
1952 jsonpath::names
const& names,
1953 jsonpath::const_iterator it,
1954 jsonpath::const_iterator it_end,
1955 std::vector<datum*>& r)
noexcept
1958 for (
auto const& name : names) {
1959 auto const name_ = datum{name};
1960 auto jt = map->find(name_);
1961 if (jt != map->cend()) {
1962 jt->second.find(it + 1, it_end, r);
1969 jsonpath::slice
const& slice,
1970 jsonpath::const_iterator it,
1971 jsonpath::const_iterator it_end,
1972 std::vector<datum*>& r)
noexcept
1975 auto const first = slice.begin(vector->size());
1976 auto const last = slice.end(vector->size());
1978 for (
auto index = first; index != last; index += slice.step) {
1979 if (index >= 0 and index < vector->size()) {
1980 (*this)[index].find(it + 1, it_end, r);
1986 void find(jsonpath::const_iterator it, jsonpath::const_iterator it_end, std::vector<datum*>& r)
noexcept
1991 }
else if (std::holds_alternative<jsonpath::root>(*it)) {
1992 find(it + 1, it_end, r);
1994 }
else if (std::holds_alternative<jsonpath::current>(*it)) {
1995 find(it + 1, it_end, r);
1997 }
else if (std::holds_alternative<jsonpath::wildcard>(*it)) {
1998 find_wildcard(it, it_end, r);
2000 }
else if (std::holds_alternative<jsonpath::descend>(*it)) {
2001 find_descend(it, it_end, r);
2003 }
else if (
auto indices = std::get_if<jsonpath::indices>(&*it)) {
2004 find_indices(*indices, it, it_end, r);
2006 }
else if (
auto names = std::get_if<jsonpath::names>(&*it)) {
2007 find_names(*names, it, it_end, r);
2009 }
else if (
auto slice = std::get_if<jsonpath::slice>(&*it)) {
2010 find_slice(*slice, it, it_end, r);
2017 [[nodiscard]]
int remove_wildcard(jsonpath::const_iterator it, jsonpath::const_iterator it_end)
noexcept
2022 auto jt = vector->begin();
2023 while (jt != vector->end()) {
2024 auto const match = jt->remove(it + 1, it_end);
2028 jt = vector->erase(jt);
2033 return vector->empty() ? 2 : r;
2036 auto jt = map->begin();
2037 while (jt != map->end()) {
2038 auto const match = jt->second.remove(it + 1, it_end);
2042 jt = map->erase(jt);
2047 return map->empty() ? 2 : r;
2054 [[nodiscard]]
int remove_descend(jsonpath::const_iterator it, jsonpath::const_iterator it_end)
noexcept
2059 auto const match = this->
remove(it + 1, it_end);
2067 auto jt = vector->begin();
2068 while (jt != vector->end()) {
2069 auto const match = jt->remove(it, it_end);
2073 jt = vector->erase(jt);
2078 return vector->empty() ? 2 : r;
2081 auto jt = map->begin();
2082 while (jt != map->end()) {
2083 auto const match = jt->second.remove(it, it_end);
2087 jt = map->erase(jt);
2092 return map->empty() ? 2 : r;
2100 remove_indices(jsonpath::indices
const& indices, jsonpath::const_iterator it, jsonpath::const_iterator it_end)
noexcept
2104 std::size_t offset = 0;
2106 for (
auto const index : indices.filter(ssize(*vector))) {
2107 auto const match = (*vector)[index - offset].remove(it + 1, it_end);
2110 vector->erase(vector->begin() + (index - offset));
2115 return vector->empty() ? 2 : r;
2123 remove_names(jsonpath::names
const& names, jsonpath::const_iterator it, jsonpath::const_iterator it_end)
noexcept
2128 for (
auto const& name : names) {
2129 auto const name_ = datum{name};
2130 auto jt = map->find(name_);
2131 if (jt != map->cend()) {
2132 auto const match = jt->second.remove(it + 1, it_end);
2140 return map->empty() ? 2 : r;
2148 remove_slice(jsonpath::slice
const& slice, jsonpath::const_iterator it, jsonpath::const_iterator it_end)
noexcept
2153 auto const first = slice.begin(vector->size());
2154 auto const last = slice.end(vector->size());
2156 std::size_t offset = 0;
2157 for (
auto index = first; index != last; index += slice.step) {
2158 if (index >= 0 and index < vector->size()) {
2159 auto const match = (*this)[index - offset].remove(it + 1, it_end);
2163 vector->erase(vector->begin() + (index - offset));
2169 return vector->empty() ? 2 : r;
2176 [[nodiscard]]
int remove(jsonpath::const_iterator it, jsonpath::const_iterator it_end)
noexcept
2182 }
else if (std::holds_alternative<jsonpath::root>(*it)) {
2183 return remove(it + 1, it_end);
2185 }
else if (std::holds_alternative<jsonpath::current>(*it)) {
2186 return remove(it + 1, it_end);
2188 }
else if (std::holds_alternative<jsonpath::wildcard>(*it)) {
2189 return remove_wildcard(it, it_end);
2191 }
else if (std::holds_alternative<jsonpath::descend>(*it)) {
2192 return remove_descend(it, it_end);
2194 }
else if (
auto indices = std::get_if<jsonpath::indices>(&*it)) {
2195 return remove_indices(*indices, it, it_end);
2197 }
else if (
auto names = std::get_if<jsonpath::names>(&*it)) {
2198 return remove_names(*names, it, it_end);
2200 }
else if (
auto slice = std::get_if<jsonpath::slice>(&*it)) {
2201 return remove_slice(*slice, it, it_end);
2208 [[nodiscard]] datum*
2209 find_one_name(datum
const& name, jsonpath::const_iterator it, jsonpath::const_iterator it_end,
bool create)
noexcept
2214 auto i = map->find(name);
2215 if (i != map->end()) {
2216 return i->second.find_one(it + 1, it_end,
create);
2219 (*map)[name] = datum{std::monostate{}};
2220 return find_one_name(name, it, it_end,
create);
2227 *
this = datum::make_map(name, std::monostate{});
2228 return find_one_name(name, it, it_end,
create);
2235 [[nodiscard]] datum*
2236 find_one_index(std::size_t index, jsonpath::const_iterator it, jsonpath::const_iterator it_end,
bool create)
noexcept
2239 if (index < vector->size()) {
2240 return (*vector)[index].find_one(it + 1, it_end,
create);
2241 }
else if (index == vector->size() and
create) {
2242 vector->push_back(datum{std::monostate{}});
2243 return find_one_index(index, it, it_end,
create);
2249 *
this = datum::make_vector(std::monostate{});
2250 return find_one_index(index, it, it_end,
create);
2257 [[nodiscard]] datum*
find_one(jsonpath::const_iterator it, jsonpath::const_iterator it_end,
bool create)
noexcept
2262 }
else if (std::holds_alternative<jsonpath::root>(*it)) {
2265 }
else if (std::holds_alternative<jsonpath::current>(*it)) {
2268 }
else if (
auto const* indices = std::get_if<jsonpath::indices>(&*it)) {
2269 hi_axiom(indices->size() == 1);
2270 return find_one_index(indices->front(), it, it_end,
create);
2272 }
else if (
auto const* names = std::get_if<jsonpath::names>(&*it)) {
2273 hi_axiom(names->size() == 1);
2274 return find_one_name(datum{names->front()}, it, it_end,
create);