211 template<
typename To>
219 r.set(
get<To>(lhs),
static_cast<To>(rhs));
222 r.set(
static_cast<To>(lhs),
get<To>(rhs));
235 if (
other.is_pointer()) {
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) {}
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>
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
280 if constexpr (
sizeof...(Args) > 0) {
281 populate_map(r,
args...);
285 template<
typename...
Args>
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...);
299 return datum{break_type{}};
304 return datum{continue_type{}};
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;
378 _tag = tag_type::string;
383 datum& operator=(
char const* value)
noexcept
386 _tag = tag_type::string;
391 datum& operator=(std::string_view value)
noexcept
394 _tag = tag_type::string;
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;
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:
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:
478 template<numeric_
integral T>
479 constexpr explicit operator T()
const
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)));
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:
537 for (
auto const&
item : *_value._vector) {
547 for (
auto const&
item : *_value._map) {
556 case tag_type::bstring:
557 return base64::encode(*_value._bstring);
563 explicit operator std::string_view()
const
566 return std::string_view{*s};
572 explicit operator vector_type()
const
581 explicit operator map_type()
const
590 explicit operator bstring()
const
593 if (_tag != tag_type::bstring) {
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;
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:
663 case tag_type::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:
708 [[
nodiscard]]
constexpr datum
const& back()
const
732 [[
nodiscard]]
constexpr datum
const& front()
const
756 [[
nodiscard]]
constexpr auto cbegin()
const
765 [[
nodiscard]]
constexpr auto begin()
const
783 [[
nodiscard]]
constexpr auto cend()
const
817 for (
auto const&
kv : *m) {
818 r.push_back(
kv.first);
833 for (
auto const&
kv : *m) {
834 r.push_back(
kv.second);
850 for (
auto const&
item : *m) {
851 r.push_back(make_vector(
item.first,
item.second));
859 constexpr void push_back(
datum const& rhs)
862 return v->push_back(rhs);
868 constexpr void push_back(datum&& rhs)
877 template<
typename Arg>
878 constexpr void push_back(
Arg&&
arg)
880 push_back(datum{std::forward<Arg>(
arg)});
883 constexpr void pop_back()
889 return v->pop_back();
895 [[
nodiscard]]
constexpr bool contains(datum
const& rhs)
const
898 return m->contains(rhs);
904 template<
typename Arg>
907 return contains(datum{
arg});
913 find(path.cbegin(), path.cend(), r);
920 const_cast<datum*
>(
this)->find(path.cbegin(), path.cend(),
tmp);
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);
979 index =
ssize(v) + index;
989 auto const it = m.find(rhs);
1001 [[
nodiscard]]
constexpr datum& operator[](datum
const& rhs)
1008 index =
ssize(v) + index;
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;
1045 [[
nodiscard]]
constexpr datum& operator--()
1048 --_value._long_long;
1055 [[
nodiscard]]
constexpr datum operator++(
int)
1059 _value._long_long++;
1065 [[
nodiscard]]
constexpr datum operator--(
int)
1069 _value._long_long--;
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
1127 return lhs._tag == rhs._tag;
1157 [[
nodiscard]]
friend constexpr std::partial_ordering operator<=>(datum
const& lhs, datum
const& rhs)
noexcept
1184 return lhs._tag <=> rhs._tag;
1198 [[
nodiscard]]
friend constexpr datum operator-(datum
const& rhs)
1220 [[
nodiscard]]
friend constexpr datum operator~(datum
const& rhs)
1244 [[
nodiscard]]
friend constexpr datum operator+(datum
const& lhs, datum
const& rhs)
1276 [[
nodiscard]]
friend constexpr datum operator-(datum
const& lhs, datum
const& rhs)
1324 [[
nodiscard]]
friend constexpr datum operator/(datum
const& lhs, datum
const& rhs)
1354 [[
nodiscard]]
friend constexpr datum operator%(datum
const& lhs, datum
const& rhs)
1377 [[
nodiscard]]
friend constexpr datum
pow(datum
const& lhs, datum
const& rhs)
1400 [[
nodiscard]]
friend constexpr datum operator&(datum
const& lhs, datum
const& rhs)
1423 [[
nodiscard]]
friend constexpr datum operator|(datum
const& lhs, datum
const& rhs)
1446 [[
nodiscard]]
friend constexpr datum operator^(datum
const& lhs, datum
const& rhs)
1471 [[
nodiscard]]
friend constexpr datum operator<<(datum
const& lhs, datum
const& rhs)
1495 [[
nodiscard]]
friend constexpr datum operator>>(datum
const& 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; \
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:
1567 for (
auto const&
item : *rhs._value._vector) {
1577 for (
auto const&
item : *rhs._value._map) {
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>
1650 if constexpr (std::is_same_v<To, double>) {
1652 }
else if constexpr (std::is_same_v<To, long long>) {
1667 template<
typename T>
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>
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>
1751 template<
typename T>
1770 template<
typename T>
1773 if (
auto* value = rhs.find_one(path)) {
1793 template<
typename T>
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;
1839 constexpr value_type(
bool value)
noexcept : _bool(value) {}
1840 constexpr value_type(std::chrono::year_month_day value)
noexcept : _year_month_day(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) {}
1851 return std::to_underlying(_tag) >= 0;
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:
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
1911 for (
auto&
item : *vector) {
1916 for (
auto&
item : *map) {
1927 for (
auto&
item : *vector) {
1932 for (
auto&
item : *map) {
1939 jsonpath::indices
const& indices,
1940 jsonpath::const_iterator
it,
1941 jsonpath::const_iterator
it_end,
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,
1958 for (
auto const& name : names) {
1959 auto const name_ = datum{name};
1961 if (
jt != map->cend()) {
1969 jsonpath::slice
const& slice,
1970 jsonpath::const_iterator
it,
1971 jsonpath::const_iterator
it_end,
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) {
1980 (*this)[index].find(
it + 1,
it_end, r);
1991 }
else if (std::holds_alternative<jsonpath::root>(*
it)) {
1994 }
else if (std::holds_alternative<jsonpath::current>(*
it)) {
1997 }
else if (std::holds_alternative<jsonpath::wildcard>(*
it)) {
2000 }
else if (std::holds_alternative<jsonpath::descend>(*
it)) {
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)) {
2009 }
else if (
auto slice = std::get_if<jsonpath::slice>(&*
it)) {
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()) {
2028 jt = vector->erase(
jt);
2033 return vector->empty() ? 2 : r;
2036 auto jt = map->begin();
2037 while (
jt != map->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
2067 auto jt = vector->begin();
2068 while (
jt != vector->end()) {
2073 jt = vector->erase(
jt);
2078 return vector->empty() ? 2 : r;
2081 auto jt = map->begin();
2082 while (
jt != map->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
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};
2131 if (
jt != map->cend()) {
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());
2157 for (
auto index = first; index != last; index += slice.step) {
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;
2182 }
else if (std::holds_alternative<jsonpath::root>(*
it)) {
2185 }
else if (std::holds_alternative<jsonpath::current>(*
it)) {
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)) {
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);
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()) {
2219 (*map)[name] = datum{std::monostate{}};
2227 *
this = datum::make_map(name, std::monostate{});
2241 }
else if (index == vector->size()
and create) {
2242 vector->push_back(datum{std::monostate{}});
2249 *
this = datum::make_vector(std::monostate{});
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);
2272 }
else if (
auto const* names = std::get_if<jsonpath::names>(&*
it)) {
2273 hi_axiom(names->size() == 1);