mirror of
https://github.com/MaaAssistantArknights/MaaAssistantArknights.git
synced 2026-07-15 17:30:27 +08:00
chore: meoJson update to v4.3.4 (#12460)
* chore: meoJson update to v4.3.2 * chore: meoJson update to v4.3.4
This commit is contained in:
320
3rdparty/include/meojson/common/array.hpp
vendored
320
3rdparty/include/meojson/common/array.hpp
vendored
@@ -1,3 +1,5 @@
|
||||
// IWYU pragma: private, include <meojson/json.hpp>
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <initializer_list>
|
||||
@@ -37,37 +39,86 @@ public:
|
||||
// explicit basic_array(const basic_value<string_t>& val);
|
||||
// explicit basic_array(basic_value<string_t>&& val);
|
||||
|
||||
template <typename collection_t,
|
||||
std::enable_if_t<_utils::is_collection<collection_t> &&
|
||||
std::is_constructible_v<value_type, _utils::range_value_t<collection_t>>,
|
||||
bool> = true>
|
||||
template <
|
||||
typename collection_t,
|
||||
std::enable_if_t<
|
||||
_utils::is_collection<collection_t>
|
||||
&& std::is_constructible_v<value_type, _utils::range_value_t<collection_t>>,
|
||||
bool> = true>
|
||||
basic_array(collection_t arr)
|
||||
: _array_data(std::make_move_iterator(arr.begin()), std::make_move_iterator(arr.end()))
|
||||
{}
|
||||
template <typename jsonization_t,
|
||||
std::enable_if_t<_utils::has_to_json_in_member<jsonization_t>::value, bool> = true>
|
||||
basic_array(const jsonization_t& value) : basic_array(value.to_json())
|
||||
{}
|
||||
template <typename jsonization_t,
|
||||
std::enable_if_t<_utils::has_to_json_in_templ_spec<jsonization_t>::value, bool> = true>
|
||||
basic_array(const jsonization_t& value) : basic_array(ext::jsonization<jsonization_t>().to_json(value))
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
template <
|
||||
typename fixed_array_t,
|
||||
std::enable_if_t<_utils::is_fixed_array<fixed_array_t>, bool> = true>
|
||||
basic_array(const fixed_array_t& arr)
|
||||
: _array_data(arr.begin(), arr.end())
|
||||
{
|
||||
}
|
||||
|
||||
template <
|
||||
typename jsonization_t,
|
||||
std::enable_if_t<_utils::has_to_json_in_member<jsonization_t>::value, bool> = true>
|
||||
basic_array(const jsonization_t& value)
|
||||
: basic_array(value.to_json())
|
||||
{
|
||||
}
|
||||
|
||||
template <
|
||||
typename jsonization_t,
|
||||
std::enable_if_t<_utils::has_to_json_in_templ_spec<jsonization_t>::value, bool> = true>
|
||||
basic_array(const jsonization_t& value)
|
||||
: basic_array(ext::jsonization<jsonization_t>().to_json(value))
|
||||
{
|
||||
}
|
||||
|
||||
template <typename... elem_ts>
|
||||
basic_array(const std::tuple<elem_ts...>& tup)
|
||||
{
|
||||
foreach_tuple(tup, std::make_index_sequence<std::tuple_size_v<std::tuple<elem_ts...>>>());
|
||||
}
|
||||
template <typename first_t, typename second_t>
|
||||
basic_array(std::pair<first_t, second_t> pair)
|
||||
: _array_data({ std::move(pair.first), std::move(pair.second) })
|
||||
{
|
||||
}
|
||||
|
||||
~basic_array() noexcept = default;
|
||||
|
||||
bool empty() const noexcept { return _array_data.empty(); }
|
||||
|
||||
size_t size() const noexcept { return _array_data.size(); }
|
||||
|
||||
bool contains(size_t pos) const { return pos < _array_data.size(); }
|
||||
|
||||
bool exists(size_t pos) const { return contains(pos); }
|
||||
|
||||
const basic_value<string_t>& at(size_t pos) const;
|
||||
|
||||
string_t dumps(std::optional<size_t> indent = std::nullopt) const { return indent ? format(*indent) : to_string(); }
|
||||
string_t dumps(std::optional<size_t> indent = std::nullopt) const
|
||||
{
|
||||
return indent ? format(*indent) : to_string();
|
||||
}
|
||||
|
||||
string_t to_string() const;
|
||||
|
||||
string_t format(size_t indent = 4) const { return format(indent, 0); }
|
||||
|
||||
template <typename value_t>
|
||||
bool all() const;
|
||||
template <typename value_t, template <typename...> typename collection_t = std::vector>
|
||||
collection_t<value_t> as_collection() const;
|
||||
template <
|
||||
typename value_t,
|
||||
size_t Size,
|
||||
template <typename, size_t> typename fixed_array_t = std::array>
|
||||
fixed_array_t<value_t, Size> as_fixed_array() const;
|
||||
template <typename... elem_ts>
|
||||
std::tuple<elem_ts...> as_tuple() const;
|
||||
template <typename first_t, typename second_t>
|
||||
std::pair<first_t, second_t> as_pair() const;
|
||||
|
||||
// Usage: get(key_1, key_2, ..., default_value);
|
||||
template <typename... key_then_default_value_t>
|
||||
@@ -112,23 +163,54 @@ public:
|
||||
|
||||
basic_array<string_t>& operator=(const basic_array<string_t>&) = default;
|
||||
basic_array<string_t>& operator=(basic_array<string_t>&&) noexcept = default;
|
||||
template <typename value_t, std::enable_if_t<std::is_convertible_v<value_t, basic_array<string_t>>, bool> = true>
|
||||
|
||||
template <
|
||||
typename value_t,
|
||||
std::enable_if_t<std::is_convertible_v<value_t, basic_array<string_t>>, bool> = true>
|
||||
basic_array<string_t>& operator=(value_t rhs)
|
||||
{
|
||||
return *this = basic_array<string_t>(std::move(rhs));
|
||||
}
|
||||
|
||||
bool operator==(const basic_array<string_t>& rhs) const;
|
||||
|
||||
bool operator!=(const basic_array<string_t>& rhs) const { return !(*this == rhs); }
|
||||
|
||||
template <typename value_t, template <typename...> typename collection_t = std::vector,
|
||||
std::enable_if_t<_utils::is_collection<collection_t<value_t>>, bool> = true>
|
||||
template <
|
||||
typename value_t,
|
||||
template <typename...> typename collection_t = std::vector,
|
||||
std::enable_if_t<_utils::is_collection<collection_t<value_t>>, bool> = true>
|
||||
explicit operator collection_t<value_t>() const
|
||||
{
|
||||
return as_collection<value_t, collection_t>();
|
||||
}
|
||||
template <typename jsonization_t,
|
||||
std::enable_if_t<_utils::has_from_json_in_member<jsonization_t, string_t>::value, bool> = true>
|
||||
|
||||
template <
|
||||
typename value_t,
|
||||
size_t Size,
|
||||
template <typename, size_t> typename fixed_array_t = std::array,
|
||||
std::enable_if_t<_utils::is_fixed_array<fixed_array_t<value_t, Size>>, bool> = true>
|
||||
explicit operator fixed_array_t<value_t, Size>() const
|
||||
{
|
||||
return as_fixed_array<value_t, Size, fixed_array_t>();
|
||||
}
|
||||
|
||||
template <typename... elem_ts>
|
||||
explicit operator std::tuple<elem_ts...>() const
|
||||
{
|
||||
return as_tuple<elem_ts...>();
|
||||
}
|
||||
|
||||
template <typename elem1_t, typename elem2_t>
|
||||
explicit operator std::pair<elem1_t, elem2_t>() const
|
||||
{
|
||||
return as_pair<elem1_t, elem2_t>();
|
||||
}
|
||||
|
||||
template <
|
||||
typename jsonization_t,
|
||||
std::enable_if_t<_utils::has_from_json_in_member<jsonization_t, string_t>::value, bool> =
|
||||
true>
|
||||
explicit operator jsonization_t() const
|
||||
{
|
||||
jsonization_t dst {};
|
||||
@@ -137,8 +219,12 @@ public:
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
template <typename jsonization_t,
|
||||
std::enable_if_t<_utils::has_from_json_in_templ_spec<jsonization_t, string_t>::value, bool> = true>
|
||||
|
||||
template <
|
||||
typename jsonization_t,
|
||||
std::enable_if_t<
|
||||
_utils::has_from_json_in_templ_spec<jsonization_t, string_t>::value,
|
||||
bool> = true>
|
||||
explicit operator jsonization_t() const
|
||||
{
|
||||
jsonization_t dst {};
|
||||
@@ -150,13 +236,25 @@ public:
|
||||
|
||||
private:
|
||||
template <typename... key_then_default_value_t, size_t... keys_indexes_t>
|
||||
auto get(std::tuple<key_then_default_value_t...> keys_then_default_value,
|
||||
std::index_sequence<keys_indexes_t...>) const;
|
||||
auto
|
||||
get(std::tuple<key_then_default_value_t...> keys_then_default_value,
|
||||
std::index_sequence<keys_indexes_t...>) const;
|
||||
template <typename value_t, typename... rest_keys_t>
|
||||
auto get_helper(const value_t& default_value, size_t pos, rest_keys_t&&... rest) const;
|
||||
template <typename value_t>
|
||||
auto get_helper(const value_t& default_value, size_t pos) const;
|
||||
|
||||
template <typename tuple_t>
|
||||
tuple_t as_tuple_templ() const;
|
||||
template <size_t index, typename tuple_t>
|
||||
void set_tuple(tuple_t& tup) const;
|
||||
|
||||
template <typename Tuple, std::size_t... Is>
|
||||
void foreach_tuple(const Tuple& t, std::index_sequence<Is...>)
|
||||
{
|
||||
(_array_data.emplace_back(std::get<Is>(t)), ...);
|
||||
}
|
||||
|
||||
string_t format(size_t indent, size_t indent_times) const;
|
||||
|
||||
private:
|
||||
@@ -164,15 +262,20 @@ private:
|
||||
};
|
||||
|
||||
template <typename string_t>
|
||||
inline basic_array<string_t>::basic_array(std::initializer_list<value_type> init_list) : _array_data(init_list)
|
||||
{}
|
||||
inline basic_array<string_t>::basic_array(std::initializer_list<value_type> init_list)
|
||||
: _array_data(init_list)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename string_t>
|
||||
inline basic_array<string_t>::basic_array(typename raw_array::size_type size) : _array_data(size)
|
||||
{}
|
||||
inline basic_array<string_t>::basic_array(typename raw_array::size_type size)
|
||||
: _array_data(size)
|
||||
{
|
||||
}
|
||||
|
||||
// template <typename string_t>
|
||||
// inline basic_array<string_t>::basic_array(const basic_value<string_t>& val) : basic_array<string_t>(val.as_array())
|
||||
// inline basic_array<string_t>::basic_array(const basic_value<string_t>& val) :
|
||||
// basic_array<string_t>(val.as_array())
|
||||
//{}
|
||||
//
|
||||
// template <typename string_t>
|
||||
@@ -202,8 +305,9 @@ template <typename string_t>
|
||||
template <typename... args_t>
|
||||
inline decltype(auto) basic_array<string_t>::emplace_back(args_t&&... args)
|
||||
{
|
||||
static_assert(std::is_constructible_v<value_type, args_t...>,
|
||||
"Parameter can't be used to construct a raw_array::value_type");
|
||||
static_assert(
|
||||
std::is_constructible_v<value_type, args_t...>,
|
||||
"Parameter can't be used to construct a raw_array::value_type");
|
||||
return _array_data.emplace_back(std::forward<args_t>(args)...);
|
||||
}
|
||||
|
||||
@@ -266,18 +370,18 @@ inline bool basic_array<string_t>::all() const
|
||||
|
||||
namespace _as_collection_helper
|
||||
{
|
||||
template <typename T>
|
||||
class has_emplace_back
|
||||
{
|
||||
template <typename U>
|
||||
static auto test(int) -> decltype(std::declval<U>().emplace_back(), std::true_type());
|
||||
template <typename T>
|
||||
class has_emplace_back
|
||||
{
|
||||
template <typename U>
|
||||
static auto test(int) -> decltype(std::declval<U>().emplace_back(), std::true_type());
|
||||
|
||||
template <typename U>
|
||||
static std::false_type test(...);
|
||||
template <typename U>
|
||||
static std::false_type test(...);
|
||||
|
||||
public:
|
||||
static constexpr bool value = decltype(test<T>(0))::value;
|
||||
};
|
||||
public:
|
||||
static constexpr bool value = decltype(test<T>(0))::value;
|
||||
};
|
||||
}
|
||||
|
||||
template <typename string_t>
|
||||
@@ -298,31 +402,94 @@ inline collection_t<value_t> basic_array<string_t>::as_collection() const
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename string_t>
|
||||
template <typename value_t, size_t Size, template <typename, size_t> typename fixed_array_t>
|
||||
inline fixed_array_t<value_t, Size> basic_array<string_t>::as_fixed_array() const
|
||||
{
|
||||
if (size() != Size) {
|
||||
throw exception("Wrong array size");
|
||||
}
|
||||
|
||||
fixed_array_t<value_t, Size> result;
|
||||
for (size_t i = 0; i < Size; ++i) {
|
||||
result.at(i) = _array_data.at(i).template as<value_t>();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename string_t>
|
||||
template <size_t index, typename tuple_t>
|
||||
inline void basic_array<string_t>::set_tuple(tuple_t& tup) const
|
||||
{
|
||||
using elem_t = std::tuple_element_t<index, tuple_t>;
|
||||
|
||||
if constexpr (index > 0) {
|
||||
set_tuple<index - 1>(tup);
|
||||
}
|
||||
|
||||
std::get<index>(tup) = static_cast<elem_t>(at(index));
|
||||
}
|
||||
|
||||
template <typename string_t>
|
||||
template <typename tuple_t>
|
||||
inline tuple_t basic_array<string_t>::as_tuple_templ() const
|
||||
{
|
||||
constexpr size_t tuple_size = std::tuple_size_v<tuple_t>;
|
||||
|
||||
if (size() != tuple_size) {
|
||||
throw exception("Wrong array size");
|
||||
}
|
||||
|
||||
tuple_t result;
|
||||
set_tuple<tuple_size - 1>(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename string_t>
|
||||
template <typename... elem_ts>
|
||||
inline std::tuple<elem_ts...> basic_array<string_t>::as_tuple() const
|
||||
{
|
||||
return as_tuple_templ<std::tuple<elem_ts...>>();
|
||||
}
|
||||
|
||||
template <typename string_t>
|
||||
template <typename first_t, typename second_t>
|
||||
inline std::pair<first_t, second_t> basic_array<string_t>::as_pair() const
|
||||
{
|
||||
return as_tuple_templ<std::pair<first_t, second_t>>();
|
||||
}
|
||||
|
||||
template <typename string_t>
|
||||
template <typename... key_then_default_value_t>
|
||||
inline auto basic_array<string_t>::get(key_then_default_value_t&&... keys_then_default_value) const
|
||||
{
|
||||
return get(std::forward_as_tuple(keys_then_default_value...),
|
||||
std::make_index_sequence<sizeof...(keys_then_default_value) - 1> {});
|
||||
return get(
|
||||
std::forward_as_tuple(keys_then_default_value...),
|
||||
std::make_index_sequence<sizeof...(keys_then_default_value) - 1> {});
|
||||
}
|
||||
|
||||
template <typename string_t>
|
||||
template <typename... key_then_default_value_t, size_t... keys_indexes_t>
|
||||
inline auto basic_array<string_t>::get(std::tuple<key_then_default_value_t...> keys_then_default_value,
|
||||
std::index_sequence<keys_indexes_t...>) const
|
||||
inline auto basic_array<string_t>::get(
|
||||
std::tuple<key_then_default_value_t...> keys_then_default_value,
|
||||
std::index_sequence<keys_indexes_t...>) const
|
||||
{
|
||||
constexpr unsigned long default_value_index = sizeof...(key_then_default_value_t) - 1;
|
||||
return get_helper(std::get<default_value_index>(keys_then_default_value),
|
||||
std::get<keys_indexes_t>(keys_then_default_value)...);
|
||||
return get_helper(
|
||||
std::get<default_value_index>(keys_then_default_value),
|
||||
std::get<keys_indexes_t>(keys_then_default_value)...);
|
||||
}
|
||||
|
||||
template <typename string_t>
|
||||
template <typename value_t, typename... rest_keys_t>
|
||||
inline auto basic_array<string_t>::get_helper(const value_t& default_value, size_t pos, rest_keys_t&&... rest) const
|
||||
inline auto basic_array<string_t>::get_helper(
|
||||
const value_t& default_value,
|
||||
size_t pos,
|
||||
rest_keys_t&&... rest) const
|
||||
{
|
||||
constexpr bool is_json = std::is_same_v<basic_value<string_t>, value_t> ||
|
||||
std::is_same_v<basic_array<string_t>, value_t> ||
|
||||
std::is_same_v<basic_object<string_t>, value_t>;
|
||||
constexpr bool is_json = std::is_same_v<basic_value<string_t>, value_t>
|
||||
|| std::is_same_v<basic_array<string_t>, value_t>
|
||||
|| std::is_same_v<basic_object<string_t>, value_t>;
|
||||
constexpr bool is_string = std::is_constructible_v<string_t, value_t> && !is_json;
|
||||
|
||||
if (!contains(pos)) {
|
||||
@@ -341,9 +508,9 @@ template <typename string_t>
|
||||
template <typename value_t>
|
||||
inline auto basic_array<string_t>::get_helper(const value_t& default_value, size_t pos) const
|
||||
{
|
||||
constexpr bool is_json = std::is_same_v<basic_value<string_t>, value_t> ||
|
||||
std::is_same_v<basic_array<string_t>, value_t> ||
|
||||
std::is_same_v<basic_object<string_t>, value_t>;
|
||||
constexpr bool is_json = std::is_same_v<basic_value<string_t>, value_t>
|
||||
|| std::is_same_v<basic_array<string_t>, value_t>
|
||||
|| std::is_same_v<basic_object<string_t>, value_t>;
|
||||
constexpr bool is_string = std::is_constructible_v<string_t, value_t> && !is_json;
|
||||
|
||||
if (!contains(pos)) {
|
||||
@@ -382,7 +549,8 @@ inline std::optional<value_t> basic_array<string_t>::find(size_t pos) const
|
||||
return std::nullopt;
|
||||
}
|
||||
const auto& val = _array_data.at(pos);
|
||||
return val.template is<value_t>() ? std::optional<value_t>(val.template as<value_t>()) : std::nullopt;
|
||||
return val.template is<value_t>() ? std::optional<value_t>(val.template as<value_t>())
|
||||
: std::nullopt;
|
||||
}
|
||||
|
||||
template <typename string_t>
|
||||
@@ -434,25 +602,29 @@ inline typename basic_array<string_t>::reverse_iterator basic_array<string_t>::r
|
||||
}
|
||||
|
||||
template <typename string_t>
|
||||
inline typename basic_array<string_t>::const_reverse_iterator basic_array<string_t>::rbegin() const noexcept
|
||||
inline typename basic_array<string_t>::const_reverse_iterator
|
||||
basic_array<string_t>::rbegin() const noexcept
|
||||
{
|
||||
return _array_data.rbegin();
|
||||
}
|
||||
|
||||
template <typename string_t>
|
||||
inline typename basic_array<string_t>::const_reverse_iterator basic_array<string_t>::rend() const noexcept
|
||||
inline typename basic_array<string_t>::const_reverse_iterator
|
||||
basic_array<string_t>::rend() const noexcept
|
||||
{
|
||||
return _array_data.rend();
|
||||
}
|
||||
|
||||
template <typename string_t>
|
||||
inline typename basic_array<string_t>::const_reverse_iterator basic_array<string_t>::crbegin() const noexcept
|
||||
inline typename basic_array<string_t>::const_reverse_iterator
|
||||
basic_array<string_t>::crbegin() const noexcept
|
||||
{
|
||||
return _array_data.crbegin();
|
||||
}
|
||||
|
||||
template <typename string_t>
|
||||
inline typename basic_array<string_t>::const_reverse_iterator basic_array<string_t>::crend() const noexcept
|
||||
inline typename basic_array<string_t>::const_reverse_iterator
|
||||
basic_array<string_t>::crend() const noexcept
|
||||
{
|
||||
return _array_data.crend();
|
||||
}
|
||||
@@ -470,7 +642,8 @@ inline const basic_value<string_t>& basic_array<string_t>::operator[](size_t pos
|
||||
}
|
||||
|
||||
template <typename string_t>
|
||||
inline basic_array<string_t> basic_array<string_t>::operator+(const basic_array<string_t>& rhs) const&
|
||||
inline basic_array<string_t>
|
||||
basic_array<string_t>::operator+(const basic_array<string_t>& rhs) const&
|
||||
{
|
||||
basic_array<string_t> temp = *this;
|
||||
temp._array_data.insert(_array_data.end(), rhs.begin(), rhs.end());
|
||||
@@ -481,8 +654,10 @@ template <typename string_t>
|
||||
inline basic_array<string_t> basic_array<string_t>::operator+(basic_array<string_t>&& rhs) const&
|
||||
{
|
||||
basic_array<string_t> temp = *this;
|
||||
temp._array_data.insert(_array_data.end(), std::make_move_iterator(rhs.begin()),
|
||||
std::make_move_iterator(rhs.end()));
|
||||
temp._array_data.insert(
|
||||
_array_data.end(),
|
||||
std::make_move_iterator(rhs.begin()),
|
||||
std::make_move_iterator(rhs.end()));
|
||||
return temp;
|
||||
}
|
||||
|
||||
@@ -496,7 +671,10 @@ inline basic_array<string_t> basic_array<string_t>::operator+(const basic_array<
|
||||
template <typename string_t>
|
||||
inline basic_array<string_t> basic_array<string_t>::operator+(basic_array<string_t>&& rhs) &&
|
||||
{
|
||||
_array_data.insert(_array_data.end(), std::make_move_iterator(rhs.begin()), std::make_move_iterator(rhs.end()));
|
||||
_array_data.insert(
|
||||
_array_data.end(),
|
||||
std::make_move_iterator(rhs.begin()),
|
||||
std::make_move_iterator(rhs.end()));
|
||||
return std::move(*this);
|
||||
}
|
||||
|
||||
@@ -510,7 +688,10 @@ inline basic_array<string_t>& basic_array<string_t>::operator+=(const basic_arra
|
||||
template <typename string_t>
|
||||
inline basic_array<string_t>& basic_array<string_t>::operator+=(basic_array<string_t>&& rhs)
|
||||
{
|
||||
_array_data.insert(_array_data.end(), std::make_move_iterator(rhs.begin()), std::make_move_iterator(rhs.end()));
|
||||
_array_data.insert(
|
||||
_array_data.end(),
|
||||
std::make_move_iterator(rhs.begin()),
|
||||
std::make_move_iterator(rhs.end()));
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -520,11 +701,14 @@ inline bool basic_array<string_t>::operator==(const basic_array<string_t>& rhs)
|
||||
return _array_data == rhs._array_data;
|
||||
}
|
||||
|
||||
template <typename ostream_t, typename string_t,
|
||||
typename std_ostream_t =
|
||||
std::basic_ostream<typename string_t::value_type, std::char_traits<typename string_t::value_type>>,
|
||||
typename enable_t =
|
||||
std::enable_if_t<std::is_same_v<std_ostream_t, ostream_t> || std::is_base_of_v<std_ostream_t, ostream_t>>>
|
||||
template <
|
||||
typename ostream_t,
|
||||
typename string_t,
|
||||
typename std_ostream_t = std::basic_ostream<
|
||||
typename string_t::value_type,
|
||||
std::char_traits<typename string_t::value_type>>,
|
||||
typename enable_t = std::enable_if_t<
|
||||
std::is_same_v<std_ostream_t, ostream_t> || std::is_base_of_v<std_ostream_t, ostream_t>>>
|
||||
ostream_t& operator<<(ostream_t& out, const basic_array<string_t>& arr)
|
||||
{
|
||||
out << arr.format();
|
||||
|
||||
13
3rdparty/include/meojson/common/exception.hpp
vendored
13
3rdparty/include/meojson/common/exception.hpp
vendored
@@ -1,3 +1,5 @@
|
||||
// IWYU pragma: private, include <meojson/json.hpp>
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <exception>
|
||||
@@ -9,7 +11,11 @@ class exception : public std::exception
|
||||
{
|
||||
public:
|
||||
exception() = default;
|
||||
exception(const std::string& msg) : _what(msg) {}
|
||||
|
||||
exception(const std::string& msg)
|
||||
: _what(msg)
|
||||
{
|
||||
}
|
||||
|
||||
exception(const exception&) = default;
|
||||
exception& operator=(const exception&) = default;
|
||||
@@ -18,7 +24,10 @@ public:
|
||||
|
||||
virtual ~exception() noexcept override = default;
|
||||
|
||||
virtual const char* what() const noexcept override { return _what.empty() ? "Unknown exception" : _what.c_str(); }
|
||||
virtual const char* what() const noexcept override
|
||||
{
|
||||
return _what.empty() ? "Unknown exception" : _what.c_str();
|
||||
}
|
||||
|
||||
protected:
|
||||
std::string _what;
|
||||
|
||||
174
3rdparty/include/meojson/common/object.hpp
vendored
174
3rdparty/include/meojson/common/object.hpp
vendored
@@ -1,3 +1,5 @@
|
||||
// IWYU pragma: private, include <meojson/json.hpp>
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <initializer_list>
|
||||
@@ -36,31 +38,54 @@ public:
|
||||
// explicit basic_object(const basic_value<string_t>& val);
|
||||
// explicit basic_object(basic_value<string_t>&& val);
|
||||
|
||||
template <typename map_t, std::enable_if_t<_utils::is_map<map_t> &&
|
||||
std::is_constructible_v<value_type, _utils::range_value_t<map_t>>,
|
||||
bool> = true>
|
||||
basic_object(map_t map) : _object_data(std::make_move_iterator(map.begin()), std::make_move_iterator(map.end()))
|
||||
{}
|
||||
template <typename jsonization_t,
|
||||
std::enable_if_t<_utils::has_to_json_in_member<jsonization_t>::value, bool> = true>
|
||||
basic_object(const jsonization_t& value) : basic_object(value.to_json())
|
||||
{}
|
||||
template <typename jsonization_t,
|
||||
std::enable_if_t<_utils::has_to_json_in_templ_spec<jsonization_t>::value, bool> = true>
|
||||
basic_object(const jsonization_t& value) : basic_object(ext::jsonization<jsonization_t>().to_json(value))
|
||||
{}
|
||||
template <
|
||||
typename map_t,
|
||||
std::enable_if_t<
|
||||
_utils::is_map<map_t>
|
||||
&& std::is_constructible_v<value_type, _utils::range_value_t<map_t>>,
|
||||
bool> = true>
|
||||
basic_object(map_t map)
|
||||
: _object_data(std::make_move_iterator(map.begin()), std::make_move_iterator(map.end()))
|
||||
{
|
||||
}
|
||||
|
||||
template <
|
||||
typename jsonization_t,
|
||||
std::enable_if_t<_utils::has_to_json_in_member<jsonization_t>::value, bool> = true>
|
||||
basic_object(const jsonization_t& value)
|
||||
: basic_object(value.to_json())
|
||||
{
|
||||
}
|
||||
|
||||
template <
|
||||
typename jsonization_t,
|
||||
std::enable_if_t<_utils::has_to_json_in_templ_spec<jsonization_t>::value, bool> = true>
|
||||
basic_object(const jsonization_t& value)
|
||||
: basic_object(ext::jsonization<jsonization_t>().to_json(value))
|
||||
{
|
||||
}
|
||||
|
||||
~basic_object() = default;
|
||||
|
||||
bool empty() const noexcept { return _object_data.empty(); }
|
||||
|
||||
size_t size() const noexcept { return _object_data.size(); }
|
||||
|
||||
bool contains(const string_t& key) const;
|
||||
|
||||
bool exists(const string_t& key) const { return contains(key); }
|
||||
|
||||
const basic_value<string_t>& at(const string_t& key) const;
|
||||
|
||||
string_t dumps(std::optional<size_t> indent = std::nullopt) const { return indent ? format(*indent) : to_string(); }
|
||||
string_t dumps(std::optional<size_t> indent = std::nullopt) const
|
||||
{
|
||||
return indent ? format(*indent) : to_string();
|
||||
}
|
||||
|
||||
string_t to_string() const;
|
||||
|
||||
string_t format(size_t indent = 4) const { return format(indent, 0); }
|
||||
|
||||
template <typename value_t>
|
||||
bool all() const;
|
||||
template <typename value_t, template <typename...> typename map_t = std::map>
|
||||
@@ -102,23 +127,32 @@ public:
|
||||
|
||||
basic_object<string_t>& operator=(const basic_object<string_t>&) = default;
|
||||
basic_object<string_t>& operator=(basic_object<string_t>&&) = default;
|
||||
template <typename value_t, std::enable_if_t<std::is_convertible_v<value_t, basic_object<string_t>>, bool> = true>
|
||||
|
||||
template <
|
||||
typename value_t,
|
||||
std::enable_if_t<std::is_convertible_v<value_t, basic_object<string_t>>, bool> = true>
|
||||
basic_object<string_t>& operator=(value_t rhs)
|
||||
{
|
||||
return *this = basic_object<string_t>(std::move(rhs));
|
||||
}
|
||||
|
||||
bool operator==(const basic_object<string_t>& rhs) const;
|
||||
|
||||
bool operator!=(const basic_object<string_t>& rhs) const { return !(*this == rhs); }
|
||||
|
||||
template <typename value_t, template <typename...> typename map_t = std::map,
|
||||
std::enable_if_t<_utils::is_map<map_t<string_t, value_t>>, bool> = true>
|
||||
template <
|
||||
typename value_t,
|
||||
template <typename...> typename map_t = std::map,
|
||||
std::enable_if_t<_utils::is_map<map_t<string_t, value_t>>, bool> = true>
|
||||
explicit operator map_t<string_t, value_t>() const
|
||||
{
|
||||
return as_map<value_t, map_t>();
|
||||
}
|
||||
template <typename jsonization_t,
|
||||
std::enable_if_t<_utils::has_from_json_in_member<jsonization_t, string_t>::value, bool> = true>
|
||||
|
||||
template <
|
||||
typename jsonization_t,
|
||||
std::enable_if_t<_utils::has_from_json_in_member<jsonization_t, string_t>::value, bool> =
|
||||
true>
|
||||
explicit operator jsonization_t() const
|
||||
{
|
||||
jsonization_t dst {};
|
||||
@@ -127,8 +161,12 @@ public:
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
template <typename jsonization_t,
|
||||
std::enable_if_t<_utils::has_from_json_in_templ_spec<jsonization_t, string_t>::value, bool> = true>
|
||||
|
||||
template <
|
||||
typename jsonization_t,
|
||||
std::enable_if_t<
|
||||
_utils::has_from_json_in_templ_spec<jsonization_t, string_t>::value,
|
||||
bool> = true>
|
||||
explicit operator jsonization_t() const
|
||||
{
|
||||
jsonization_t dst {};
|
||||
@@ -140,8 +178,9 @@ public:
|
||||
|
||||
private:
|
||||
template <typename... key_then_default_value_t, size_t... keys_indexes_t>
|
||||
auto get(std::tuple<key_then_default_value_t...> keys_then_default_value,
|
||||
std::index_sequence<keys_indexes_t...>) const;
|
||||
auto
|
||||
get(std::tuple<key_then_default_value_t...> keys_then_default_value,
|
||||
std::index_sequence<keys_indexes_t...>) const;
|
||||
template <typename value_t, typename... rest_keys_t>
|
||||
auto get_helper(const value_t& default_value, const string_t& key, rest_keys_t&&... rest) const;
|
||||
template <typename value_t>
|
||||
@@ -155,8 +194,11 @@ private:
|
||||
|
||||
template <typename string_t>
|
||||
inline basic_object<string_t>::basic_object(std::initializer_list<value_type> init_list)
|
||||
: _object_data(std::make_move_iterator(init_list.begin()), std::make_move_iterator(init_list.end()))
|
||||
{}
|
||||
: _object_data(
|
||||
std::make_move_iterator(init_list.begin()),
|
||||
std::make_move_iterator(init_list.end()))
|
||||
{
|
||||
}
|
||||
|
||||
// template <typename string_t>
|
||||
// inline basic_object<string_t>::basic_object(const basic_value<string_t>& val) :
|
||||
@@ -202,9 +244,10 @@ template <typename string_t>
|
||||
template <typename... args_t>
|
||||
inline decltype(auto) basic_object<string_t>::emplace(args_t&&... args)
|
||||
{
|
||||
static_assert(std::is_constructible_v<value_type, args_t...>,
|
||||
"Parameter can't be used to construct a raw_object::value_type");
|
||||
return _object_data.emplace(std::forward<args_t>(args)...);
|
||||
static_assert(
|
||||
std::is_constructible_v<value_type, args_t...>,
|
||||
"Parameter can't be used to construct a raw_object::value_type");
|
||||
return _object_data.insert_or_assign(std::forward<args_t>(args)...);
|
||||
}
|
||||
|
||||
template <typename string_t>
|
||||
@@ -220,7 +263,8 @@ inline string_t basic_object<string_t>::to_string() const
|
||||
string_t str { '{' };
|
||||
for (auto iter = _object_data.cbegin(); iter != _object_data.cend();) {
|
||||
const auto& [key, val] = *iter;
|
||||
str += char_t('"') + _utils::unescape_string(key) + string_t { '\"', ':' } + val.to_string();
|
||||
str +=
|
||||
char_t('"') + _utils::unescape_string(key) + string_t { '\"', ':' } + val.to_string();
|
||||
if (++iter != _object_data.cend()) {
|
||||
str += ',';
|
||||
}
|
||||
@@ -238,8 +282,8 @@ inline string_t basic_object<string_t>::format(size_t indent, size_t indent_time
|
||||
string_t str { '{', '\n' };
|
||||
for (auto iter = _object_data.cbegin(); iter != _object_data.cend();) {
|
||||
const auto& [key, val] = *iter;
|
||||
str += body_indent + char_t('"') + _utils::unescape_string(key) + string_t { '\"', ':', ' ' } +
|
||||
val.format(indent, indent_times + 1);
|
||||
str += body_indent + char_t('"') + _utils::unescape_string(key)
|
||||
+ string_t { '\"', ':', ' ' } + val.format(indent, indent_times + 1);
|
||||
if (++iter != _object_data.cend()) {
|
||||
str += ',';
|
||||
}
|
||||
@@ -276,28 +320,33 @@ template <typename string_t>
|
||||
template <typename... key_then_default_value_t>
|
||||
inline auto basic_object<string_t>::get(key_then_default_value_t&&... keys_then_default_value) const
|
||||
{
|
||||
return get(std::forward_as_tuple(keys_then_default_value...),
|
||||
std::make_index_sequence<sizeof...(keys_then_default_value) - 1> {});
|
||||
return get(
|
||||
std::forward_as_tuple(keys_then_default_value...),
|
||||
std::make_index_sequence<sizeof...(keys_then_default_value) - 1> {});
|
||||
}
|
||||
|
||||
template <typename string_t>
|
||||
template <typename... key_then_default_value_t, size_t... keys_indexes_t>
|
||||
inline auto basic_object<string_t>::get(std::tuple<key_then_default_value_t...> keys_then_default_value,
|
||||
std::index_sequence<keys_indexes_t...>) const
|
||||
inline auto basic_object<string_t>::get(
|
||||
std::tuple<key_then_default_value_t...> keys_then_default_value,
|
||||
std::index_sequence<keys_indexes_t...>) const
|
||||
{
|
||||
constexpr unsigned long default_value_index = sizeof...(key_then_default_value_t) - 1;
|
||||
return get_helper(std::get<default_value_index>(keys_then_default_value),
|
||||
std::get<keys_indexes_t>(keys_then_default_value)...);
|
||||
return get_helper(
|
||||
std::get<default_value_index>(keys_then_default_value),
|
||||
std::get<keys_indexes_t>(keys_then_default_value)...);
|
||||
}
|
||||
|
||||
template <typename string_t>
|
||||
template <typename value_t, typename... rest_keys_t>
|
||||
inline auto basic_object<string_t>::get_helper(const value_t& default_value, const string_t& key,
|
||||
rest_keys_t&&... rest) const
|
||||
inline auto basic_object<string_t>::get_helper(
|
||||
const value_t& default_value,
|
||||
const string_t& key,
|
||||
rest_keys_t&&... rest) const
|
||||
{
|
||||
constexpr bool is_json = std::is_same_v<basic_value<string_t>, value_t> ||
|
||||
std::is_same_v<basic_array<string_t>, value_t> ||
|
||||
std::is_same_v<basic_object<string_t>, value_t>;
|
||||
constexpr bool is_json = std::is_same_v<basic_value<string_t>, value_t>
|
||||
|| std::is_same_v<basic_array<string_t>, value_t>
|
||||
|| std::is_same_v<basic_object<string_t>, value_t>;
|
||||
constexpr bool is_string = std::is_constructible_v<string_t, value_t> && !is_json;
|
||||
|
||||
if (!contains(key)) {
|
||||
@@ -314,11 +363,12 @@ inline auto basic_object<string_t>::get_helper(const value_t& default_value, con
|
||||
|
||||
template <typename string_t>
|
||||
template <typename value_t>
|
||||
inline auto basic_object<string_t>::get_helper(const value_t& default_value, const string_t& key) const
|
||||
inline auto
|
||||
basic_object<string_t>::get_helper(const value_t& default_value, const string_t& key) const
|
||||
{
|
||||
constexpr bool is_json = std::is_same_v<basic_value<string_t>, value_t> ||
|
||||
std::is_same_v<basic_array<string_t>, value_t> ||
|
||||
std::is_same_v<basic_object<string_t>, value_t>;
|
||||
constexpr bool is_json = std::is_same_v<basic_value<string_t>, value_t>
|
||||
|| std::is_same_v<basic_array<string_t>, value_t>
|
||||
|| std::is_same_v<basic_object<string_t>, value_t>;
|
||||
constexpr bool is_string = std::is_constructible_v<string_t, value_t> && !is_json;
|
||||
|
||||
if (!contains(key)) {
|
||||
@@ -358,7 +408,8 @@ inline std::optional<value_t> basic_object<string_t>::find(const string_t& key)
|
||||
return std::nullopt;
|
||||
}
|
||||
const auto& val = iter->second;
|
||||
return val.template is<value_t>() ? std::optional<value_t>(val.template as<value_t>()) : std::nullopt;
|
||||
return val.template is<value_t>() ? std::optional<value_t>(val.template as<value_t>())
|
||||
: std::nullopt;
|
||||
}
|
||||
|
||||
template <typename string_t>
|
||||
@@ -374,7 +425,8 @@ inline typename basic_object<string_t>::iterator basic_object<string_t>::end() n
|
||||
}
|
||||
|
||||
template <typename string_t>
|
||||
inline typename basic_object<string_t>::const_iterator basic_object<string_t>::begin() const noexcept
|
||||
inline typename basic_object<string_t>::const_iterator
|
||||
basic_object<string_t>::begin() const noexcept
|
||||
{
|
||||
return _object_data.begin();
|
||||
}
|
||||
@@ -386,7 +438,8 @@ inline typename basic_object<string_t>::const_iterator basic_object<string_t>::e
|
||||
}
|
||||
|
||||
template <typename string_t>
|
||||
inline typename basic_object<string_t>::const_iterator basic_object<string_t>::cbegin() const noexcept
|
||||
inline typename basic_object<string_t>::const_iterator
|
||||
basic_object<string_t>::cbegin() const noexcept
|
||||
{
|
||||
return _object_data.cbegin();
|
||||
}
|
||||
@@ -410,7 +463,8 @@ inline basic_value<string_t>& basic_object<string_t>::operator[](string_t&& key)
|
||||
}
|
||||
|
||||
template <typename string_t>
|
||||
inline basic_object<string_t> basic_object<string_t>::operator|(const basic_object<string_t>& rhs) const&
|
||||
inline basic_object<string_t>
|
||||
basic_object<string_t>::operator|(const basic_object<string_t>& rhs) const&
|
||||
{
|
||||
basic_object<string_t> temp = *this;
|
||||
temp._object_data.insert(rhs.begin(), rhs.end());
|
||||
@@ -422,12 +476,15 @@ inline basic_object<string_t> basic_object<string_t>::operator|(basic_object<str
|
||||
{
|
||||
basic_object<string_t> temp = *this;
|
||||
// temp._object_data.merge(std::move(rhs._object_data));
|
||||
temp._object_data.insert(std::make_move_iterator(rhs.begin()), std::make_move_iterator(rhs.end()));
|
||||
temp._object_data.insert(
|
||||
std::make_move_iterator(rhs.begin()),
|
||||
std::make_move_iterator(rhs.end()));
|
||||
return temp;
|
||||
}
|
||||
|
||||
template <typename string_t>
|
||||
inline basic_object<string_t> basic_object<string_t>::operator|(const basic_object<string_t>& rhs) &&
|
||||
inline basic_object<string_t>
|
||||
basic_object<string_t>::operator|(const basic_object<string_t>& rhs) &&
|
||||
{
|
||||
_object_data.insert(rhs.begin(), rhs.end());
|
||||
return std::move(*this);
|
||||
@@ -461,11 +518,14 @@ inline bool basic_object<string_t>::operator==(const basic_object<string_t>& rhs
|
||||
return _object_data == rhs._object_data;
|
||||
}
|
||||
|
||||
template <typename ostream_t, typename string_t,
|
||||
typename std_ostream_t =
|
||||
std::basic_ostream<typename string_t::value_type, std::char_traits<typename string_t::value_type>>,
|
||||
typename enable_t =
|
||||
std::enable_if_t<std::is_same_v<std_ostream_t, ostream_t> || std::is_base_of_v<std_ostream_t, ostream_t>>>
|
||||
template <
|
||||
typename ostream_t,
|
||||
typename string_t,
|
||||
typename std_ostream_t = std::basic_ostream<
|
||||
typename string_t::value_type,
|
||||
std::char_traits<typename string_t::value_type>>,
|
||||
typename enable_t = std::enable_if_t<
|
||||
std::is_same_v<std_ostream_t, ostream_t> || std::is_base_of_v<std_ostream_t, ostream_t>>>
|
||||
ostream_t& operator<<(ostream_t& out, const basic_object<string_t>& obj)
|
||||
{
|
||||
out << obj.format();
|
||||
|
||||
179
3rdparty/include/meojson/common/serialization.hpp
vendored
179
3rdparty/include/meojson/common/serialization.hpp
vendored
@@ -1,3 +1,5 @@
|
||||
// IWYU pragma: private, include <meojson/json.hpp>
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <type_traits>
|
||||
@@ -9,96 +11,101 @@ namespace json
|
||||
{
|
||||
namespace _serialization_helper
|
||||
{
|
||||
template <typename in_t, typename serializer_t>
|
||||
class is_serializable
|
||||
{
|
||||
template <typename U>
|
||||
static auto test(int) -> decltype(std::declval<serializer_t>()(std::declval<U>()), std::true_type());
|
||||
template <typename in_t, typename serializer_t>
|
||||
class is_serializable
|
||||
{
|
||||
template <typename U>
|
||||
static auto test(int)
|
||||
-> decltype(std::declval<serializer_t>()(std::declval<U>()), std::true_type());
|
||||
|
||||
template <typename U>
|
||||
static std::false_type test(...);
|
||||
template <typename U>
|
||||
static std::false_type test(...);
|
||||
|
||||
public:
|
||||
static constexpr bool value = decltype(test<in_t>(0))::value;
|
||||
};
|
||||
public:
|
||||
static constexpr bool value = decltype(test<in_t>(0))::value;
|
||||
};
|
||||
|
||||
struct empty_serializer
|
||||
{
|
||||
// sample:
|
||||
// json::value operator()(const type_1&) const { return ...; }
|
||||
// json::value operator()(const type_2&) const { return ...; }
|
||||
// json::value operator()(const type_3&) const { return ...; }
|
||||
};
|
||||
struct empty_serializer
|
||||
{
|
||||
// sample:
|
||||
// json::value operator()(const type_1&) const { return ...; }
|
||||
// json::value operator()(const type_2&) const { return ...; }
|
||||
// json::value operator()(const type_3&) const { return ...; }
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
void unable_to_serialize()
|
||||
{
|
||||
static_assert(!sizeof(T), "Unable to serialize T. "
|
||||
template <typename T>
|
||||
void unable_to_serialize()
|
||||
{
|
||||
static_assert(
|
||||
!sizeof(T),
|
||||
"Unable to serialize T. "
|
||||
#ifdef _MSC_VER
|
||||
"See T below: " __FUNCSIG__
|
||||
"See T below: " __FUNCSIG__
|
||||
#else
|
||||
// "See T below: " __PRETTY_FUNCTION__
|
||||
// "See T below: " __PRETTY_FUNCTION__
|
||||
|
||||
#endif
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
namespace _serialization_helper
|
||||
{
|
||||
template <typename out_t, typename deserializer_t, typename string_t = default_string_t>
|
||||
class is_deserializable
|
||||
{
|
||||
template <typename U>
|
||||
static auto test(int)
|
||||
-> decltype(std::declval<deserializer_t>()(std::declval<basic_value<string_t>>(), std::declval<U&>()),
|
||||
std::true_type());
|
||||
template <typename out_t, typename deserializer_t, typename string_t = default_string_t>
|
||||
class is_deserializable
|
||||
{
|
||||
template <typename U>
|
||||
static auto test(int)
|
||||
-> decltype(std::declval<deserializer_t>()(std::declval<basic_value<string_t>>(), std::declval<U&>()), std::true_type());
|
||||
|
||||
template <typename U>
|
||||
static std::false_type test(...);
|
||||
template <typename U>
|
||||
static std::false_type test(...);
|
||||
|
||||
public:
|
||||
static constexpr bool value = decltype(test<out_t>(0))::value;
|
||||
};
|
||||
public:
|
||||
static constexpr bool value = decltype(test<out_t>(0))::value;
|
||||
};
|
||||
|
||||
struct empty_deserializer
|
||||
{
|
||||
// sample:
|
||||
// bool operator()(const json::value&, type_1&) const { return ...; }
|
||||
// bool operator()(const json::value&, type_2&) const { return ...; }
|
||||
// bool operator()(const json::value&, type_3&) const { return ...; }
|
||||
};
|
||||
struct empty_deserializer
|
||||
{
|
||||
// sample:
|
||||
// bool operator()(const json::value&, type_1&) const { return ...; }
|
||||
// bool operator()(const json::value&, type_2&) const { return ...; }
|
||||
// bool operator()(const json::value&, type_3&) const { return ...; }
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
void unable_to_deserialize()
|
||||
{
|
||||
static_assert(!sizeof(T), "Unable to deserialize T. "
|
||||
template <typename T>
|
||||
void unable_to_deserialize()
|
||||
{
|
||||
static_assert(
|
||||
!sizeof(T),
|
||||
"Unable to deserialize T. "
|
||||
#ifdef _MSC_VER
|
||||
"See T below: " __FUNCSIG__
|
||||
"See T below: " __FUNCSIG__
|
||||
#else
|
||||
// "See T below: " __PRETTY_FUNCTION__
|
||||
// "See T below: " __PRETTY_FUNCTION__
|
||||
|
||||
#endif
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename in_t, typename serializer_t = _serialization_helper::empty_serializer,
|
||||
typename string_t = default_string_t>
|
||||
template <
|
||||
typename in_t,
|
||||
typename serializer_t = _serialization_helper::empty_serializer,
|
||||
typename string_t = default_string_t>
|
||||
basic_value<string_t> serialize(in_t&& in, const serializer_t& serializer = {})
|
||||
{
|
||||
if constexpr (_serialization_helper::is_serializable<in_t, serializer_t>::value) {
|
||||
return serializer(std::forward<in_t>(in));
|
||||
}
|
||||
else if constexpr (std::is_constructible_v<basic_value<string_t>, in_t>) {
|
||||
return basic_value<string_t>(std::forward<in_t>(in));
|
||||
}
|
||||
else if constexpr (_utils::is_collection<std::decay_t<in_t>>) {
|
||||
else if constexpr (
|
||||
_utils::is_collection<std::decay_t<in_t>> || _utils::is_fixed_array<std::decay_t<in_t>>) {
|
||||
basic_array<string_t> arr;
|
||||
for (auto&& elem : in) {
|
||||
using elem_t = decltype(elem);
|
||||
|
||||
auto j_elem = serialize<elem_t, serializer_t, string_t>(std::forward<elem_t>(elem), serializer);
|
||||
auto j_elem =
|
||||
serialize<elem_t, serializer_t, string_t>(std::forward<elem_t>(elem), serializer);
|
||||
arr.emplace_back(std::move(j_elem));
|
||||
}
|
||||
return arr;
|
||||
@@ -109,27 +116,32 @@ basic_value<string_t> serialize(in_t&& in, const serializer_t& serializer = {})
|
||||
using key_t = decltype(key);
|
||||
using elem_t = decltype(elem);
|
||||
|
||||
auto j_elem = serialize<elem_t, serializer_t, string_t>(std::forward<elem_t>(elem), serializer);
|
||||
auto j_elem =
|
||||
serialize<elem_t, serializer_t, string_t>(std::forward<elem_t>(elem), serializer);
|
||||
obj.emplace(std::forward<key_t>(key), std::move(j_elem));
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
else if constexpr (std::is_constructible_v<basic_value<string_t>, in_t>) {
|
||||
return basic_value<string_t>(std::forward<in_t>(in));
|
||||
}
|
||||
else {
|
||||
_serialization_helper::unable_to_serialize<in_t>();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename out_t, typename deserializer_t = _serialization_helper::empty_deserializer,
|
||||
typename string_t = default_string_t>
|
||||
bool deserialize(const basic_value<string_t>& in, out_t& out, const deserializer_t& deserializer = {})
|
||||
template <
|
||||
typename out_t,
|
||||
typename deserializer_t = _serialization_helper::empty_deserializer,
|
||||
typename string_t = default_string_t>
|
||||
bool deserialize(
|
||||
const basic_value<string_t>& in,
|
||||
out_t& out,
|
||||
const deserializer_t& deserializer = {})
|
||||
{
|
||||
if constexpr (_serialization_helper::is_deserializable<out_t, deserializer_t>::value) {
|
||||
return deserializer(in, out);
|
||||
}
|
||||
else if constexpr (std::is_constructible_v<out_t, basic_value<string_t>>) {
|
||||
out = out_t(in);
|
||||
return true;
|
||||
}
|
||||
else if constexpr (_utils::is_collection<std::decay_t<out_t>>) {
|
||||
if (!in.is_array()) {
|
||||
return false;
|
||||
@@ -149,20 +161,45 @@ bool deserialize(const basic_value<string_t>& in, out_t& out, const deserializer
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else if constexpr (_utils::is_map<std::decay_t<out_t>>) {
|
||||
if (!in.is_object()) {
|
||||
else if constexpr (_utils::is_fixed_array<std::decay_t<out_t>>) {
|
||||
if (!in.is_array()) {
|
||||
return false;
|
||||
}
|
||||
for (auto&& [key, j_elem] : in.as_object()) {
|
||||
auto&& in_as_arr = in.as_array();
|
||||
constexpr size_t out_size = _utils::fixed_array_size<out_t>;
|
||||
if (in_as_arr.size() != out_size) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < out_size; ++i) {
|
||||
auto&& j_elem = in_as_arr.at(i);
|
||||
using elem_t = typename out_t::value_type;
|
||||
elem_t elem {};
|
||||
if (!deserialize<elem_t, deserializer_t, string_t>(j_elem, elem, deserializer)) {
|
||||
return false;
|
||||
}
|
||||
out.emplace(std::move(elem));
|
||||
out.at(i) = std::move(elem);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else if constexpr (_utils::is_map<std::decay_t<out_t>>) {
|
||||
if (!in.is_object()) {
|
||||
return false;
|
||||
}
|
||||
for (auto&& [key, j_elem] : in.as_object()) {
|
||||
using elem_t = typename out_t::mapped_type;
|
||||
elem_t elem {};
|
||||
if (!deserialize<elem_t, deserializer_t, string_t>(j_elem, elem, deserializer)) {
|
||||
return false;
|
||||
}
|
||||
out.emplace(std::forward<decltype(key)>(key), std::move(elem));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else if constexpr (std::is_constructible_v<out_t, basic_value<string_t>>) {
|
||||
out = out_t(in);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
_serialization_helper::unable_to_deserialize<out_t>();
|
||||
}
|
||||
|
||||
4
3rdparty/include/meojson/common/types.hpp
vendored
4
3rdparty/include/meojson/common/types.hpp
vendored
@@ -1,5 +1,7 @@
|
||||
// IWYU pragma: private, include <meojson/json.hpp>
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "array.hpp"
|
||||
#include "object.hpp"
|
||||
#include "value.hpp"
|
||||
#include "value.hpp"
|
||||
|
||||
122
3rdparty/include/meojson/common/utils.hpp
vendored
122
3rdparty/include/meojson/common/utils.hpp
vendored
@@ -1,7 +1,14 @@
|
||||
// IWYU pragma: private, include <meojson/json.hpp>
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <iomanip>
|
||||
#include <limits>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <variant>
|
||||
|
||||
namespace json
|
||||
{
|
||||
@@ -61,12 +68,38 @@ constexpr bool is_container<T, std::void_t<typename T::value_type, range_value_t
|
||||
template <typename T, typename = void>
|
||||
constexpr bool is_map = false;
|
||||
template <typename T>
|
||||
constexpr bool is_map<T, std::void_t<typename T::key_type, typename T::mapped_type>> = is_container<T>;
|
||||
constexpr bool is_map<T, std::void_t<typename T::key_type, typename T::mapped_type>> =
|
||||
is_container<T>;
|
||||
|
||||
template <typename T, typename = void>
|
||||
constexpr bool is_fixed_array = false;
|
||||
template <template <typename, size_t> typename arr_t, typename value_t, size_t size>
|
||||
constexpr bool is_fixed_array<arr_t<value_t, size>> = true;
|
||||
|
||||
template <typename T, typename = std::enable_if_t<is_fixed_array<T>>>
|
||||
constexpr size_t fixed_array_size = 0;
|
||||
template <template <typename, size_t> typename arr_t, typename value_t, size_t size>
|
||||
constexpr size_t fixed_array_size<arr_t<value_t, size>> = size;
|
||||
|
||||
template <typename T, typename = void>
|
||||
constexpr bool is_collection = false;
|
||||
template <typename T>
|
||||
constexpr bool is_collection<T> = is_container<T> && !is_map<T>;
|
||||
constexpr bool is_collection<T> = is_container<T> && !is_map<T> && !is_fixed_array<T>;
|
||||
|
||||
template <typename T>
|
||||
constexpr bool is_variant = false;
|
||||
template <typename... args_t>
|
||||
constexpr bool is_variant<std::variant<args_t...>> = true;
|
||||
|
||||
template <typename T>
|
||||
constexpr bool is_tuple = false;
|
||||
template <typename... args_t>
|
||||
constexpr bool is_tuple<std::tuple<args_t...>> = true;
|
||||
|
||||
template <typename T>
|
||||
constexpr bool is_pair = false;
|
||||
template <typename... args_t>
|
||||
constexpr bool is_pair<std::pair<args_t...>> = true;
|
||||
|
||||
template <typename T>
|
||||
class has_to_json_in_member
|
||||
@@ -85,7 +118,8 @@ template <typename T>
|
||||
class has_to_json_in_templ_spec
|
||||
{
|
||||
template <typename U>
|
||||
static auto test(int) -> decltype(std::declval<ext::jsonization<U>>().to_json(std::declval<U>()), std::true_type());
|
||||
static auto test(int)
|
||||
-> decltype(std::declval<ext::jsonization<U>>().to_json(std::declval<U>()), std::true_type());
|
||||
|
||||
template <typename U>
|
||||
static std::false_type test(...);
|
||||
@@ -113,8 +147,7 @@ class has_check_json_in_templ_spec
|
||||
{
|
||||
template <typename U>
|
||||
static auto test(int)
|
||||
-> decltype(std::declval<ext::jsonization<U>>().check_json(std::declval<json::basic_value<string_t>>()),
|
||||
std::true_type());
|
||||
-> decltype(std::declval<ext::jsonization<U>>().check_json(std::declval<json::basic_value<string_t>>()), std::true_type());
|
||||
|
||||
template <typename U>
|
||||
static std::false_type test(...);
|
||||
@@ -142,9 +175,7 @@ class has_from_json_in_templ_spec
|
||||
{
|
||||
template <typename U>
|
||||
static auto test(int)
|
||||
-> decltype(std::declval<ext::jsonization<U>>().from_json(std::declval<json::basic_value<string_t>>(),
|
||||
std::declval<U&>()),
|
||||
std::true_type());
|
||||
-> decltype(std::declval<ext::jsonization<U>>().from_json(std::declval<json::basic_value<string_t>>(), std::declval<U&>()), std::true_type());
|
||||
|
||||
template <typename U>
|
||||
static std::false_type test(...);
|
||||
@@ -154,7 +185,7 @@ public:
|
||||
};
|
||||
|
||||
template <typename string_t>
|
||||
static constexpr string_t unescape_string(const string_t& str)
|
||||
inline constexpr string_t unescape_string(const string_t& str)
|
||||
{
|
||||
using char_t = typename string_t::value_type;
|
||||
|
||||
@@ -202,26 +233,41 @@ static constexpr string_t unescape_string(const string_t& str)
|
||||
}
|
||||
|
||||
template <typename string_t>
|
||||
static constexpr string_t true_string()
|
||||
inline constexpr string_t true_string()
|
||||
{
|
||||
return { 't', 'r', 'u', 'e' };
|
||||
}
|
||||
|
||||
template <typename string_t>
|
||||
static constexpr string_t false_string()
|
||||
inline constexpr string_t false_string()
|
||||
{
|
||||
return { 'f', 'a', 'l', 's', 'e' };
|
||||
}
|
||||
|
||||
template <typename string_t>
|
||||
static constexpr string_t null_string()
|
||||
inline constexpr string_t null_string()
|
||||
{
|
||||
return { 'n', 'u', 'l', 'l' };
|
||||
}
|
||||
|
||||
template <typename string_t, typename any_t>
|
||||
string_t to_basic_string(any_t&& arg)
|
||||
inline string_t to_basic_string(any_t&& arg)
|
||||
{
|
||||
#ifdef MEOJSON_KEEP_FLOATING_PRECISION
|
||||
using real_type = std::remove_reference_t<any_t>;
|
||||
if constexpr (std::is_floating_point_v<real_type>) {
|
||||
if constexpr (std::is_same_v<string_t, std::string>) {
|
||||
std::ostringstream oss;
|
||||
oss << std::setprecision(std::numeric_limits<real_type>::max_digits10) << arg;
|
||||
return oss.str();
|
||||
}
|
||||
else if constexpr (std::is_same_v<string_t, std::wstring>) {
|
||||
std::wostringstream oss;
|
||||
oss << std::setprecision(std::numeric_limits<real_type>::max_digits10) << arg;
|
||||
return oss.str();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if constexpr (std::is_same_v<string_t, std::string>) {
|
||||
return std::to_string(std::forward<any_t>(arg));
|
||||
}
|
||||
@@ -232,4 +278,54 @@ string_t to_basic_string(any_t&& arg)
|
||||
static_assert(!sizeof(any_t), "Unsupported type");
|
||||
}
|
||||
}
|
||||
|
||||
template <std::size_t id, typename string_t, typename variant_t>
|
||||
inline bool _serialize_variant_impl(basic_value<string_t>& val, variant_t&& var)
|
||||
{
|
||||
if (var.index() != id) {
|
||||
return false;
|
||||
}
|
||||
val = basic_value<string_t>(std::get<id>(std::forward<variant_t>(var)));
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename string_t, typename variant_t, std::size_t... ids>
|
||||
inline basic_value<string_t> serialize_variant(variant_t&& var, std::index_sequence<ids...>)
|
||||
{
|
||||
basic_value<string_t> val;
|
||||
(_serialize_variant_impl<ids>(val, std::forward<variant_t>(var)) || ...);
|
||||
return val;
|
||||
}
|
||||
|
||||
template <std::size_t id, typename string_t, typename variant_t>
|
||||
inline bool _deserialize_variant_impl(const basic_value<string_t>& val, variant_t& var)
|
||||
{
|
||||
using alt_t = std::variant_alternative_t<id, variant_t>;
|
||||
if (!val.template is<alt_t>()) {
|
||||
return false;
|
||||
}
|
||||
var = val.template as<alt_t>();
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename string_t, typename variant_t, std::size_t... ids>
|
||||
inline variant_t deserialize_variant(const basic_value<string_t>& val, std::index_sequence<ids...>)
|
||||
{
|
||||
variant_t var;
|
||||
(_deserialize_variant_impl<ids>(val, var) || ...);
|
||||
return var;
|
||||
}
|
||||
|
||||
template <typename string_t, typename variant_t, std::size_t... ids>
|
||||
inline bool detect_variant(const basic_value<string_t>& val, std::index_sequence<ids...>)
|
||||
{
|
||||
return (val.template is<std::variant_alternative_t<ids, variant_t>>() || ...);
|
||||
}
|
||||
|
||||
template <typename string_t, typename tuple_t, std::size_t... ids>
|
||||
inline bool detect_tuple(const basic_value<string_t>& val, std::index_sequence<ids...>)
|
||||
{
|
||||
return val.is_array() && val.as_array().size() == std::tuple_size_v<tuple_t>
|
||||
&& (val.at(ids).template is<std::tuple_element_t<ids, tuple_t>>() || ...);
|
||||
}
|
||||
} // namespace json::_utils
|
||||
|
||||
445
3rdparty/include/meojson/common/value.hpp
vendored
445
3rdparty/include/meojson/common/value.hpp
vendored
@@ -1,3 +1,5 @@
|
||||
// IWYU pragma: private, include <meojson/json.hpp>
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
@@ -7,6 +9,8 @@
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <variant>
|
||||
|
||||
#include "exception.hpp"
|
||||
@@ -64,30 +68,87 @@ public:
|
||||
template <typename... args_t>
|
||||
basic_value(value_type type, args_t&&... args);
|
||||
|
||||
template <typename collection_t,
|
||||
std::enable_if_t<_utils::is_collection<collection_t> &&
|
||||
std::is_constructible_v<typename basic_array<string_t>::value_type,
|
||||
_utils::range_value_t<collection_t>>,
|
||||
bool> = true>
|
||||
basic_value(collection_t&& collection) : basic_value(basic_array<string_t>(std::forward<collection_t>(collection)))
|
||||
{}
|
||||
template <typename map_t, std::enable_if_t<_utils::is_map<map_t> &&
|
||||
std::is_constructible_v<typename basic_object<string_t>::value_type,
|
||||
_utils::range_value_t<map_t>>,
|
||||
bool> = true>
|
||||
basic_value(map_t&& map) : basic_value(basic_object<string_t>(std::forward<map_t>(map)))
|
||||
{}
|
||||
template <
|
||||
typename collection_t,
|
||||
std::enable_if_t<
|
||||
_utils::is_collection<collection_t>
|
||||
&& std::is_constructible_v<
|
||||
typename basic_array<string_t>::value_type,
|
||||
_utils::range_value_t<collection_t>>,
|
||||
bool> = true>
|
||||
basic_value(collection_t&& collection)
|
||||
: basic_value(basic_array<string_t>(std::forward<collection_t>(collection)))
|
||||
{
|
||||
}
|
||||
|
||||
template <typename jsonization_t,
|
||||
std::enable_if_t<_utils::has_to_json_in_member<jsonization_t>::value, bool> = true>
|
||||
basic_value(const jsonization_t& value) : basic_value(value.to_json())
|
||||
{}
|
||||
template <typename jsonization_t,
|
||||
std::enable_if_t<_utils::has_to_json_in_templ_spec<jsonization_t>::value, bool> = true>
|
||||
basic_value(const jsonization_t& value) : basic_value(ext::jsonization<jsonization_t>().to_json(value))
|
||||
{}
|
||||
template <
|
||||
typename fixed_array_t,
|
||||
std::enable_if_t<_utils::is_fixed_array<fixed_array_t>, bool> = true>
|
||||
basic_value(const fixed_array_t& arr)
|
||||
: basic_value(basic_array<string_t>(arr))
|
||||
{
|
||||
}
|
||||
|
||||
template <typename value_t, std::enable_if_t<!std::is_convertible_v<value_t, basic_value<string_t>>, bool> = true>
|
||||
template <
|
||||
typename map_t,
|
||||
std::enable_if_t<
|
||||
_utils::is_map<map_t>
|
||||
&& std::is_constructible_v<
|
||||
typename basic_object<string_t>::value_type,
|
||||
_utils::range_value_t<map_t>>,
|
||||
bool> = true>
|
||||
basic_value(map_t&& map)
|
||||
: basic_value(basic_object<string_t>(std::forward<map_t>(map)))
|
||||
{
|
||||
}
|
||||
|
||||
template <typename enum_t, std::enable_if_t<std::is_enum_v<enum_t>, bool> = true>
|
||||
basic_value(enum_t e)
|
||||
: basic_value(static_cast<std::underlying_type_t<enum_t>>(e))
|
||||
{
|
||||
}
|
||||
|
||||
template <
|
||||
typename jsonization_t,
|
||||
std::enable_if_t<_utils::has_to_json_in_member<jsonization_t>::value, bool> = true>
|
||||
basic_value(const jsonization_t& value)
|
||||
: basic_value(value.to_json())
|
||||
{
|
||||
}
|
||||
|
||||
template <
|
||||
typename jsonization_t,
|
||||
std::enable_if_t<_utils::has_to_json_in_templ_spec<jsonization_t>::value, bool> = true>
|
||||
basic_value(const jsonization_t& value)
|
||||
: basic_value(ext::jsonization<jsonization_t>().to_json(value))
|
||||
{
|
||||
}
|
||||
|
||||
template <typename... elem_ts>
|
||||
basic_value(std::tuple<elem_ts...>&& tup)
|
||||
: basic_value(basic_array<string_t>(std::forward<std::tuple<elem_ts...>>(tup)))
|
||||
{
|
||||
}
|
||||
|
||||
template <typename elem1_t, typename elem2_t>
|
||||
basic_value(std::pair<elem1_t, elem2_t>&& pair)
|
||||
: basic_value(basic_array<string_t>(std::pair<elem1_t, elem2_t>(pair)))
|
||||
{
|
||||
}
|
||||
|
||||
template <
|
||||
typename variant_t,
|
||||
std::enable_if_t<_utils::is_variant<std::decay_t<variant_t>>, bool> = true>
|
||||
basic_value(variant_t&& var)
|
||||
: basic_value(_utils::serialize_variant<string_t>(
|
||||
std::forward<variant_t>(var),
|
||||
std::make_index_sequence<std::variant_size_v<std::decay_t<variant_t>>>()))
|
||||
{
|
||||
}
|
||||
|
||||
template <
|
||||
typename value_t,
|
||||
std::enable_if_t<!std::is_convertible_v<value_t, basic_value<string_t>>, bool> = true>
|
||||
basic_value(value_t) = delete;
|
||||
|
||||
// I don't know if you want to convert char to string or number, so I delete these constructors.
|
||||
@@ -99,13 +160,21 @@ public:
|
||||
~basic_value();
|
||||
|
||||
bool valid() const noexcept { return _type != value_type::invalid; }
|
||||
|
||||
bool empty() const noexcept { return is_null(); }
|
||||
|
||||
bool is_null() const noexcept { return _type == value_type::null; }
|
||||
|
||||
bool is_number() const noexcept { return _type == value_type::number; }
|
||||
|
||||
bool is_boolean() const noexcept { return _type == value_type::boolean; }
|
||||
|
||||
bool is_string() const noexcept { return _type == value_type::string; }
|
||||
|
||||
bool is_array() const noexcept { return _type == value_type::array; }
|
||||
|
||||
bool is_object() const noexcept { return _type == value_type::object; }
|
||||
|
||||
template <typename value_t>
|
||||
bool is() const noexcept;
|
||||
|
||||
@@ -114,9 +183,13 @@ public:
|
||||
|
||||
bool contains(const string_t& key) const;
|
||||
bool contains(size_t pos) const;
|
||||
|
||||
bool exists(const string_t& key) const { return contains(key); }
|
||||
|
||||
bool exists(size_t pos) const { return contains(pos); }
|
||||
|
||||
value_type type() const noexcept { return _type; }
|
||||
|
||||
const basic_value<string_t>& at(size_t pos) const;
|
||||
const basic_value<string_t>& at(const string_t& key) const;
|
||||
|
||||
@@ -148,6 +221,11 @@ public:
|
||||
|
||||
template <typename value_t, template <typename...> typename collection_t = std::vector>
|
||||
collection_t<value_t> as_collection() const;
|
||||
template <
|
||||
typename value_t,
|
||||
size_t Size,
|
||||
template <typename, size_t> typename fixed_array_t = std::array>
|
||||
fixed_array_t<value_t, Size> as_fixed_array() const;
|
||||
template <typename value_t, template <typename...> typename map_t = std::map>
|
||||
map_t<string_t, value_t> as_map() const;
|
||||
|
||||
@@ -162,20 +240,29 @@ public:
|
||||
|
||||
void clear() noexcept;
|
||||
|
||||
string_t dumps(std::optional<size_t> indent = std::nullopt) const { return indent ? format(*indent) : to_string(); }
|
||||
string_t dumps(std::optional<size_t> indent = std::nullopt) const
|
||||
{
|
||||
return indent ? format(*indent) : to_string();
|
||||
}
|
||||
|
||||
// return raw string
|
||||
string_t to_string() const;
|
||||
|
||||
string_t format(size_t indent = 4) const { return format(indent, 0); }
|
||||
|
||||
basic_value<string_t>& operator=(const basic_value<string_t>& rhs);
|
||||
basic_value<string_t>& operator=(basic_value<string_t>&&) noexcept;
|
||||
template <typename value_t, std::enable_if_t<std::is_convertible_v<value_t, basic_value<string_t>>, bool> = true>
|
||||
|
||||
template <
|
||||
typename value_t,
|
||||
std::enable_if_t<std::is_convertible_v<value_t, basic_value<string_t>>, bool> = true>
|
||||
basic_value<string_t>& operator=(value_t rhs)
|
||||
{
|
||||
return *this = basic_value<string_t>(std::move(rhs));
|
||||
}
|
||||
|
||||
bool operator==(const basic_value<string_t>& rhs) const;
|
||||
|
||||
bool operator!=(const basic_value<string_t>& rhs) const { return !(*this == rhs); }
|
||||
|
||||
const basic_value<string_t>& operator[](size_t pos) const;
|
||||
@@ -200,34 +287,63 @@ public:
|
||||
basic_value<string_t>& operator+=(basic_array<string_t>&& rhs);
|
||||
|
||||
explicit operator bool() const { return as_boolean(); }
|
||||
|
||||
explicit operator int() const { return as_integer(); }
|
||||
|
||||
explicit operator unsigned() const { return as_unsigned(); }
|
||||
|
||||
explicit operator long() const { return as_long(); }
|
||||
|
||||
explicit operator unsigned long() const { return as_unsigned_long(); }
|
||||
|
||||
explicit operator long long() const { return as_long_long(); }
|
||||
|
||||
explicit operator unsigned long long() const { return as_unsigned_long_long(); }
|
||||
|
||||
explicit operator float() const { return as_float(); }
|
||||
|
||||
explicit operator double() const { return as_double(); }
|
||||
|
||||
explicit operator long double() const { return as_long_double(); }
|
||||
|
||||
explicit operator string_t() const { return as_string(); }
|
||||
|
||||
explicit operator basic_array<string_t>() const { return as_array(); }
|
||||
|
||||
explicit operator basic_object<string_t>() const { return as_object(); }
|
||||
|
||||
template <typename value_t, template <typename...> typename collection_t = std::vector,
|
||||
std::enable_if_t<_utils::is_collection<collection_t<value_t>>, bool> = true>
|
||||
template <
|
||||
typename value_t,
|
||||
template <typename...> typename collection_t = std::vector,
|
||||
std::enable_if_t<_utils::is_collection<collection_t<value_t>>, bool> = true>
|
||||
explicit operator collection_t<value_t>() const
|
||||
{
|
||||
return as_collection<value_t, collection_t>();
|
||||
}
|
||||
template <typename value_t, template <typename...> typename map_t = std::map,
|
||||
std::enable_if_t<_utils::is_map<map_t<string_t, value_t>>, bool> = true>
|
||||
|
||||
template <
|
||||
typename value_t,
|
||||
size_t Size,
|
||||
template <typename, size_t> typename fixed_array_t = std::array,
|
||||
std::enable_if_t<_utils::is_fixed_array<fixed_array_t<value_t, Size>>, bool> = true>
|
||||
explicit operator fixed_array_t<value_t, Size>() const
|
||||
{
|
||||
return as_fixed_array<value_t, Size, fixed_array_t>();
|
||||
}
|
||||
|
||||
template <
|
||||
typename value_t,
|
||||
template <typename...> typename map_t = std::map,
|
||||
std::enable_if_t<_utils::is_map<map_t<string_t, value_t>>, bool> = true>
|
||||
explicit operator map_t<string_t, value_t>() const
|
||||
{
|
||||
return as_map<value_t, map_t>();
|
||||
}
|
||||
template <typename jsonization_t,
|
||||
std::enable_if_t<_utils::has_from_json_in_member<jsonization_t, string_t>::value, bool> = true>
|
||||
|
||||
template <
|
||||
typename jsonization_t,
|
||||
std::enable_if_t<_utils::has_from_json_in_member<jsonization_t, string_t>::value, bool> =
|
||||
true>
|
||||
explicit operator jsonization_t() const
|
||||
{
|
||||
jsonization_t dst {};
|
||||
@@ -236,8 +352,12 @@ public:
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
template <typename jsonization_t,
|
||||
std::enable_if_t<_utils::has_from_json_in_templ_spec<jsonization_t, string_t>::value, bool> = true>
|
||||
|
||||
template <
|
||||
typename jsonization_t,
|
||||
std::enable_if_t<
|
||||
_utils::has_from_json_in_templ_spec<jsonization_t, string_t>::value,
|
||||
bool> = true>
|
||||
explicit operator jsonization_t() const
|
||||
{
|
||||
jsonization_t dst {};
|
||||
@@ -247,6 +367,32 @@ public:
|
||||
return dst;
|
||||
}
|
||||
|
||||
template <typename enum_t, std::enable_if_t<std::is_enum_v<enum_t>, bool> = true>
|
||||
explicit operator enum_t() const
|
||||
{
|
||||
return static_cast<enum_t>(static_cast<std::underlying_type_t<enum_t>>(*this));
|
||||
}
|
||||
|
||||
template <typename... elem_ts>
|
||||
explicit operator std::tuple<elem_ts...>() const
|
||||
{
|
||||
return as_array().template as_tuple<elem_ts...>();
|
||||
}
|
||||
|
||||
template <typename elem1_t, typename elem2_t>
|
||||
explicit operator std::pair<elem1_t, elem2_t>() const
|
||||
{
|
||||
return as_array().template as_pair<elem1_t, elem2_t>();
|
||||
}
|
||||
|
||||
template <typename... args_t>
|
||||
explicit operator std::variant<args_t...>() const
|
||||
{
|
||||
return _utils::deserialize_variant<string_t, std::variant<args_t...>>(
|
||||
*this,
|
||||
std::make_index_sequence<std::variant_size_v<std::variant<args_t...>>>());
|
||||
}
|
||||
|
||||
private:
|
||||
friend class basic_array<string_t>;
|
||||
friend class basic_object<string_t>;
|
||||
@@ -256,8 +402,9 @@ private:
|
||||
static var_t deep_copy(const var_t& src);
|
||||
|
||||
template <typename... key_then_default_value_t, size_t... keys_indexes_t>
|
||||
auto get(std::tuple<key_then_default_value_t...> keys_then_default_value,
|
||||
std::index_sequence<keys_indexes_t...>) const;
|
||||
auto
|
||||
get(std::tuple<key_then_default_value_t...> keys_then_default_value,
|
||||
std::index_sequence<keys_indexes_t...>) const;
|
||||
|
||||
template <typename value_t, typename first_key_t, typename... rest_keys_t>
|
||||
auto get_helper(const value_t& default_value, first_key_t&& first, rest_keys_t&&... rest) const;
|
||||
@@ -276,89 +423,125 @@ inline basic_value<string_t>::basic_value() = default;
|
||||
|
||||
template <typename string_t>
|
||||
inline basic_value<string_t>::basic_value(const basic_value<string_t>& rhs)
|
||||
: _type(rhs._type), _raw_data(deep_copy(rhs._raw_data))
|
||||
{}
|
||||
: _type(rhs._type)
|
||||
, _raw_data(deep_copy(rhs._raw_data))
|
||||
{
|
||||
}
|
||||
|
||||
template <typename string_t>
|
||||
inline basic_value<string_t>::basic_value(basic_value<string_t>&& rhs) noexcept = default;
|
||||
|
||||
template <typename string_t>
|
||||
inline basic_value<string_t>::basic_value(bool b)
|
||||
: _type(value_type::boolean),
|
||||
_raw_data(string_t(b ? _utils::true_string<string_t>() : _utils::false_string<string_t>()))
|
||||
{}
|
||||
: _type(value_type::boolean)
|
||||
, _raw_data(string_t(b ? _utils::true_string<string_t>() : _utils::false_string<string_t>()))
|
||||
{
|
||||
}
|
||||
|
||||
template <typename string_t>
|
||||
inline basic_value<string_t>::basic_value(int num)
|
||||
: _type(value_type::number), _raw_data(_utils::to_basic_string<string_t>(num))
|
||||
{}
|
||||
: _type(value_type::number)
|
||||
, _raw_data(_utils::to_basic_string<string_t>(num))
|
||||
{
|
||||
}
|
||||
|
||||
template <typename string_t>
|
||||
inline basic_value<string_t>::basic_value(unsigned num)
|
||||
: _type(value_type::number), _raw_data(_utils::to_basic_string<string_t>(num))
|
||||
{}
|
||||
: _type(value_type::number)
|
||||
, _raw_data(_utils::to_basic_string<string_t>(num))
|
||||
{
|
||||
}
|
||||
|
||||
template <typename string_t>
|
||||
inline basic_value<string_t>::basic_value(long num)
|
||||
: _type(value_type::number), _raw_data(_utils::to_basic_string<string_t>(num))
|
||||
{}
|
||||
: _type(value_type::number)
|
||||
, _raw_data(_utils::to_basic_string<string_t>(num))
|
||||
{
|
||||
}
|
||||
|
||||
template <typename string_t>
|
||||
inline basic_value<string_t>::basic_value(unsigned long num)
|
||||
: _type(value_type::number), _raw_data(_utils::to_basic_string<string_t>(num))
|
||||
{}
|
||||
: _type(value_type::number)
|
||||
, _raw_data(_utils::to_basic_string<string_t>(num))
|
||||
{
|
||||
}
|
||||
|
||||
template <typename string_t>
|
||||
inline basic_value<string_t>::basic_value(long long num)
|
||||
: _type(value_type::number), _raw_data(_utils::to_basic_string<string_t>(num))
|
||||
{}
|
||||
: _type(value_type::number)
|
||||
, _raw_data(_utils::to_basic_string<string_t>(num))
|
||||
{
|
||||
}
|
||||
|
||||
template <typename string_t>
|
||||
inline basic_value<string_t>::basic_value(unsigned long long num)
|
||||
: _type(value_type::number), _raw_data(_utils::to_basic_string<string_t>(num))
|
||||
{}
|
||||
: _type(value_type::number)
|
||||
, _raw_data(_utils::to_basic_string<string_t>(num))
|
||||
{
|
||||
}
|
||||
|
||||
template <typename string_t>
|
||||
inline basic_value<string_t>::basic_value(float num)
|
||||
: _type(value_type::number), _raw_data(_utils::to_basic_string<string_t>(num))
|
||||
{}
|
||||
: _type(value_type::number)
|
||||
, _raw_data(_utils::to_basic_string<string_t>(num))
|
||||
{
|
||||
}
|
||||
|
||||
template <typename string_t>
|
||||
inline basic_value<string_t>::basic_value(double num)
|
||||
: _type(value_type::number), _raw_data(_utils::to_basic_string<string_t>(num))
|
||||
{}
|
||||
: _type(value_type::number)
|
||||
, _raw_data(_utils::to_basic_string<string_t>(num))
|
||||
{
|
||||
}
|
||||
|
||||
template <typename string_t>
|
||||
inline basic_value<string_t>::basic_value(long double num)
|
||||
: _type(value_type::number), _raw_data(_utils::to_basic_string<string_t>(num))
|
||||
{}
|
||||
: _type(value_type::number)
|
||||
, _raw_data(_utils::to_basic_string<string_t>(num))
|
||||
{
|
||||
}
|
||||
|
||||
template <typename string_t>
|
||||
inline basic_value<string_t>::basic_value(const char_t* str) : _type(value_type::string), _raw_data(string_t(str))
|
||||
{}
|
||||
inline basic_value<string_t>::basic_value(const char_t* str)
|
||||
: _type(value_type::string)
|
||||
, _raw_data(string_t(str))
|
||||
{
|
||||
}
|
||||
|
||||
template <typename string_t>
|
||||
inline basic_value<string_t>::basic_value(string_t str) : _type(value_type::string), _raw_data(std::move(str))
|
||||
{}
|
||||
inline basic_value<string_t>::basic_value(string_t str)
|
||||
: _type(value_type::string)
|
||||
, _raw_data(std::move(str))
|
||||
{
|
||||
}
|
||||
|
||||
template <typename string_t>
|
||||
inline basic_value<string_t>::basic_value(std::nullptr_t) : _type(value_type::null)
|
||||
{}
|
||||
inline basic_value<string_t>::basic_value(std::nullptr_t)
|
||||
: _type(value_type::null)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename string_t>
|
||||
inline basic_value<string_t>::basic_value(basic_array<string_t> arr)
|
||||
: _type(value_type::array), _raw_data(std::make_unique<basic_array<string_t>>(std::move(arr)))
|
||||
{}
|
||||
: _type(value_type::array)
|
||||
, _raw_data(std::make_unique<basic_array<string_t>>(std::move(arr)))
|
||||
{
|
||||
}
|
||||
|
||||
template <typename string_t>
|
||||
inline basic_value<string_t>::basic_value(basic_object<string_t> obj)
|
||||
: _type(value_type::object), _raw_data(std::make_unique<basic_object<string_t>>(std::move(obj)))
|
||||
{}
|
||||
: _type(value_type::object)
|
||||
, _raw_data(std::make_unique<basic_object<string_t>>(std::move(obj)))
|
||||
{
|
||||
}
|
||||
|
||||
template <typename string_t>
|
||||
inline basic_value<string_t>::basic_value(std::initializer_list<typename basic_object<string_t>::value_type> init_list)
|
||||
: _type(value_type::object), _raw_data(std::make_unique<basic_object<string_t>>(init_list))
|
||||
{}
|
||||
inline basic_value<string_t>::basic_value(
|
||||
std::initializer_list<typename basic_object<string_t>::value_type> init_list)
|
||||
: _type(value_type::object)
|
||||
, _raw_data(std::make_unique<basic_object<string_t>>(init_list))
|
||||
{
|
||||
}
|
||||
|
||||
// for Pimpl
|
||||
template <typename string_t>
|
||||
@@ -380,7 +563,7 @@ inline bool basic_value<string_t>::is() const noexcept
|
||||
else if constexpr (std::is_same_v<bool, value_t>) {
|
||||
return is_boolean();
|
||||
}
|
||||
else if constexpr (std::is_arithmetic_v<value_t>) {
|
||||
else if constexpr (std::is_arithmetic_v<value_t> || std::is_enum_v<value_t>) {
|
||||
return is_number();
|
||||
}
|
||||
else if constexpr (std::is_constructible_v<string_t, value_t>) {
|
||||
@@ -392,12 +575,31 @@ inline bool basic_value<string_t>::is() const noexcept
|
||||
else if constexpr (_utils::is_collection<value_t>) {
|
||||
return is_array() && all<typename value_t::value_type>();
|
||||
}
|
||||
else if constexpr (_utils::is_fixed_array<value_t>) {
|
||||
return is_array() && all<typename value_t::value_type>()
|
||||
&& as_array().size() == _utils::fixed_array_size<value_t>;
|
||||
}
|
||||
else if constexpr (std::is_same_v<basic_object<string_t>, value_t>) {
|
||||
return is_object();
|
||||
}
|
||||
else if constexpr (_utils::is_map<value_t>) {
|
||||
return is_object() && std::is_constructible_v<string_t, typename value_t::key_type> &&
|
||||
all<typename value_t::mapped_type>();
|
||||
return is_object() && std::is_constructible_v<string_t, typename value_t::key_type>
|
||||
&& all<typename value_t::mapped_type>();
|
||||
}
|
||||
else if constexpr (_utils::is_variant<value_t>) {
|
||||
return _utils::detect_variant<string_t, value_t>(
|
||||
*this,
|
||||
std::make_index_sequence<std::variant_size_v<value_t>>());
|
||||
}
|
||||
else if constexpr (_utils::is_pair<value_t>) {
|
||||
return is_array() && as_array().size() == 2
|
||||
&& at(0).template is<typename value_t::first_type>()
|
||||
&& at(1).template is<typename value_t::second_type>();
|
||||
}
|
||||
else if constexpr (_utils::is_tuple<value_t>) {
|
||||
return _utils::detect_tuple<string_t, value_t>(
|
||||
*this,
|
||||
std::make_index_sequence<std::tuple_size_v<value_t>>());
|
||||
}
|
||||
else {
|
||||
static_assert(!sizeof(value_t), "Unsupported type");
|
||||
@@ -444,33 +646,42 @@ template <typename string_t>
|
||||
template <typename... key_then_default_value_t>
|
||||
inline auto basic_value<string_t>::get(key_then_default_value_t&&... keys_then_default_value) const
|
||||
{
|
||||
return get(std::forward_as_tuple(keys_then_default_value...),
|
||||
std::make_index_sequence<sizeof...(keys_then_default_value) - 1> {});
|
||||
return get(
|
||||
std::forward_as_tuple(keys_then_default_value...),
|
||||
std::make_index_sequence<sizeof...(keys_then_default_value) - 1> {});
|
||||
}
|
||||
|
||||
template <typename string_t>
|
||||
template <typename... key_then_default_value_t, size_t... keys_indexes_t>
|
||||
inline auto basic_value<string_t>::get(std::tuple<key_then_default_value_t...> keys_then_default_value,
|
||||
std::index_sequence<keys_indexes_t...>) const
|
||||
inline auto basic_value<string_t>::get(
|
||||
std::tuple<key_then_default_value_t...> keys_then_default_value,
|
||||
std::index_sequence<keys_indexes_t...>) const
|
||||
{
|
||||
constexpr unsigned long default_value_index = sizeof...(key_then_default_value_t) - 1;
|
||||
return get_helper(std::get<default_value_index>(keys_then_default_value),
|
||||
std::get<keys_indexes_t>(keys_then_default_value)...);
|
||||
return get_helper(
|
||||
std::get<default_value_index>(keys_then_default_value),
|
||||
std::get<keys_indexes_t>(keys_then_default_value)...);
|
||||
}
|
||||
|
||||
template <typename string_t>
|
||||
template <typename value_t, typename first_key_t, typename... rest_keys_t>
|
||||
inline auto basic_value<string_t>::get_helper(const value_t& default_value, first_key_t&& first,
|
||||
rest_keys_t&&... rest) const
|
||||
inline auto basic_value<string_t>::get_helper(
|
||||
const value_t& default_value,
|
||||
first_key_t&& first,
|
||||
rest_keys_t&&... rest) const
|
||||
{
|
||||
if constexpr (std::is_constructible_v<string_t, first_key_t>) {
|
||||
return is_object() ? as_object().get_helper(default_value, std::forward<first_key_t>(first),
|
||||
std::forward<rest_keys_t>(rest)...)
|
||||
return is_object() ? as_object().get_helper(
|
||||
default_value,
|
||||
std::forward<first_key_t>(first),
|
||||
std::forward<rest_keys_t>(rest)...)
|
||||
: default_value;
|
||||
}
|
||||
else if constexpr (std::is_integral_v<std::decay_t<first_key_t>>) {
|
||||
return is_array() ? as_array().get_helper(default_value, std::forward<first_key_t>(first),
|
||||
std::forward<rest_keys_t>(rest)...)
|
||||
return is_array() ? as_array().get_helper(
|
||||
default_value,
|
||||
std::forward<first_key_t>(first),
|
||||
std::forward<rest_keys_t>(rest)...)
|
||||
: default_value;
|
||||
}
|
||||
else {
|
||||
@@ -480,16 +691,22 @@ inline auto basic_value<string_t>::get_helper(const value_t& default_value, firs
|
||||
|
||||
template <typename string_t>
|
||||
template <typename value_t, typename unique_key_t>
|
||||
inline auto basic_value<string_t>::get_helper(const value_t& default_value, unique_key_t&& first) const
|
||||
inline auto
|
||||
basic_value<string_t>::get_helper(const value_t& default_value, unique_key_t&& first) const
|
||||
{
|
||||
if constexpr (std::is_constructible_v<string_t, unique_key_t>) {
|
||||
return is_object() ? as_object().get_helper(default_value, std::forward<unique_key_t>(first)) : default_value;
|
||||
return is_object()
|
||||
? as_object().get_helper(default_value, std::forward<unique_key_t>(first))
|
||||
: default_value;
|
||||
}
|
||||
else if constexpr (std::is_integral_v<std::decay_t<unique_key_t>>) {
|
||||
return is_array() ? as_array().get_helper(default_value, std::forward<unique_key_t>(first)) : default_value;
|
||||
return is_array() ? as_array().get_helper(default_value, std::forward<unique_key_t>(first))
|
||||
: default_value;
|
||||
}
|
||||
else {
|
||||
static_assert(!sizeof(unique_key_t), "Parameter must be integral or string_t constructible");
|
||||
static_assert(
|
||||
!sizeof(unique_key_t),
|
||||
"Parameter must be integral or string_t constructible");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -722,10 +939,14 @@ template <typename string_t>
|
||||
template <typename... args_t>
|
||||
inline decltype(auto) basic_value<string_t>::emplace(args_t&&... args)
|
||||
{
|
||||
constexpr bool is_array_args = std::is_constructible_v<typename basic_array<string_t>::value_type, args_t...>;
|
||||
constexpr bool is_object_args = std::is_constructible_v<typename basic_object<string_t>::value_type, args_t...>;
|
||||
constexpr bool is_array_args =
|
||||
std::is_constructible_v<typename basic_array<string_t>::value_type, args_t...>;
|
||||
constexpr bool is_object_args =
|
||||
std::is_constructible_v<typename basic_object<string_t>::value_type, args_t...>;
|
||||
|
||||
static_assert(is_array_args || is_object_args, "Args can not constructure a array or object value");
|
||||
static_assert(
|
||||
is_array_args || is_object_args,
|
||||
"Args can not constructure a array or object value");
|
||||
|
||||
if constexpr (is_array_args) {
|
||||
return as_array().emplace_back(std::forward<args_t>(args)...);
|
||||
@@ -801,6 +1022,13 @@ inline collection_t<value_t> basic_value<string_t>::as_collection() const
|
||||
return as_array().template as_collection<value_t, collection_t>();
|
||||
}
|
||||
|
||||
template <typename string_t>
|
||||
template <typename value_t, size_t Size, template <typename, size_t> typename fixed_array_t>
|
||||
inline fixed_array_t<value_t, Size> basic_value<string_t>::as_fixed_array() const
|
||||
{
|
||||
return as_array().template as_fixed_array<value_t, Size>();
|
||||
}
|
||||
|
||||
template <typename string_t>
|
||||
template <typename value_t, template <typename...> typename map_t>
|
||||
inline map_t<string_t, value_t> basic_value<string_t>::as_map() const
|
||||
@@ -818,12 +1046,15 @@ inline basic_value<string_t>& basic_value<string_t>::operator=(const basic_value
|
||||
}
|
||||
|
||||
template <typename string_t>
|
||||
inline basic_value<string_t>& basic_value<string_t>::operator=(basic_value<string_t>&& rhs) noexcept = default;
|
||||
inline basic_value<string_t>&
|
||||
basic_value<string_t>::operator=(basic_value<string_t>&& rhs) noexcept = default;
|
||||
|
||||
template <typename string_t>
|
||||
inline bool basic_value<string_t>::operator==(const basic_value<string_t>& rhs) const
|
||||
{
|
||||
if (_type != rhs._type) return false;
|
||||
if (_type != rhs._type) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (_type) {
|
||||
case value_type::null:
|
||||
@@ -878,7 +1109,8 @@ inline basic_value<string_t>& basic_value<string_t>::operator[](string_t&& key)
|
||||
}
|
||||
|
||||
template <typename string_t>
|
||||
inline basic_value<string_t> basic_value<string_t>::operator|(const basic_object<string_t>& rhs) const&
|
||||
inline basic_value<string_t>
|
||||
basic_value<string_t>::operator|(const basic_object<string_t>& rhs) const&
|
||||
{
|
||||
return as_object() | rhs;
|
||||
}
|
||||
@@ -916,7 +1148,8 @@ inline basic_value<string_t>& basic_value<string_t>::operator|=(basic_object<str
|
||||
}
|
||||
|
||||
template <typename string_t>
|
||||
inline basic_value<string_t> basic_value<string_t>::operator+(const basic_array<string_t>& rhs) const&
|
||||
inline basic_value<string_t>
|
||||
basic_value<string_t>::operator+(const basic_array<string_t>& rhs) const&
|
||||
{
|
||||
return as_array() + rhs;
|
||||
}
|
||||
@@ -956,9 +1189,12 @@ inline basic_value<string_t>& basic_value<string_t>::operator+=(basic_array<stri
|
||||
template <typename string_t>
|
||||
template <typename... args_t>
|
||||
inline basic_value<string_t>::basic_value(value_type type, args_t&&... args)
|
||||
: _type(type), _raw_data(std::forward<args_t>(args)...)
|
||||
: _type(type)
|
||||
, _raw_data(std::forward<args_t>(args)...)
|
||||
{
|
||||
static_assert(std::is_constructible_v<var_t, args_t...>, "Parameter can't be used to construct a var_t");
|
||||
static_assert(
|
||||
std::is_constructible_v<var_t, args_t...>,
|
||||
"Parameter can't be used to construct a var_t");
|
||||
}
|
||||
|
||||
template <typename string_t>
|
||||
@@ -981,11 +1217,14 @@ inline typename basic_value<string_t>::var_t basic_value<string_t>::deep_copy(co
|
||||
return dst;
|
||||
}
|
||||
|
||||
template <typename ostream_t, typename string_t,
|
||||
typename std_ostream_t =
|
||||
std::basic_ostream<typename string_t::value_type, std::char_traits<typename string_t::value_type>>,
|
||||
typename =
|
||||
std::enable_if_t<std::is_same_v<std_ostream_t, ostream_t> || std::is_base_of_v<std_ostream_t, ostream_t>>>
|
||||
template <
|
||||
typename ostream_t,
|
||||
typename string_t,
|
||||
typename std_ostream_t = std::basic_ostream<
|
||||
typename string_t::value_type,
|
||||
std::char_traits<typename string_t::value_type>>,
|
||||
typename = std::enable_if_t<
|
||||
std::is_same_v<std_ostream_t, ostream_t> || std::is_base_of_v<std_ostream_t, ostream_t>>>
|
||||
ostream_t& operator<<(ostream_t& out, const basic_value<string_t>& val)
|
||||
{
|
||||
out << val.format();
|
||||
|
||||
4
3rdparty/include/meojson/json.hpp
vendored
4
3rdparty/include/meojson/json.hpp
vendored
@@ -1,6 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
// IWYU pragma: begin_exports
|
||||
|
||||
#include "common/serialization.hpp"
|
||||
#include "common/types.hpp"
|
||||
#include "parser/parser.hpp"
|
||||
#include "reflection/jsonization.hpp"
|
||||
|
||||
// IWYU pragma: end_exports
|
||||
|
||||
6
3rdparty/include/meojson/json5.hpp
vendored
6
3rdparty/include/meojson/json5.hpp
vendored
@@ -1,4 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
// IWYU pragma: begin_exports
|
||||
|
||||
#include "common/types.hpp"
|
||||
#include "parser5/parser5.hpp"
|
||||
#include "parser5/parser5.hpp"
|
||||
|
||||
// IWYU pragma: end_exports
|
||||
|
||||
37
3rdparty/include/meojson/parser/bitops.hpp
vendored
37
3rdparty/include/meojson/parser/bitops.hpp
vendored
@@ -1,13 +1,17 @@
|
||||
// IWYU pragma: private, include <meojson/json.hpp>
|
||||
|
||||
#pragma once
|
||||
|
||||
#if __cplusplus >= 202002L || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)
|
||||
#include <bit>
|
||||
|
||||
namespace json::_bitops
|
||||
{
|
||||
using std::countl_one;
|
||||
using std::countl_zero;
|
||||
using std::countr_one;
|
||||
using std::countr_zero;
|
||||
|
||||
inline constexpr bool is_little_endian()
|
||||
{
|
||||
return std::endian::native == std::endian::little;
|
||||
@@ -15,25 +19,37 @@ inline constexpr bool is_little_endian()
|
||||
}
|
||||
#else
|
||||
#include <cstdint>
|
||||
|
||||
namespace json::_bitops
|
||||
{
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
inline constexpr int countl_zero(uint32_t x)
|
||||
{
|
||||
if constexpr (sizeof(uint32_t) == sizeof(unsigned int)) return x == 0 ? 32 : __builtin_clz(x);
|
||||
if constexpr (sizeof(uint32_t) == sizeof(unsigned long)) return x == 0 ? 32 : __builtin_clzl(x);
|
||||
if constexpr (sizeof(uint32_t) == sizeof(unsigned int)) {
|
||||
return x == 0 ? 32 : __builtin_clz(x);
|
||||
}
|
||||
if constexpr (sizeof(uint32_t) == sizeof(unsigned long)) {
|
||||
return x == 0 ? 32 : __builtin_clzl(x);
|
||||
}
|
||||
return x == 0 ? 32 : __builtin_clzll(x);
|
||||
}
|
||||
|
||||
inline constexpr int countr_zero(uint32_t x)
|
||||
{
|
||||
if constexpr (sizeof(uint32_t) == sizeof(unsigned int)) return x == 0 ? 32 : __builtin_ctz(x);
|
||||
if constexpr (sizeof(uint32_t) == sizeof(unsigned long)) return x == 0 ? 32 : __builtin_ctzl(x);
|
||||
if constexpr (sizeof(uint32_t) == sizeof(unsigned int)) {
|
||||
return x == 0 ? 32 : __builtin_ctz(x);
|
||||
}
|
||||
if constexpr (sizeof(uint32_t) == sizeof(unsigned long)) {
|
||||
return x == 0 ? 32 : __builtin_ctzl(x);
|
||||
}
|
||||
return x == 0 ? 32 : __builtin_ctzll(x);
|
||||
}
|
||||
|
||||
inline constexpr int countl_zero(uint64_t x)
|
||||
{
|
||||
return x == 0 ? 64 : __builtin_clzll(x);
|
||||
}
|
||||
|
||||
inline constexpr int countr_zero(uint64_t x)
|
||||
{
|
||||
return x == 0 ? 64 : __builtin_ctzll(x);
|
||||
@@ -45,14 +61,17 @@ inline int countl_zero(uint32_t x)
|
||||
{
|
||||
return __lzcnt(x);
|
||||
}
|
||||
|
||||
inline int countr_zero(uint32_t x)
|
||||
{
|
||||
return _tzcnt_u32(x);
|
||||
}
|
||||
|
||||
inline int countl_zero(uint64_t x)
|
||||
{
|
||||
return (int)__lzcnt64(x);
|
||||
}
|
||||
|
||||
inline int countr_zero(uint64_t x)
|
||||
{
|
||||
return (int)_tzcnt_u64(x);
|
||||
@@ -63,16 +82,19 @@ inline constexpr int countl_zero(uint32_t x)
|
||||
unsigned long index = 0;
|
||||
return _BitScanReverse(&index, x) ? 31 - index : 32;
|
||||
}
|
||||
|
||||
inline constexpr int countr_zero(uint32_t x)
|
||||
{
|
||||
unsigned long index = 0;
|
||||
return _BitScanForward(&index, x) ? index : 32;
|
||||
}
|
||||
|
||||
inline constexpr int countl_zero(uint64_t x)
|
||||
{
|
||||
unsigned long index = 0;
|
||||
return _BitScanReverse64(&index, x) ? 63 - index : 64;
|
||||
}
|
||||
|
||||
inline constexpr int countr_zero(uint64_t x)
|
||||
{
|
||||
unsigned long index = 0;
|
||||
@@ -86,14 +108,17 @@ inline int countl_one(uint32_t x)
|
||||
{
|
||||
return countl_zero(~x);
|
||||
}
|
||||
|
||||
inline int countr_one(uint32_t x)
|
||||
{
|
||||
return countr_zero(~x);
|
||||
}
|
||||
|
||||
inline int countl_one(uint64_t x)
|
||||
{
|
||||
return countl_zero(~x);
|
||||
}
|
||||
|
||||
inline int countr_one(uint64_t x)
|
||||
{
|
||||
return countr_zero(~x);
|
||||
@@ -102,10 +127,12 @@ inline int countr_one(uint64_t x)
|
||||
// no constexpr endian awareness before C++20
|
||||
inline bool is_little_endian()
|
||||
{
|
||||
union {
|
||||
union
|
||||
{
|
||||
uint32_t u32;
|
||||
uint8_t u8;
|
||||
} u = { 0x01020304 };
|
||||
|
||||
return u.u8 == 4;
|
||||
}
|
||||
} // namespace json::_bitops
|
||||
|
||||
42
3rdparty/include/meojson/parser/packed_bytes.hpp
vendored
42
3rdparty/include/meojson/parser/packed_bytes.hpp
vendored
@@ -1,3 +1,5 @@
|
||||
// IWYU pragma: private, include <meojson/json.hpp>
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
@@ -28,11 +30,13 @@ struct packed_bytes
|
||||
};
|
||||
}
|
||||
|
||||
#ifndef MEOJSON_DISABLE_PACKED_BYTES
|
||||
#if defined(__SSE2__) || defined(_M_X64) || (defined(_M_IX86_FP) && _M_IX86_FP)
|
||||
#include "packed_bytes_x86.hpp"
|
||||
#elif defined(__ARM_NEON) || defined(_M_ARM) || defined(_M_ARM64)
|
||||
#include "packed_bytes_arm.hpp"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace json::_packed_bytes
|
||||
{
|
||||
@@ -66,14 +70,19 @@ struct packed_bytes_trait_uint64
|
||||
return is_zero_memberwise((x) ^ (UINT64_C(0x0101010101010101) * (n)));
|
||||
}
|
||||
|
||||
__packed_bytes_strong_inline static value_type bitwise_or(value_type a, value_type b) { return a | b; }
|
||||
__packed_bytes_strong_inline static value_type bitwise_or(value_type a, value_type b)
|
||||
{
|
||||
return a | b;
|
||||
}
|
||||
|
||||
__packed_bytes_strong_inline static size_t first_nonzero_byte(value_type x)
|
||||
{
|
||||
if (_bitops::is_little_endian())
|
||||
if (_bitops::is_little_endian()) {
|
||||
return _bitops::countr_zero(x) / 8;
|
||||
else
|
||||
}
|
||||
else {
|
||||
return _bitops::countl_zero(x) / 8;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -108,16 +117,22 @@ struct packed_bytes_trait_uint32
|
||||
return is_zero_memberwise((x) ^ (~UINT32_C(0) / 255 * (n)));
|
||||
}
|
||||
|
||||
__packed_bytes_strong_inline static value_type bitwise_or(value_type a, value_type b) { return a | b; }
|
||||
__packed_bytes_strong_inline static value_type bitwise_or(value_type a, value_type b)
|
||||
{
|
||||
return a | b;
|
||||
}
|
||||
|
||||
__packed_bytes_strong_inline static size_t first_nonzero_byte(value_type x)
|
||||
{
|
||||
if (_bitops::is_little_endian())
|
||||
if (_bitops::is_little_endian()) {
|
||||
return _bitops::countr_zero(x) / 8;
|
||||
else
|
||||
}
|
||||
else {
|
||||
return _bitops::countl_zero(x) / 8;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct packed_bytes<8>
|
||||
{
|
||||
@@ -133,9 +148,14 @@ struct packed_bytes<4>
|
||||
template <size_t N>
|
||||
using packed_bytes_trait = typename packed_bytes<N>::traits;
|
||||
|
||||
using packed_bytes_trait_max =
|
||||
std::conditional_t<packed_bytes_trait<32>::available, packed_bytes_trait<32>,
|
||||
std::conditional_t<packed_bytes_trait<16>::available, packed_bytes_trait<16>,
|
||||
std::conditional_t<packed_bytes_trait<8>::available, packed_bytes_trait<8>,
|
||||
packed_bytes_trait<4>>>>;
|
||||
using packed_bytes_trait_max = std::conditional_t<
|
||||
packed_bytes_trait<32>::available,
|
||||
packed_bytes_trait<32>,
|
||||
std::conditional_t<
|
||||
packed_bytes_trait<16>::available,
|
||||
packed_bytes_trait<16>,
|
||||
std::conditional_t<
|
||||
packed_bytes_trait<8>::available,
|
||||
packed_bytes_trait<8>,
|
||||
packed_bytes_trait<4>>>>;
|
||||
} // namespace json::_packed_bytes
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// IWYU pragma: private, include <meojson/json.hpp>
|
||||
|
||||
#pragma once
|
||||
|
||||
// current NEON implementation doesn't outperform 64-bit scalar implementation
|
||||
@@ -17,7 +19,10 @@ struct packed_bytes_trait_neon
|
||||
static constexpr auto step = 16;
|
||||
using value_type = uint8x16_t;
|
||||
|
||||
__packed_bytes_strong_inline static value_type load_unaligned(const void* ptr) { return vld1q_u8((uint8_t*)ptr); }
|
||||
__packed_bytes_strong_inline static value_type load_unaligned(const void* ptr)
|
||||
{
|
||||
return vld1q_u8((uint8_t*)ptr);
|
||||
}
|
||||
|
||||
__packed_bytes_strong_inline static value_type less(value_type x, uint8_t n)
|
||||
{
|
||||
@@ -26,19 +31,31 @@ struct packed_bytes_trait_neon
|
||||
return is_less;
|
||||
}
|
||||
|
||||
__packed_bytes_strong_inline static value_type equal(value_type x, uint8_t n) { return vceqq_u8(x, vdupq_n_u8(n)); }
|
||||
__packed_bytes_strong_inline static value_type equal(value_type x, uint8_t n)
|
||||
{
|
||||
return vceqq_u8(x, vdupq_n_u8(n));
|
||||
}
|
||||
|
||||
__packed_bytes_strong_inline static value_type equal(value_type x, value_type y) { return vceqq_u8(x, y); }
|
||||
__packed_bytes_strong_inline static value_type equal(value_type x, value_type y)
|
||||
{
|
||||
return vceqq_u8(x, y);
|
||||
}
|
||||
|
||||
__packed_bytes_strong_inline static value_type bitwise_or(value_type a, value_type b) { return vorrq_u8(a, b); }
|
||||
__packed_bytes_strong_inline static value_type bitwise_or(value_type a, value_type b)
|
||||
{
|
||||
return vorrq_u8(a, b);
|
||||
}
|
||||
|
||||
__packed_bytes_strong_inline static bool is_all_zero(value_type x)
|
||||
{
|
||||
#ifdef __packed_bytes_trait_arm64
|
||||
return vmaxvq_u8(x) == 0;
|
||||
#else
|
||||
auto fold64 = vorr_u64(vget_high_u64(vreinterpretq_u8_u64(x), 0), vget_low_u64(vreinterpretq_u8_u64(x), 1));
|
||||
auto fold32 = vget_lane_u32(vreinterpret_u64_u32(fold64), 0) | vget_lane_u32(vreinterpret_u64_u32(fold64), 1);
|
||||
auto fold64 = vorr_u64(
|
||||
vget_high_u64(vreinterpretq_u8_u64(x), 0),
|
||||
vget_low_u64(vreinterpretq_u8_u64(x), 1));
|
||||
auto fold32 = vget_lane_u32(vreinterpret_u64_u32(fold64), 0)
|
||||
| vget_lane_u32(vreinterpret_u64_u32(fold64), 1);
|
||||
return fold32 == 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
// IWYU pragma: private, include <meojson/json.hpp>
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "packed_bytes.hpp"
|
||||
|
||||
#include <emmintrin.h>
|
||||
@@ -35,9 +38,15 @@ struct packed_bytes_trait_sse
|
||||
return _mm_cmpeq_epi8(x, _mm_set1_epi8(static_cast<char>(n)));
|
||||
}
|
||||
|
||||
__packed_bytes_strong_inline static value_type equal(value_type x, value_type y) { return _mm_cmpeq_epi8(x, y); }
|
||||
__packed_bytes_strong_inline static value_type equal(value_type x, value_type y)
|
||||
{
|
||||
return _mm_cmpeq_epi8(x, y);
|
||||
}
|
||||
|
||||
__packed_bytes_strong_inline static value_type bitwise_or(value_type a, value_type b) { return _mm_or_si128(a, b); }
|
||||
__packed_bytes_strong_inline static value_type bitwise_or(value_type a, value_type b)
|
||||
{
|
||||
return _mm_or_si128(a, b);
|
||||
}
|
||||
|
||||
__packed_bytes_strong_inline static bool is_all_zero(value_type x)
|
||||
{
|
||||
@@ -97,14 +106,20 @@ struct packed_bytes_trait_avx2
|
||||
return _mm256_cmpeq_epi8(x, _mm256_set1_epi8(static_cast<char>(n)));
|
||||
}
|
||||
|
||||
__packed_bytes_strong_inline static value_type equal(value_type x, value_type y) { return _mm256_cmpeq_epi8(x, y); }
|
||||
__packed_bytes_strong_inline static value_type equal(value_type x, value_type y)
|
||||
{
|
||||
return _mm256_cmpeq_epi8(x, y);
|
||||
}
|
||||
|
||||
__packed_bytes_strong_inline static value_type bitwise_or(value_type a, value_type b)
|
||||
{
|
||||
return _mm256_or_si256(a, b);
|
||||
}
|
||||
|
||||
__packed_bytes_strong_inline static bool is_all_zero(value_type x) { return (bool)_mm256_testz_si256(x, x); }
|
||||
__packed_bytes_strong_inline static bool is_all_zero(value_type x)
|
||||
{
|
||||
return (bool)_mm256_testz_si256(x, x);
|
||||
}
|
||||
|
||||
__packed_bytes_strong_inline static size_t first_nonzero_byte(value_type x)
|
||||
{
|
||||
|
||||
256
3rdparty/include/meojson/parser/parser.hpp
vendored
256
3rdparty/include/meojson/parser/parser.hpp
vendored
@@ -1,5 +1,8 @@
|
||||
// IWYU pragma: private, include <meojson/json.hpp>
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cctype>
|
||||
#include <fstream>
|
||||
#include <optional>
|
||||
#include <ostream>
|
||||
@@ -15,8 +18,10 @@ namespace json
|
||||
// * parser declare *
|
||||
// ****************************
|
||||
|
||||
template <typename string_t = default_string_t, typename parsing_t = void,
|
||||
typename accel_traits = _packed_bytes::packed_bytes_trait_max>
|
||||
template <
|
||||
typename string_t = default_string_t,
|
||||
typename parsing_t = void,
|
||||
typename accel_traits = _packed_bytes::packed_bytes_trait_max>
|
||||
class parser
|
||||
{
|
||||
public:
|
||||
@@ -28,7 +33,12 @@ public:
|
||||
static std::optional<basic_value<string_t>> parse(const parsing_t& content);
|
||||
|
||||
private:
|
||||
parser(parsing_iter_t cbegin, parsing_iter_t cend) noexcept : _cur(cbegin), _end(cend) { ; }
|
||||
parser(parsing_iter_t cbegin, parsing_iter_t cend) noexcept
|
||||
: _cur(cbegin)
|
||||
, _end(cend)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
std::optional<basic_value<string_t>> parse();
|
||||
basic_value<string_t> parse_value();
|
||||
@@ -47,6 +57,7 @@ private:
|
||||
bool skip_string_literal_with_accel();
|
||||
bool skip_whitespace() noexcept;
|
||||
bool skip_digit();
|
||||
bool skip_unicode_escape(uint16_t& pair_high, string_t& result);
|
||||
|
||||
private:
|
||||
parsing_iter_t _cur;
|
||||
@@ -63,8 +74,10 @@ auto parse(const parsing_t& content);
|
||||
template <typename char_t>
|
||||
auto parse(char_t* content);
|
||||
|
||||
template <typename istream_t,
|
||||
typename = std::enable_if_t<std::is_base_of_v<std::basic_istream<typename istream_t::char_type>, istream_t>>>
|
||||
template <
|
||||
typename istream_t,
|
||||
typename = std::enable_if_t<
|
||||
std::is_base_of_v<std::basic_istream<typename istream_t::char_type>, istream_t>>>
|
||||
auto parse(istream_t& istream, bool check_bom);
|
||||
|
||||
template <typename ifstream_t = std::ifstream, typename path_t = void>
|
||||
@@ -72,17 +85,17 @@ auto open(const path_t& path, bool check_bom = false);
|
||||
|
||||
namespace literals
|
||||
{
|
||||
value operator""_json(const char* str, size_t len);
|
||||
wvalue operator""_json(const wchar_t* str, size_t len);
|
||||
value operator""_json(const char* str, size_t len);
|
||||
wvalue operator""_json(const wchar_t* str, size_t len);
|
||||
|
||||
value operator""_jvalue(const char* str, size_t len);
|
||||
wvalue operator""_jvalue(const wchar_t* str, size_t len);
|
||||
value operator""_jvalue(const char* str, size_t len);
|
||||
wvalue operator""_jvalue(const wchar_t* str, size_t len);
|
||||
|
||||
array operator""_jarray(const char* str, size_t len);
|
||||
warray operator""_jarray(const wchar_t* str, size_t len);
|
||||
array operator""_jarray(const char* str, size_t len);
|
||||
warray operator""_jarray(const wchar_t* str, size_t len);
|
||||
|
||||
object operator""_jobject(const char* str, size_t len);
|
||||
wobject operator""_jobject(const wchar_t* str, size_t len);
|
||||
object operator""_jobject(const char* str, size_t len);
|
||||
wobject operator""_jobject(const wchar_t* str, size_t len);
|
||||
}
|
||||
|
||||
template <typename string_t = default_string_t>
|
||||
@@ -93,7 +106,8 @@ const basic_value<string_t> invalid_value();
|
||||
// *************************
|
||||
|
||||
template <typename string_t, typename parsing_t, typename accel_traits>
|
||||
inline std::optional<basic_value<string_t>> parser<string_t, parsing_t, accel_traits>::parse(const parsing_t& content)
|
||||
inline std::optional<basic_value<string_t>>
|
||||
parser<string_t, parsing_t, accel_traits>::parse(const parsing_t& content)
|
||||
{
|
||||
return parser<string_t, parsing_t, accel_traits>(content.cbegin(), content.cend()).parse();
|
||||
}
|
||||
@@ -252,7 +266,9 @@ inline basic_value<string_t> parser<string_t, parsing_t, accel_traits>::parse_st
|
||||
if (!string_opt) {
|
||||
return invalid_value<string_t>();
|
||||
}
|
||||
return basic_value<string_t>(basic_value<string_t>::value_type::string, std::move(string_opt).value());
|
||||
return basic_value<string_t>(
|
||||
basic_value<string_t>::value_type::string,
|
||||
std::move(string_opt).value());
|
||||
}
|
||||
|
||||
template <typename string_t, typename parsing_t, typename accel_traits>
|
||||
@@ -350,7 +366,10 @@ inline basic_value<string_t> parser<string_t, parsing_t, accel_traits>::parse_ob
|
||||
return invalid_value<string_t>();
|
||||
}
|
||||
|
||||
result.emplace(std::move(*key_opt), std::move(val));
|
||||
auto emplaced = result.emplace(std::move(*key_opt), std::move(val)).second;
|
||||
if (!emplaced) {
|
||||
return invalid_value<string_t>();
|
||||
}
|
||||
|
||||
if (*_cur == ',') {
|
||||
++_cur;
|
||||
@@ -382,6 +401,7 @@ inline std::optional<string_t> parser<string_t, parsing_t, accel_traits>::parse_
|
||||
|
||||
string_t result;
|
||||
auto no_escape_beg = _cur;
|
||||
uint16_t pair_high = 0;
|
||||
|
||||
while (_cur != _end) {
|
||||
if constexpr (sizeof(*_cur) == 1 && accel_traits::available) {
|
||||
@@ -399,6 +419,9 @@ inline std::optional<string_t> parser<string_t, parsing_t, accel_traits>::parse_
|
||||
if (_cur == _end) {
|
||||
return std::nullopt;
|
||||
}
|
||||
if (pair_high && *_cur != 'u') {
|
||||
return std::nullopt;
|
||||
}
|
||||
switch (*_cur) {
|
||||
case '"':
|
||||
result.push_back('"');
|
||||
@@ -424,9 +447,11 @@ inline std::optional<string_t> parser<string_t, parsing_t, accel_traits>::parse_
|
||||
case 't':
|
||||
result.push_back('\t');
|
||||
break;
|
||||
// case 'u':
|
||||
// result.push_back('\u');
|
||||
// break;
|
||||
case 'u':
|
||||
if (!skip_unicode_escape(pair_high, result)) {
|
||||
return std::nullopt;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// Illegal backslash escape
|
||||
return std::nullopt;
|
||||
@@ -435,10 +460,16 @@ inline std::optional<string_t> parser<string_t, parsing_t, accel_traits>::parse_
|
||||
break;
|
||||
}
|
||||
case '"': {
|
||||
if (pair_high) {
|
||||
return std::nullopt;
|
||||
}
|
||||
result += string_t(no_escape_beg, _cur++);
|
||||
return result;
|
||||
}
|
||||
default:
|
||||
if (pair_high) {
|
||||
return std::nullopt;
|
||||
}
|
||||
++_cur;
|
||||
break;
|
||||
}
|
||||
@@ -446,6 +477,103 @@ inline std::optional<string_t> parser<string_t, parsing_t, accel_traits>::parse_
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
template <typename string_t, typename parsing_t, typename accel_traits>
|
||||
inline bool parser<string_t, parsing_t, accel_traits>::skip_unicode_escape(
|
||||
uint16_t& pair_high,
|
||||
string_t& result)
|
||||
{
|
||||
uint16_t cp = 0;
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
if (++_cur == _end) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!std::isxdigit(static_cast<unsigned char>(*_cur))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
cp <<= 4;
|
||||
|
||||
if ('0' <= *_cur && *_cur <= '9') {
|
||||
cp |= *_cur - '0';
|
||||
}
|
||||
else if ('a' <= *_cur && *_cur <= 'f') {
|
||||
cp |= *_cur - 'a' + 10;
|
||||
}
|
||||
else if ('A' <= *_cur && *_cur <= 'F') {
|
||||
cp |= *_cur - 'A' + 10;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t ext_cp = cp;
|
||||
uint16_t hi_cp = 0, lo_cp = 0;
|
||||
|
||||
if (0xD800 <= cp && cp <= 0xDBFF) {
|
||||
if (pair_high) {
|
||||
return false;
|
||||
}
|
||||
pair_high = cp;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (0xDC00 <= cp && cp <= 0xDFFF) {
|
||||
if (!pair_high) {
|
||||
return false;
|
||||
}
|
||||
ext_cp = (((pair_high - 0xD800) << 10) | (cp - 0xDC00)) + 0x10000;
|
||||
hi_cp = pair_high;
|
||||
lo_cp = cp;
|
||||
pair_high = 0;
|
||||
}
|
||||
|
||||
if constexpr (std::is_same_v<typename string_t::value_type, char>) {
|
||||
// utf8
|
||||
if (ext_cp <= 0x7F) {
|
||||
result.push_back(static_cast<char>(ext_cp));
|
||||
}
|
||||
else if (ext_cp <= 0x7FF) {
|
||||
result.push_back(static_cast<char>(((ext_cp >> 6) & 0b00011111) | 0b11000000u));
|
||||
result.push_back(static_cast<char>((ext_cp & 0b00111111) | 0b10000000u));
|
||||
}
|
||||
else if (ext_cp <= 0xFFFF) {
|
||||
result.push_back(static_cast<char>(((ext_cp >> 12) & 0b00001111) | 0b11100000u));
|
||||
result.push_back(static_cast<char>(((ext_cp >> 6) & 0b00111111) | 0b10000000u));
|
||||
result.push_back(static_cast<char>((ext_cp & 0b00111111) | 0b10000000u));
|
||||
}
|
||||
else {
|
||||
result.push_back(static_cast<char>(((ext_cp >> 18) & 0b00000111) | 0b11110000u));
|
||||
result.push_back(static_cast<char>(((ext_cp >> 12) & 0b00111111) | 0b10000000u));
|
||||
result.push_back(static_cast<char>(((ext_cp >> 6) & 0b00111111) | 0b10000000u));
|
||||
result.push_back(static_cast<char>((ext_cp & 0b00111111) | 0b10000000u));
|
||||
}
|
||||
}
|
||||
else if constexpr (std::is_same_v<typename string_t::value_type, wchar_t>) {
|
||||
if constexpr (sizeof(wchar_t) == 4) {
|
||||
result.push_back(static_cast<wchar_t>(ext_cp));
|
||||
}
|
||||
else if constexpr (sizeof(wchar_t) == 2) {
|
||||
if (ext_cp <= 0xFFFF) {
|
||||
result.push_back(static_cast<wchar_t>(ext_cp));
|
||||
}
|
||||
else {
|
||||
result.push_back(static_cast<wchar_t>(hi_cp));
|
||||
result.push_back(static_cast<wchar_t>(lo_cp));
|
||||
}
|
||||
}
|
||||
else {
|
||||
static_assert(!sizeof(typename string_t::value_type), "Unsupported wchar");
|
||||
}
|
||||
}
|
||||
else {
|
||||
static_assert(!sizeof(typename string_t::value_type), "Unsupported type");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename string_t, typename parsing_t, typename accel_traits>
|
||||
inline bool parser<string_t, parsing_t, accel_traits>::skip_string_literal_with_accel()
|
||||
{
|
||||
@@ -456,8 +584,10 @@ inline bool parser<string_t, parsing_t, accel_traits>::skip_string_literal_with_
|
||||
while (_end - _cur >= accel_traits::step) {
|
||||
auto pack = accel_traits::load_unaligned(&(*_cur));
|
||||
auto result = accel_traits::less(pack, 32);
|
||||
result = accel_traits::bitwise_or(result, accel_traits::equal(pack, static_cast<uint8_t>('"')));
|
||||
result = accel_traits::bitwise_or(result, accel_traits::equal(pack, static_cast<uint8_t>('\\')));
|
||||
result =
|
||||
accel_traits::bitwise_or(result, accel_traits::equal(pack, static_cast<uint8_t>('"')));
|
||||
result =
|
||||
accel_traits::bitwise_or(result, accel_traits::equal(pack, static_cast<uint8_t>('\\')));
|
||||
|
||||
if (accel_traits::is_all_zero(result)) {
|
||||
_cur += accel_traits::step;
|
||||
@@ -551,8 +681,8 @@ auto parse(istream_t& ifs, bool check_bom)
|
||||
static constexpr uchar Bom_1 = 0xBB;
|
||||
static constexpr uchar Bom_2 = 0xBF;
|
||||
|
||||
if (str.size() >= 3 && static_cast<uchar>(str.at(0)) == Bom_0 && static_cast<uchar>(str.at(1)) == Bom_1 &&
|
||||
static_cast<uchar>(str.at(2)) == Bom_2) {
|
||||
if (str.size() >= 3 && static_cast<uchar>(str.at(0)) == Bom_0
|
||||
&& static_cast<uchar>(str.at(1)) == Bom_1 && static_cast<uchar>(str.at(2)) == Bom_2) {
|
||||
str.assign(str.begin() + 3, str.end());
|
||||
}
|
||||
}
|
||||
@@ -578,50 +708,56 @@ auto open(const path_t& filepath, bool check_bom)
|
||||
|
||||
namespace literals
|
||||
{
|
||||
inline value operator""_json(const char* str, size_t len)
|
||||
{
|
||||
return operator""_jvalue(str, len);
|
||||
}
|
||||
inline wvalue operator""_json(const wchar_t* str, size_t len)
|
||||
{
|
||||
return operator""_jvalue(str, len);
|
||||
}
|
||||
inline value operator""_json(const char* str, size_t len)
|
||||
{
|
||||
return operator""_jvalue(str, len);
|
||||
}
|
||||
|
||||
inline value operator""_jvalue(const char* str, size_t len)
|
||||
{
|
||||
return parse(std::string_view(str, len)).value_or(value());
|
||||
}
|
||||
inline wvalue operator""_jvalue(const wchar_t* str, size_t len)
|
||||
{
|
||||
return parse(std::wstring_view(str, len)).value_or(wvalue());
|
||||
}
|
||||
inline wvalue operator""_json(const wchar_t* str, size_t len)
|
||||
{
|
||||
return operator""_jvalue(str, len);
|
||||
}
|
||||
|
||||
inline array operator""_jarray(const char* str, size_t len)
|
||||
{
|
||||
auto val = parse(std::string_view(str, len)).value_or(value());
|
||||
return val.is_array() ? val.as_array() : array();
|
||||
}
|
||||
inline warray operator""_jarray(const wchar_t* str, size_t len)
|
||||
{
|
||||
auto val = parse(std::wstring_view(str, len)).value_or(wvalue());
|
||||
return val.is_array() ? val.as_array() : warray();
|
||||
}
|
||||
inline value operator""_jvalue(const char* str, size_t len)
|
||||
{
|
||||
return parse(std::string_view(str, len)).value_or(value());
|
||||
}
|
||||
|
||||
inline object operator""_jobject(const char* str, size_t len)
|
||||
{
|
||||
auto val = parse(std::string_view(str, len)).value_or(value());
|
||||
return val.is_object() ? val.as_object() : object();
|
||||
}
|
||||
inline wobject operator""_jobject(const wchar_t* str, size_t len)
|
||||
{
|
||||
auto val = parse(std::wstring_view(str, len)).value_or(wvalue());
|
||||
return val.is_object() ? val.as_object() : wobject();
|
||||
}
|
||||
inline wvalue operator""_jvalue(const wchar_t* str, size_t len)
|
||||
{
|
||||
return parse(std::wstring_view(str, len)).value_or(wvalue());
|
||||
}
|
||||
|
||||
inline array operator""_jarray(const char* str, size_t len)
|
||||
{
|
||||
auto val = parse(std::string_view(str, len)).value_or(value());
|
||||
return val.is_array() ? val.as_array() : array();
|
||||
}
|
||||
|
||||
inline warray operator""_jarray(const wchar_t* str, size_t len)
|
||||
{
|
||||
auto val = parse(std::wstring_view(str, len)).value_or(wvalue());
|
||||
return val.is_array() ? val.as_array() : warray();
|
||||
}
|
||||
|
||||
inline object operator""_jobject(const char* str, size_t len)
|
||||
{
|
||||
auto val = parse(std::string_view(str, len)).value_or(value());
|
||||
return val.is_object() ? val.as_object() : object();
|
||||
}
|
||||
|
||||
inline wobject operator""_jobject(const wchar_t* str, size_t len)
|
||||
{
|
||||
auto val = parse(std::wstring_view(str, len)).value_or(wvalue());
|
||||
return val.is_object() ? val.as_object() : wobject();
|
||||
}
|
||||
} // namespace literals
|
||||
|
||||
template <typename string_t>
|
||||
const basic_value<string_t> invalid_value()
|
||||
{
|
||||
return basic_value<string_t>(basic_value<string_t>::value_type::invalid, typename basic_value<string_t>::var_t());
|
||||
return basic_value<string_t>(
|
||||
basic_value<string_t>::value_type::invalid,
|
||||
typename basic_value<string_t>::var_t());
|
||||
}
|
||||
} // namespace json
|
||||
|
||||
103
3rdparty/include/meojson/parser5/parser5.hpp
vendored
103
3rdparty/include/meojson/parser5/parser5.hpp
vendored
@@ -1,10 +1,11 @@
|
||||
// IWYU pragma: private, include <meojson/json5.hpp>
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <cmath>
|
||||
#include <iomanip>
|
||||
#include <regex>
|
||||
#include <sstream>
|
||||
#include <stack>
|
||||
#include <vector>
|
||||
@@ -31,6 +32,7 @@ public:
|
||||
{
|
||||
public:
|
||||
exception() = default;
|
||||
|
||||
exception(const std::string& type, const std::string& msg, const std::string& detail)
|
||||
{
|
||||
std::stringstream ss;
|
||||
@@ -38,6 +40,7 @@ public:
|
||||
ss << detail << std::endl;
|
||||
_what = ss.str();
|
||||
}
|
||||
|
||||
exception(const exception&) = default;
|
||||
exception& operator=(const exception&) = default;
|
||||
exception(exception&&) = default;
|
||||
@@ -50,8 +53,12 @@ public:
|
||||
{
|
||||
public:
|
||||
InvalidChar(u8char ch = 0, const std::string& detail = "")
|
||||
: exception("Invalid Char", "Unexpected token \'" + StringFromCharCode(ch) + "\'", detail)
|
||||
{}
|
||||
: exception(
|
||||
"Invalid Char",
|
||||
"Unexpected token \'" + StringFromCharCode(ch) + "\'",
|
||||
detail)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class InvalidIdentifier : public exception
|
||||
@@ -59,14 +66,17 @@ public:
|
||||
public:
|
||||
InvalidIdentifier(const std::string& msg = "", const std::string& detail = "")
|
||||
: exception("Invalid Identifier", msg, detail)
|
||||
{}
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class InvalidEOF : public exception
|
||||
{
|
||||
public:
|
||||
InvalidEOF(const std::string& msg = "", const std::string& detail = "") : exception("Invalid EOF", msg, detail)
|
||||
{}
|
||||
InvalidEOF(const std::string& msg = "", const std::string& detail = "")
|
||||
: exception("Invalid EOF", msg, detail)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
@@ -175,7 +185,13 @@ public:
|
||||
static std::optional<value> parse(const string_t& content, std::string* error = nullptr);
|
||||
|
||||
private:
|
||||
parser5(string_iter_t cbegin, string_iter_t cend) noexcept : _cur(cbegin), _end(cend), _line_begin_cur(cbegin) {}
|
||||
parser5(string_iter_t cbegin, string_iter_t cend) noexcept
|
||||
: _cur(cbegin)
|
||||
, _end(cend)
|
||||
, _line_begin_cur(cbegin)
|
||||
{
|
||||
}
|
||||
|
||||
std::optional<value> parse();
|
||||
|
||||
private:
|
||||
@@ -272,62 +288,68 @@ inline bool parser5<string_t>::unicode::isSpaceSeparator(u8char ch)
|
||||
template <typename string_t>
|
||||
inline bool parser5<string_t>::unicode::isIdStartChar(u8char ch)
|
||||
{
|
||||
return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch == '$') || (ch == '_') ||
|
||||
findInRange(json::unicode::id_start, toUnicode(ch));
|
||||
return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch == '$') || (ch == '_')
|
||||
|| findInRange(json::unicode::id_start, toUnicode(ch));
|
||||
}
|
||||
|
||||
template <typename string_t>
|
||||
inline bool parser5<string_t>::unicode::isIdContinueChar(u8char ch)
|
||||
{
|
||||
return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9') || (ch == '$') ||
|
||||
(ch == '_') || findInRange(json::unicode::id_continue, toUnicode(ch));
|
||||
return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9')
|
||||
|| (ch == '$') || (ch == '_') || findInRange(json::unicode::id_continue, toUnicode(ch));
|
||||
}
|
||||
|
||||
template <typename string_t>
|
||||
inline bool parser5<string_t>::unicode::isDigit(u8char ch)
|
||||
{
|
||||
auto str = StringFromCharCode(ch);
|
||||
return std::regex_search(str, std::regex(R"([0-9])"));
|
||||
return (ch >= '0' && ch <= '9');
|
||||
}
|
||||
|
||||
template <typename string_t>
|
||||
inline bool parser5<string_t>::unicode::isHexDigit(u8char ch)
|
||||
{
|
||||
auto str = StringFromCharCode(ch);
|
||||
return std::regex_search(str, std::regex(R"([0-9A-Fa-f])"));
|
||||
return (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F') || (ch >= '0' && ch <= '9');
|
||||
}
|
||||
|
||||
template <typename string_t>
|
||||
inline uint64_t parser5<string_t>::unicode::toUnicode(u8char ch)
|
||||
{
|
||||
std::stack<uint8_t> coded;
|
||||
if (ch == 0) {
|
||||
return ch;
|
||||
}
|
||||
|
||||
std::stack<uint8_t> coded;
|
||||
while (ch > 0) {
|
||||
coded.push(ch & 0xff);
|
||||
ch = ch >> 8;
|
||||
ch >>= 8;
|
||||
}
|
||||
|
||||
u8char charcode = 0;
|
||||
uint8_t t = coded.top();
|
||||
coded.pop();
|
||||
if (t < 128) {
|
||||
return t;
|
||||
}
|
||||
uint8_t high_bit_mask = (1 << 6) - 1;
|
||||
|
||||
uint8_t high_bit_mask = 0b00111111;
|
||||
uint8_t high_bit_shift = 0;
|
||||
int total_bits = 0;
|
||||
const int other_bits = 6;
|
||||
|
||||
while ((t & 0xC0) == 0xC0) {
|
||||
t <<= 1;
|
||||
t &= 0xff;
|
||||
total_bits += 6;
|
||||
total_bits += other_bits;
|
||||
high_bit_mask >>= 1;
|
||||
high_bit_shift++;
|
||||
charcode <<= other_bits;
|
||||
charcode |= coded.top() & ((1 << other_bits) - 1);
|
||||
coded.pop();
|
||||
|
||||
if (!coded.empty()) {
|
||||
charcode <<= other_bits;
|
||||
charcode |= coded.top() & ((1 << other_bits) - 1);
|
||||
coded.pop();
|
||||
}
|
||||
}
|
||||
|
||||
charcode |= static_cast<uint64_t>((t >> high_bit_shift) & high_bit_mask) << total_bits;
|
||||
return charcode;
|
||||
}
|
||||
@@ -346,7 +368,8 @@ inline bool parser5<string_t>::unicode::findInRange(const array_t& range, u8char
|
||||
return false;
|
||||
}
|
||||
// set 中保存的是类似于 { start1, end1, start2, end2, ... } 的形式, 区间可表示为[start, end)
|
||||
// 判断lb是否位于start的位置, 如果是, 则表示codePoint在某个区间的内部, 如果不是, 则表示codePoint在两个区间中间
|
||||
// 判断lb是否位于start的位置, 如果是, 则表示codePoint在某个区间的内部, 如果不是,
|
||||
// 则表示codePoint在两个区间中间
|
||||
return std::distance(begin, lb) % 2 == 0;
|
||||
}
|
||||
|
||||
@@ -519,11 +542,13 @@ inline typename parser5<string_t>::u8char parser5<string_t>::unicodeEscape()
|
||||
|
||||
/* utf-8 reader */
|
||||
template <typename string_t>
|
||||
inline typename parser5<string_t>::u8char parser5<string_t>::peek(const string_iter_t& begin, const string_iter_t& end,
|
||||
size_t* plen)
|
||||
inline typename parser5<string_t>::u8char
|
||||
parser5<string_t>::peek(const string_iter_t& begin, const string_iter_t& end, size_t* plen)
|
||||
{
|
||||
if (begin == end) {
|
||||
if (plen) *plen = 0;
|
||||
if (plen) {
|
||||
*plen = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
uint8_t head = *begin;
|
||||
@@ -549,10 +574,12 @@ inline typename parser5<string_t>::u8char parser5<string_t>::peek(const std::str
|
||||
{
|
||||
return peek(str.cbegin(), str.cend());
|
||||
}
|
||||
|
||||
inline constexpr size_t operator"" _sz(unsigned long long size)
|
||||
{
|
||||
return size;
|
||||
}
|
||||
|
||||
template <typename string_t>
|
||||
inline typename parser5<string_t>::u8char parser5<string_t>::read()
|
||||
{
|
||||
@@ -581,11 +608,15 @@ inline typename parser5<string_t>::u8char parser5<string_t>::read()
|
||||
template <typename string_t>
|
||||
inline std::string parser5<string_t>::StringFromCharCode(typename parser5<string_t>::u8char code)
|
||||
{
|
||||
if (code == 0) return "";
|
||||
if (code == 0) {
|
||||
return "";
|
||||
}
|
||||
std::string str;
|
||||
for (auto i = 0; i < 8; ++i) {
|
||||
auto ch = (0xff & code);
|
||||
if (ch) str.insert(0, 1, static_cast<char>(ch));
|
||||
if (ch) {
|
||||
str.insert(0, 1, static_cast<char>(ch));
|
||||
}
|
||||
code >>= 8;
|
||||
}
|
||||
return str;
|
||||
@@ -700,7 +731,8 @@ inline std::optional<typename parser5<string_t>::Token> parser5<string_t>::lex_m
|
||||
}
|
||||
|
||||
template <typename string_t>
|
||||
inline std::optional<typename parser5<string_t>::Token> parser5<string_t>::lex_multiLineCommentAsterisk()
|
||||
inline std::optional<typename parser5<string_t>::Token>
|
||||
parser5<string_t>::lex_multiLineCommentAsterisk()
|
||||
{
|
||||
switch (_current_char) {
|
||||
case '*':
|
||||
@@ -808,7 +840,8 @@ inline std::optional<typename parser5<string_t>::Token> parser5<string_t>::lex_v
|
||||
}
|
||||
|
||||
template <typename string_t>
|
||||
inline std::optional<typename parser5<string_t>::Token> parser5<string_t>::lex_identifierNameStartEscape()
|
||||
inline std::optional<typename parser5<string_t>::Token>
|
||||
parser5<string_t>::lex_identifierNameStartEscape()
|
||||
{
|
||||
if (_current_char != 'u') {
|
||||
throw InvalidChar(_current_char, exceptionDetailInfo());
|
||||
@@ -855,7 +888,8 @@ inline std::optional<typename parser5<string_t>::Token> parser5<string_t>::lex_i
|
||||
}
|
||||
|
||||
template <typename string_t>
|
||||
inline std::optional<typename parser5<string_t>::Token> parser5<string_t>::lex_identifierNameEscape()
|
||||
inline std::optional<typename parser5<string_t>::Token>
|
||||
parser5<string_t>::lex_identifierNameEscape()
|
||||
{
|
||||
if (_current_char != 'u') {
|
||||
throw InvalidChar(_current_char, exceptionDetailInfo());
|
||||
@@ -1047,7 +1081,8 @@ inline std::optional<typename parser5<string_t>::Token> parser5<string_t>::lex_d
|
||||
}
|
||||
|
||||
template <typename string_t>
|
||||
inline std::optional<typename parser5<string_t>::Token> parser5<string_t>::lex_decimalExponentInteger()
|
||||
inline std::optional<typename parser5<string_t>::Token>
|
||||
parser5<string_t>::lex_decimalExponentInteger()
|
||||
{
|
||||
if (unicode::isDigit(_current_char)) {
|
||||
_buffer += StringFromCharCode(read());
|
||||
@@ -1386,7 +1421,8 @@ inline void parser5<string_t>::parse_afterArrayValue()
|
||||
|
||||
template <typename string_t>
|
||||
inline void parser5<string_t>::parse_end()
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
template <typename string_t>
|
||||
inline void parser5<string_t>::parseStates(ParseState state)
|
||||
@@ -1417,6 +1453,7 @@ inline void parser5<string_t>::parseStates(ParseState state)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* stack operation */
|
||||
template <typename string_t>
|
||||
inline void parser5<string_t>::push()
|
||||
|
||||
2
3rdparty/include/meojson/parser5/unicode.h
vendored
2
3rdparty/include/meojson/parser5/unicode.h
vendored
@@ -1,3 +1,5 @@
|
||||
// IWYU pragma: private, include <meojson/json5.hpp>
|
||||
|
||||
// This is a generated file. Do not edit.
|
||||
#pragma once
|
||||
#include <array>
|
||||
|
||||
456
3rdparty/include/meojson/reflection/jsonization.hpp
vendored
456
3rdparty/include/meojson/reflection/jsonization.hpp
vendored
@@ -1,3 +1,5 @@
|
||||
// IWYU pragma: private, include <meojson/json.hpp>
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
@@ -8,9 +10,12 @@
|
||||
namespace json::_jsonization_helper
|
||||
{
|
||||
struct next_is_optional_t
|
||||
{};
|
||||
{
|
||||
};
|
||||
|
||||
struct va_arg_end
|
||||
{};
|
||||
{
|
||||
};
|
||||
|
||||
struct dumper
|
||||
{
|
||||
@@ -21,19 +26,25 @@ struct dumper
|
||||
result.emplace(key, var);
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename... rest_t>
|
||||
json::value _to_json(const char*, next_is_optional_t, rest_t&&... rest) const
|
||||
{
|
||||
return _to_json(std::forward<rest_t>(rest)...);
|
||||
}
|
||||
|
||||
json::value _to_json(va_arg_end) const { return {}; }
|
||||
};
|
||||
|
||||
struct checker
|
||||
{
|
||||
template <typename var_t, typename... rest_t>
|
||||
bool _check_json(const json::value& in, std::string& error_key, const char* key, const var_t&,
|
||||
rest_t&&... rest) const
|
||||
bool _check_json(
|
||||
const json::value& in,
|
||||
std::string& error_key,
|
||||
const char* key,
|
||||
const var_t&,
|
||||
rest_t&&... rest) const
|
||||
{
|
||||
auto opt = in.find(key);
|
||||
if (!opt || !opt->is<var_t>()) {
|
||||
@@ -42,9 +53,16 @@ struct checker
|
||||
}
|
||||
return _check_json(in, error_key, std::forward<rest_t>(rest)...);
|
||||
}
|
||||
|
||||
template <typename var_t, typename... rest_t>
|
||||
bool _check_json(const json::value& in, std::string& error_key, const char*, next_is_optional_t, const char* key,
|
||||
const var_t&, rest_t&&... rest) const
|
||||
bool _check_json(
|
||||
const json::value& in,
|
||||
std::string& error_key,
|
||||
const char*,
|
||||
next_is_optional_t,
|
||||
const char* key,
|
||||
const var_t&,
|
||||
rest_t&&... rest) const
|
||||
{
|
||||
auto opt = in.find(key);
|
||||
if (opt) {
|
||||
@@ -56,13 +74,19 @@ struct checker
|
||||
|
||||
return _check_json(in, error_key, std::forward<rest_t>(rest)...);
|
||||
}
|
||||
|
||||
bool _check_json(const json::value&, std::string&, va_arg_end) const { return true; }
|
||||
};
|
||||
|
||||
struct loader
|
||||
{
|
||||
template <typename var_t, typename... rest_t>
|
||||
bool _from_json(const json::value& in, std::string& error_key, const char* key, var_t& var, rest_t&&... rest) const
|
||||
bool _from_json(
|
||||
const json::value& in,
|
||||
std::string& error_key,
|
||||
const char* key,
|
||||
var_t& var,
|
||||
rest_t&&... rest) const
|
||||
{
|
||||
auto opt = in.find(key);
|
||||
if (!opt || !opt->is<var_t>()) {
|
||||
@@ -73,9 +97,16 @@ struct loader
|
||||
|
||||
return _from_json(in, error_key, std::forward<rest_t>(rest)...);
|
||||
}
|
||||
|
||||
template <typename var_t, typename... rest_t>
|
||||
bool _from_json(const json::value& in, std::string& error_key, const char*, next_is_optional_t, const char* key,
|
||||
var_t& var, rest_t&&... rest) const
|
||||
bool _from_json(
|
||||
const json::value& in,
|
||||
std::string& error_key,
|
||||
const char*,
|
||||
next_is_optional_t,
|
||||
const char* key,
|
||||
var_t& var,
|
||||
rest_t&&... rest) const
|
||||
{
|
||||
auto opt = in.find(key);
|
||||
if (opt) {
|
||||
@@ -88,6 +119,7 @@ struct loader
|
||||
|
||||
return _from_json(in, error_key, std::forward<rest_t>(rest)...);
|
||||
}
|
||||
|
||||
bool _from_json(const json::value&, std::string&, va_arg_end) const { return true; }
|
||||
};
|
||||
} // namespace json::_jsonization_helper
|
||||
@@ -111,122 +143,322 @@ namespace json::_private_macro
|
||||
|
||||
#define _MEOJSON_FOR_EACH_0(pred, ...)
|
||||
#define _MEOJSON_FOR_EACH_1(pred, x, ...) pred(x)
|
||||
#define _MEOJSON_FOR_EACH_2(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_1(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_3(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_2(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_4(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_3(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_5(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_4(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_6(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_5(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_7(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_6(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_8(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_7(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_9(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_8(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_10(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_9(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_11(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_10(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_12(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_11(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_13(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_12(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_14(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_13(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_15(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_14(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_16(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_15(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_17(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_16(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_18(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_17(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_19(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_18(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_20(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_19(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_21(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_20(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_22(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_21(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_23(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_22(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_24(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_23(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_25(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_24(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_26(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_25(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_27(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_26(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_28(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_27(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_29(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_28(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_30(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_29(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_31(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_30(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_32(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_31(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_33(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_32(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_34(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_33(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_35(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_34(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_36(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_35(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_37(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_36(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_38(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_37(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_39(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_38(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_40(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_39(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_41(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_40(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_42(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_41(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_43(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_42(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_44(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_43(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_45(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_44(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_46(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_45(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_47(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_46(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_48(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_47(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_49(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_48(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_50(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_49(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_51(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_50(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_52(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_51(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_53(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_52(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_54(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_53(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_55(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_54(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_56(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_55(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_57(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_56(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_58(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_57(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_59(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_58(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_60(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_59(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_61(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_60(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_62(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_61(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_63(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_62(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_64(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_63(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_2(pred, x, ...) \
|
||||
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_1(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_3(pred, x, ...) \
|
||||
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_2(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_4(pred, x, ...) \
|
||||
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_3(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_5(pred, x, ...) \
|
||||
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_4(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_6(pred, x, ...) \
|
||||
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_5(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_7(pred, x, ...) \
|
||||
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_6(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_8(pred, x, ...) \
|
||||
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_7(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_9(pred, x, ...) \
|
||||
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_8(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_10(pred, x, ...) \
|
||||
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_9(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_11(pred, x, ...) \
|
||||
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_10(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_12(pred, x, ...) \
|
||||
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_11(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_13(pred, x, ...) \
|
||||
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_12(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_14(pred, x, ...) \
|
||||
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_13(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_15(pred, x, ...) \
|
||||
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_14(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_16(pred, x, ...) \
|
||||
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_15(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_17(pred, x, ...) \
|
||||
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_16(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_18(pred, x, ...) \
|
||||
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_17(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_19(pred, x, ...) \
|
||||
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_18(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_20(pred, x, ...) \
|
||||
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_19(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_21(pred, x, ...) \
|
||||
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_20(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_22(pred, x, ...) \
|
||||
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_21(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_23(pred, x, ...) \
|
||||
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_22(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_24(pred, x, ...) \
|
||||
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_23(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_25(pred, x, ...) \
|
||||
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_24(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_26(pred, x, ...) \
|
||||
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_25(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_27(pred, x, ...) \
|
||||
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_26(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_28(pred, x, ...) \
|
||||
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_27(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_29(pred, x, ...) \
|
||||
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_28(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_30(pred, x, ...) \
|
||||
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_29(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_31(pred, x, ...) \
|
||||
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_30(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_32(pred, x, ...) \
|
||||
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_31(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_33(pred, x, ...) \
|
||||
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_32(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_34(pred, x, ...) \
|
||||
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_33(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_35(pred, x, ...) \
|
||||
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_34(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_36(pred, x, ...) \
|
||||
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_35(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_37(pred, x, ...) \
|
||||
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_36(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_38(pred, x, ...) \
|
||||
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_37(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_39(pred, x, ...) \
|
||||
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_38(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_40(pred, x, ...) \
|
||||
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_39(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_41(pred, x, ...) \
|
||||
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_40(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_42(pred, x, ...) \
|
||||
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_41(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_43(pred, x, ...) \
|
||||
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_42(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_44(pred, x, ...) \
|
||||
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_43(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_45(pred, x, ...) \
|
||||
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_44(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_46(pred, x, ...) \
|
||||
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_45(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_47(pred, x, ...) \
|
||||
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_46(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_48(pred, x, ...) \
|
||||
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_47(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_49(pred, x, ...) \
|
||||
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_48(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_50(pred, x, ...) \
|
||||
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_49(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_51(pred, x, ...) \
|
||||
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_50(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_52(pred, x, ...) \
|
||||
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_51(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_53(pred, x, ...) \
|
||||
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_52(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_54(pred, x, ...) \
|
||||
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_53(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_55(pred, x, ...) \
|
||||
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_54(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_56(pred, x, ...) \
|
||||
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_55(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_57(pred, x, ...) \
|
||||
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_56(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_58(pred, x, ...) \
|
||||
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_57(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_59(pred, x, ...) \
|
||||
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_58(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_60(pred, x, ...) \
|
||||
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_59(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_61(pred, x, ...) \
|
||||
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_60(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_62(pred, x, ...) \
|
||||
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_61(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_63(pred, x, ...) \
|
||||
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_62(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_64(pred, x, ...) \
|
||||
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_63(pred, __VA_ARGS__))
|
||||
|
||||
#define _MEOJSON_ARG_COUNT(...) \
|
||||
_MEOJSON_EXPAND(_MEOJSON_ARG_COUNT1(0, ##__VA_ARGS__, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, \
|
||||
49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, \
|
||||
30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, \
|
||||
11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0))
|
||||
#define _MEOJSON_ARG_COUNT1(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, \
|
||||
_20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, \
|
||||
_38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, \
|
||||
_56, _57, _58, _59, _60, _61, _62, _63, _64, N, ...) \
|
||||
#define _MEOJSON_ARG_COUNT(...) \
|
||||
_MEOJSON_EXPAND(_MEOJSON_ARG_COUNT1( \
|
||||
0, \
|
||||
##__VA_ARGS__, \
|
||||
64, \
|
||||
63, \
|
||||
62, \
|
||||
61, \
|
||||
60, \
|
||||
59, \
|
||||
58, \
|
||||
57, \
|
||||
56, \
|
||||
55, \
|
||||
54, \
|
||||
53, \
|
||||
52, \
|
||||
51, \
|
||||
50, \
|
||||
49, \
|
||||
48, \
|
||||
47, \
|
||||
46, \
|
||||
45, \
|
||||
44, \
|
||||
43, \
|
||||
42, \
|
||||
41, \
|
||||
40, \
|
||||
39, \
|
||||
38, \
|
||||
37, \
|
||||
36, \
|
||||
35, \
|
||||
34, \
|
||||
33, \
|
||||
32, \
|
||||
31, \
|
||||
30, \
|
||||
29, \
|
||||
28, \
|
||||
27, \
|
||||
26, \
|
||||
25, \
|
||||
24, \
|
||||
23, \
|
||||
22, \
|
||||
21, \
|
||||
20, \
|
||||
19, \
|
||||
18, \
|
||||
17, \
|
||||
16, \
|
||||
15, \
|
||||
14, \
|
||||
13, \
|
||||
12, \
|
||||
11, \
|
||||
10, \
|
||||
9, \
|
||||
8, \
|
||||
7, \
|
||||
6, \
|
||||
5, \
|
||||
4, \
|
||||
3, \
|
||||
2, \
|
||||
1, \
|
||||
0))
|
||||
#define _MEOJSON_ARG_COUNT1( \
|
||||
_0, \
|
||||
_1, \
|
||||
_2, \
|
||||
_3, \
|
||||
_4, \
|
||||
_5, \
|
||||
_6, \
|
||||
_7, \
|
||||
_8, \
|
||||
_9, \
|
||||
_10, \
|
||||
_11, \
|
||||
_12, \
|
||||
_13, \
|
||||
_14, \
|
||||
_15, \
|
||||
_16, \
|
||||
_17, \
|
||||
_18, \
|
||||
_19, \
|
||||
_20, \
|
||||
_21, \
|
||||
_22, \
|
||||
_23, \
|
||||
_24, \
|
||||
_25, \
|
||||
_26, \
|
||||
_27, \
|
||||
_28, \
|
||||
_29, \
|
||||
_30, \
|
||||
_31, \
|
||||
_32, \
|
||||
_33, \
|
||||
_34, \
|
||||
_35, \
|
||||
_36, \
|
||||
_37, \
|
||||
_38, \
|
||||
_39, \
|
||||
_40, \
|
||||
_41, \
|
||||
_42, \
|
||||
_43, \
|
||||
_44, \
|
||||
_45, \
|
||||
_46, \
|
||||
_47, \
|
||||
_48, \
|
||||
_49, \
|
||||
_50, \
|
||||
_51, \
|
||||
_52, \
|
||||
_53, \
|
||||
_54, \
|
||||
_55, \
|
||||
_56, \
|
||||
_57, \
|
||||
_58, \
|
||||
_59, \
|
||||
_60, \
|
||||
_61, \
|
||||
_62, \
|
||||
_63, \
|
||||
_64, \
|
||||
N, \
|
||||
...) \
|
||||
N
|
||||
|
||||
#define _MEOJSON_FOR_EACH_(N, pred, ...) _MEOJSON_EXPAND(_MEOJSON_CONCATENATE(_MEOJSON_FOR_EACH_, N)(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH_(N, pred, ...) \
|
||||
_MEOJSON_EXPAND(_MEOJSON_CONCATENATE(_MEOJSON_FOR_EACH_, N)(pred, __VA_ARGS__))
|
||||
#define _MEOJSON_FOR_EACH(pred, ...) \
|
||||
_MEOJSON_EXPAND(_MEOJSON_FOR_EACH_(_MEOJSON_EXPAND(_MEOJSON_ARG_COUNT(__VA_ARGS__)), pred, __VA_ARGS__))
|
||||
_MEOJSON_EXPAND( \
|
||||
_MEOJSON_FOR_EACH_(_MEOJSON_EXPAND(_MEOJSON_ARG_COUNT(__VA_ARGS__)), pred, __VA_ARGS__))
|
||||
|
||||
#define _MEOJSON_VARNAME(x) _MEOJSON_CONCATENATE(_meojson_jsonization_, x)
|
||||
#define _MEOJSON_KEY_VALUE(x) _MEOJSON_STRINGIZE(x), x,
|
||||
} // namespace json::_private_macro
|
||||
|
||||
#define MEO_TOJSON(...) \
|
||||
json::value to_json() const \
|
||||
{ \
|
||||
return json::_jsonization_helper::dumper()._to_json(_MEOJSON_EXPAND( \
|
||||
_MEOJSON_FOR_EACH(_MEOJSON_KEY_VALUE, __VA_ARGS__)) json::_jsonization_helper::va_arg_end {}); \
|
||||
#define MEO_TOJSON(...) \
|
||||
json::value to_json() const \
|
||||
{ \
|
||||
return json::_jsonization_helper::dumper()._to_json( \
|
||||
_MEOJSON_EXPAND(_MEOJSON_FOR_EACH(_MEOJSON_KEY_VALUE, __VA_ARGS__)) \
|
||||
json::_jsonization_helper::va_arg_end {}); \
|
||||
}
|
||||
|
||||
#define MEO_CHECKJSON(...) \
|
||||
bool check_json(const json::value& _MEOJSON_VARNAME(in)) const \
|
||||
{ \
|
||||
std::string _MEOJSON_VARNAME(error_key); \
|
||||
return check_json(_MEOJSON_VARNAME(in), _MEOJSON_VARNAME(error_key)); \
|
||||
} \
|
||||
bool check_json(const json::value& _MEOJSON_VARNAME(in), std::string& _MEOJSON_VARNAME(error_key)) const \
|
||||
{ \
|
||||
return json::_jsonization_helper::checker()._check_json( \
|
||||
_MEOJSON_VARNAME(in), _MEOJSON_VARNAME(error_key), \
|
||||
_MEOJSON_EXPAND(_MEOJSON_FOR_EACH(_MEOJSON_KEY_VALUE, __VA_ARGS__)) \
|
||||
json::_jsonization_helper::va_arg_end {}); \
|
||||
#define MEO_CHECKJSON(...) \
|
||||
bool check_json(const json::value& _MEOJSON_VARNAME(in)) const \
|
||||
{ \
|
||||
std::string _MEOJSON_VARNAME(error_key); \
|
||||
return check_json(_MEOJSON_VARNAME(in), _MEOJSON_VARNAME(error_key)); \
|
||||
} \
|
||||
bool check_json( \
|
||||
const json::value& _MEOJSON_VARNAME(in), \
|
||||
std::string& _MEOJSON_VARNAME(error_key)) const \
|
||||
{ \
|
||||
return json::_jsonization_helper::checker()._check_json( \
|
||||
_MEOJSON_VARNAME(in), \
|
||||
_MEOJSON_VARNAME(error_key), \
|
||||
_MEOJSON_EXPAND(_MEOJSON_FOR_EACH(_MEOJSON_KEY_VALUE, __VA_ARGS__)) \
|
||||
json::_jsonization_helper::va_arg_end {}); \
|
||||
}
|
||||
|
||||
#define MEO_FROMJSON(...) \
|
||||
bool from_json(const json::value& _MEOJSON_VARNAME(in)) \
|
||||
{ \
|
||||
std::string _MEOJSON_VARNAME(error_key); \
|
||||
return from_json(_MEOJSON_VARNAME(in), _MEOJSON_VARNAME(error_key)); \
|
||||
} \
|
||||
bool from_json(const json::value& _MEOJSON_VARNAME(in), std::string& _MEOJSON_VARNAME(error_key)) \
|
||||
{ \
|
||||
return json::_jsonization_helper::loader()._from_json( \
|
||||
_MEOJSON_VARNAME(in), _MEOJSON_VARNAME(error_key), \
|
||||
_MEOJSON_EXPAND(_MEOJSON_FOR_EACH(_MEOJSON_KEY_VALUE, __VA_ARGS__)) \
|
||||
json::_jsonization_helper::va_arg_end {}); \
|
||||
#define MEO_FROMJSON(...) \
|
||||
bool from_json(const json::value& _MEOJSON_VARNAME(in)) \
|
||||
{ \
|
||||
std::string _MEOJSON_VARNAME(error_key); \
|
||||
return from_json(_MEOJSON_VARNAME(in), _MEOJSON_VARNAME(error_key)); \
|
||||
} \
|
||||
bool from_json( \
|
||||
const json::value& _MEOJSON_VARNAME(in), \
|
||||
std::string& _MEOJSON_VARNAME(error_key)) \
|
||||
{ \
|
||||
return json::_jsonization_helper::loader()._from_json( \
|
||||
_MEOJSON_VARNAME(in), \
|
||||
_MEOJSON_VARNAME(error_key), \
|
||||
_MEOJSON_EXPAND(_MEOJSON_FOR_EACH(_MEOJSON_KEY_VALUE, __VA_ARGS__)) \
|
||||
json::_jsonization_helper::va_arg_end {}); \
|
||||
}
|
||||
|
||||
#define MEO_JSONIZATION(...) \
|
||||
|
||||
Reference in New Issue
Block a user