20#include <initializer_list>
38 static int compare(
const value& a, std::string_view b)
40 return compare_text(a, b);
45struct enum_text_order_icase
48 static int compare(
const value& a, std::string_view b)
50 return compare_text_icase(a, b);
58template <
typename FValueComp,
typename TTextOrder>
61 using is_transparent = void;
64 bool operator()(
const value& a,
const value& b)
const
66 return FValueComp()(a, b);
70 bool operator()(
const value& a, std::string_view b)
const
72 return TTextOrder::compare(a, b) < 0;
76 bool operator()(std::string_view a,
const value& b)
const
79 return TTextOrder::compare(b, a) > 0;
87template <
typename FValueComp>
88struct enum_value_order
90 using type = FValueComp;
92 static constexpr bool reads_text =
false;
96struct enum_value_order<
std::less<value>>
98 using type = enum_value_less<std::less<value>, enum_text_order>;
100 static constexpr bool reads_text =
true;
104struct enum_value_order<value_less>
106 using type = enum_value_less<value_less, enum_text_order>;
108 static constexpr bool reads_text =
true;
112struct enum_value_order<value_less_icase>
114 using type = enum_value_less<value_less_icase, enum_text_order_icase>;
116 static constexpr bool reads_text =
true;
145template <
typename TEnum,
146 typename FEnumComp = std::less<TEnum>,
147 typename FValueComp = std::less<value>
156 template <
typename TForwardIterator>
157 explicit enum_adapter(std::string enum_name, TForwardIterator first, TForwardIterator last) :
158 _enum_name(
std::move(enum_name))
160 for (
auto iter = first; iter != last; ++iter)
162 _val_to_cpp.insert({ iter->second, iter->first });
163 _cpp_to_val.insert(*iter);
190 explicit enum_adapter(std::string enum_name, std::initializer_list<std::pair<TEnum, value>> mapping) :
200 return settle(
context, from, *lent);
202 if constexpr (value_order::reads_text)
212 return settle(
context, from, std::string_view(decoded));
225 auto iter = _cpp_to_val.find(from);
226 if (iter != end(_cpp_to_val))
227 to.
write(iter->second);
233 using value_order = detail::enum_value_order<FValueComp>;
236 template <
typename TKey>
239 auto iter = _val_to_cpp.find(key);
240 if (iter == _val_to_cpp.end())
250 TEnum out = iter->second;
264 std::string describe_miss(
const value& found)
const
266 std::string message =
"Invalid value for " + _enum_name +
": " +
to_string(found);
267 if (!_val_to_cpp.empty())
269 const char* separator =
" (expected one of ";
270 for (
const auto& accepted : _val_to_cpp)
272 message += separator;
282 std::string _enum_name;
283 std::map<value, TEnum, typename value_order::type> _val_to_cpp;
284 std::map<TEnum, value, FEnumComp> _cpp_to_val;
290template <
typename TEnum,
typename FEnumComp = std::less<TEnum>>
Copyright (c) 2015-2026 by Travis Gockel.
Utilities for directly dealing with a JSON AST.
An adapter for the type T.
const T & as() const
Get the underlying data of this node as T.
Provides extra information to routines used for deserialization and serialization.
Provides extra information to routines used for deserialization, collects the problems they encounter...
void note_value_consumed(const reader &from) noexcept
Note that the failure about to be reported has already consumed, from from, the value it failed on,...
An adapter for enumeration types.
virtual std::expected< TEnum, ast_node_type > create(deserialization_context &context, reader &from) const override
Create an instance of T by reading from.
virtual void serialize(const serialization_context &, const TEnum &from, writer &to) const override
Write from into to.
enum_adapter(std::string enum_name, TForwardIterator first, TForwardIterator last)
Create an adapter with mapping values from the range [first, last).
enum_adapter(std::string enum_name, std::initializer_list< std::pair< TEnum, value > > mapping)
Create an adapter with the specified mapping values.
A reader instance reads from some form of JSON source (probably a string) and converts it into a JSON...
bool next_value() noexcept
Go to one past the value this reader is on.
ast_node_type current_type() const
Get the type of the current AST node, which is always current().type().
const ast_node & current() const
Get the current AST node this reader is pointing at.
optional< const value & > current_value() const noexcept
Get the in-memory value this reader is positioned on, if it has one to lend.
bool good() const
Check if this reader is still good to read from.
Provides extra information to routines used for serialization: the formats to find other serializers ...
Represents a single JSON value, which can be any one of a potential kind, each behaving slightly diff...
A writer instance writes a JSON ast_node sequence to some form of sink: an encoder,...
writer & write(const value &source)
Write the whole of source as one value, as encoder::encode does.
writer & null()
Write a scalar value.
Copyright (c) 2014-2020 by Travis Gockel.
A collection of function objects a la <functional>.
int compare(const value &a, const value &b, const TCompareTraits &traits)
Compare the values a and b using the comparison traits.
#define JSONV_NODISCARD
Warn if the caller discards the result of this function.
JSONV_PUBLIC std::string to_string(const ast_node_type &type)
Get what operator<< writes for type as a std::string.
Conversion between C++ types and JSON values.