223 template<
typename To>
224 [[nodiscard]]
friend constexpr auto promote_if(datum
const& lhs, datum
const& rhs)
noexcept
231 r.set(
get<To>(lhs),
static_cast<To
>(rhs));
234 r.set(
static_cast<To
>(lhs),
get<To>(rhs));
240 constexpr ~datum() noexcept
247 if (
other.is_pointer()) {
252 constexpr datum(datum&&
other) noexcept : _tag(
other._tag), _value(
other._value)
254 other._tag = tag_type::monostate;
255 other._value._long_long = 0;
258 constexpr datum() noexcept : _tag(tag_type::monostate), _value(0) {}
259 constexpr explicit datum(std::monostate) noexcept : _tag(tag_type::monostate), _value(0) {}
260 constexpr explicit datum(nullptr_t) noexcept : _tag(tag_type::null), _value(0) {}
261 constexpr explicit datum(
continue_type) noexcept : _tag(tag_type::flow_continue), _value(0) {}
262 constexpr explicit datum(
break_type) noexcept : _tag(tag_type::flow_break), _value(0) {}
263 constexpr explicit datum(
bool value) noexcept : _tag(tag_type::boolean), _value(value) {}
264 constexpr explicit datum(std::floating_point
auto value) noexcept :
269 constexpr explicit datum(numeric_integral
auto value) noexcept :
274 constexpr explicit datum(std::chrono::year_month_day value) noexcept : _tag(tag_type::year_month_day), _value(value) {}
275 explicit datum(std::string value) noexcept : _tag(tag_type::string), _value(
new std::string{
std::move(value)}) {}
276 explicit datum(std::string_view value) noexcept : _tag(tag_type::string), _value(
new std::string{value}) {}
277 explicit datum(
char const *value) noexcept : _tag(tag_type::string), _value(
new std::string{value}) {}
278 explicit datum(vector_type value) noexcept : _tag(tag_type::vector), _value(
new vector_type{
std::move(value)}) {}
279 explicit datum(map_type value) noexcept : _tag(tag_type::map), _value(
new map_type{
std::move(value)}) {}
280 explicit datum(bstring value) noexcept : _tag(tag_type::bstring), _value(
new bstring{
std::move(value)}) {}
282 template<
typename... Args>
283 [[nodiscard]]
static datum make_vector(Args
const&...args)
noexcept
285 return datum{vector_type{datum{args}...}};
288 template<
typename Key,
typename Value,
typename... Args>
289 static void populate_map(map_type& r, Key
const& key, Value
const& value, Args
const&...args)
noexcept
291 r.insert(std::pair<datum, datum>{datum{key}, datum{value}});
292 if constexpr (
sizeof...(Args) > 0) {
293 populate_map(r, args...);
297 template<
typename... Args>
298 [[nodiscard]]
static datum make_map(Args
const&...args)
noexcept
300 static_assert(
sizeof...(Args) % 2 == 0,
"Expect key value pairs for the arguments of make_map()");
303 if constexpr (
sizeof...(Args) > 0) {
304 populate_map(r, args...);
309 [[nodiscard]]
static datum make_break() noexcept
314 [[nodiscard]]
static datum make_continue() noexcept
319 constexpr datum& operator=(datum
const&
other)
noexcept
321 hi_return_on_self_assignment(
other);
325 _value =
other._value;
326 if (
other.is_pointer()) {
332 constexpr datum& operator=(datum&&
other)
noexcept
339 constexpr datum& operator=(std::floating_point
auto value)
noexcept(
sizeof(value) <= 4)
342 _tag = tag_type::floating_point;
343 _value =
static_cast<double>(value);
347 constexpr datum& operator=(numeric_integral
auto value)
noexcept(
sizeof(value) <= 4)
350 _tag = tag_type::integral;
351 _value =
static_cast<long long>(value);
355 constexpr datum& operator=(
bool value)
noexcept
358 _tag = tag_type::boolean;
363 constexpr datum& operator=(std::chrono::year_month_day value)
noexcept
366 _tag = tag_type::year_month_day;
371 constexpr datum& operator=(std::monostate)
noexcept
374 _tag = tag_type::monostate;
379 constexpr datum& operator=(nullptr_t)
noexcept
382 _tag = tag_type::null;
387 datum& operator=(std::string value)
noexcept
390 _tag = tag_type::string;
391 _value =
new std::string{
std::move(value)};
395 datum& operator=(
char const *value)
noexcept
398 _tag = tag_type::string;
399 _value =
new std::string{value};
403 datum& operator=(std::string_view value)
noexcept
406 _tag = tag_type::string;
407 _value =
new std::string{value};
411 datum& operator=(vector_type value)
noexcept
414 _tag = tag_type::vector;
415 _value =
new vector_type{
std::move(value)};
419 datum& operator=(map_type value)
noexcept
422 _tag = tag_type::map;
427 datum& operator=(bstring value)
noexcept
430 _tag = tag_type::bstring;
435 constexpr explicit operator bool() const noexcept
438 case tag_type::floating_point:
440 case tag_type::boolean:
442 case tag_type::integral:
444 case tag_type::year_month_day:
446 case tag_type::string:
448 case tag_type::vector:
452 case tag_type::bstring:
459 [[nodiscard]]
constexpr bool empty()
const
462 case tag_type::string:
464 case tag_type::vector:
468 case tag_type::bstring:
471 throw std::domain_error(std::format(
"Type {} can not be checked for empty", repr(*
this)));
475 template<std::
floating_po
int T>
476 constexpr explicit operator T()
const
479 case tag_type::floating_point:
481 case tag_type::integral:
483 case tag_type::boolean:
486 throw std::domain_error(std::format(
"Can't convert {} to floating point", repr(*
this)));
490 template<numeric_
integral T>
491 constexpr explicit operator T()
const
498 throw std::overflow_error(
"double to integral");
500 return round_cast<T>(r);
504 throw std::overflow_error(
"long long to integral");
512 throw std::domain_error(std::format(
"Can't convert {} to an integral", repr(*
this)));
516 constexpr explicit operator std::chrono::year_month_day()
const
521 throw std::domain_error(std::format(
"Can't convert {} to an std::chrono::year_month_day", repr(*
this)));
525 explicit operator std::string() const noexcept
528 case tag_type::monostate:
530 case tag_type::floating_point:
531 return hi::to_string(_value._double);
532 case tag_type::integral:
534 case tag_type::boolean:
535 return _value._bool ?
"true" :
"false";
536 case tag_type::year_month_day:
537 return std::format(
"{:%Y-%m-%d}", _value._year_month_day);
540 case tag_type::flow_break:
542 case tag_type::flow_continue:
544 case tag_type::string:
545 return *_value._string;
546 case tag_type::vector:
548 auto r = std::string{
"["};
549 for (
auto const& item : *_value._vector) {
558 auto r = std::string{
"{"};
559 for (
auto const& item : *_value._map) {
560 r += repr(item.first);
562 r += repr(item.second);
568 case tag_type::bstring:
569 return base64::encode(*_value._bstring);
575 explicit operator std::string_view()
const
578 return std::string_view{*s};
580 throw std::domain_error(std::format(
"Can't convert {} to an std::string_view", repr(*
this)));
584 explicit operator vector_type()
const
589 throw std::domain_error(std::format(
"Can't convert {} to an vector", repr(*
this)));
593 explicit operator map_type()
const
598 throw std::domain_error(std::format(
"Can't convert {} to an map", repr(*
this)));
602 explicit operator bstring()
const
605 if (_tag != tag_type::bstring) {
606 throw std::domain_error(std::format(
"Can't convert {} to an bstring", repr(*
this)));
611 [[nodiscard]]
constexpr char const *type_name() const noexcept
614 case tag_type::floating_point:
616 case tag_type::integral:
618 case tag_type::boolean:
620 case tag_type::year_month_day:
622 case tag_type::string:
624 case tag_type::vector:
628 case tag_type::bstring:
639 return _tag == tag_type::monostate;
645 [[nodiscard]]
constexpr bool is_break() const noexcept
647 return _tag == tag_type::flow_break;
655 return _tag == tag_type::flow_continue;
661 case tag_type::floating_point:
663 case tag_type::integral:
665 case tag_type::boolean:
667 case tag_type::year_month_day:
673 return std::hash<uint32_t>{}(r);
675 case tag_type::string:
676 return std::hash<std::string>{}(*_value._string);
677 case tag_type::vector:
680 for (
auto const& v : *_value._vector) {
681 r = hash_mix(r, v.hash());
688 for (
auto const& kv : *_value._map) {
689 r = hash_mix(r, kv.first.hash(), kv.second.hash());
693 case tag_type::bstring:
694 return std::hash<bstring>{}(*_value._bstring);
700 [[nodiscard]]
constexpr std::size_t size()
const
711 throw std::domain_error(std::format(
"Can not evaluate {}.size()", repr(*
this)));
715 [[nodiscard]]
constexpr friend std::size_t size(datum
const& rhs)
720 [[nodiscard]]
constexpr datum
const& back()
const
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& back()
736 throw std::domain_error(std::format(
"Empty vector {}.back()", repr(*
this)));
740 throw std::domain_error(std::format(
"Can not evaluate {}.back()", repr(*
this)));
744 [[nodiscard]]
constexpr datum
const& front()
const
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 datum& front()
760 throw std::domain_error(std::format(
"Empty vector {}.front()", repr(*
this)));
764 throw std::domain_error(std::format(
"Can not evaluate {}.front()", repr(*
this)));
768 [[nodiscard]]
constexpr auto cbegin()
const
773 throw std::domain_error(std::format(
"Can not evaluate {}.cbegin()", repr(*
this)));
777 [[nodiscard]]
constexpr auto begin()
const
782 throw std::domain_error(std::format(
"Can not evaluate {}.begin()", repr(*
this)));
786 [[nodiscard]]
constexpr auto begin()
791 throw std::domain_error(std::format(
"Can not evaluate {}.begin()", repr(*
this)));
795 [[nodiscard]]
constexpr auto cend()
const
800 throw std::domain_error(std::format(
"Can not evaluate {}.cend()", repr(*
this)));
804 [[nodiscard]]
constexpr auto end()
const
809 throw std::domain_error(std::format(
"Can not evaluate {}.end()", repr(*
this)));
813 [[nodiscard]]
constexpr auto end()
818 throw std::domain_error(std::format(
"Can not evaluate {}.end()", repr(*
this)));
824 [[nodiscard]] vector_type
keys()
const
827 auto r = vector_type{};
828 r.reserve(m->size());
829 for (
auto const& kv : *m) {
830 r.push_back(kv.first);
843 auto r = vector_type{};
844 r.reserve(m->size());
845 for (
auto const& kv : *m) {
846 r.push_back(kv.second);
850 throw std::domain_error(std::format(
"Can not evaluate {}.values()", repr(*
this)));
856 [[nodiscard]] vector_type
items()
const
859 auto r = vector_type{};
860 r.reserve(m->size());
862 for (
auto const& item : *m) {
863 r.push_back(make_vector(item.first, item.second));
867 throw std::domain_error(std::format(
"Can not evaluate {}.items()", repr(*
this)));
871 constexpr void push_back(
datum const& rhs)
873 if (
auto *v = get_if<vector_type>(*
this)) {
874 return v->push_back(rhs);
876 throw std::domain_error(std::format(
"Can not evaluate {}.push_back({})", repr(*
this), repr(rhs)));
880 constexpr void push_back(datum&& rhs)
885 throw std::domain_error(std::format(
"Can not evaluate {}.push_back({})", repr(*
this), repr(rhs)));
889 template<
typename Arg>
890 constexpr void push_back(Arg&& arg)
895 constexpr void pop_back()
899 throw std::domain_error(std::format(
"Empty vector {}.pop_back()", repr(*
this)));
901 return v->pop_back();
903 throw std::domain_error(std::format(
"Can not evaluate {}.pop_back()", repr(*
this)));
907 [[nodiscard]]
constexpr bool contains(datum
const& rhs)
const
910 return m->contains(rhs);
912 throw std::domain_error(std::format(
"Can not evaluate {}.contains({})", repr(*
this), repr(rhs)));
916 template<
typename Arg>
917 [[nodiscard]]
constexpr bool contains(Arg
const& arg)
const
919 return contains(datum{arg});
922 [[nodiscard]] std::vector<datum *> find(jsonpath
const& path)
noexcept
924 auto r = std::vector<datum *>{};
925 find(path.cbegin(), path.cend(), r);
929 [[nodiscard]] std::vector<datum const *> find(jsonpath
const& path)
const noexcept
931 auto tmp = std::vector<datum *>{};
932 const_cast<datum *
>(
this)->find(path.cbegin(), path.cend(), tmp);
933 auto r = std::vector<datum const *>{};
948 return to_bool(
remove(path.cbegin(), path.cend()));
958 hi_axiom(path.is_singular());
959 return find_one(path.cbegin(), path.cend(),
false);
969 hi_axiom(path.is_singular());
970 return find_one(path.cbegin(), path.cend(),
true);
980 hi_axiom(path.is_singular());
981 return const_cast<datum *
>(
this)->
find_one(path.cbegin(), path.cend(),
false);
984 [[nodiscard]]
datum const& operator[](
datum const& rhs)
const
991 index = ssize(v) + index;
993 if (index < 0 or index >= ssize(v)) {
1001 auto const it = m.find(rhs);
1002 if (it == m.end()) {
1003 throw std::overflow_error(std::format(
"Key {} not found in map", repr(rhs)));
1009 throw std::domain_error(std::format(
"Can not evaluate {}[{}]", repr(*
this), repr(rhs)));
1013 [[nodiscard]]
constexpr datum& operator[](datum
const& rhs)
1020 index = ssize(v) + index;
1022 if (index < 0 or index >= ssize(v)) {
1023 throw std::overflow_error(std::format(
"Index {} beyond bounds of vector", repr(rhs)));
1033 throw std::domain_error(std::format(
"Can not evaluate {}[{}]", repr(*
this), repr(rhs)));
1037 [[nodiscard]]
constexpr datum
const& operator[](
auto const& rhs)
const
1039 return (*
this)[datum{rhs}];
1042 [[nodiscard]]
constexpr datum& operator[](
auto const& rhs)
1044 return (*
this)[datum{rhs}];
1047 [[nodiscard]]
constexpr datum& operator++()
1050 ++_value._long_long;
1053 throw std::domain_error(std::format(
"Can not evaluate ++{}", repr(*
this)));
1057 [[nodiscard]]
constexpr datum& operator--()
1060 --_value._long_long;
1063 throw std::domain_error(std::format(
"Can not evaluate --{}", repr(*
this)));
1067 [[nodiscard]]
constexpr datum operator++(
int)
1071 _value._long_long++;
1074 throw std::domain_error(std::format(
"Can not evaluate {}++", repr(*
this)));
1077 [[nodiscard]]
constexpr datum operator--(
int)
1081 _value._long_long--;
1084 throw std::domain_error(std::format(
"Can not evaluate {}--", repr(*
this)));
1088 constexpr datum& operator+=(
auto const& rhs)
1094 return (*
this) = (*this) + rhs;
1098#define X(op, inner_op) \
1099 constexpr datum& operator op(auto const& rhs) \
1101 return (*this) = (*this)inner_op rhs; \
1115 [[nodiscard]]
friend constexpr bool operator==(datum
const& lhs, datum
const& rhs)
noexcept
1118 return doubles.lhs() == doubles.rhs();
1121 return long_longs.lhs() == long_longs.rhs();
1124 return bools.lhs() == bools.rhs();
1127 return ymds.lhs() == ymds.rhs();
1130 return strings.lhs() == strings.rhs();
1133 return vectors.lhs() == vectors.rhs();
1136 return maps.lhs() == maps.rhs();
1139 return lhs._tag == rhs._tag;
1169 [[nodiscard]]
friend constexpr std::partial_ordering operator<=>(datum
const& lhs, datum
const& rhs)
noexcept
1172 return doubles.lhs() <=> doubles.rhs();
1175 return long_longs.lhs() <=> long_longs.rhs();
1178 return bools.lhs() <=> bools.rhs();
1181 return year_month_days.lhs() <=> year_month_days.rhs();
1184 return strings.lhs() <=> strings.rhs();
1187 return vectors.lhs() <=> vectors.rhs();
1190 return maps.lhs() <=> maps.rhs();
1193 return bstrings.lhs() <=> bstrings.rhs();
1196 return lhs._tag <=> rhs._tag;
1210 [[nodiscard]]
friend constexpr datum operator-(datum
const& rhs)
1213 return datum{-*rhs_double};
1216 return datum{-*rhs_long_long};
1219 throw std::domain_error(std::format(
"Can not evaluate -{}", repr(rhs)));
1232 [[nodiscard]]
friend constexpr datum operator~(datum
const& rhs)
1235 return datum{~*rhs_long_long};
1238 throw std::domain_error(std::format(
"Can not evaluate ~{}", repr(rhs)));
1256 [[nodiscard]]
friend constexpr datum operator+(datum
const& lhs, datum
const& rhs)
1259 return datum{doubles.lhs() + doubles.rhs()};
1262 return datum{long_longs.lhs() + long_longs.rhs()};
1265 return datum{strings.lhs() + strings.rhs()};
1268 auto r = vectors.lhs();
1269 r.insert(r.end(), vectors.rhs().begin(), vectors.rhs().end());
1273 throw std::domain_error(std::format(
"Can not evaluate {} '+' {}", repr(lhs), repr(rhs)));
1288 [[nodiscard]]
friend constexpr datum operator-(datum
const& lhs, datum
const& rhs)
1291 return datum{doubles.lhs() - doubles.rhs()};
1294 return datum{long_longs.lhs() - long_longs.rhs()};
1297 throw std::domain_error(std::format(
"Can not evaluate {} '-' {}", repr(lhs), repr(rhs)));
1312 [[nodiscard]]
friend constexpr datum
operator*(datum
const& lhs, datum
const& rhs)
1315 return datum{doubles.lhs() * doubles.rhs()};
1318 return datum{long_longs.lhs() * long_longs.rhs()};
1321 throw std::domain_error(std::format(
"Can not evaluate {} '*' {}", repr(lhs), repr(rhs)));
1336 [[nodiscard]]
friend constexpr datum operator/(datum
const& lhs, datum
const& rhs)
1339 if (doubles.rhs() == 0) {
1340 throw std::domain_error(std::format(
"Divide by zero {} '/' {}", repr(lhs), repr(rhs)));
1342 return datum{doubles.lhs() / doubles.rhs()};
1345 if (long_longs.rhs() == 0) {
1346 throw std::domain_error(std::format(
"Divide by zero {} '/' {}", repr(lhs), repr(rhs)));
1348 return datum{long_longs.lhs() / long_longs.rhs()};
1351 throw std::domain_error(std::format(
"Can not evaluate {} '/' {}", repr(lhs), repr(rhs)));
1366 [[nodiscard]]
friend constexpr datum operator%(datum
const& lhs, datum
const& rhs)
1369 if (long_longs.rhs() == 0) {
1370 throw std::domain_error(std::format(
"Divide by zero {} '%' {}", repr(lhs), repr(rhs)));
1372 return datum{long_longs.lhs() % long_longs.rhs()};
1375 throw std::domain_error(std::format(
"Can not evaluate {} '%' {}", repr(lhs), repr(rhs)));
1389 [[nodiscard]]
friend constexpr datum
pow(datum
const& lhs, datum
const& rhs)
1392 return datum{
pow(doubles.lhs(), doubles.rhs())};
1395 return datum{
pow(long_longs.lhs(), long_longs.rhs())};
1398 throw std::domain_error(std::format(
"Can not evaluate pow({}, {})", repr(lhs), repr(rhs)));
1412 [[nodiscard]]
friend constexpr datum operator&(datum
const& lhs, datum
const& rhs)
1415 return datum{long_longs.lhs() & long_longs.rhs()};
1418 return datum{bools.lhs() and bools.rhs()};
1421 throw std::domain_error(std::format(
"Can not evaluate {} '&' {}", repr(lhs), repr(rhs)));
1435 [[nodiscard]]
friend constexpr datum operator|(datum
const& lhs, datum
const& rhs)
1438 return datum{long_longs.lhs() | long_longs.rhs()};
1441 return datum{bools.lhs() or bools.rhs()};
1444 throw std::domain_error(std::format(
"Can not evaluate {} '|' {}", repr(lhs), repr(rhs)));
1458 [[nodiscard]]
friend constexpr datum operator^(datum
const& lhs, datum
const& rhs)
1461 return datum{long_longs.lhs() ^ long_longs.rhs()};
1464 return datum{bools.lhs() != bools.rhs()};
1467 throw std::domain_error(std::format(
"Can not evaluate {} '^' {}", repr(lhs), repr(rhs)));
1483 [[nodiscard]]
friend constexpr datum operator<<(datum
const& lhs, datum
const& rhs)
1486 if (long_longs.rhs() < 0 or long_longs.rhs() > (
sizeof(
long long) * CHAR_BIT - 1)) {
1487 throw std::domain_error(std::format(
"Invalid shift count {} '<<' {}", repr(lhs), repr(rhs)));
1489 return datum{long_longs.lhs() << long_longs.rhs()};
1492 throw std::domain_error(std::format(
"Can not evaluate {} '<<' {}", repr(lhs), repr(rhs)));
1507 [[nodiscard]]
friend constexpr datum operator>>(datum
const& lhs, datum
const& rhs)
1510 if (long_longs.rhs() < 0 or long_longs.rhs() > (
sizeof(
long long) * CHAR_BIT - 1)) {
1511 throw std::domain_error(std::format(
"Invalid shift count {} '>>' {}", repr(lhs), repr(rhs)));
1513 return datum{long_longs.lhs() >> long_longs.rhs()};
1516 throw std::domain_error(std::format(
"Can not evaluate {} '>>' {}", repr(lhs), repr(rhs)));
1520 friend std::ostream& operator<<(std::ostream& lhs, datum
const& rhs)
1526 [[nodiscard]] friend constexpr auto operator op(datum const& lhs, auto const& rhs) \
1528 return lhs op datum{rhs}; \
1530 [[nodiscard]] friend constexpr auto operator op(auto const& lhs, datum const& rhs) \
1532 return datum{lhs} op rhs; \
1549 [[nodiscard]]
friend std::string repr(datum
const& rhs)
noexcept
1552 case tag_type::monostate:
1554 case tag_type::floating_point:
1555 return std::format(
"{:.1f}", rhs._value._double);
1556 case tag_type::integral:
1557 return std::format(
"{}", rhs._value._long_long);
1558 case tag_type::boolean:
1559 return rhs._value._bool ?
"true" :
"false";
1560 case tag_type::year_month_day:
1561 return std::format(
"{:%Y-%m-%d}", rhs._value._year_month_day);
1562 case tag_type::null:
1564 case tag_type::flow_break:
1566 case tag_type::flow_continue:
1568 case tag_type::string:
1569 return std::format(
"\"{}\"", *rhs._value._string);
1570 case tag_type::vector:
1572 auto r = std::string{
"["};
1573 for (
auto const& item : *rhs._value._vector) {
1582 auto r = std::string{
"{"};
1583 for (
auto const& item : *rhs._value._map) {
1584 r += repr(item.first);
1586 r += repr(item.second);
1592 case tag_type::bstring:
1593 return base64::encode(*rhs._value._bstring);
1612 template<
typename T>
1615 if constexpr (std::is_same_v<T, double>) {
1616 return rhs._tag == tag_type::floating_point;
1617 }
else if constexpr (std::is_same_v<T, long long>) {
1618 return rhs._tag == tag_type::integral;
1619 }
else if constexpr (std::is_same_v<T, bool>) {
1620 return rhs._tag == tag_type::boolean;
1621 }
else if constexpr (std::is_same_v<T, std::chrono::year_month_day>) {
1622 return rhs._tag == tag_type::year_month_day;
1623 }
else if constexpr (std::is_same_v<T, nullptr_t>) {
1624 return rhs._tag == tag_type::null;
1625 }
else if constexpr (std::is_same_v<T, std::monostate>) {
1626 return rhs._tag == tag_type::monostate;
1627 }
else if constexpr (std::is_same_v<T, break_type>) {
1628 return rhs._tag == tag_type::flow_break;
1629 }
else if constexpr (std::is_same_v<T, continue_type>) {
1630 return rhs._tag == tag_type::flow_continue;
1631 }
else if constexpr (std::is_same_v<T, std::string>) {
1632 return rhs._tag == tag_type::string;
1633 }
else if constexpr (std::is_same_v<T, vector_type>) {
1634 return rhs._tag == tag_type::vector;
1635 }
else if constexpr (std::is_same_v<T, map_type>) {
1636 return rhs._tag == tag_type::map;
1637 }
else if constexpr (std::is_same_v<T, bstring>) {
1638 return rhs._tag == tag_type::bstring;
1640 hi_static_no_default();
1653 template<
typename To>
1654 [[nodiscard]]
friend constexpr bool promotable_to(
datum const& rhs)
noexcept
1656 if constexpr (std::is_same_v<To, double>) {
1659 }
else if constexpr (std::is_same_v<To, long long>) {
1674 template<
typename T>
1675 [[nodiscard]]
friend constexpr T
const&
get(datum
const& rhs)
noexcept
1678 if constexpr (std::is_same_v<T, double>) {
1679 return rhs._value._double;
1680 }
else if constexpr (std::is_same_v<T, long long>) {
1681 return rhs._value._long_long;
1682 }
else if constexpr (std::is_same_v<T, bool>) {
1683 return rhs._value._bool;
1684 }
else if constexpr (std::is_same_v<T, std::chrono::year_month_day>) {
1685 return rhs._value._year_month_day;
1686 }
else if constexpr (std::is_same_v<T, std::string>) {
1687 return *rhs._value._string;
1688 }
else if constexpr (std::is_same_v<T, vector_type>) {
1689 return *rhs._value._vector;
1690 }
else if constexpr (std::is_same_v<T, map_type>) {
1691 return *rhs._value._map;
1692 }
else if constexpr (std::is_same_v<T, bstring>) {
1693 return *rhs._value._bstring;
1695 hi_static_no_default();
1707 template<
typename T>
1708 [[nodiscard]]
friend constexpr T&
get(datum& rhs)
noexcept
1711 if constexpr (std::is_same_v<T, double>) {
1712 return rhs._value._double;
1713 }
else if constexpr (std::is_same_v<T, long long>) {
1714 return rhs._value._long_long;
1715 }
else if constexpr (std::is_same_v<T, bool>) {
1716 return rhs._value._bool;
1717 }
else if constexpr (std::is_same_v<T, std::chrono::year_month_day>) {
1718 return rhs._value._year_month_day;
1719 }
else if constexpr (std::is_same_v<T, std::string>) {
1720 return *rhs._value._string;
1721 }
else if constexpr (std::is_same_v<T, vector_type>) {
1722 return *rhs._value._vector;
1723 }
else if constexpr (std::is_same_v<T, map_type>) {
1724 return *rhs._value._map;
1725 }
else if constexpr (std::is_same_v<T, bstring>) {
1726 return *rhs._value._bstring;
1728 hi_static_no_default();
1740 template<
typename T>
1741 [[nodiscard]]
friend constexpr T *
get_if(datum& rhs)
noexcept
1758 template<
typename T>
1759 [[nodiscard]]
friend constexpr T
const *
get_if(datum
const& rhs)
noexcept
1777 template<
typename T>
1780 if (
auto *value = rhs.find_one(path)) {
1800 template<
typename T>
1801 [[nodiscard]]
friend T
const *
get_if(datum
const& rhs,
jsonpath const& path)
noexcept
1803 if (
auto *value =
const_cast<datum&
>(rhs).
find_one(path)) {
1815 enum class tag_type :
signed char {
1833 tag_type _tag = tag_type::monostate;
1836 long long _long_long;
1838 std::chrono::year_month_day _year_month_day;
1840 vector_type *_vector;
1844 constexpr value_type(numeric_integral
auto value) noexcept : _long_long(
narrow_cast<long long>(value)) {}
1845 constexpr value_type(std::floating_point
auto value) noexcept : _double(
narrow_cast<double>(value)) {}
1846 constexpr value_type(
bool value) noexcept : _bool(value) {}
1847 constexpr value_type(std::chrono::year_month_day value) noexcept : _year_month_day(value) {}
1848 constexpr value_type(std::string *value) noexcept : _string(value) {}
1849 constexpr value_type(vector_type *value) noexcept : _vector(value) {}
1850 constexpr value_type(map_type *value) noexcept : _map(value) {}
1851 constexpr value_type(bstring *value) noexcept : _bstring(value) {}
1856 [[nodiscard]]
constexpr bool is_scalar() const noexcept
1858 return std::to_underlying(_tag) >= 0;
1861 [[nodiscard]]
constexpr bool is_pointer() const noexcept
1863 return std::to_underlying(_tag) < 0;
1866 hi_no_inline
void copy_pointer(datum
const&
other)
noexcept
1868 hi_axiom(
other.is_pointer());
1869 switch (
other._tag) {
1870 case tag_type::string:
1871 _value._string =
new std::string{*
other._value._string};
1873 case tag_type::vector:
1874 _value._vector =
new vector_type{*
other._value._vector};
1877 _value._map =
new map_type{*
other._value._map};
1879 case tag_type::bstring:
1880 _value._bstring =
new bstring{*
other._value._bstring};
1887 hi_no_inline
void _delete_pointer() noexcept
1889 hi_axiom(is_pointer());
1891 case tag_type::string:
1892 delete _value._string;
1894 case tag_type::vector:
1895 delete _value._vector;
1900 case tag_type::bstring:
1901 delete _value._bstring;
1908 constexpr void delete_pointer() noexcept
1915 void find_wildcard(jsonpath::const_iterator it, jsonpath::const_iterator it_end, std::vector<datum *>& r)
noexcept
1918 for (
auto& item : *vector) {
1919 item.find(it + 1, it_end, r);
1923 for (
auto& item : *map) {
1924 item.second.find(it + 1, it_end, r);
1929 void find_descend(jsonpath::const_iterator it, jsonpath::const_iterator it_end, std::vector<datum *>& r)
noexcept
1931 this->find(it + 1, it_end, r);
1934 for (
auto& item : *vector) {
1935 item.find(it, it_end, r);
1939 for (
auto& item : *map) {
1940 item.second.find(it, it_end, r);
1946 jsonpath::indices
const& indices,
1947 jsonpath::const_iterator it,
1948 jsonpath::const_iterator it_end,
1949 std::vector<datum *>& r)
noexcept
1952 for (
auto const index : indices.filter(ssize(*vector))) {
1953 (*vector)[index].find(it + 1, it_end, r);
1959 jsonpath::names
const& names,
1960 jsonpath::const_iterator it,
1961 jsonpath::const_iterator it_end,
1962 std::vector<datum *>& r)
noexcept
1965 for (
auto const& name : names) {
1966 auto const name_ = datum{name};
1967 auto jt = map->find(name_);
1968 if (jt != map->cend()) {
1969 jt->second.find(it + 1, it_end, r);
1976 jsonpath::slice
const& slice,
1977 jsonpath::const_iterator it,
1978 jsonpath::const_iterator it_end,
1979 std::vector<datum *>& r)
noexcept
1982 auto const first = slice.begin(vector->size());
1983 auto const last = slice.end(vector->size());
1985 for (
auto index = first; index != last; index += slice.step) {
1986 if (index >= 0 and index < vector->size()) {
1987 (*this)[index].find(it + 1, it_end, r);
1993 void find(jsonpath::const_iterator it, jsonpath::const_iterator it_end, std::vector<datum *>& r)
noexcept
1998 }
else if (std::holds_alternative<jsonpath::root>(*it)) {
1999 find(it + 1, it_end, r);
2001 }
else if (std::holds_alternative<jsonpath::current>(*it)) {
2002 find(it + 1, it_end, r);
2004 }
else if (std::holds_alternative<jsonpath::wildcard>(*it)) {
2005 find_wildcard(it, it_end, r);
2007 }
else if (std::holds_alternative<jsonpath::descend>(*it)) {
2008 find_descend(it, it_end, r);
2010 }
else if (
auto indices = std::get_if<jsonpath::indices>(&*it)) {
2011 find_indices(*indices, it, it_end, r);
2013 }
else if (
auto names = std::get_if<jsonpath::names>(&*it)) {
2014 find_names(*names, it, it_end, r);
2016 }
else if (
auto slice = std::get_if<jsonpath::slice>(&*it)) {
2017 find_slice(*slice, it, it_end, r);
2024 [[nodiscard]]
int remove_wildcard(jsonpath::const_iterator it, jsonpath::const_iterator it_end)
noexcept
2029 auto jt = vector->begin();
2030 while (jt != vector->end()) {
2031 auto const match = jt->remove(it + 1, it_end);
2035 jt = vector->erase(jt);
2040 return vector->empty() ? 2 : r;
2043 auto jt = map->begin();
2044 while (jt != map->end()) {
2045 auto const match = jt->second.remove(it + 1, it_end);
2049 jt = map->erase(jt);
2054 return map->empty() ? 2 : r;
2061 [[nodiscard]]
int remove_descend(jsonpath::const_iterator it, jsonpath::const_iterator it_end)
noexcept
2066 auto const match = this->
remove(it + 1, it_end);
2074 auto jt = vector->begin();
2075 while (jt != vector->end()) {
2076 auto const match = jt->remove(it, it_end);
2080 jt = vector->erase(jt);
2085 return vector->empty() ? 2 : r;
2088 auto jt = map->begin();
2089 while (jt != map->end()) {
2090 auto const match = jt->second.remove(it, it_end);
2094 jt = map->erase(jt);
2099 return map->empty() ? 2 : r;
2107 remove_indices(jsonpath::indices
const& indices, jsonpath::const_iterator it, jsonpath::const_iterator it_end)
noexcept
2111 std::size_t offset = 0;
2113 for (
auto const index : indices.filter(ssize(*vector))) {
2114 auto const match = (*vector)[index - offset].remove(it + 1, it_end);
2117 vector->erase(vector->begin() + (index - offset));
2122 return vector->empty() ? 2 : r;
2130 remove_names(jsonpath::names
const& names, jsonpath::const_iterator it, jsonpath::const_iterator it_end)
noexcept
2135 for (
auto const& name : names) {
2136 auto const name_ = datum{name};
2137 auto jt = map->find(name_);
2138 if (jt != map->cend()) {
2139 auto const match = jt->second.remove(it + 1, it_end);
2147 return map->empty() ? 2 : r;
2155 remove_slice(jsonpath::slice
const& slice, jsonpath::const_iterator it, jsonpath::const_iterator it_end)
noexcept
2160 auto const first = slice.begin(vector->size());
2161 auto const last = slice.end(vector->size());
2163 std::size_t offset = 0;
2164 for (
auto index = first; index != last; index += slice.step) {
2165 if (index >= 0 and index < vector->size()) {
2166 auto const match = (*this)[index - offset].remove(it + 1, it_end);
2170 vector->erase(vector->begin() + (index - offset));
2176 return vector->empty() ? 2 : r;
2183 [[nodiscard]]
int remove(jsonpath::const_iterator it, jsonpath::const_iterator it_end)
noexcept
2189 }
else if (std::holds_alternative<jsonpath::root>(*it)) {
2190 return remove(it + 1, it_end);
2192 }
else if (std::holds_alternative<jsonpath::current>(*it)) {
2193 return remove(it + 1, it_end);
2195 }
else if (std::holds_alternative<jsonpath::wildcard>(*it)) {
2196 return remove_wildcard(it, it_end);
2198 }
else if (std::holds_alternative<jsonpath::descend>(*it)) {
2199 return remove_descend(it, it_end);
2201 }
else if (
auto indices = std::get_if<jsonpath::indices>(&*it)) {
2202 return remove_indices(*indices, it, it_end);
2204 }
else if (
auto names = std::get_if<jsonpath::names>(&*it)) {
2205 return remove_names(*names, it, it_end);
2207 }
else if (
auto slice = std::get_if<jsonpath::slice>(&*it)) {
2208 return remove_slice(*slice, it, it_end);
2215 [[nodiscard]] datum *
2216 find_one_name(datum
const& name, jsonpath::const_iterator it, jsonpath::const_iterator it_end,
bool create)
noexcept
2221 auto i = map->find(name);
2222 if (i != map->end()) {
2223 return i->second.find_one(it + 1, it_end,
create);
2226 (*map)[name] = datum{std::monostate{}};
2227 return find_one_name(name, it, it_end,
create);
2234 *
this = datum::make_map(name, std::monostate{});
2235 return find_one_name(name, it, it_end,
create);
2242 [[nodiscard]] datum *
2243 find_one_index(std::size_t index, jsonpath::const_iterator it, jsonpath::const_iterator it_end,
bool create)
noexcept
2246 if (index < vector->size()) {
2247 return (*vector)[index].find_one(it + 1, it_end,
create);
2248 }
else if (index == vector->size() and
create) {
2249 vector->push_back(datum{std::monostate{}});
2250 return find_one_index(index, it, it_end,
create);
2256 *
this = datum::make_vector(std::monostate{});
2257 return find_one_index(index, it, it_end,
create);
2264 [[nodiscard]] datum *
find_one(jsonpath::const_iterator it, jsonpath::const_iterator it_end,
bool create)
noexcept
2269 }
else if (std::holds_alternative<jsonpath::root>(*it)) {
2272 }
else if (std::holds_alternative<jsonpath::current>(*it)) {
2275 }
else if (
auto const *indices = std::get_if<jsonpath::indices>(&*it)) {
2276 hi_axiom(indices->size() == 1);
2277 return find_one_index(indices->front(), it, it_end,
create);
2279 }
else if (
auto const *names = std::get_if<jsonpath::names>(&*it)) {
2280 hi_axiom(names->size() == 1);
2281 return find_one_name(datum{names->front()}, it, it_end,
create);