223 template<
typename To>
231 r.set(
get<To>(lhs),
static_cast<To>(rhs));
234 r.set(
static_cast<To>(lhs),
get<To>(rhs));
247 if (
other.is_pointer()) {
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) {}
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>
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
292 if constexpr (
sizeof...(Args) > 0) {
293 populate_map(r,
args...);
297 template<
typename...
Args>
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...);
311 return datum{break_type{}};
316 return datum{continue_type{}};
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;
390 _tag = tag_type::string;
395 datum& operator=(
char const *value)
noexcept
398 _tag = tag_type::string;
403 datum& operator=(std::string_view value)
noexcept
406 _tag = tag_type::string;
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;
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:
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:
490 template<numeric_
integral T>
491 constexpr explicit operator T()
const
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)));
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:
549 for (
auto const&
item : *_value._vector) {
559 for (
auto const&
item : *_value._map) {
568 case tag_type::bstring:
569 return base64::encode(*_value._bstring);
575 explicit operator std::string_view()
const
578 return std::string_view{*s};
584 explicit operator vector_type()
const
593 explicit operator map_type()
const
602 explicit operator bstring()
const
605 if (_tag != tag_type::bstring) {
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;
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:
675 case tag_type::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:
720 [[
nodiscard]]
constexpr datum
const& back()
const
744 [[
nodiscard]]
constexpr datum
const& front()
const
768 [[
nodiscard]]
constexpr auto cbegin()
const
777 [[
nodiscard]]
constexpr auto begin()
const
795 [[
nodiscard]]
constexpr auto cend()
const
829 for (
auto const&
kv : *m) {
830 r.push_back(
kv.first);
845 for (
auto const&
kv : *m) {
846 r.push_back(
kv.second);
862 for (
auto const&
item : *m) {
863 r.push_back(make_vector(
item.first,
item.second));
871 constexpr void push_back(
datum const& rhs)
874 return v->push_back(rhs);
880 constexpr void push_back(datum&& rhs)
889 template<
typename Arg>
890 constexpr void push_back(
Arg&&
arg)
892 push_back(datum{std::forward<Arg>(
arg)});
895 constexpr void pop_back()
901 return v->pop_back();
907 [[
nodiscard]]
constexpr bool contains(datum
const& rhs)
const
910 return m->contains(rhs);
916 template<
typename Arg>
919 return contains(datum{
arg});
925 find(path.cbegin(), path.cend(), r);
932 const_cast<datum *
>(
this)->find(path.cbegin(), path.cend(),
tmp);
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);
991 index =
ssize(v) + index;
1001 auto const it = m.find(rhs);
1002 if (
it == m.end()) {
1013 [[
nodiscard]]
constexpr datum& operator[](datum
const& rhs)
1020 index =
ssize(v) + index;
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;
1057 [[
nodiscard]]
constexpr datum& operator--()
1060 --_value._long_long;
1067 [[
nodiscard]]
constexpr datum operator++(
int)
1071 _value._long_long++;
1077 [[
nodiscard]]
constexpr datum operator--(
int)
1081 _value._long_long--;
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
1139 return lhs._tag == rhs._tag;
1169 [[
nodiscard]]
friend constexpr std::partial_ordering operator<=>(datum
const& lhs, datum
const& rhs)
noexcept
1196 return lhs._tag <=> rhs._tag;
1210 [[
nodiscard]]
friend constexpr datum operator-(datum
const& rhs)
1232 [[
nodiscard]]
friend constexpr datum operator~(datum
const& rhs)
1256 [[
nodiscard]]
friend constexpr datum operator+(datum
const& lhs, datum
const& rhs)
1288 [[
nodiscard]]
friend constexpr datum operator-(datum
const& lhs, datum
const& rhs)
1336 [[
nodiscard]]
friend constexpr datum operator/(datum
const& lhs, datum
const& rhs)
1366 [[
nodiscard]]
friend constexpr datum operator%(datum
const& lhs, datum
const& rhs)
1389 [[
nodiscard]]
friend constexpr datum
pow(datum
const& lhs, datum
const& rhs)
1412 [[
nodiscard]]
friend constexpr datum operator&(datum
const& lhs, datum
const& rhs)
1435 [[
nodiscard]]
friend constexpr datum operator|(datum
const& lhs, datum
const& rhs)
1458 [[
nodiscard]]
friend constexpr datum operator^(datum
const& lhs, datum
const& rhs)
1483 [[
nodiscard]]
friend constexpr datum operator<<(datum
const& lhs, datum
const& rhs)
1507 [[
nodiscard]]
friend constexpr datum operator>>(datum
const& 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; \
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:
1573 for (
auto const&
item : *rhs._value._vector) {
1583 for (
auto const&
item : *rhs._value._map) {
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>
1656 if constexpr (std::is_same_v<To, double>) {
1659 }
else if constexpr (std::is_same_v<To, long long>) {
1674 template<
typename T>
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>
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>
1758 template<
typename T>
1777 template<
typename T>
1780 if (
auto *value = rhs.find_one(path)) {
1800 template<
typename T>
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;
1846 constexpr value_type(
bool value)
noexcept : _bool(value) {}
1847 constexpr value_type(std::chrono::year_month_day value)
noexcept : _year_month_day(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) {}
1858 return std::to_underlying(_tag) >= 0;
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:
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
1918 for (
auto&
item : *vector) {
1923 for (
auto&
item : *map) {
1934 for (
auto&
item : *vector) {
1939 for (
auto&
item : *map) {
1946 jsonpath::indices
const& indices,
1947 jsonpath::const_iterator
it,
1948 jsonpath::const_iterator
it_end,
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,
1965 for (
auto const& name : names) {
1966 auto const name_ = datum{name};
1968 if (
jt != map->cend()) {
1976 jsonpath::slice
const& slice,
1977 jsonpath::const_iterator
it,
1978 jsonpath::const_iterator
it_end,
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) {
1987 (*this)[index].find(
it + 1,
it_end, r);
1998 }
else if (std::holds_alternative<jsonpath::root>(*
it)) {
2001 }
else if (std::holds_alternative<jsonpath::current>(*
it)) {
2004 }
else if (std::holds_alternative<jsonpath::wildcard>(*
it)) {
2007 }
else if (std::holds_alternative<jsonpath::descend>(*
it)) {
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)) {
2016 }
else if (
auto slice = std::get_if<jsonpath::slice>(&*
it)) {
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()) {
2035 jt = vector->erase(
jt);
2040 return vector->empty() ? 2 : r;
2043 auto jt = map->begin();
2044 while (
jt != map->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
2074 auto jt = vector->begin();
2075 while (
jt != vector->end()) {
2080 jt = vector->erase(
jt);
2085 return vector->empty() ? 2 : r;
2088 auto jt = map->begin();
2089 while (
jt != map->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
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};
2138 if (
jt != map->cend()) {
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());
2164 for (
auto index = first; index != last; index += slice.step) {
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;
2189 }
else if (std::holds_alternative<jsonpath::root>(*
it)) {
2192 }
else if (std::holds_alternative<jsonpath::current>(*
it)) {
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)) {
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);
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()) {
2226 (*map)[name] = datum{std::monostate{}};
2234 *
this = datum::make_map(name, std::monostate{});
2248 }
else if (index == vector->size()
and create) {
2249 vector->push_back(datum{std::monostate{}});
2256 *
this = datum::make_vector(std::monostate{});
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);
2279 }
else if (
auto const *names = std::get_if<jsonpath::names>(&*
it)) {
2280 hi_axiom(names->size() == 1);