55template <
typename TPo
inter>
72 _subtype_ctors.emplace_back(std::move(
pred),
89 std::type_index
tidx = std::type_index(
typeid(T));
109 _check_null_input =
on;
112 bool check_null_input()
const
114 return _check_null_input;
122 _check_null_output =
on;
125 bool check_null_output()
const
127 return _check_null_output;
132 virtual TPointer create(
const extraction_context& context,
const value& from)
const override
137 if (_check_null_input && from.is_null())
140 auto iter = std::find_if(begin(_subtype_ctors), end(_subtype_ctors),
141 [&] (
const std::pair<match_predicate, create_function>& pair)
143 return pair.first(context, from);
146 if (iter != end(_subtype_ctors))
147 return iter->second(context, from);
149 throw extraction_error(context.path(),
150 std::string(
"No discriminators matched JSON value: ") + to_string(from)
154 virtual value to_json(
const serialization_context& context,
const TPointer& from)
const override
156 if (_check_null_output && !from)
159 value serialized = context.to_json(
typeid(*from),
static_cast<const void*
>(&*from));
161 auto action_iter = _serialization_actions.find(std::type_index(
typeid(*from)));
162 if (action_iter != _serialization_actions.end())
166 return " polymorphic_adapter<" +
demangle(
typeid(TPointer).name()) +
">"
167 "subtype(" +
demangle(
typeid(*from).name()) +
")";
170 const std::string& key = std::get<0>(action_iter->second);
171 const value& val = std::get<1>(action_iter->second);
179 if (!serialized.is_object())
180 throw std::runtime_error(
"Expected keyed subtype to serialize as an object." + errmsg());
181 if (!serialized.count(key))
182 throw std::runtime_error(
"Expected subtype key not found." + errmsg());
183 if (serialized.at(key) != val)
184 throw std::runtime_error(
"Expected subtype key is not the expected value." + errmsg());
187 if (!serialized.is_object())
188 throw std::runtime_error(
"Expected keyed subtype to serialize as an object." + errmsg());
189 if (serialized.count(key))
190 throw std::runtime_error(
"Subtype key already present when trying to insert." + errmsg());
191 serialized[key] = val;
194 throw std::runtime_error(
"Unknown keyed_subtype_action.");
202 using create_function = std::function<TPointer (
const extraction_context&,
const value&)>;
205 using serialization_action = std::tuple<std::string, value, keyed_subtype_action>;
207 std::vector<std::pair<match_predicate, create_function>> _subtype_ctors;
208 std::map<std::type_index, serialization_action> _serialization_actions;
209 bool _check_null_input =
false;
210 bool _check_null_output =
false;
An adapter for the type T.
virtual void extract(const extraction_context &context, const value &from, void *into) const override
Extract a the type from a value into a region of memory.
Exception thrown if an insertion of an extractor or serializer into a formats is attempted,...
An adapter for enumeration types.
An adapter which can create polymorphic types.
void add_subtype_keyed(std::string key, value expected_value, keyed_subtype_action action=keyed_subtype_action::none)
Add a subtype which can be transformed into TPointer which will be called if given a JSON value with ...
void check_null_output(bool on)
}
void check_null_input(bool on)
void add_subtype(match_predicate pred)
Add a subtype which can be transformed into TPointer which will be called if the discriminator pred i...
Represents a single JSON value, which can be any one of a potential kind, each behaving slightly diff...
object_iterator end_object()
Get an iterator to the one past the end of this object.
object_iterator find(const std::string &key)
Attempt to locate a key-value pair with the provided key in this object.
bool is_object() const
Tests if this kind is kind::object.
Copyright (c) 2014-2020 by Travis Gockel.
JSONV_PUBLIC std::string demangle(string_view source)
Convert the input source from a mangled type into a human-friendly version.
keyed_subtype_action
What to do when serializing a keyed subtype of a polymorphic_adapter.
@ check
Ensure the correct key/value pair was inserted by serialization. Throws std::runtime_error if it wasn...
@ none
Don't do any checking or insertion of the expected key/value pair.
@ insert
Insert the correct key/value pair as part of serialization.
JSONV_PUBLIC const value null
An instance with kind::null.
Conversion between C++ types and JSON values.