mirror of
https://github.com/nlohmann/json.git
synced 2025-01-19 15:53:00 +08:00
replace constructor by from/to_json: array_t
- tweaked a bit how `get<container<json>>` is handled - added a from_json overload for forward list
This commit is contained in:
parent
6d427acdde
commit
c847e0eea2
196
src/json.hpp
196
src/json.hpp
@ -39,6 +39,7 @@ SOFTWARE.
|
||||
#include <cstdint> // int64_t, uint64_t
|
||||
#include <cstdlib> // strtod, strtof, strtold, strtoul
|
||||
#include <cstring> // strlen
|
||||
#include <forward_list> // forward_list
|
||||
#include <functional> // function, hash, less
|
||||
#include <initializer_list> // initializer_list
|
||||
#include <iomanip> // setw
|
||||
@ -272,6 +273,32 @@ struct external_constructor<value_t::number_integer>
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct external_constructor<value_t::array>
|
||||
{
|
||||
template <typename Json>
|
||||
static void construct(Json &j, const typename Json::array_t& arr)
|
||||
{
|
||||
j.m_type = value_t::array;
|
||||
j.m_value = arr;
|
||||
j.assert_invariant();
|
||||
}
|
||||
|
||||
template <typename Json, typename CompatibleArrayType,
|
||||
enable_if_t<not std::is_same<CompatibleArrayType,
|
||||
typename Json::array_t>::value,
|
||||
int> = 0>
|
||||
static void construct(Json &j, const CompatibleArrayType &arr)
|
||||
{
|
||||
using std::begin;
|
||||
using std::end;
|
||||
j.m_type = value_t::array;
|
||||
j.m_value.array =
|
||||
j.template create<typename Json::array_t>(begin(arr), end(arr));
|
||||
j.assert_invariant();
|
||||
}
|
||||
};
|
||||
|
||||
// very useful construct against boilerplate (more boilerplate needed than in
|
||||
// C++17: http://en.cppreference.com/w/cpp/types/void_t)
|
||||
template <typename...> struct make_void
|
||||
@ -432,8 +459,6 @@ template <typename T, typename BasicJson>
|
||||
struct is_compatible_basic_json_type
|
||||
{
|
||||
static auto constexpr value =
|
||||
std::is_same<T, BasicJson>::value or
|
||||
is_compatible_array_type<BasicJson, T>::value or
|
||||
is_compatible_object_type<typename BasicJson::object_t, T>::value;
|
||||
};
|
||||
|
||||
@ -575,6 +600,17 @@ void to_json(Json &j, UnscopedEnumType e)
|
||||
external_constructor<value_t::number_integer>::construct(j, e);
|
||||
}
|
||||
|
||||
template <
|
||||
typename Json, typename CompatibleArrayType,
|
||||
enable_if_t<
|
||||
is_compatible_array_type<Json, CompatibleArrayType>::value or
|
||||
std::is_same<typename Json::array_t, CompatibleArrayType>::value,
|
||||
int> = 0>
|
||||
void to_json(Json &j, CompatibleArrayType const &arr)
|
||||
{
|
||||
external_constructor<value_t::array>::construct(j, arr);
|
||||
}
|
||||
|
||||
template <typename Json>
|
||||
void from_json(Json const& j, typename Json::boolean_t& b)
|
||||
{
|
||||
@ -618,6 +654,59 @@ void from_json(Json const &j, UnscopedEnumType& e)
|
||||
e = static_cast<UnscopedEnumType>(val);
|
||||
}
|
||||
|
||||
template <typename Json>
|
||||
void from_json(Json const &j, typename Json::array_t &arr)
|
||||
{
|
||||
if (!j.is_array())
|
||||
throw std::domain_error("type must be array, but is " + type_name(j));
|
||||
arr = *const_cast<Json&>(j).template get_ptr<typename Json::array_t*>();
|
||||
}
|
||||
|
||||
// forward_list doesn't have an insert method, TODO find a way to avoid including forward_list
|
||||
template <typename Json, typename T, typename Allocator>
|
||||
void from_json(Json const&j, std::forward_list<T, Allocator>& l)
|
||||
{
|
||||
// do not perform the check when user wants to retrieve jsons
|
||||
// (except when it's null.. ?)
|
||||
if (j.is_null())
|
||||
throw std::domain_error("type must be array, but is " + type_name(j));
|
||||
if (not std::is_same<T, Json>::value)
|
||||
{
|
||||
if (!j.is_array())
|
||||
throw std::domain_error("type must be array, but is " + type_name(j));
|
||||
}
|
||||
for (auto it = j.rbegin(), end = j.rend(); it != end; ++it)
|
||||
l.push_front(it->template get<T>());
|
||||
}
|
||||
|
||||
template <
|
||||
typename Json, typename CompatibleArrayType,
|
||||
enable_if_t<is_compatible_array_type<Json, CompatibleArrayType>::value and
|
||||
not std::is_same<typename Json::array_t,
|
||||
CompatibleArrayType>::value,
|
||||
int> = 0>
|
||||
void from_json(Json const &j, CompatibleArrayType &arr)
|
||||
{
|
||||
if (j.is_null())
|
||||
throw std::domain_error("type must be array, but is " + type_name(j));
|
||||
// when T == Json, do not check if value_t is correct
|
||||
if (not std::is_same<typename CompatibleArrayType::value_type, Json>::value)
|
||||
{
|
||||
if (!j.is_array())
|
||||
throw std::domain_error("type must be array, but is " + type_name(j));
|
||||
}
|
||||
|
||||
using std::begin;
|
||||
using std::end;
|
||||
std::transform(
|
||||
j.begin(), j.end(), std::inserter(arr, end(arr)), [](Json const &i)
|
||||
{
|
||||
// get<Json>() returns *this, this won't call a from_json method when
|
||||
// value_type is Json
|
||||
return i.template get<typename CompatibleArrayType::value_type>();
|
||||
});
|
||||
}
|
||||
|
||||
// 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..
|
||||
@ -1780,69 +1869,6 @@ class basic_json
|
||||
assert_invariant();
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief create an array (explicit)
|
||||
|
||||
Create an array JSON value with a given content.
|
||||
|
||||
@param[in] val a value for the array
|
||||
|
||||
@complexity Linear in the size of the passed @a val.
|
||||
|
||||
@throw std::bad_alloc if allocation for array value fails
|
||||
|
||||
@liveexample{The following code shows the constructor with an @ref array_t
|
||||
parameter.,basic_json__array_t}
|
||||
|
||||
@sa @ref basic_json(const CompatibleArrayType&) -- create an array value
|
||||
from a compatible STL containers
|
||||
|
||||
@since version 1.0.0
|
||||
*/
|
||||
basic_json(const array_t& val)
|
||||
: m_type(value_t::array), m_value(val)
|
||||
{
|
||||
assert_invariant();
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief create an array (implicit)
|
||||
|
||||
Create an array JSON value with a given content. This constructor allows
|
||||
any type @a CompatibleArrayType that can be used to construct values of
|
||||
type @ref array_t.
|
||||
|
||||
@tparam CompatibleArrayType An object type whose `value_type` is
|
||||
compatible to @ref array_t. Examples include `std::vector`, `std::deque`,
|
||||
`std::list`, `std::forward_list`, `std::array`, `std::set`,
|
||||
`std::unordered_set`, `std::multiset`, and `unordered_multiset` with a
|
||||
`value_type` from which a @ref basic_json value can be constructed.
|
||||
|
||||
@param[in] val a value for the array
|
||||
|
||||
@complexity Linear in the size of the passed @a val.
|
||||
|
||||
@throw std::bad_alloc if allocation for array value fails
|
||||
|
||||
@liveexample{The following code shows the constructor with several
|
||||
compatible array type parameters.,basic_json__CompatibleArrayType}
|
||||
|
||||
@sa @ref basic_json(const array_t&) -- create an array value
|
||||
|
||||
@since version 1.0.0
|
||||
*/
|
||||
template <class CompatibleArrayType,
|
||||
enable_if_t<detail::is_compatible_array_type<basic_json_t, CompatibleArrayType>::value,
|
||||
int> = 0>
|
||||
basic_json(const CompatibleArrayType& val) : m_type(value_t::array)
|
||||
{
|
||||
using std::begin;
|
||||
using std::end;
|
||||
m_value.array = create<array_t>(begin(val), end(val));
|
||||
assert_invariant();
|
||||
}
|
||||
|
||||
|
||||
// constructor chosen when:
|
||||
// - JSONSerializer::to_json exists for type T
|
||||
// - T is not a istream, nor convertible to basic_json (float, vectors, etc)
|
||||
@ -1851,6 +1877,7 @@ class basic_json
|
||||
typename T,
|
||||
enable_if_t<not std::is_base_of<std::istream, uncvref_t<T>>::value and
|
||||
not detail::is_basic_json_nested_class<uncvref_t<T>, basic_json_t, primitive_iterator_t>::value and
|
||||
not std::is_same<uncvref_t<T>, basic_json_t>::value and
|
||||
not std::is_same<uncvref_t<T>, typename basic_json_t::array_t::iterator>::value and
|
||||
not std::is_same<uncvref_t<T>, typename basic_json_t::object_t::iterator>::value and
|
||||
detail::conjunction<detail::negation<detail::is_compatible_basic_json_type<
|
||||
@ -3211,23 +3238,34 @@ class basic_json
|
||||
return get_impl(static_cast<ValueType *>(nullptr));
|
||||
}
|
||||
|
||||
// if T is basic_json, simply returns *this
|
||||
template <typename T,
|
||||
enable_if_t<std::is_same<T, basic_json_t>::value, int> = 0>
|
||||
basic_json get() const
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <
|
||||
typename T,
|
||||
enable_if_t<detail::conjunction<detail::negation<detail::is_compatible_basic_json_type<
|
||||
uncvref_t<T>, basic_json_t>>,
|
||||
detail::has_from_json<JSONSerializer, basic_json_t,
|
||||
uncvref_t<T>>>::value,
|
||||
int> = 0 >
|
||||
auto get() const -> uncvref_t<T>
|
||||
enable_if_t<detail::conjunction<
|
||||
detail::negation<detail::is_compatible_basic_json_type<
|
||||
uncvref_t<T>, basic_json_t>>,
|
||||
detail::has_from_json<JSONSerializer, basic_json_t,
|
||||
uncvref_t<T>>>::value and
|
||||
not std::is_same<basic_json_t, uncvref_t<T>>::value,
|
||||
int> = 0>
|
||||
// do we really want the uncvref ? if a user call get<int &>, shouldn't we static assert ?
|
||||
auto get() const -> uncvref_t<T>
|
||||
{
|
||||
using type = uncvref_t<T>;
|
||||
static_assert(std::is_default_constructible<type>::value&&
|
||||
std::is_copy_constructible<type>::value,
|
||||
"user-defined types must be DefaultConstructible and "
|
||||
"CopyConstructible when used with get");
|
||||
type ret;
|
||||
JSONSerializer<type>::from_json(*this, ret);
|
||||
return ret;
|
||||
using type = uncvref_t<T>;
|
||||
static_assert(std::is_default_constructible<type>::value &&
|
||||
std::is_copy_constructible<type>::value,
|
||||
"user-defined types must be DefaultConstructible and "
|
||||
"CopyConstructible when used with get");
|
||||
type ret;
|
||||
JSONSerializer<type>::from_json(*this, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// This overload is chosen for non-default constructible user-defined-types
|
||||
|
@ -39,6 +39,7 @@ SOFTWARE.
|
||||
#include <cstdint> // int64_t, uint64_t
|
||||
#include <cstdlib> // strtod, strtof, strtold, strtoul
|
||||
#include <cstring> // strlen
|
||||
#include <forward_list> // forward_list
|
||||
#include <functional> // function, hash, less
|
||||
#include <initializer_list> // initializer_list
|
||||
#include <iomanip> // setw
|
||||
@ -272,6 +273,32 @@ struct external_constructor<value_t::number_integer>
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct external_constructor<value_t::array>
|
||||
{
|
||||
template <typename Json>
|
||||
static void construct(Json &j, const typename Json::array_t& arr)
|
||||
{
|
||||
j.m_type = value_t::array;
|
||||
j.m_value = arr;
|
||||
j.assert_invariant();
|
||||
}
|
||||
|
||||
template <typename Json, typename CompatibleArrayType,
|
||||
enable_if_t<not std::is_same<CompatibleArrayType,
|
||||
typename Json::array_t>::value,
|
||||
int> = 0>
|
||||
static void construct(Json &j, const CompatibleArrayType &arr)
|
||||
{
|
||||
using std::begin;
|
||||
using std::end;
|
||||
j.m_type = value_t::array;
|
||||
j.m_value.array =
|
||||
j.template create<typename Json::array_t>(begin(arr), end(arr));
|
||||
j.assert_invariant();
|
||||
}
|
||||
};
|
||||
|
||||
// very useful construct against boilerplate (more boilerplate needed than in
|
||||
// C++17: http://en.cppreference.com/w/cpp/types/void_t)
|
||||
template <typename...> struct make_void
|
||||
@ -432,8 +459,6 @@ template <typename T, typename BasicJson>
|
||||
struct is_compatible_basic_json_type
|
||||
{
|
||||
static auto constexpr value =
|
||||
std::is_same<T, BasicJson>::value or
|
||||
is_compatible_array_type<BasicJson, T>::value or
|
||||
is_compatible_object_type<typename BasicJson::object_t, T>::value;
|
||||
};
|
||||
|
||||
@ -575,6 +600,17 @@ void to_json(Json &j, UnscopedEnumType e)
|
||||
external_constructor<value_t::number_integer>::construct(j, e);
|
||||
}
|
||||
|
||||
template <
|
||||
typename Json, typename CompatibleArrayType,
|
||||
enable_if_t<
|
||||
is_compatible_array_type<Json, CompatibleArrayType>::value or
|
||||
std::is_same<typename Json::array_t, CompatibleArrayType>::value,
|
||||
int> = 0>
|
||||
void to_json(Json &j, CompatibleArrayType const &arr)
|
||||
{
|
||||
external_constructor<value_t::array>::construct(j, arr);
|
||||
}
|
||||
|
||||
template <typename Json>
|
||||
void from_json(Json const& j, typename Json::boolean_t& b)
|
||||
{
|
||||
@ -618,6 +654,59 @@ void from_json(Json const &j, UnscopedEnumType& e)
|
||||
e = static_cast<UnscopedEnumType>(val);
|
||||
}
|
||||
|
||||
template <typename Json>
|
||||
void from_json(Json const &j, typename Json::array_t &arr)
|
||||
{
|
||||
if (!j.is_array())
|
||||
throw std::domain_error("type must be array, but is " + type_name(j));
|
||||
arr = *const_cast<Json&>(j).template get_ptr<typename Json::array_t*>();
|
||||
}
|
||||
|
||||
// forward_list doesn't have an insert method, TODO find a way to avoid including forward_list
|
||||
template <typename Json, typename T, typename Allocator>
|
||||
void from_json(Json const&j, std::forward_list<T, Allocator>& l)
|
||||
{
|
||||
// do not perform the check when user wants to retrieve jsons
|
||||
// (except when it's null.. ?)
|
||||
if (j.is_null())
|
||||
throw std::domain_error("type must be array, but is " + type_name(j));
|
||||
if (not std::is_same<T, Json>::value)
|
||||
{
|
||||
if (!j.is_array())
|
||||
throw std::domain_error("type must be array, but is " + type_name(j));
|
||||
}
|
||||
for (auto it = j.rbegin(), end = j.rend(); it != end; ++it)
|
||||
l.push_front(it->template get<T>());
|
||||
}
|
||||
|
||||
template <
|
||||
typename Json, typename CompatibleArrayType,
|
||||
enable_if_t<is_compatible_array_type<Json, CompatibleArrayType>::value and
|
||||
not std::is_same<typename Json::array_t,
|
||||
CompatibleArrayType>::value,
|
||||
int> = 0>
|
||||
void from_json(Json const &j, CompatibleArrayType &arr)
|
||||
{
|
||||
if (j.is_null())
|
||||
throw std::domain_error("type must be array, but is " + type_name(j));
|
||||
// when T == Json, do not check if value_t is correct
|
||||
if (not std::is_same<typename CompatibleArrayType::value_type, Json>::value)
|
||||
{
|
||||
if (!j.is_array())
|
||||
throw std::domain_error("type must be array, but is " + type_name(j));
|
||||
}
|
||||
|
||||
using std::begin;
|
||||
using std::end;
|
||||
std::transform(
|
||||
j.begin(), j.end(), std::inserter(arr, end(arr)), [](Json const &i)
|
||||
{
|
||||
// get<Json>() returns *this, this won't call a from_json method when
|
||||
// value_type is Json
|
||||
return i.template get<typename CompatibleArrayType::value_type>();
|
||||
});
|
||||
}
|
||||
|
||||
// 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..
|
||||
@ -1781,69 +1870,6 @@ class basic_json
|
||||
assert_invariant();
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief create an array (explicit)
|
||||
|
||||
Create an array JSON value with a given content.
|
||||
|
||||
@param[in] val a value for the array
|
||||
|
||||
@complexity Linear in the size of the passed @a val.
|
||||
|
||||
@throw std::bad_alloc if allocation for array value fails
|
||||
|
||||
@liveexample{The following code shows the constructor with an @ref array_t
|
||||
parameter.,basic_json__array_t}
|
||||
|
||||
@sa @ref basic_json(const CompatibleArrayType&) -- create an array value
|
||||
from a compatible STL containers
|
||||
|
||||
@since version 1.0.0
|
||||
*/
|
||||
basic_json(const array_t& val)
|
||||
: m_type(value_t::array), m_value(val)
|
||||
{
|
||||
assert_invariant();
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief create an array (implicit)
|
||||
|
||||
Create an array JSON value with a given content. This constructor allows
|
||||
any type @a CompatibleArrayType that can be used to construct values of
|
||||
type @ref array_t.
|
||||
|
||||
@tparam CompatibleArrayType An object type whose `value_type` is
|
||||
compatible to @ref array_t. Examples include `std::vector`, `std::deque`,
|
||||
`std::list`, `std::forward_list`, `std::array`, `std::set`,
|
||||
`std::unordered_set`, `std::multiset`, and `unordered_multiset` with a
|
||||
`value_type` from which a @ref basic_json value can be constructed.
|
||||
|
||||
@param[in] val a value for the array
|
||||
|
||||
@complexity Linear in the size of the passed @a val.
|
||||
|
||||
@throw std::bad_alloc if allocation for array value fails
|
||||
|
||||
@liveexample{The following code shows the constructor with several
|
||||
compatible array type parameters.,basic_json__CompatibleArrayType}
|
||||
|
||||
@sa @ref basic_json(const array_t&) -- create an array value
|
||||
|
||||
@since version 1.0.0
|
||||
*/
|
||||
template <class CompatibleArrayType,
|
||||
enable_if_t<detail::is_compatible_array_type<basic_json_t, CompatibleArrayType>::value,
|
||||
int> = 0>
|
||||
basic_json(const CompatibleArrayType& val) : m_type(value_t::array)
|
||||
{
|
||||
using std::begin;
|
||||
using std::end;
|
||||
m_value.array = create<array_t>(begin(val), end(val));
|
||||
assert_invariant();
|
||||
}
|
||||
|
||||
|
||||
// constructor chosen when:
|
||||
// - JSONSerializer::to_json exists for type T
|
||||
// - T is not a istream, nor convertible to basic_json (float, vectors, etc)
|
||||
@ -1852,6 +1878,7 @@ class basic_json
|
||||
typename T,
|
||||
enable_if_t<not std::is_base_of<std::istream, uncvref_t<T>>::value and
|
||||
not detail::is_basic_json_nested_class<uncvref_t<T>, basic_json_t, primitive_iterator_t>::value and
|
||||
not std::is_same<uncvref_t<T>, basic_json_t>::value and
|
||||
not std::is_same<uncvref_t<T>, typename basic_json_t::array_t::iterator>::value and
|
||||
not std::is_same<uncvref_t<T>, typename basic_json_t::object_t::iterator>::value and
|
||||
detail::conjunction<detail::negation<detail::is_compatible_basic_json_type<
|
||||
@ -3209,23 +3236,34 @@ class basic_json
|
||||
return get_impl(static_cast<ValueType *>(nullptr));
|
||||
}
|
||||
|
||||
// if T is basic_json, simply returns *this
|
||||
template <typename T,
|
||||
enable_if_t<std::is_same<T, basic_json_t>::value, int> = 0>
|
||||
basic_json get() const
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <
|
||||
typename T,
|
||||
enable_if_t<detail::conjunction<detail::negation<detail::is_compatible_basic_json_type<
|
||||
uncvref_t<T>, basic_json_t>>,
|
||||
detail::has_from_json<JSONSerializer, basic_json_t,
|
||||
uncvref_t<T>>>::value,
|
||||
int> = 0 >
|
||||
auto get() const -> uncvref_t<T>
|
||||
enable_if_t<detail::conjunction<
|
||||
detail::negation<detail::is_compatible_basic_json_type<
|
||||
uncvref_t<T>, basic_json_t>>,
|
||||
detail::has_from_json<JSONSerializer, basic_json_t,
|
||||
uncvref_t<T>>>::value and
|
||||
not std::is_same<basic_json_t, uncvref_t<T>>::value,
|
||||
int> = 0>
|
||||
// do we really want the uncvref ? if a user call get<int &>, shouldn't we static assert ?
|
||||
auto get() const -> uncvref_t<T>
|
||||
{
|
||||
using type = uncvref_t<T>;
|
||||
static_assert(std::is_default_constructible<type>::value&&
|
||||
std::is_copy_constructible<type>::value,
|
||||
"user-defined types must be DefaultConstructible and "
|
||||
"CopyConstructible when used with get");
|
||||
type ret;
|
||||
JSONSerializer<type>::from_json(*this, ret);
|
||||
return ret;
|
||||
using type = uncvref_t<T>;
|
||||
static_assert(std::is_default_constructible<type>::value &&
|
||||
std::is_copy_constructible<type>::value,
|
||||
"user-defined types must be DefaultConstructible and "
|
||||
"CopyConstructible when used with get");
|
||||
type ret;
|
||||
JSONSerializer<type>::from_json(*this, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// This overload is chosen for non-default constructible user-defined-types
|
||||
|
@ -1004,6 +1004,8 @@ TEST_CASE("value conversion")
|
||||
CHECK_THROWS_AS((json().get<std::vector<json>>()), std::logic_error);
|
||||
CHECK_THROWS_AS((json().get<std::list<json>>()), std::logic_error);
|
||||
|
||||
// does type really must be an array? or it rather must not be null?
|
||||
// that's what I thought when other test like this one broke
|
||||
CHECK_THROWS_WITH((json().get<std::list<int>>()), "type must be array, but is null");
|
||||
CHECK_THROWS_WITH((json().get<std::vector<int>>()), "type must be array, but is null");
|
||||
CHECK_THROWS_WITH((json().get<std::vector<json>>()), "type must be array, but is null");
|
||||
|
@ -391,19 +391,19 @@ TEST_CASE("adl_serializer specialization", "[udt]")
|
||||
|
||||
namespace nlohmann
|
||||
{
|
||||
// this might work in the future, not in the scope of this PR though
|
||||
// we have to make this very clear in the doc
|
||||
template <typename T>
|
||||
struct adl_serializer<std::vector<T>>
|
||||
{
|
||||
static void to_json(json& j, std::vector<T> const& opt)
|
||||
{
|
||||
}
|
||||
|
||||
static void from_json(json const& j, std::vector<T>& opt)
|
||||
{
|
||||
}
|
||||
};
|
||||
// TODO provide a real example, since this works now :)
|
||||
// template <typename T>
|
||||
// struct adl_serializer<std::vector<T>>
|
||||
// {
|
||||
// static void to_json(json& j, std::vector<T> const& opt)
|
||||
// {
|
||||
//
|
||||
// }
|
||||
//
|
||||
// static void from_json(json const& j, std::vector<T>& opt)
|
||||
// {
|
||||
// }
|
||||
// };
|
||||
}
|
||||
|
||||
TEST_CASE("current supported types are preferred over specializations", "[udt]")
|
||||
|
Loading…
Reference in New Issue
Block a user