replace constructor by from/to_json: array_t
This commit is contained in:
parent
c847e0eea2
commit
7e6a6f978e
2 changed files with 110 additions and 130 deletions
120
src/json.hpp
120
src/json.hpp
|
@ -299,6 +299,33 @@ struct external_constructor<value_t::array>
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct external_constructor<value_t::object>
|
||||||
|
{
|
||||||
|
template <typename Json>
|
||||||
|
static void construct(Json &j, const typename Json::object_t& obj)
|
||||||
|
{
|
||||||
|
j.m_type = value_t::object;
|
||||||
|
j.m_value = obj;
|
||||||
|
j.assert_invariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Json, typename CompatibleObjectType,
|
||||||
|
enable_if_t<not std::is_same<CompatibleObjectType,
|
||||||
|
typename Json::object_t>::value,
|
||||||
|
int> = 0>
|
||||||
|
static void construct(Json &j, const CompatibleObjectType &obj)
|
||||||
|
{
|
||||||
|
using std::begin;
|
||||||
|
using std::end;
|
||||||
|
|
||||||
|
j.m_type = value_t::object;
|
||||||
|
j.m_value.object =
|
||||||
|
j.template create<typename Json::object_t>(begin(obj), end(obj));
|
||||||
|
j.assert_invariant();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// very useful construct against boilerplate (more boilerplate needed than in
|
// very useful construct against boilerplate (more boilerplate needed than in
|
||||||
// C++17: http://en.cppreference.com/w/cpp/types/void_t)
|
// C++17: http://en.cppreference.com/w/cpp/types/void_t)
|
||||||
template <typename...> struct make_void
|
template <typename...> struct make_void
|
||||||
|
@ -458,8 +485,7 @@ struct is_compatible_float_type
|
||||||
template <typename T, typename BasicJson>
|
template <typename T, typename BasicJson>
|
||||||
struct is_compatible_basic_json_type
|
struct is_compatible_basic_json_type
|
||||||
{
|
{
|
||||||
static auto constexpr value =
|
static auto constexpr value = false;
|
||||||
is_compatible_object_type<typename BasicJson::object_t, T>::value;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, typename BasicJson, typename PrimitiveIterator>
|
template <typename T, typename BasicJson, typename PrimitiveIterator>
|
||||||
|
@ -611,6 +637,15 @@ void to_json(Json &j, CompatibleArrayType const &arr)
|
||||||
external_constructor<value_t::array>::construct(j, arr);
|
external_constructor<value_t::array>::construct(j, arr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <
|
||||||
|
typename Json, typename CompatibleObjectType,
|
||||||
|
enable_if_t<is_compatible_object_type<typename Json::object_t, CompatibleObjectType>::value,
|
||||||
|
int> = 0>
|
||||||
|
void to_json(Json &j, CompatibleObjectType const &arr)
|
||||||
|
{
|
||||||
|
external_constructor<value_t::object>::construct(j, arr);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename Json>
|
template <typename Json>
|
||||||
void from_json(Json const& j, typename Json::boolean_t& b)
|
void from_json(Json const& j, typename Json::boolean_t& b)
|
||||||
{
|
{
|
||||||
|
@ -707,6 +742,24 @@ void from_json(Json const &j, CompatibleArrayType &arr)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <
|
||||||
|
typename Json, typename CompatibleObjectType,
|
||||||
|
enable_if_t<is_compatible_object_type<typename Json::object_t, CompatibleObjectType>::value,
|
||||||
|
int> = 0>
|
||||||
|
void from_json(Json const &j, CompatibleObjectType &obj)
|
||||||
|
{
|
||||||
|
if (!j.is_object())
|
||||||
|
throw std::domain_error("type must be object, but is " + type_name(j));
|
||||||
|
|
||||||
|
auto inner_object = const_cast<Json&>(j).template get_ptr<typename Json::object_t*>();
|
||||||
|
using std::begin;
|
||||||
|
using std::end;
|
||||||
|
// we could avoid the assignment, but this might require a for loop, which
|
||||||
|
// might be less efficient than the container constructor for some containers (would it?)
|
||||||
|
obj = CompatibleObjectType(begin(*inner_object), end(*inner_object));
|
||||||
|
}
|
||||||
|
|
||||||
// overload for arithmetic types, not chosen for basic_json template arguments (BooleanType, etc..)
|
// overload for arithmetic types, not chosen for basic_json template arguments (BooleanType, etc..)
|
||||||
//
|
//
|
||||||
// note: Is it really necessary to provide explicit overloads for boolean_t etc..
|
// note: Is it really necessary to provide explicit overloads for boolean_t etc..
|
||||||
|
@ -1806,69 +1859,6 @@ class basic_json
|
||||||
assert_invariant();
|
assert_invariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
@brief create an object (explicit)
|
|
||||||
|
|
||||||
Create an object JSON value with a given content.
|
|
||||||
|
|
||||||
@param[in] val a value for the object
|
|
||||||
|
|
||||||
@complexity Linear in the size of the passed @a val.
|
|
||||||
|
|
||||||
@throw std::bad_alloc if allocation for object value fails
|
|
||||||
|
|
||||||
@liveexample{The following code shows the constructor with an @ref
|
|
||||||
object_t parameter.,basic_json__object_t}
|
|
||||||
|
|
||||||
@sa @ref basic_json(const CompatibleObjectType&) -- create an object value
|
|
||||||
from a compatible STL container
|
|
||||||
|
|
||||||
@since version 1.0.0
|
|
||||||
*/
|
|
||||||
basic_json(const object_t& val)
|
|
||||||
: m_type(value_t::object), m_value(val)
|
|
||||||
{
|
|
||||||
assert_invariant();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
@brief create an object (implicit)
|
|
||||||
|
|
||||||
Create an object JSON value with a given content. This constructor allows
|
|
||||||
any type @a CompatibleObjectType that can be used to construct values of
|
|
||||||
type @ref object_t.
|
|
||||||
|
|
||||||
@tparam CompatibleObjectType An object type whose `key_type` and
|
|
||||||
`value_type` is compatible to @ref object_t. Examples include `std::map`,
|
|
||||||
`std::unordered_map`, `std::multimap`, and `std::unordered_multimap` with
|
|
||||||
a `key_type` of `std::string`, and a `value_type` from which a @ref
|
|
||||||
basic_json value can be constructed.
|
|
||||||
|
|
||||||
@param[in] val a value for the object
|
|
||||||
|
|
||||||
@complexity Linear in the size of the passed @a val.
|
|
||||||
|
|
||||||
@throw std::bad_alloc if allocation for object value fails
|
|
||||||
|
|
||||||
@liveexample{The following code shows the constructor with several
|
|
||||||
compatible object type parameters.,basic_json__CompatibleObjectType}
|
|
||||||
|
|
||||||
@sa @ref basic_json(const object_t&) -- create an object value
|
|
||||||
|
|
||||||
@since version 1.0.0
|
|
||||||
*/
|
|
||||||
template <class CompatibleObjectType,
|
|
||||||
enable_if_t<detail::is_compatible_object_type<
|
|
||||||
object_t, CompatibleObjectType>::value,
|
|
||||||
int> = 0>
|
|
||||||
basic_json(const CompatibleObjectType& val) : m_type(value_t::object)
|
|
||||||
{
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
m_value.object = create<object_t>(begin(val), end(val));
|
|
||||||
assert_invariant();
|
|
||||||
}
|
|
||||||
|
|
||||||
// constructor chosen when:
|
// constructor chosen when:
|
||||||
// - JSONSerializer::to_json exists for type T
|
// - JSONSerializer::to_json exists for type T
|
||||||
// - T is not a istream, nor convertible to basic_json (float, vectors, etc)
|
// - T is not a istream, nor convertible to basic_json (float, vectors, etc)
|
||||||
|
|
|
@ -299,6 +299,33 @@ struct external_constructor<value_t::array>
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct external_constructor<value_t::object>
|
||||||
|
{
|
||||||
|
template <typename Json>
|
||||||
|
static void construct(Json &j, const typename Json::object_t& obj)
|
||||||
|
{
|
||||||
|
j.m_type = value_t::object;
|
||||||
|
j.m_value = obj;
|
||||||
|
j.assert_invariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Json, typename CompatibleObjectType,
|
||||||
|
enable_if_t<not std::is_same<CompatibleObjectType,
|
||||||
|
typename Json::object_t>::value,
|
||||||
|
int> = 0>
|
||||||
|
static void construct(Json &j, const CompatibleObjectType &obj)
|
||||||
|
{
|
||||||
|
using std::begin;
|
||||||
|
using std::end;
|
||||||
|
|
||||||
|
j.m_type = value_t::object;
|
||||||
|
j.m_value.object =
|
||||||
|
j.template create<typename Json::object_t>(begin(obj), end(obj));
|
||||||
|
j.assert_invariant();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// very useful construct against boilerplate (more boilerplate needed than in
|
// very useful construct against boilerplate (more boilerplate needed than in
|
||||||
// C++17: http://en.cppreference.com/w/cpp/types/void_t)
|
// C++17: http://en.cppreference.com/w/cpp/types/void_t)
|
||||||
template <typename...> struct make_void
|
template <typename...> struct make_void
|
||||||
|
@ -458,8 +485,7 @@ struct is_compatible_float_type
|
||||||
template <typename T, typename BasicJson>
|
template <typename T, typename BasicJson>
|
||||||
struct is_compatible_basic_json_type
|
struct is_compatible_basic_json_type
|
||||||
{
|
{
|
||||||
static auto constexpr value =
|
static auto constexpr value = false;
|
||||||
is_compatible_object_type<typename BasicJson::object_t, T>::value;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, typename BasicJson, typename PrimitiveIterator>
|
template <typename T, typename BasicJson, typename PrimitiveIterator>
|
||||||
|
@ -611,6 +637,15 @@ void to_json(Json &j, CompatibleArrayType const &arr)
|
||||||
external_constructor<value_t::array>::construct(j, arr);
|
external_constructor<value_t::array>::construct(j, arr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <
|
||||||
|
typename Json, typename CompatibleObjectType,
|
||||||
|
enable_if_t<is_compatible_object_type<typename Json::object_t, CompatibleObjectType>::value,
|
||||||
|
int> = 0>
|
||||||
|
void to_json(Json &j, CompatibleObjectType const &arr)
|
||||||
|
{
|
||||||
|
external_constructor<value_t::object>::construct(j, arr);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename Json>
|
template <typename Json>
|
||||||
void from_json(Json const& j, typename Json::boolean_t& b)
|
void from_json(Json const& j, typename Json::boolean_t& b)
|
||||||
{
|
{
|
||||||
|
@ -707,6 +742,24 @@ void from_json(Json const &j, CompatibleArrayType &arr)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <
|
||||||
|
typename Json, typename CompatibleObjectType,
|
||||||
|
enable_if_t<is_compatible_object_type<typename Json::object_t, CompatibleObjectType>::value,
|
||||||
|
int> = 0>
|
||||||
|
void from_json(Json const &j, CompatibleObjectType &obj)
|
||||||
|
{
|
||||||
|
if (!j.is_object())
|
||||||
|
throw std::domain_error("type must be object, but is " + type_name(j));
|
||||||
|
|
||||||
|
auto inner_object = const_cast<Json&>(j).template get_ptr<typename Json::object_t*>();
|
||||||
|
using std::begin;
|
||||||
|
using std::end;
|
||||||
|
// we could avoid the assignment, but this might require a for loop, which
|
||||||
|
// might be less efficient than the container constructor for some containers (would it?)
|
||||||
|
obj = CompatibleObjectType(begin(*inner_object), end(*inner_object));
|
||||||
|
}
|
||||||
|
|
||||||
// overload for arithmetic types, not chosen for basic_json template arguments (BooleanType, etc..)
|
// overload for arithmetic types, not chosen for basic_json template arguments (BooleanType, etc..)
|
||||||
//
|
//
|
||||||
// note: Is it really necessary to provide explicit overloads for boolean_t etc..
|
// note: Is it really necessary to provide explicit overloads for boolean_t etc..
|
||||||
|
@ -1807,69 +1860,6 @@ class basic_json
|
||||||
assert_invariant();
|
assert_invariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
@brief create an object (explicit)
|
|
||||||
|
|
||||||
Create an object JSON value with a given content.
|
|
||||||
|
|
||||||
@param[in] val a value for the object
|
|
||||||
|
|
||||||
@complexity Linear in the size of the passed @a val.
|
|
||||||
|
|
||||||
@throw std::bad_alloc if allocation for object value fails
|
|
||||||
|
|
||||||
@liveexample{The following code shows the constructor with an @ref
|
|
||||||
object_t parameter.,basic_json__object_t}
|
|
||||||
|
|
||||||
@sa @ref basic_json(const CompatibleObjectType&) -- create an object value
|
|
||||||
from a compatible STL container
|
|
||||||
|
|
||||||
@since version 1.0.0
|
|
||||||
*/
|
|
||||||
basic_json(const object_t& val)
|
|
||||||
: m_type(value_t::object), m_value(val)
|
|
||||||
{
|
|
||||||
assert_invariant();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
@brief create an object (implicit)
|
|
||||||
|
|
||||||
Create an object JSON value with a given content. This constructor allows
|
|
||||||
any type @a CompatibleObjectType that can be used to construct values of
|
|
||||||
type @ref object_t.
|
|
||||||
|
|
||||||
@tparam CompatibleObjectType An object type whose `key_type` and
|
|
||||||
`value_type` is compatible to @ref object_t. Examples include `std::map`,
|
|
||||||
`std::unordered_map`, `std::multimap`, and `std::unordered_multimap` with
|
|
||||||
a `key_type` of `std::string`, and a `value_type` from which a @ref
|
|
||||||
basic_json value can be constructed.
|
|
||||||
|
|
||||||
@param[in] val a value for the object
|
|
||||||
|
|
||||||
@complexity Linear in the size of the passed @a val.
|
|
||||||
|
|
||||||
@throw std::bad_alloc if allocation for object value fails
|
|
||||||
|
|
||||||
@liveexample{The following code shows the constructor with several
|
|
||||||
compatible object type parameters.,basic_json__CompatibleObjectType}
|
|
||||||
|
|
||||||
@sa @ref basic_json(const object_t&) -- create an object value
|
|
||||||
|
|
||||||
@since version 1.0.0
|
|
||||||
*/
|
|
||||||
template <class CompatibleObjectType,
|
|
||||||
enable_if_t<detail::is_compatible_object_type<
|
|
||||||
object_t, CompatibleObjectType>::value,
|
|
||||||
int> = 0>
|
|
||||||
basic_json(const CompatibleObjectType& val) : m_type(value_t::object)
|
|
||||||
{
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
m_value.object = create<object_t>(begin(val), end(val));
|
|
||||||
assert_invariant();
|
|
||||||
}
|
|
||||||
|
|
||||||
// constructor chosen when:
|
// constructor chosen when:
|
||||||
// - JSONSerializer::to_json exists for type T
|
// - JSONSerializer::to_json exists for type T
|
||||||
// - T is not a istream, nor convertible to basic_json (float, vectors, etc)
|
// - T is not a istream, nor convertible to basic_json (float, vectors, etc)
|
||||||
|
|
Loading…
Reference in a new issue