3 #include "fly/concepts/concepts.hpp"
4 #include "fly/types/json/concepts.hpp"
5 #include "fly/types/json/detail/array_util.hpp"
6 #include "fly/types/json/detail/json_iterator.hpp"
7 #include "fly/types/json/detail/json_reverse_iterator.hpp"
8 #include "fly/types/json/json_exception.hpp"
9 #include "fly/types/json/types.hpp"
10 #include "fly/types/numeric/literals.hpp"
11 #include "fly/types/string/concepts.hpp"
12 #include "fly/types/string/string.hpp"
19 #include <initializer_list>
23 #include <type_traits>
28 #define FLY_JSON_CHR(ch) FLY_CHR(fly::json_char_type, ch)
29 #define FLY_JSON_STR(str) FLY_STR(fly::json_char_type, str)
30 #define FLY_JSON_ARR(arr) FLY_ARR(fly::json_char_type, arr)
168 using size_type = std::size_t;
169 using difference_type = std::ptrdiff_t;
170 using allocator_type = std::allocator<value_type>;
173 using pointer =
typename std::allocator_traits<allocator_type>::pointer;
174 using const_pointer =
typename std::allocator_traits<allocator_type>::const_pointer;
190 Json(json_null_type value) noexcept;
203 template <JsonStringLike T>
204 Json(T value) noexcept(
false);
217 template <JsonObject T>
230 template <JsonArray T>
242 template <JsonBoolean T>
254 template <JsonSignedInteger T>
266 template <JsonUn
signedInteger T>
278 template <JsonFloatingPo
int T>
305 Json(std::initializer_list<Json> initializer) noexcept;
386 explicit operator json_null_type() const noexcept(false);
403 template <JsonString T>
404 explicit operator T() const &noexcept(false);
414 explicit operator json_string_type() &&noexcept(false);
427 template <JsonObject T>
428 explicit operator T() const &noexcept(false);
438 explicit operator json_object_type() &&noexcept(false);
452 template <JsonArray T>
453 explicit operator T() const &noexcept(false);
463 explicit operator json_array_type() &&noexcept(false);
478 template <typename T, std::
size_t N>
479 explicit operator std::array<T, N>() const noexcept(false);
491 template <JsonBoolean T>
492 explicit operator T() const noexcept;
508 template <JsonNumber T>
509 explicit operator T() const noexcept(false);
532 template <JsonStringLike T>
550 template <JsonStringLike T>
597 template <JsonStringLike T>
613 template <JsonStringLike T>
849 size_type
size() const;
921 template <JsonStringLike Key>
940 template <JsonStringLike Key>
1048 template <JsonStringLike Key>
1069 template <JsonStringLike Key, typename Value>
1085 template <typename... Args>
1129 template <JsonStringLike T>
1130 size_type
erase(T key);
1140 void erase(size_type index);
1194 template <JsonString T>
1195 void swap(T &other);
1208 template <JsonObject T>
1222 template <JsonArray T>
1268 template <JsonObject T>
1269 void merge(T &other);
1284 template <JsonObject T>
1285 void merge(T &&other);
1306 template <JsonStringLike T>
1307 size_type
count(T key) const;
1323 template <JsonStringLike T>
1340 template <JsonStringLike T>
1356 template <JsonStringLike T>
1437 friend struct std::hash<
Json>;
1450 template <JsonStringLike T>
1451 static json_string_type convert_to_string(T value);
1463 static json_string_type validate_string(json_string_type &&value);
1476 static
void read_escaped_character(json_string_type &value, json_string_type::
iterator &it);
1486 static
void write_escaped_character(
1487 json_string_type &output,
1495 template <typename... Args>
1496 using object_insertion_result = std::conditional_t<
1497 std::is_void_v<decltype(std::declval<json_object_type>().
insert(std::declval<Args>()...))>,
1516 template <typename... Args>
1517 object_insertion_result<Args...> object_inserter(Args &&...args);
1533 template <typename... Args>
1548 template <typename T>
1549 T &get(const
char *error_message);
1564 template <typename T>
1565 T &get_or_promote(const
char *error_message);
1579 template <typename T>
1580 const T &get(const
char *error_message) const;
1582 json_type m_value {
nullptr};
1586 template <JsonStringLike T>
1587 Json::Json(T value) noexcept(
false) : m_value(convert_to_string(std::move(value)))
1592 template <JsonObject T>
1593 Json::Json(T value) noexcept(
false) : m_value(json_object_type())
1595 for (
auto &it : value)
1597 insert(std::move(it.first), std::move(it.second));
1602 template <JsonArray T>
1603 Json::Json(T value) noexcept(
false) : m_value(json_array_type())
1605 reserve(detail::json_array_size(value));
1607 for (
auto &it : value)
1609 push_back(std::move(it));
1614 template <JsonBoolean T>
1615 Json::Json(T value) noexcept : m_value(
static_cast<json_boolean_type
>(value))
1620 template <JsonSignedInteger T>
1621 Json::Json(T value) noexcept : m_value(
static_cast<json_signed_integer_type
>(value))
1626 template <JsonUn
signedInteger T>
1627 Json::Json(T value) noexcept : m_value(
static_cast<json_unsigned_integer_type
>(value))
1632 template <JsonFloatingPo
int T>
1633 Json::Json(T value) noexcept : m_value(
static_cast<json_floating_point_type
>(value))
1638 template <JsonString T>
1639 Json::operator T() const &noexcept(false)
1641 auto visitor = [
this](
const auto &storage) -> T {
1642 using S = decltype(storage);
1644 if constexpr (JsonString<S>)
1646 if constexpr (fly::SameAs<T, json_string_type>)
1654 return *(JsonStringType::convert<T>(storage));
1657 else if constexpr (JsonNumber<S>)
1659 using char_type =
typename T::value_type;
1664 throw JsonException(*
this,
"JSON type is not a string");
1668 return std::visit(std::move(visitor), m_value);
1672 template <JsonObject T>
1673 Json::operator T() const &noexcept(false)
1675 const auto &storage = get<json_object_type>(
"JSON type is not an object");
1678 for (
const auto &it : storage)
1681 auto key = *std::move(JsonStringType::convert<typename T::key_type>(it.first));
1682 result.emplace(std::move(key), it.second);
1689 template <JsonArray T>
1690 Json::operator T() const &noexcept(false)
1692 const auto &storage = get<json_array_type>(
"JSON type is not an array");
1695 for (
const auto &it : storage)
1697 auto copy =
static_cast<typename T::value_type
>(it);
1698 detail::json_array_append(result, std::move(copy));
1705 template <
typename T, std::
size_t N>
1706 Json::operator std::array<T, N>() const noexcept(false)
1708 const auto &storage = get<json_array_type>(
"JSON type is not an array");
1709 std::array<T, N> result {};
1711 for (std::size_t i = 0; i < std::min(N, storage.size()); ++i)
1713 result[i] = T(storage.at(i));
1720 template <JsonBoolean T>
1721 Json::operator T() const noexcept
1723 auto visitor = [](
const auto &storage) noexcept -> T {
1724 using S = decltype(storage);
1726 if constexpr (JsonContainer<S>)
1728 return !storage.empty();
1730 else if constexpr (JsonFloatingPoint<S>)
1732 return std::abs(storage) >
static_cast<S
>(0);
1734 else if constexpr (JsonNull<S>)
1740 return storage !=
static_cast<S
>(0);
1744 return std::visit(std::move(visitor), m_value);
1748 template <JsonNumber T>
1749 Json::operator T() const noexcept(false)
1751 auto visitor = [
this](
const auto &storage) -> T {
1752 using S = decltype(storage);
1754 if constexpr (JsonString<S>)
1756 if (
auto converted = JsonStringType::convert<T>(storage); converted)
1758 return *std::move(converted);
1761 else if constexpr (JsonNumber<S>)
1763 return static_cast<T
>(storage);
1766 throw JsonException(*
this,
"JSON type is not numeric");
1769 return std::visit(std::move(visitor), m_value);
1773 template <JsonStringLike T>
1776 auto &storage = get<json_object_type>(
"JSON type invalid for operator[key]");
1777 auto it = storage.find(convert_to_string(std::move(key)));
1779 if (it == storage.end())
1788 template <JsonStringLike T>
1791 const auto &storage = get<json_object_type>(
"JSON type invalid for operator[key]");
1792 const auto it = storage.find(convert_to_string(std::move(key)));
1794 if (it == storage.end())
1803 template <JsonStringLike T>
1806 auto &storage = get_or_promote<json_object_type>(
"JSON type invalid for operator[key]");
1807 return storage[convert_to_string(std::move(key))];
1811 template <JsonStringLike T>
1818 template <JsonStringLike Key>
1821 return object_inserter(std::make_pair(convert_to_string(std::move(key)), value));
1825 template <JsonStringLike Key>
1828 return object_inserter(std::make_pair(convert_to_string(std::move(key)), std::move(value)));
1832 template <JsonStringLike Key>
1835 auto result =
insert(key, value);
1839 auto &it = std::get<typename iterator::object_iterator_type>(result.first.m_iterator);
1840 it->second.swap(value);
1847 template <JsonStringLike Key,
typename Value>
1850 auto &storage = get_or_promote<json_object_type>(
"JSON type invalid for object emplacement");
1851 auto result = storage.emplace(convert_to_string(std::move(key)), std::forward<Value>(value));
1854 it.m_iterator = result.first;
1856 return {it, result.second};
1860 template <
typename... Args>
1863 auto &storage = get_or_promote<json_array_type>(
"JSON type invalid for array emplacement");
1864 return storage.emplace_back(std::forward<Args>(args)...);
1868 template <JsonStringLike T>
1871 auto &storage = get<json_object_type>(
"JSON type invalid for erase(key)");
1872 return storage.erase(convert_to_string(std::move(key)));
1876 template <JsonString T>
1881 throw JsonException(*
this,
"JSON type invalid for swap(string)");
1884 T
string =
static_cast<T
>(*this);
1886 *
this = std::move(other);
1887 other = std::move(
string);
1891 template <JsonObject T>
1896 throw JsonException(*
this,
"JSON type invalid for swap(object)");
1899 T
object =
static_cast<T
>(*this);
1901 *
this = std::move(other);
1902 other = std::move(
object);
1906 template <JsonArray T>
1911 throw JsonException(*
this,
"JSON type invalid for swap(array)");
1914 T array =
static_cast<T
>(*this);
1916 *
this = std::move(other);
1917 other = std::move(array);
1921 template <JsonObject T>
1924 get_or_promote<json_object_type>(
"JSON type invalid for merging");
1927 for (
auto it = other.begin(); it != other.end();)
1935 insert(std::move(it->first), std::move(it->second));
1936 it = other.erase(it);
1942 template <JsonObject T>
1945 get_or_promote<json_object_type>(
"JSON type invalid for merging");
1948 for (
auto &&it : other)
1952 insert(std::move(it.first), std::move(it.second));
1958 template <JsonStringLike T>
1961 const auto &storage = get<json_object_type>(
"JSON type invalid for count(key)");
1962 return storage.count(convert_to_string(std::move(key)));
1966 template <JsonStringLike T>
1969 auto &storage = get<json_object_type>(
"JSON type invalid for find(key)");
1972 it.m_iterator = storage.find(convert_to_string(std::move(key)));
1978 template <JsonStringLike T>
1981 const auto &storage = get<json_object_type>(
"JSON type invalid for find(key)");
1984 it.m_iterator = storage.find(convert_to_string(std::move(key)));
1990 template <JsonStringLike T>
1993 const auto &storage = get<json_object_type>(
"JSON type invalid for contains(key)");
1994 return storage.contains(convert_to_string(std::move(key)));
1998 template <JsonStringLike T>
1999 json_string_type Json::convert_to_string(T value)
2003 if constexpr (fly::SameAs<typename StringType::string_type, json_string_type>)
2005 if (StringType::validate(value))
2007 return validate_string(std::move(value));
2012 if (
auto result = StringType::template convert<json_string_type>(value); result)
2014 return validate_string(*std::move(result));
2018 throw JsonException(
"Could not convert string-like type to a JSON string");
2022 template <
typename... Args>
2023 Json::object_insertion_result<Args...> Json::object_inserter(Args &&...args)
2025 auto &storage = get<json_object_type>(
"JSON type invalid for object insertion");
2027 if constexpr (std::is_void_v<object_insertion_result<Args...>>)
2029 storage.insert(std::forward<Args>(args)...);
2033 auto result = storage.insert(std::forward<Args>(args)...);
2036 it.m_iterator = result.first;
2038 return {it, result.second};
2043 template <
typename... Args>
2044 Json::iterator Json::array_inserter(const_iterator position, Args &&...args)
2046 auto &storage = get<json_array_type>(
"JSON type invalid for array insertion");
2048 if (position.m_json !=
this)
2050 throw JsonException(
"Provided iterator is for a different Json instance");
2053 const auto &position_iterator =
2054 std::get<typename const_iterator::array_iterator_type>(position.m_iterator);
2057 it.m_iterator = storage.insert(position_iterator, std::forward<Args>(args)...);
2063 template <
typename T>
2064 inline T &Json::get(
const char *error_message)
2066 auto *storage = std::get_if<T>(&m_value);
2068 if (storage ==
nullptr)
2070 throw JsonException(*
this, error_message);
2077 template <
typename T>
2078 inline T &Json::get_or_promote(
const char *error_message)
2080 auto *storage = std::get_if<T>(&m_value);
2082 if (storage ==
nullptr)
2086 return m_value.emplace<T>();
2089 throw JsonException(*
this, error_message);
2096 template <
typename T>
2097 inline const T &Json::get(
const char *error_message)
const
2099 const auto *storage = std::get_if<T>(&m_value);
2101 if (storage ==
nullptr)
2103 throw JsonException(*
this, error_message);
2112 template <
typename CharType>
2116 using string_type = std::basic_string<CharType>;
2126 template <
typename FormatContext>
2129 if constexpr (fly::SameAs<CharType, fly::json_char_type>)
2135 auto serialized = JsonStringType::convert<string_type>(json.
serialize());
2145 struct std::hash<fly::Json>
2156 std::size_t type = json.m_value.index();
2158 auto visitor = [type](
const auto &storage) -> std::size_t {
2159 using S = decltype(storage);
2161 if constexpr (fly::JsonNull<S>)
2163 return hash_combine(type, 0);
2165 else if constexpr (fly::JsonObject<S>)
2167 std::hash<typename fly::json_object_type::key_type> key_hasher {};
2168 std::hash<typename fly::json_object_type::mapped_type> value_hasher {};
2169 std::size_t result = hash_combine(type, storage.size());
2171 for (
const auto &value : storage)
2173 result = hash_combine(result, key_hasher(value.first));
2174 result = hash_combine(result, value_hasher(value.second));
2179 else if constexpr (fly::JsonArray<S>)
2181 std::hash<typename fly::json_array_type::value_type> hasher {};
2182 std::size_t result = hash_combine(type, storage.size());
2184 for (
const auto &value : storage)
2186 result = hash_combine(result, hasher(value));
2193 std::hash<std::remove_cvref_t<S>> hasher {};
2194 return hash_combine(type, hasher(storage));
2198 return std::visit(std::move(visitor), json.m_value);
2210 static constexpr std::size_t hash_combine(std::size_t value1, std::size_t value2)
2212 using namespace fly::literals::numeric_literals;
2214 value1 ^= value2 + 0x9e3779b9_zu + (value1 << 6_zu) + (value1 >> 2_zu);
Definition: string.hpp:51
static string_type format(FormatString< ParameterTypes... > &&fmt, ParameterTypes &&...parameters)
Definition: json_exception.hpp:19
void pop_back()
Definition: json.cpp:612
size_type erase(T key)
Definition: json.hpp:1869
bool empty() const
Definition: json.cpp:388
const_iterator cbegin() const
Definition: json.cpp:328
reference front()
Definition: json.cpp:274
reference operator=(Json json) noexcept
Definition: json.cpp:57
const_reverse_iterator crend() const
Definition: json.cpp:382
bool is_signed_integer() const
Definition: json.cpp:178
size_type capacity() const
Definition: json.cpp:453
iterator end()
Definition: json.cpp:334
bool is_string() const
Definition: json.cpp:146
std::pair< iterator, bool > insert_or_assign(Key key, Json &&value)
Definition: json.hpp:1833
const_reverse_iterator crbegin() const
Definition: json.cpp:364
bool is_null() const
Definition: json.cpp:140
bool is_boolean() const
Definition: json.cpp:172
bool is_float() const
Definition: json.cpp:190
void clear()
Definition: json.cpp:507
iterator find(T key)
Definition: json.hpp:1967
bool contains(T key) const
Definition: json.hpp:1991
bool is_unsigned_integer() const
Definition: json.cpp:184
iterator begin()
Definition: json.cpp:316
bool is_object_like() const
Definition: json.cpp:158
reference back()
Definition: json.cpp:286
const_iterator cend() const
Definition: json.cpp:346
json_string_type serialize() const
Definition: json.cpp:64
bool is_object() const
Definition: json.cpp:152
reference at(T key)
Definition: json.hpp:1774
std::pair< iterator, bool > insert(Key key, const Json &value)
Definition: json.hpp:1819
void merge(Json &other)
Definition: json.cpp:710
void reserve(size_type capacity)
Definition: json.cpp:480
reference operator[](T key)
Definition: json.hpp:1804
reverse_iterator rend()
Definition: json.cpp:370
void resize(size_type size)
Definition: json.cpp:434
Json(T value) noexcept(false)
reverse_iterator rbegin()
Definition: json.cpp:352
size_type count(T key) const
Definition: json.hpp:1959
void push_back(const Json &value)
Definition: json.cpp:598
std::pair< iterator, bool > emplace(Key key, Value &&value)
Definition: json.hpp:1848
Json::reference emplace_back(Args &&...args)
Definition: json.hpp:1861
size_type size() const
Definition: json.cpp:411
bool is_array() const
Definition: json.cpp:166
void swap(reference json)
Definition: json.cpp:704
Definition: json_iterator.hpp:58
Definition: json_reverse_iterator.hpp:22
std::size_t operator()(const fly::Json &json) const
Definition: json.hpp:2154