225 template<
typename To>
226 [[nodiscard]]
friend constexpr auto promote_if(datum
const& lhs, datum
const& rhs)
noexcept
233 r.set(
get<To>(lhs),
static_cast<To
>(rhs));
236 r.set(
static_cast<To
>(lhs),
get<To>(rhs));
242 constexpr ~datum() noexcept
249 if (
other.is_pointer()) {
254 constexpr datum(datum&&
other) noexcept : _tag(
other._tag), _value(
other._value)
256 other._tag = tag_type::monostate;
257 other._value._long_long = 0;
260 constexpr datum() noexcept : _tag(tag_type::monostate), _value(0) {}
261 constexpr explicit datum(std::monostate) noexcept : _tag(tag_type::monostate), _value(0) {}
262 constexpr explicit datum(nullptr_t) noexcept : _tag(tag_type::null), _value(0) {}
263 constexpr explicit datum(
continue_type) noexcept : _tag(tag_type::flow_continue), _value(0) {}
264 constexpr explicit datum(
break_type) noexcept : _tag(tag_type::flow_break), _value(0) {}
265 constexpr explicit datum(
bool value) noexcept : _tag(tag_type::boolean), _value(value) {}
266 constexpr explicit datum(std::floating_point
auto value) noexcept :
271 constexpr explicit datum(numeric_integral
auto value) noexcept :
276 constexpr explicit datum(decimal value) noexcept : _tag(tag_type::decimal), _value(value) {}
277 constexpr explicit datum(std::chrono::year_month_day value) noexcept : _tag(tag_type::year_month_day), _value(value) {}
278 explicit datum(std::string value) noexcept : _tag(tag_type::string), _value(
new std::string{
std::move(value)}) {}
279 explicit datum(std::string_view value) noexcept : _tag(tag_type::string), _value(
new std::string{value}) {}
280 explicit datum(
char const *value) noexcept : _tag(tag_type::string), _value(
new std::string{value}) {}
281 explicit datum(vector_type value) noexcept : _tag(tag_type::vector), _value(
new vector_type{
std::move(value)}) {}
282 explicit datum(map_type value) noexcept : _tag(tag_type::map), _value(
new map_type{
std::move(value)}) {}
283 explicit datum(bstring value) noexcept : _tag(tag_type::bstring), _value(
new bstring{
std::move(value)}) {}
285 template<
typename... Args>
286 [[nodiscard]]
static datum make_vector(Args
const&...args)
noexcept
288 return datum{vector_type{datum{args}...}};
291 template<
typename Key,
typename Value,
typename... Args>
292 static void populate_map(map_type& r, Key
const& key, Value
const& value, Args
const&...args)
noexcept
294 r.insert(std::pair<datum, datum>{datum{key}, datum{value}});
295 if constexpr (
sizeof...(Args) > 0) {
296 populate_map(r, args...);
300 template<
typename... Args>
301 [[nodiscard]]
static datum make_map(Args
const&...args)
noexcept
303 static_assert(
sizeof...(Args) % 2 == 0,
"Expect key value pairs for the arguments of make_map()");
306 if constexpr (
sizeof...(Args) > 0) {
307 populate_map(r, args...);
312 [[nodiscard]]
static datum make_break() noexcept
317 [[nodiscard]]
static datum make_continue() noexcept
322 constexpr datum& operator=(datum
const&
other)
noexcept
324 hi_return_on_self_assignment(
other);
328 _value =
other._value;
329 if (
other.is_pointer()) {
335 constexpr datum& operator=(datum&&
other)
noexcept
342 constexpr datum& operator=(std::floating_point
auto value)
noexcept(
sizeof(value) <= 4)
345 _tag = tag_type::floating_point;
346 _value =
static_cast<double>(value);
350 constexpr datum& operator=(numeric_integral
auto value)
noexcept(
sizeof(value) <= 4)
353 _tag = tag_type::integral;
354 _value =
static_cast<long long>(value);
358 constexpr datum& operator=(decimal value)
361 _tag = tag_type::decimal;
365 constexpr datum& operator=(
bool value)
noexcept
368 _tag = tag_type::boolean;
373 constexpr datum& operator=(std::chrono::year_month_day value)
noexcept
376 _tag = tag_type::year_month_day;
381 constexpr datum& operator=(std::monostate)
noexcept
384 _tag = tag_type::monostate;
389 constexpr datum& operator=(nullptr_t)
noexcept
392 _tag = tag_type::null;
397 datum& operator=(std::string value)
noexcept
400 _tag = tag_type::string;
401 _value =
new std::string{
std::move(value)};
405 datum& operator=(
char const *value)
noexcept
408 _tag = tag_type::string;
409 _value =
new std::string{value};
413 datum& operator=(std::string_view value)
noexcept
416 _tag = tag_type::string;
417 _value =
new std::string{value};
421 datum& operator=(vector_type value)
noexcept
424 _tag = tag_type::vector;
425 _value =
new vector_type{
std::move(value)};
429 datum& operator=(map_type value)
noexcept
432 _tag = tag_type::map;
437 datum& operator=(bstring value)
noexcept
440 _tag = tag_type::bstring;
445 constexpr explicit operator bool() const noexcept
448 case tag_type::floating_point:
450 case tag_type::decimal:
452 case tag_type::boolean:
454 case tag_type::integral:
456 case tag_type::year_month_day:
458 case tag_type::string:
460 case tag_type::vector:
464 case tag_type::bstring:
471 [[nodiscard]]
constexpr bool empty()
const
474 case tag_type::string:
476 case tag_type::vector:
480 case tag_type::bstring:
483 throw std::domain_error(std::format(
"Type {} can not be checked for empty", *
this));
487 template<std::
floating_po
int T>
488 constexpr explicit operator T()
const
491 case tag_type::floating_point:
493 case tag_type::integral:
495 case tag_type::decimal:
497 case tag_type::boolean:
500 throw std::domain_error(std::format(
"Can't convert {} to floating point", *
this));
504 constexpr explicit operator decimal()
const
507 case tag_type::floating_point:
509 case tag_type::integral:
511 case tag_type::decimal:
513 case tag_type::boolean:
516 throw std::domain_error(std::format(
"Can't convert {} to floating point", *
this));
520 template<numeric_
integral T>
521 constexpr explicit operator T()
const
528 throw std::overflow_error(
"double to integral");
530 return round_cast<T>(r);
534 throw std::overflow_error(
"long long to integral");
539 hilet r =
static_cast<long long>(*d);
541 throw std::overflow_error(
"decimal to integral");
549 throw std::domain_error(std::format(
"Can't convert {} to an integral", repr(*
this)));
553 constexpr explicit operator std::chrono::year_month_day()
const
558 throw std::domain_error(std::format(
"Can't convert {} to an std::chrono::year_month_day", repr(*
this)));
562 explicit operator std::string() const noexcept
565 case tag_type::monostate:
567 case tag_type::floating_point:
568 return hi::to_string(_value._double);
569 case tag_type::decimal:
571 case tag_type::integral:
573 case tag_type::boolean:
574 return _value._bool ?
"true" :
"false";
575 case tag_type::year_month_day:
576 return std::format(
"{:%Y-%m-%d}", _value._year_month_day);
579 case tag_type::flow_break:
581 case tag_type::flow_continue:
583 case tag_type::string:
584 return *_value._string;
585 case tag_type::vector:
587 auto r = std::string{
"["};
588 for (hilet& item : *_value._vector) {
597 auto r = std::string{
"{"};
598 for (hilet& item : *_value._map) {
599 r += repr(item.first);
601 r += repr(item.second);
607 case tag_type::bstring:
608 return base64::encode(*_value._bstring);
614 explicit operator std::string_view()
const
617 return std::string_view{*s};
619 throw std::domain_error(std::format(
"Can't convert {} to an std::string_view", repr(*
this)));
623 explicit operator vector_type()
const
628 throw std::domain_error(std::format(
"Can't convert {} to an vector", repr(*
this)));
632 explicit operator map_type()
const
637 throw std::domain_error(std::format(
"Can't convert {} to an map", repr(*
this)));
641 explicit operator bstring()
const
644 if (_tag != tag_type::bstring) {
645 throw std::domain_error(std::format(
"Can't convert {} to an bstring", repr(*
this)));
650 [[nodiscard]]
constexpr char const *type_name() const noexcept
653 case tag_type::floating_point:
655 case tag_type::decimal:
657 case tag_type::integral:
659 case tag_type::boolean:
661 case tag_type::year_month_day:
663 case tag_type::string:
665 case tag_type::vector:
669 case tag_type::bstring:
680 return _tag == tag_type::monostate;
686 [[nodiscard]]
constexpr bool is_break() const noexcept
688 return _tag == tag_type::flow_break;
696 return _tag == tag_type::flow_continue;
702 case tag_type::floating_point:
704 case tag_type::decimal:
706 case tag_type::integral:
708 case tag_type::boolean:
709 return std::hash<bool>{}(_value._bool);
710 case tag_type::year_month_day:
716 return std::hash<uint32_t>{}(r);
718 case tag_type::string:
719 return std::hash<std::string>{}(*_value._string);
720 case tag_type::vector:
723 for (hilet& v : *_value._vector) {
724 r = hash_mix(r, v.hash());
731 for (hilet& kv : *_value._map) {
732 r = hash_mix(r, kv.first.hash(), kv.second.hash());
736 case tag_type::bstring:
737 return std::hash<bstring>{}(*_value._bstring);
743 [[nodiscard]]
constexpr std::size_t size()
const
754 throw std::domain_error(std::format(
"Can not evaluate {}.size()", repr(*
this)));
758 [[nodiscard]]
constexpr friend std::size_t size(datum
const& rhs)
763 [[nodiscard]]
constexpr datum
const& back()
const
767 throw std::domain_error(std::format(
"Empty vector {}.back()", repr(*
this)));
771 throw std::domain_error(std::format(
"Can not evaluate {}.back()", repr(*
this)));
775 [[nodiscard]]
constexpr datum& back()
779 throw std::domain_error(std::format(
"Empty vector {}.back()", repr(*
this)));
783 throw std::domain_error(std::format(
"Can not evaluate {}.back()", repr(*
this)));
787 [[nodiscard]]
constexpr datum
const& front()
const
791 throw std::domain_error(std::format(
"Empty vector {}.front()", repr(*
this)));
795 throw std::domain_error(std::format(
"Can not evaluate {}.front()", repr(*
this)));
799 [[nodiscard]]
constexpr datum& front()
803 throw std::domain_error(std::format(
"Empty vector {}.front()", repr(*
this)));
807 throw std::domain_error(std::format(
"Can not evaluate {}.front()", repr(*
this)));
811 [[nodiscard]]
constexpr auto cbegin()
const
816 throw std::domain_error(std::format(
"Can not evaluate {}.cbegin()", repr(*
this)));
820 [[nodiscard]]
constexpr auto begin()
const
825 throw std::domain_error(std::format(
"Can not evaluate {}.begin()", repr(*
this)));
829 [[nodiscard]]
constexpr auto begin()
834 throw std::domain_error(std::format(
"Can not evaluate {}.begin()", repr(*
this)));
838 [[nodiscard]]
constexpr auto cend()
const
843 throw std::domain_error(std::format(
"Can not evaluate {}.cend()", repr(*
this)));
847 [[nodiscard]]
constexpr auto end()
const
852 throw std::domain_error(std::format(
"Can not evaluate {}.end()", repr(*
this)));
856 [[nodiscard]]
constexpr auto end()
861 throw std::domain_error(std::format(
"Can not evaluate {}.end()", repr(*
this)));
867 [[nodiscard]] vector_type
keys()
const
870 auto r = vector_type{};
871 r.reserve(m->size());
872 for (hilet& kv : *m) {
873 r.push_back(kv.first);
886 auto r = vector_type{};
887 r.reserve(m->size());
888 for (hilet& kv : *m) {
889 r.push_back(kv.second);
893 throw std::domain_error(std::format(
"Can not evaluate {}.values()", repr(*
this)));
899 [[nodiscard]] vector_type
items()
const
902 auto r = vector_type{};
903 r.reserve(m->size());
905 for (hilet& item : *m) {
906 r.push_back(make_vector(item.first, item.second));
910 throw std::domain_error(std::format(
"Can not evaluate {}.items()", repr(*
this)));
914 constexpr void push_back(
datum const& rhs)
916 if (
auto *v = get_if<vector_type>(*
this)) {
917 return v->push_back(rhs);
919 throw std::domain_error(std::format(
"Can not evaluate {}.push_back({})", repr(*
this), repr(rhs)));
923 constexpr void push_back(datum&& rhs)
928 throw std::domain_error(std::format(
"Can not evaluate {}.push_back({})", repr(*
this), repr(rhs)));
932 template<
typename Arg>
933 constexpr void push_back(Arg&& arg)
938 constexpr void pop_back()
942 throw std::domain_error(std::format(
"Empty vector {}.pop_back()", repr(*
this)));
944 return v->pop_back();
946 throw std::domain_error(std::format(
"Can not evaluate {}.pop_back()", repr(*
this)));
950 [[nodiscard]]
constexpr bool contains(datum
const& rhs)
const
953 return m->contains(rhs);
955 throw std::domain_error(std::format(
"Can not evaluate {}.contains({})", repr(*
this), repr(rhs)));
959 template<
typename Arg>
960 [[nodiscard]]
constexpr bool contains(Arg
const& arg)
const
962 return contains(datum{arg});
965 [[nodiscard]] std::vector<datum *> find(jsonpath
const& path)
noexcept
967 auto r = std::vector<datum *>{};
968 find(path.cbegin(), path.cend(), r);
972 [[nodiscard]] std::vector<datum const *> find(jsonpath
const& path)
const noexcept
974 auto tmp = std::vector<datum *>{};
975 const_cast<datum *
>(
this)->find(path.cbegin(), path.cend(), tmp);
976 auto r = std::vector<datum const *>{};
991 return to_bool(
remove(path.cbegin(), path.cend()));
1001 hi_axiom(path.is_singular());
1002 return find_one(path.cbegin(), path.cend(),
false);
1012 hi_axiom(path.is_singular());
1013 return find_one(path.cbegin(), path.cend(),
true);
1023 hi_axiom(path.is_singular());
1024 return const_cast<datum *
>(
this)->
find_one(path.cbegin(), path.cend(),
false);
1027 [[nodiscard]]
datum const& operator[](
datum const& rhs)
const
1034 index = ssize(v) + index;
1036 if (index < 0 or index >= ssize(v)) {
1044 hilet it = m.find(rhs);
1045 if (it == m.end()) {
1046 throw std::overflow_error(std::format(
"Key {} not found in map", repr(rhs)));
1052 throw std::domain_error(std::format(
"Can not evaluate {}[{}]", repr(*
this), repr(rhs)));
1056 [[nodiscard]]
constexpr datum& operator[](datum
const& rhs)
1063 index = ssize(v) + index;
1065 if (index < 0 or index >= ssize(v)) {
1066 throw std::overflow_error(std::format(
"Index {} beyond bounds of vector", repr(rhs)));
1076 throw std::domain_error(std::format(
"Can not evaluate {}[{}]", repr(*
this), repr(rhs)));
1080 [[nodiscard]]
constexpr datum
const& operator[](
auto const& rhs)
const
1082 return (*
this)[datum{rhs}];
1085 [[nodiscard]]
constexpr datum& operator[](
auto const& rhs)
1087 return (*
this)[datum{rhs}];
1090 [[nodiscard]]
constexpr datum& operator++()
1093 ++_value._long_long;
1096 throw std::domain_error(std::format(
"Can not evaluate ++{}", repr(*
this)));
1100 [[nodiscard]]
constexpr datum& operator--()
1103 --_value._long_long;
1106 throw std::domain_error(std::format(
"Can not evaluate --{}", repr(*
this)));
1110 [[nodiscard]]
constexpr datum operator++(
int)
1114 _value._long_long++;
1117 throw std::domain_error(std::format(
"Can not evaluate {}++", repr(*
this)));
1120 [[nodiscard]]
constexpr datum operator--(
int)
1124 _value._long_long--;
1127 throw std::domain_error(std::format(
"Can not evaluate {}--", repr(*
this)));
1131 constexpr datum& operator+=(
auto const& rhs)
1137 return (*
this) = (*this) + rhs;
1141#define X(op, inner_op) \
1142 constexpr datum& operator op(auto const& rhs) \
1144 return (*this) = (*this)inner_op rhs; \
1158 [[nodiscard]]
friend constexpr bool operator==(datum
const& lhs, datum
const& rhs)
noexcept
1161 return doubles.lhs() == doubles.rhs();
1164 return decimals.lhs() == decimals.rhs();
1167 return long_longs.lhs() == long_longs.rhs();
1170 return bools.lhs() == bools.rhs();
1173 return ymds.lhs() == ymds.rhs();
1176 return strings.lhs() == strings.rhs();
1179 return vectors.lhs() == vectors.rhs();
1182 return maps.lhs() == maps.rhs();
1185 return lhs._tag == rhs._tag;
1217 [[nodiscard]]
friend constexpr std::partial_ordering operator<=>(datum
const& lhs, datum
const& rhs)
noexcept
1220 return doubles.lhs() <=> doubles.rhs();
1223 return decimals.lhs() <=> decimals.rhs();
1226 return long_longs.lhs() <=> long_longs.rhs();
1229 return bools.lhs() <=> bools.rhs();
1232 return year_month_days.lhs() <=> year_month_days.rhs();
1235 return strings.lhs() <=> strings.rhs();
1238 return vectors.lhs() <=> vectors.rhs();
1241 return maps.lhs() <=> maps.rhs();
1244 return bstrings.lhs() <=> bstrings.rhs();
1247 return lhs._tag <=> rhs._tag;
1261 [[nodiscard]]
friend constexpr datum operator-(datum
const& rhs)
1264 return datum{-*rhs_double};
1267 return datum{-*rhs_decimal};
1270 return datum{-*rhs_long_long};
1273 throw std::domain_error(std::format(
"Can not evaluate -{}", repr(rhs)));
1286 [[nodiscard]]
friend constexpr datum operator~(datum
const& rhs)
1289 return datum{~*rhs_long_long};
1292 throw std::domain_error(std::format(
"Can not evaluate ~{}", repr(rhs)));
1310 [[nodiscard]]
friend constexpr datum operator+(datum
const& lhs, datum
const& rhs)
1313 return datum{doubles.lhs() + doubles.rhs()};
1316 return datum{decimals.lhs() + decimals.rhs()};
1319 return datum{long_longs.lhs() + long_longs.rhs()};
1322 return datum{strings.lhs() + strings.rhs()};
1325 auto r = vectors.lhs();
1326 r.insert(r.end(), vectors.rhs().begin(), vectors.rhs().end());
1330 throw std::domain_error(std::format(
"Can not evaluate {} '+' {}", repr(lhs), repr(rhs)));
1345 [[nodiscard]]
friend constexpr datum operator-(datum
const& lhs, datum
const& rhs)
1348 return datum{doubles.lhs() - doubles.rhs()};
1351 return datum{decimals.lhs() - decimals.rhs()};
1354 return datum{long_longs.lhs() - long_longs.rhs()};
1357 throw std::domain_error(std::format(
"Can not evaluate {} '-' {}", repr(lhs), repr(rhs)));
1372 [[nodiscard]]
friend constexpr datum operator*(datum
const& lhs, datum
const& rhs)
1375 return datum{doubles.lhs() * doubles.rhs()};
1378 return datum{decimals.lhs() * decimals.rhs()};
1381 return datum{long_longs.lhs() * long_longs.rhs()};
1384 throw std::domain_error(std::format(
"Can not evaluate {} '*' {}", repr(lhs), repr(rhs)));
1399 [[nodiscard]]
friend constexpr datum operator/(datum
const& lhs, datum
const& rhs)
1402 if (doubles.rhs() == 0) {
1403 throw std::domain_error(std::format(
"Divide by zero {} '/' {}", repr(lhs), repr(rhs)));
1405 return datum{doubles.lhs() / doubles.rhs()};
1408 if (decimals.rhs() == 0) {
1409 throw std::domain_error(std::format(
"Divide by zero {} '/' {}", repr(lhs), repr(rhs)));
1411 return datum{decimals.lhs() / decimals.rhs()};
1414 if (long_longs.rhs() == 0) {
1415 throw std::domain_error(std::format(
"Divide by zero {} '/' {}", repr(lhs), repr(rhs)));
1417 return datum{long_longs.lhs() / long_longs.rhs()};
1420 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 if (long_longs.rhs() == 0) {
1439 throw std::domain_error(std::format(
"Divide by zero {} '%' {}", repr(lhs), repr(rhs)));
1441 return datum{long_longs.lhs() % long_longs.rhs()};
1444 throw std::domain_error(std::format(
"Can not evaluate {} '%' {}", repr(lhs), repr(rhs)));
1458 [[nodiscard]]
friend constexpr datum
pow(datum
const& lhs, datum
const& rhs)
1461 return datum{
pow(doubles.lhs(), doubles.rhs())};
1464 return datum{
pow(long_longs.lhs(), long_longs.rhs())};
1467 throw std::domain_error(std::format(
"Can not evaluate pow({}, {})", repr(lhs), repr(rhs)));
1481 [[nodiscard]]
friend constexpr datum operator&(datum
const& lhs, datum
const& rhs)
1484 return datum{long_longs.lhs() & long_longs.rhs()};
1487 return datum{bools.lhs() and bools.rhs()};
1490 throw std::domain_error(std::format(
"Can not evaluate {} '&' {}", repr(lhs), repr(rhs)));
1504 [[nodiscard]]
friend constexpr datum operator|(datum
const& lhs, datum
const& rhs)
1507 return datum{long_longs.lhs() | long_longs.rhs()};
1510 return datum{bools.lhs() or bools.rhs()};
1513 throw std::domain_error(std::format(
"Can not evaluate {} '|' {}", repr(lhs), repr(rhs)));
1527 [[nodiscard]]
friend constexpr datum operator^(datum
const& lhs, datum
const& rhs)
1530 return datum{long_longs.lhs() ^ long_longs.rhs()};
1533 return datum{bools.lhs() != bools.rhs()};
1536 throw std::domain_error(std::format(
"Can not evaluate {} '^' {}", repr(lhs), repr(rhs)));
1552 [[nodiscard]]
friend constexpr datum operator<<(datum
const& lhs, datum
const& rhs)
1555 if (long_longs.rhs() < 0 or long_longs.rhs() > (
sizeof(
long long) * CHAR_BIT - 1)) {
1556 throw std::domain_error(std::format(
"Invalid shift count {} '<<' {}", repr(lhs), repr(rhs)));
1558 return datum{long_longs.lhs() << long_longs.rhs()};
1561 throw std::domain_error(std::format(
"Can not evaluate {} '<<' {}", repr(lhs), repr(rhs)));
1576 [[nodiscard]]
friend constexpr datum operator>>(datum
const& lhs, datum
const& rhs)
1579 if (long_longs.rhs() < 0 or long_longs.rhs() > (
sizeof(
long long) * CHAR_BIT - 1)) {
1580 throw std::domain_error(std::format(
"Invalid shift count {} '>>' {}", repr(lhs), repr(rhs)));
1582 return datum{long_longs.lhs() >> long_longs.rhs()};
1585 throw std::domain_error(std::format(
"Can not evaluate {} '>>' {}", repr(lhs), repr(rhs)));
1589 friend std::ostream& operator<<(std::ostream& lhs, datum
const& rhs)
1595 [[nodiscard]] friend constexpr auto operator op(datum const& lhs, auto const& rhs) \
1597 return lhs op datum{rhs}; \
1599 [[nodiscard]] friend constexpr auto operator op(auto const& lhs, datum const& rhs) \
1601 return datum{lhs} op rhs; \
1618 [[nodiscard]]
friend std::string repr(datum
const& rhs)
noexcept
1621 case tag_type::monostate:
1623 case tag_type::floating_point:
1624 return std::format(
"{:.1f}", rhs._value._double);
1625 case tag_type::decimal:
1627 case tag_type::integral:
1628 return std::format(
"{}", rhs._value._long_long);
1629 case tag_type::boolean:
1630 return rhs._value._bool ?
"true" :
"false";
1631 case tag_type::year_month_day:
1632 return std::format(
"{:%Y-%m-%d}", rhs._value._year_month_day);
1633 case tag_type::null:
1635 case tag_type::flow_break:
1637 case tag_type::flow_continue:
1639 case tag_type::string:
1640 return std::format(
"\"{}\"", *rhs._value._string);
1641 case tag_type::vector:
1643 auto r = std::string{
"["};
1644 for (hilet& item : *rhs._value._vector) {
1653 auto r = std::string{
"{"};
1654 for (hilet& item : *rhs._value._map) {
1655 r += repr(item.first);
1657 r += repr(item.second);
1663 case tag_type::bstring:
1664 return base64::encode(*rhs._value._bstring);
1683 template<
typename T>
1686 if constexpr (std::is_same_v<T, double>) {
1687 return rhs._tag == tag_type::floating_point;
1688 }
else if constexpr (std::is_same_v<T, decimal>) {
1689 return rhs._tag == tag_type::decimal;
1690 }
else if constexpr (std::is_same_v<T, long long>) {
1691 return rhs._tag == tag_type::integral;
1692 }
else if constexpr (std::is_same_v<T, bool>) {
1693 return rhs._tag == tag_type::boolean;
1694 }
else if constexpr (std::is_same_v<T, std::chrono::year_month_day>) {
1695 return rhs._tag == tag_type::year_month_day;
1696 }
else if constexpr (std::is_same_v<T, nullptr_t>) {
1697 return rhs._tag == tag_type::null;
1698 }
else if constexpr (std::is_same_v<T, std::monostate>) {
1699 return rhs._tag == tag_type::monostate;
1700 }
else if constexpr (std::is_same_v<T, break_type>) {
1701 return rhs._tag == tag_type::flow_break;
1702 }
else if constexpr (std::is_same_v<T, continue_type>) {
1703 return rhs._tag == tag_type::flow_continue;
1704 }
else if constexpr (std::is_same_v<T, std::string>) {
1705 return rhs._tag == tag_type::string;
1706 }
else if constexpr (std::is_same_v<T, vector_type>) {
1707 return rhs._tag == tag_type::vector;
1708 }
else if constexpr (std::is_same_v<T, map_type>) {
1709 return rhs._tag == tag_type::map;
1710 }
else if constexpr (std::is_same_v<T, bstring>) {
1711 return rhs._tag == tag_type::bstring;
1713 hi_static_no_default();
1728 template<
typename To>
1729 [[nodiscard]]
friend constexpr bool promotable_to(
datum const& rhs)
noexcept
1731 if constexpr (std::is_same_v<To, double>) {
1734 }
else if constexpr (std::is_same_v<To, decimal>) {
1736 }
else if constexpr (std::is_same_v<To, long long>) {
1751 template<
typename T>
1752 [[nodiscard]]
friend constexpr T
const&
get(datum
const& rhs)
noexcept
1755 if constexpr (std::is_same_v<T, double>) {
1756 return rhs._value._double;
1757 }
else if constexpr (std::is_same_v<T, decimal>) {
1758 return rhs._value._decimal;
1759 }
else if constexpr (std::is_same_v<T, long long>) {
1760 return rhs._value._long_long;
1761 }
else if constexpr (std::is_same_v<T, bool>) {
1762 return rhs._value._bool;
1763 }
else if constexpr (std::is_same_v<T, std::chrono::year_month_day>) {
1764 return rhs._value._year_month_day;
1765 }
else if constexpr (std::is_same_v<T, std::string>) {
1766 return *rhs._value._string;
1767 }
else if constexpr (std::is_same_v<T, vector_type>) {
1768 return *rhs._value._vector;
1769 }
else if constexpr (std::is_same_v<T, map_type>) {
1770 return *rhs._value._map;
1771 }
else if constexpr (std::is_same_v<T, bstring>) {
1772 return *rhs._value._bstring;
1774 hi_static_no_default();
1786 template<
typename T>
1787 [[nodiscard]]
friend constexpr T&
get(datum& rhs)
noexcept
1790 if constexpr (std::is_same_v<T, double>) {
1791 return rhs._value._double;
1792 }
else if constexpr (std::is_same_v<T, decimal>) {
1793 return rhs._value._decimal;
1794 }
else if constexpr (std::is_same_v<T, long long>) {
1795 return rhs._value._long_long;
1796 }
else if constexpr (std::is_same_v<T, bool>) {
1797 return rhs._value._bool;
1798 }
else if constexpr (std::is_same_v<T, std::chrono::year_month_day>) {
1799 return rhs._value._year_month_day;
1800 }
else if constexpr (std::is_same_v<T, std::string>) {
1801 return *rhs._value._string;
1802 }
else if constexpr (std::is_same_v<T, vector_type>) {
1803 return *rhs._value._vector;
1804 }
else if constexpr (std::is_same_v<T, map_type>) {
1805 return *rhs._value._map;
1806 }
else if constexpr (std::is_same_v<T, bstring>) {
1807 return *rhs._value._bstring;
1809 hi_static_no_default();
1821 template<
typename T>
1822 [[nodiscard]]
friend constexpr T *
get_if(datum& rhs)
noexcept
1839 template<
typename T>
1840 [[nodiscard]]
friend constexpr T
const *
get_if(datum
const& rhs)
noexcept
1858 template<
typename T>
1861 if (
auto *value = rhs.find_one(path)) {
1881 template<
typename T>
1882 [[nodiscard]]
friend T
const *
get_if(datum
const& rhs,
jsonpath const& path)
noexcept
1884 if (
auto *value =
const_cast<datum&
>(rhs).
find_one(path)) {
1896 enum class tag_type :
signed char {
1915 tag_type _tag = tag_type::monostate;
1918 long long _long_long;
1921 std::chrono::year_month_day _year_month_day;
1923 vector_type *_vector;
1927 constexpr value_type(numeric_integral
auto value) noexcept : _long_long(
narrow_cast<long long>(value)) {}
1928 constexpr value_type(std::floating_point
auto value) noexcept : _double(
narrow_cast<double>(value)) {}
1929 constexpr value_type(decimal value) noexcept : _decimal(value) {}
1930 constexpr value_type(
bool value) noexcept : _bool(value) {}
1931 constexpr value_type(std::chrono::year_month_day value) noexcept : _year_month_day(value) {}
1932 constexpr value_type(std::string *value) noexcept : _string(value) {}
1933 constexpr value_type(vector_type *value) noexcept : _vector(value) {}
1934 constexpr value_type(map_type *value) noexcept : _map(value) {}
1935 constexpr value_type(bstring *value) noexcept : _bstring(value) {}
1940 [[nodiscard]]
constexpr bool is_scalar() const noexcept
1942 return std::to_underlying(_tag) >= 0;
1945 [[nodiscard]]
constexpr bool is_pointer() const noexcept
1947 return std::to_underlying(_tag) < 0;
1950 hi_no_inline
void copy_pointer(datum
const&
other)
noexcept
1952 hi_axiom(
other.is_pointer());
1953 switch (
other._tag) {
1954 case tag_type::string:
1955 _value._string =
new std::string{*
other._value._string};
1957 case tag_type::vector:
1958 _value._vector =
new vector_type{*
other._value._vector};
1961 _value._map =
new map_type{*
other._value._map};
1963 case tag_type::bstring:
1964 _value._bstring =
new bstring{*
other._value._bstring};
1971 hi_no_inline
void _delete_pointer() noexcept
1973 hi_axiom(is_pointer());
1975 case tag_type::string:
1976 delete _value._string;
1978 case tag_type::vector:
1979 delete _value._vector;
1984 case tag_type::bstring:
1985 delete _value._bstring;
1992 constexpr void delete_pointer() noexcept
1999 void find_wildcard(jsonpath::const_iterator it, jsonpath::const_iterator it_end, std::vector<datum *>& r)
noexcept
2002 for (
auto& item : *vector) {
2003 item.find(it + 1, it_end, r);
2007 for (
auto& item : *map) {
2008 item.second.find(it + 1, it_end, r);
2013 void find_descend(jsonpath::const_iterator it, jsonpath::const_iterator it_end, std::vector<datum *>& r)
noexcept
2015 this->find(it + 1, it_end, r);
2018 for (
auto& item : *vector) {
2019 item.find(it, it_end, r);
2023 for (
auto& item : *map) {
2024 item.second.find(it, it_end, r);
2030 jsonpath::indices
const& indices,
2031 jsonpath::const_iterator it,
2032 jsonpath::const_iterator it_end,
2033 std::vector<datum *>& r)
noexcept
2036 for (hilet index : indices.filter(ssize(*vector))) {
2037 (*vector)[index].find(it + 1, it_end, r);
2043 jsonpath::names
const& names,
2044 jsonpath::const_iterator it,
2045 jsonpath::const_iterator it_end,
2046 std::vector<datum *>& r)
noexcept
2049 for (hilet& name : names) {
2050 hilet name_ = datum{name};
2051 auto jt = map->find(name_);
2052 if (jt != map->cend()) {
2053 jt->second.find(it + 1, it_end, r);
2060 jsonpath::slice
const& slice,
2061 jsonpath::const_iterator it,
2062 jsonpath::const_iterator it_end,
2063 std::vector<datum *>& r)
noexcept
2066 hilet first = slice.begin(vector->size());
2067 hilet last = slice.end(vector->size());
2069 for (
auto index = first; index != last; index += slice.step) {
2070 if (index >= 0 and index < vector->size()) {
2071 (*this)[index].find(it + 1, it_end, r);
2077 void find(jsonpath::const_iterator it, jsonpath::const_iterator it_end, std::vector<datum *>& r)
noexcept
2082 }
else if (std::holds_alternative<jsonpath::root>(*it)) {
2083 find(it + 1, it_end, r);
2085 }
else if (std::holds_alternative<jsonpath::current>(*it)) {
2086 find(it + 1, it_end, r);
2088 }
else if (std::holds_alternative<jsonpath::wildcard>(*it)) {
2089 find_wildcard(it, it_end, r);
2091 }
else if (std::holds_alternative<jsonpath::descend>(*it)) {
2092 find_descend(it, it_end, r);
2094 }
else if (
auto indices = std::get_if<jsonpath::indices>(&*it)) {
2095 find_indices(*indices, it, it_end, r);
2097 }
else if (
auto names = std::get_if<jsonpath::names>(&*it)) {
2098 find_names(*names, it, it_end, r);
2100 }
else if (
auto slice = std::get_if<jsonpath::slice>(&*it)) {
2101 find_slice(*slice, it, it_end, r);
2108 [[nodiscard]]
int remove_wildcard(jsonpath::const_iterator it, jsonpath::const_iterator it_end)
noexcept
2113 auto jt = vector->begin();
2114 while (jt != vector->end()) {
2115 hilet match = jt->remove(it + 1, it_end);
2119 jt = vector->erase(jt);
2124 return vector->empty() ? 2 : r;
2127 auto jt = map->begin();
2128 while (jt != map->end()) {
2129 hilet match = jt->second.remove(it + 1, it_end);
2133 jt = map->erase(jt);
2138 return map->empty() ? 2 : r;
2145 [[nodiscard]]
int remove_descend(jsonpath::const_iterator it, jsonpath::const_iterator it_end)
noexcept
2150 hilet match = this->
remove(it + 1, it_end);
2158 auto jt = vector->begin();
2159 while (jt != vector->end()) {
2160 hilet match = jt->remove(it, it_end);
2164 jt = vector->erase(jt);
2169 return vector->empty() ? 2 : r;
2172 auto jt = map->begin();
2173 while (jt != map->end()) {
2174 hilet match = jt->second.remove(it, it_end);
2178 jt = map->erase(jt);
2183 return map->empty() ? 2 : r;
2191 remove_indices(jsonpath::indices
const& indices, jsonpath::const_iterator it, jsonpath::const_iterator it_end)
noexcept
2195 std::size_t offset = 0;
2197 for (hilet index : indices.filter(ssize(*vector))) {
2198 hilet match = (*vector)[index - offset].remove(it + 1, it_end);
2201 vector->erase(vector->begin() + (index - offset));
2206 return vector->empty() ? 2 : r;
2214 remove_names(jsonpath::names
const& names, jsonpath::const_iterator it, jsonpath::const_iterator it_end)
noexcept
2219 for (hilet& name : names) {
2220 hilet name_ = datum{name};
2221 auto jt = map->find(name_);
2222 if (jt != map->cend()) {
2223 hilet match = jt->second.remove(it + 1, it_end);
2231 return map->empty() ? 2 : r;
2239 remove_slice(jsonpath::slice
const& slice, jsonpath::const_iterator it, jsonpath::const_iterator it_end)
noexcept
2244 hilet first = slice.begin(vector->size());
2245 hilet last = slice.end(vector->size());
2247 std::size_t offset = 0;
2248 for (
auto index = first; index != last; index += slice.step) {
2249 if (index >= 0 and index < vector->size()) {
2250 hilet match = (*this)[index - offset].remove(it + 1, it_end);
2254 vector->erase(vector->begin() + (index - offset));
2260 return vector->empty() ? 2 : r;
2267 [[nodiscard]]
int remove(jsonpath::const_iterator it, jsonpath::const_iterator it_end)
noexcept
2273 }
else if (std::holds_alternative<jsonpath::root>(*it)) {
2274 return remove(it + 1, it_end);
2276 }
else if (std::holds_alternative<jsonpath::current>(*it)) {
2277 return remove(it + 1, it_end);
2279 }
else if (std::holds_alternative<jsonpath::wildcard>(*it)) {
2280 return remove_wildcard(it, it_end);
2282 }
else if (std::holds_alternative<jsonpath::descend>(*it)) {
2283 return remove_descend(it, it_end);
2285 }
else if (
auto indices = std::get_if<jsonpath::indices>(&*it)) {
2286 return remove_indices(*indices, it, it_end);
2288 }
else if (
auto names = std::get_if<jsonpath::names>(&*it)) {
2289 return remove_names(*names, it, it_end);
2291 }
else if (
auto slice = std::get_if<jsonpath::slice>(&*it)) {
2292 return remove_slice(*slice, it, it_end);
2299 [[nodiscard]] datum *
2300 find_one_name(datum
const& name, jsonpath::const_iterator it, jsonpath::const_iterator it_end,
bool create)
noexcept
2305 auto i = map->find(name);
2306 if (i != map->end()) {
2307 return i->second.find_one(it + 1, it_end,
create);
2310 (*map)[name] = datum{std::monostate{}};
2311 return find_one_name(name, it, it_end,
create);
2318 *
this = datum::make_map(name, std::monostate{});
2319 return find_one_name(name, it, it_end,
create);
2326 [[nodiscard]] datum *
2327 find_one_index(std::size_t index, jsonpath::const_iterator it, jsonpath::const_iterator it_end,
bool create)
noexcept
2330 if (index < vector->size()) {
2331 return (*vector)[index].find_one(it + 1, it_end,
create);
2332 }
else if (index == vector->size() and
create) {
2333 vector->push_back(datum{std::monostate{}});
2334 return find_one_index(index, it, it_end,
create);
2340 *
this = datum::make_vector(std::monostate{});
2341 return find_one_index(index, it, it_end,
create);
2348 [[nodiscard]] datum *
find_one(jsonpath::const_iterator it, jsonpath::const_iterator it_end,
bool create)
noexcept
2353 }
else if (std::holds_alternative<jsonpath::root>(*it)) {
2356 }
else if (std::holds_alternative<jsonpath::current>(*it)) {
2359 }
else if (hilet *indices = std::get_if<jsonpath::indices>(&*it)) {
2360 hi_axiom(indices->size() == 1);
2361 return find_one_index(indices->front(), it, it_end,
create);
2363 }
else if (hilet *names = std::get_if<jsonpath::names>(&*it)) {
2364 hi_axiom(names->size() == 1);
2365 return find_one_name(datum{names->front()}, it, it_end,
create);