💄 overworked documentation and indentation

This commit is contained in:
Niels Lohmann 2017-01-24 13:47:33 +01:00
parent 030cf674ef
commit 250e5bf43d
2 changed files with 486 additions and 436 deletions

View file

@ -107,12 +107,15 @@ SOFTWARE.
*/
namespace nlohmann
{
// TODO update this doc
/*!
@brief unnamed namespace with internal helper functions
@since version 1.0.0
*/
This namespace collects some functions that could not be defined inside the
@ref basic_json class.
@since version 2.1.0
*/
namespace detail
{
///////////////////////////
@ -122,22 +125,24 @@ namespace detail
/*!
@brief the JSON type enumeration
This enumeration collects the different JSON types. It is internally used
to distinguish the stored values, and the functions @ref basic_json::is_null(), @ref
basic_json::is_object(), @ref basic_json::is_array(), @ref basic_json::is_string(), @ref basic_json::is_boolean(), @ref
basic_json::is_number() (with @ref basic_json::is_number_integer(), @ref basic_json::is_number_unsigned(), and
@ref basic_json::is_number_float()), @ref basic_json::is_discarded(), @ref basic_json::is_primitive(), and
This enumeration collects the different JSON types. It is internally used to
distinguish the stored values, and the functions @ref basic_json::is_null(),
@ref basic_json::is_object(), @ref basic_json::is_array(),
@ref basic_json::is_string(), @ref basic_json::is_boolean(),
@ref basic_json::is_number() (with @ref basic_json::is_number_integer(),
@ref basic_json::is_number_unsigned(), and @ref basic_json::is_number_float()),
@ref basic_json::is_discarded(), @ref basic_json::is_primitive(), and
@ref basic_json::is_structured() rely on it.
@note There are three enumeration entries (number_integer,
number_unsigned, and number_float), because the library distinguishes
these three types for numbers: @ref basic_json::number_unsigned_t is used for unsigned
integers, @ref basic_json::number_integer_t is used for signed integers, and @ref
basic_json::number_float_t is used for floating-point numbers or to approximate
integers which do not fit in the limits of their respective type.
@note There are three enumeration entries (number_integer, number_unsigned, and
number_float), because the library distinguishes these three types for numbers:
@ref basic_json::number_unsigned_t is used for unsigned integers,
@ref basic_json::number_integer_t is used for signed integers, and
@ref basic_json::number_float_t is used for floating-point numbers or to
approximate integers which do not fit in the limits of their respective type.
@sa @ref basic_json::basic_json(const value_t value_type) -- create a JSON value with
the default value for a given type
@sa @ref basic_json::basic_json(const value_t value_type) -- create a JSON
value with the default value for a given type
@since version 1.0.0
*/
@ -154,12 +159,6 @@ enum class value_t : uint8_t
discarded ///< discarded by the the parser callback function
};
//////////////////////////////////////////
// lexicographical comparison operators //
//////////////////////////////////////////
/// @name lexicographical comparison operators
/// @{
/*!
@brief comparison operator for JSON types
@ -193,6 +192,11 @@ inline bool operator<(const value_t lhs, const value_t rhs) noexcept
order[static_cast<std::size_t>(rhs)];
}
/////////////
// helpers //
/////////////
// alias templates to reduce boilerplate
template<bool B, typename T = void>
using enable_if_t = typename std::enable_if<B, T>::type;
@ -206,32 +210,38 @@ using is_unscoped_enum =
std::integral_constant<bool, std::is_convertible<T, int>::value and
std::is_enum<T>::value>;
// Implementation of 2 C++17 constructs: conjunction, negation.
// This is needed to avoid evaluating all the traits in a condition
//
// For example: not std::is_same<void, T>::value and has_value_type<T>::value
// will not compile when T = void (on MSVC at least)
// Whereas conjunction<negation<std::is_same<void, T>>, has_value_type<T>>::value
// will stop evaluating if negation<...>::value == false
//
// Please note that those constructs must be used with caution, since symbols can
// become very long quickly (which can slow down compilation and cause MSVC internal compiler errors)
// Only use it when you have too (see example ahead)
/*
Implementation of 2 C++17 constructs: conjunction, negation. This is needed
to avoid evaluating all the traits in a condition
For example: not std::is_same<void, T>::value and has_value_type<T>::value
will not compile when T = void (on MSVC at least). Whereas
conjunction<negation<std::is_same<void, T>>, has_value_type<T>>::value will
stop evaluating if negation<...>::value == false
Please note that those constructs must be used with caution, since symbols can
become very long quickly (which can slow down compilation and cause MSVC
internal compiler errors). Only use it when you have to (see example ahead).
*/
template<class...> struct conjunction : std::true_type {};
template<class B1> struct conjunction<B1> : B1 {};
template<class B1, class... Bn>
struct conjunction<B1, Bn...>
: std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
struct conjunction<B1, Bn...> : std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
template<class B> struct negation : std::integral_constant < bool, !B::value > {};
// dispatch utility (taken from ranges-v3)
template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
template<> struct priority_tag<0> {};
//////////////////
// constructors //
//////////////////
// This is an experiment. I need this to move constructors out of basic_json.
// I'm sure there is a better way, but this might need a big basic_json refactoring
// I'm sure there is a better way, but this might need a big basic_json
// refactoring
template<value_t> struct external_constructor;
template<>
@ -266,7 +276,9 @@ struct external_constructor<value_t::number_float>
{
// replace infinity and NAN by null
if (not std::isfinite(val))
{
j = BasicJsonType{};
}
else
{
j.m_type = value_t::number_float;
@ -320,8 +332,7 @@ struct external_constructor<value_t::array>
using std::begin;
using std::end;
j.m_type = value_t::array;
j.m_value.array =
j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
j.assert_invariant();
}
};
@ -347,12 +358,16 @@ struct external_constructor<value_t::object>
using std::end;
j.m_type = value_t::object;
j.m_value.object =
j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
j.assert_invariant();
}
};
////////////////////////
// has_/is_ functions //
////////////////////////
/*!
@brief Helper to determine whether there's a key_type for T.
@ -417,8 +432,6 @@ struct is_basic_json_nested_type
template<class BasicJsonType, class CompatibleArrayType>
struct is_compatible_array_type
{
// TODO concept Container?
// this might not make VS happy
static auto constexpr value =
conjunction<negation<std::is_same<void, CompatibleArrayType>>,
negation<is_compatible_object_type<
@ -450,13 +463,14 @@ struct is_compatible_integer_type_impl<true, RealIntegerType, CompatibleNumberIn
template<typename RealIntegerType, typename CompatibleNumberIntegerType>
struct is_compatible_integer_type
{
static constexpr auto
value = is_compatible_integer_type_impl <
static constexpr auto value =
is_compatible_integer_type_impl <
std::is_integral<CompatibleNumberIntegerType>::value and
not std::is_same<bool, CompatibleNumberIntegerType>::value,
RealIntegerType, CompatibleNumberIntegerType > ::value;
};
// This trait checks if JSONSerializer<T>::from_json(json const&, udt&) exists
template<typename BasicJsonType, typename T>
struct has_from_json
@ -506,34 +520,10 @@ struct has_to_json
std::declval<typename BasicJsonType::template json_serializer<T, void>>()))>::value;
};
// overloads for basic_json template parameters
template <typename BasicJsonType, typename ArithmeticType,
enable_if_t<std::is_arithmetic<ArithmeticType>::value and
not std::is_same<ArithmeticType,
typename BasicJsonType::boolean_t>::value,
int> = 0>
void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
{
switch (static_cast<value_t>(j))
{
case value_t::number_unsigned:
val = static_cast<ArithmeticType>(
*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
break;
case value_t::number_integer:
val = static_cast<ArithmeticType>(
*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
break;
case value_t::number_float:
val = static_cast<ArithmeticType>(
*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
break;
default:
JSON_THROW(
std::domain_error("type must be number, but is " + j.type_name()));
}
}
/////////////
// to_json //
/////////////
template<typename BasicJsonType>
void to_json(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
@ -557,7 +547,6 @@ void to_json(BasicJsonType& j, FloatType val) noexcept
external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
}
template <
typename BasicJsonType, typename CompatibleNumberUnsignedType,
enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t,
@ -605,6 +594,47 @@ void to_json(BasicJsonType& j, const CompatibleObjectType& arr)
external_constructor<value_t::object>::construct(j, arr);
}
///////////////
// from_json //
///////////////
// overloads for basic_json template parameters
template<typename BasicJsonType, typename ArithmeticType,
enable_if_t<std::is_arithmetic<ArithmeticType>::value and
not std::is_same<ArithmeticType,
typename BasicJsonType::boolean_t>::value,
int> = 0>
void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
{
switch (static_cast<value_t>(j))
{
case value_t::number_unsigned:
{
val = static_cast<ArithmeticType>(
*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
break;
}
case value_t::number_integer:
{
val = static_cast<ArithmeticType>(
*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
break;
}
case value_t::number_float:
{
val = static_cast<ArithmeticType>(
*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
break;
}
default:
{
JSON_THROW(
std::domain_error("type must be number, but is " + j.type_name()));
}
}
}
template<typename BasicJsonType>
void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
{
@ -662,7 +692,8 @@ void from_json(const BasicJsonType& j, typename BasicJsonType::array_t& arr)
arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
}
// forward_list doesn't have an insert method, TODO find a way to avoid including forward_list
// forward_list doesn't have an insert method
// TODO find a way to avoid including forward_list
template<typename BasicJsonType, typename T, typename Allocator>
void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
{
@ -691,11 +722,11 @@ void from_json_array_impl(const BasicJsonType& j, CompatibleArrayType& arr, pri
using std::begin;
using std::end;
std::transform(
j.begin(), j.end(), std::inserter(arr, end(arr)), [](const BasicJsonType & i)
std::transform(j.begin(), j.end(),
std::inserter(arr, end(arr)), [](const BasicJsonType & i)
{
// get<BasicJsonType>() returns *this, this won't call a from_json method when
// value_type is BasicJsonType
// get<BasicJsonType>() returns *this, this won't call a from_json
// method when value_type is BasicJsonType
return i.template get<typename CompatibleArrayType::value_type>();
});
}
@ -713,24 +744,22 @@ auto from_json_array_impl(const BasicJsonType& j, CompatibleArrayType& arr, pri
std::transform(
j.begin(), j.end(), std::inserter(arr, end(arr)), [](const BasicJsonType & i)
{
// get<BasicJsonType>() returns *this, this won't call a from_json method when
// value_type is BasicJsonType
// get<BasicJsonType>() returns *this, this won't call a from_json
// method when value_type is BasicJsonType
return i.template get<typename CompatibleArrayType::value_type>();
});
}
template <
typename BasicJsonType, typename CompatibleArrayType,
template<typename BasicJsonType, typename CompatibleArrayType,
enable_if_t<is_compatible_array_type<BasicJsonType, CompatibleArrayType>::value and
not std::is_same<typename BasicJsonType::array_t,
CompatibleArrayType>::value,
int> = 0 >
not std::is_same<typename BasicJsonType::array_t, CompatibleArrayType>::value, int> = 0>
void from_json(const BasicJsonType& j, CompatibleArrayType& arr)
{
if (j.is_null())
{
JSON_THROW(std::domain_error("type must be array, but is " + j.type_name()));
}
// when T == BasicJsonType, do not check if value_t is correct
if (not std::is_same<typename CompatibleArrayType::value_type, BasicJsonType>::value)
{
@ -742,11 +771,8 @@ void from_json(const BasicJsonType& j, CompatibleArrayType& arr)
from_json_array_impl(j, arr, priority_tag<1> {});
}
template <
typename BasicJsonType, typename CompatibleObjectType,
enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value,
int> = 0 >
template<typename BasicJsonType, typename CompatibleObjectType,
enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value, int> = 0>
void from_json(const BasicJsonType& j, CompatibleObjectType& obj)
{
if (!j.is_object())
@ -766,16 +792,12 @@ void from_json(const BasicJsonType& j, CompatibleObjectType& obj)
//
// note: Is it really necessary to provide explicit overloads for boolean_t etc..
// in case of a custom BooleanType which is not an arithmetic type?
template <
typename BasicJsonType, typename ArithmeticType,
template<typename BasicJsonType, typename ArithmeticType,
enable_if_t <
std::is_arithmetic<ArithmeticType>::value and
not std::is_same<ArithmeticType,
typename BasicJsonType::number_unsigned_t>::value and
not std::is_same<ArithmeticType,
typename BasicJsonType::number_integer_t>::value and
not std::is_same<ArithmeticType,
typename BasicJsonType::number_float_t>::value and
not std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value and
not std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value and
not std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value and
not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
int> = 0>
void from_json(const BasicJsonType& j, ArithmeticType& val)
@ -783,34 +805,27 @@ void from_json(const BasicJsonType& j, ArithmeticType& val)
switch (static_cast<value_t>(j))
{
case value_t::number_unsigned:
val = static_cast<ArithmeticType>(
*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
break;
case value_t::number_integer:
val = static_cast<ArithmeticType>(
*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
break;
case value_t::number_float:
val = static_cast<ArithmeticType>(
*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
break;
case value_t::boolean:
val = static_cast<ArithmeticType>(
*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
break;
default:
JSON_THROW(
std::domain_error("type must be number, but is " + j.type_name()));
JSON_THROW(std::domain_error("type must be number, but is " + j.type_name()));
}
}
struct to_json_fn
{
template<typename BasicJsonType, typename T>
auto call(BasicJsonType& j, T&& val, priority_tag<1>) const
noexcept(noexcept(to_json(j, std::forward<T>(val))))
-> decltype(to_json(j, std::forward<T>(val)),
void())
auto call(BasicJsonType& j, T&& val, priority_tag<1>) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
-> decltype(to_json(j, std::forward<T>(val)), void())
{
return to_json(j, std::forward<T>(val));
}
@ -866,6 +881,7 @@ struct static_const
template<typename T>
constexpr T static_const<T>::value;
/*!
@brief helper class to create locales with decimal point
@ -885,7 +901,8 @@ struct DecimalSeparator : std::numpunct<char>
return '.';
}
};
}
} // namespace detail
namespace
{
@ -912,6 +929,7 @@ struct adl_serializer
}
};
/*!
@brief a class to store JSON values
@ -5714,6 +5732,13 @@ class basic_json
/// @}
public:
//////////////////////////////////////////
// lexicographical comparison operators //
//////////////////////////////////////////
/// @name lexicographical comparison operators
/// @{
/*!
@brief comparison: equal
@ -10795,7 +10820,7 @@ basic_json_parser_66:
for (; curptr < m_cursor; curptr++)
{
// quickly skip tests if a digit
if (*curptr < '0' || *curptr > '9')
if (*curptr < '0' or* curptr > '9')
{
if (*curptr == '.')
{

View file

@ -107,12 +107,15 @@ SOFTWARE.
*/
namespace nlohmann
{
// TODO update this doc
/*!
@brief unnamed namespace with internal helper functions
@since version 1.0.0
*/
This namespace collects some functions that could not be defined inside the
@ref basic_json class.
@since version 2.1.0
*/
namespace detail
{
///////////////////////////
@ -122,22 +125,24 @@ namespace detail
/*!
@brief the JSON type enumeration
This enumeration collects the different JSON types. It is internally used
to distinguish the stored values, and the functions @ref basic_json::is_null(), @ref
basic_json::is_object(), @ref basic_json::is_array(), @ref basic_json::is_string(), @ref basic_json::is_boolean(), @ref
basic_json::is_number() (with @ref basic_json::is_number_integer(), @ref basic_json::is_number_unsigned(), and
@ref basic_json::is_number_float()), @ref basic_json::is_discarded(), @ref basic_json::is_primitive(), and
This enumeration collects the different JSON types. It is internally used to
distinguish the stored values, and the functions @ref basic_json::is_null(),
@ref basic_json::is_object(), @ref basic_json::is_array(),
@ref basic_json::is_string(), @ref basic_json::is_boolean(),
@ref basic_json::is_number() (with @ref basic_json::is_number_integer(),
@ref basic_json::is_number_unsigned(), and @ref basic_json::is_number_float()),
@ref basic_json::is_discarded(), @ref basic_json::is_primitive(), and
@ref basic_json::is_structured() rely on it.
@note There are three enumeration entries (number_integer,
number_unsigned, and number_float), because the library distinguishes
these three types for numbers: @ref basic_json::number_unsigned_t is used for unsigned
integers, @ref basic_json::number_integer_t is used for signed integers, and @ref
basic_json::number_float_t is used for floating-point numbers or to approximate
integers which do not fit in the limits of their respective type.
@note There are three enumeration entries (number_integer, number_unsigned, and
number_float), because the library distinguishes these three types for numbers:
@ref basic_json::number_unsigned_t is used for unsigned integers,
@ref basic_json::number_integer_t is used for signed integers, and
@ref basic_json::number_float_t is used for floating-point numbers or to
approximate integers which do not fit in the limits of their respective type.
@sa @ref basic_json::basic_json(const value_t value_type) -- create a JSON value with
the default value for a given type
@sa @ref basic_json::basic_json(const value_t value_type) -- create a JSON
value with the default value for a given type
@since version 1.0.0
*/
@ -154,12 +159,6 @@ enum class value_t : uint8_t
discarded ///< discarded by the the parser callback function
};
//////////////////////////////////////////
// lexicographical comparison operators //
//////////////////////////////////////////
/// @name lexicographical comparison operators
/// @{
/*!
@brief comparison operator for JSON types
@ -193,6 +192,11 @@ inline bool operator<(const value_t lhs, const value_t rhs) noexcept
order[static_cast<std::size_t>(rhs)];
}
/////////////
// helpers //
/////////////
// alias templates to reduce boilerplate
template<bool B, typename T = void>
using enable_if_t = typename std::enable_if<B, T>::type;
@ -206,32 +210,38 @@ using is_unscoped_enum =
std::integral_constant<bool, std::is_convertible<T, int>::value and
std::is_enum<T>::value>;
// Implementation of 2 C++17 constructs: conjunction, negation.
// This is needed to avoid evaluating all the traits in a condition
//
// For example: not std::is_same<void, T>::value and has_value_type<T>::value
// will not compile when T = void (on MSVC at least)
// Whereas conjunction<negation<std::is_same<void, T>>, has_value_type<T>>::value
// will stop evaluating if negation<...>::value == false
//
// Please note that those constructs must be used with caution, since symbols can
// become very long quickly (which can slow down compilation and cause MSVC internal compiler errors)
// Only use it when you have too (see example ahead)
/*
Implementation of 2 C++17 constructs: conjunction, negation. This is needed
to avoid evaluating all the traits in a condition
For example: not std::is_same<void, T>::value and has_value_type<T>::value
will not compile when T = void (on MSVC at least). Whereas
conjunction<negation<std::is_same<void, T>>, has_value_type<T>>::value will
stop evaluating if negation<...>::value == false
Please note that those constructs must be used with caution, since symbols can
become very long quickly (which can slow down compilation and cause MSVC
internal compiler errors). Only use it when you have to (see example ahead).
*/
template<class...> struct conjunction : std::true_type {};
template<class B1> struct conjunction<B1> : B1 {};
template<class B1, class... Bn>
struct conjunction<B1, Bn...>
: std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
struct conjunction<B1, Bn...> : std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
template<class B> struct negation : std::integral_constant < bool, !B::value > {};
// dispatch utility (taken from ranges-v3)
template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
template<> struct priority_tag<0> {};
//////////////////
// constructors //
//////////////////
// This is an experiment. I need this to move constructors out of basic_json.
// I'm sure there is a better way, but this might need a big basic_json refactoring
// I'm sure there is a better way, but this might need a big basic_json
// refactoring
template<value_t> struct external_constructor;
template<>
@ -266,7 +276,9 @@ struct external_constructor<value_t::number_float>
{
// replace infinity and NAN by null
if (not std::isfinite(val))
{
j = BasicJsonType{};
}
else
{
j.m_type = value_t::number_float;
@ -320,8 +332,7 @@ struct external_constructor<value_t::array>
using std::begin;
using std::end;
j.m_type = value_t::array;
j.m_value.array =
j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
j.assert_invariant();
}
};
@ -347,12 +358,16 @@ struct external_constructor<value_t::object>
using std::end;
j.m_type = value_t::object;
j.m_value.object =
j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
j.assert_invariant();
}
};
////////////////////////
// has_/is_ functions //
////////////////////////
/*!
@brief Helper to determine whether there's a key_type for T.
@ -417,8 +432,6 @@ struct is_basic_json_nested_type
template<class BasicJsonType, class CompatibleArrayType>
struct is_compatible_array_type
{
// TODO concept Container?
// this might not make VS happy
static auto constexpr value =
conjunction<negation<std::is_same<void, CompatibleArrayType>>,
negation<is_compatible_object_type<
@ -450,13 +463,14 @@ struct is_compatible_integer_type_impl<true, RealIntegerType, CompatibleNumberIn
template<typename RealIntegerType, typename CompatibleNumberIntegerType>
struct is_compatible_integer_type
{
static constexpr auto
value = is_compatible_integer_type_impl <
static constexpr auto value =
is_compatible_integer_type_impl <
std::is_integral<CompatibleNumberIntegerType>::value and
not std::is_same<bool, CompatibleNumberIntegerType>::value,
RealIntegerType, CompatibleNumberIntegerType > ::value;
};
// This trait checks if JSONSerializer<T>::from_json(json const&, udt&) exists
template<typename BasicJsonType, typename T>
struct has_from_json
@ -506,34 +520,10 @@ struct has_to_json
std::declval<typename BasicJsonType::template json_serializer<T, void>>()))>::value;
};
// overloads for basic_json template parameters
template <typename BasicJsonType, typename ArithmeticType,
enable_if_t<std::is_arithmetic<ArithmeticType>::value and
not std::is_same<ArithmeticType,
typename BasicJsonType::boolean_t>::value,
int> = 0>
void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
{
switch (static_cast<value_t>(j))
{
case value_t::number_unsigned:
val = static_cast<ArithmeticType>(
*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
break;
case value_t::number_integer:
val = static_cast<ArithmeticType>(
*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
break;
case value_t::number_float:
val = static_cast<ArithmeticType>(
*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
break;
default:
JSON_THROW(
std::domain_error("type must be number, but is " + j.type_name()));
}
}
/////////////
// to_json //
/////////////
template<typename BasicJsonType>
void to_json(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
@ -557,7 +547,6 @@ void to_json(BasicJsonType& j, FloatType val) noexcept
external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
}
template <
typename BasicJsonType, typename CompatibleNumberUnsignedType,
enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t,
@ -605,6 +594,47 @@ void to_json(BasicJsonType& j, const CompatibleObjectType& arr)
external_constructor<value_t::object>::construct(j, arr);
}
///////////////
// from_json //
///////////////
// overloads for basic_json template parameters
template<typename BasicJsonType, typename ArithmeticType,
enable_if_t<std::is_arithmetic<ArithmeticType>::value and
not std::is_same<ArithmeticType,
typename BasicJsonType::boolean_t>::value,
int> = 0>
void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
{
switch (static_cast<value_t>(j))
{
case value_t::number_unsigned:
{
val = static_cast<ArithmeticType>(
*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
break;
}
case value_t::number_integer:
{
val = static_cast<ArithmeticType>(
*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
break;
}
case value_t::number_float:
{
val = static_cast<ArithmeticType>(
*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
break;
}
default:
{
JSON_THROW(
std::domain_error("type must be number, but is " + j.type_name()));
}
}
}
template<typename BasicJsonType>
void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
{
@ -662,7 +692,8 @@ void from_json(const BasicJsonType& j, typename BasicJsonType::array_t& arr)
arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
}
// forward_list doesn't have an insert method, TODO find a way to avoid including forward_list
// forward_list doesn't have an insert method
// TODO find a way to avoid including forward_list
template<typename BasicJsonType, typename T, typename Allocator>
void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
{
@ -691,11 +722,11 @@ void from_json_array_impl(const BasicJsonType& j, CompatibleArrayType& arr, pri
using std::begin;
using std::end;
std::transform(
j.begin(), j.end(), std::inserter(arr, end(arr)), [](const BasicJsonType & i)
std::transform(j.begin(), j.end(),
std::inserter(arr, end(arr)), [](const BasicJsonType & i)
{
// get<BasicJsonType>() returns *this, this won't call a from_json method when
// value_type is BasicJsonType
// get<BasicJsonType>() returns *this, this won't call a from_json
// method when value_type is BasicJsonType
return i.template get<typename CompatibleArrayType::value_type>();
});
}
@ -713,24 +744,22 @@ auto from_json_array_impl(const BasicJsonType& j, CompatibleArrayType& arr, pri
std::transform(
j.begin(), j.end(), std::inserter(arr, end(arr)), [](const BasicJsonType & i)
{
// get<BasicJsonType>() returns *this, this won't call a from_json method when
// value_type is BasicJsonType
// get<BasicJsonType>() returns *this, this won't call a from_json
// method when value_type is BasicJsonType
return i.template get<typename CompatibleArrayType::value_type>();
});
}
template <
typename BasicJsonType, typename CompatibleArrayType,
template<typename BasicJsonType, typename CompatibleArrayType,
enable_if_t<is_compatible_array_type<BasicJsonType, CompatibleArrayType>::value and
not std::is_same<typename BasicJsonType::array_t,
CompatibleArrayType>::value,
int> = 0 >
not std::is_same<typename BasicJsonType::array_t, CompatibleArrayType>::value, int> = 0>
void from_json(const BasicJsonType& j, CompatibleArrayType& arr)
{
if (j.is_null())
{
JSON_THROW(std::domain_error("type must be array, but is " + j.type_name()));
}
// when T == BasicJsonType, do not check if value_t is correct
if (not std::is_same<typename CompatibleArrayType::value_type, BasicJsonType>::value)
{
@ -742,11 +771,8 @@ void from_json(const BasicJsonType& j, CompatibleArrayType& arr)
from_json_array_impl(j, arr, priority_tag<1> {});
}
template <
typename BasicJsonType, typename CompatibleObjectType,
enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value,
int> = 0 >
template<typename BasicJsonType, typename CompatibleObjectType,
enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value, int> = 0>
void from_json(const BasicJsonType& j, CompatibleObjectType& obj)
{
if (!j.is_object())
@ -766,16 +792,12 @@ void from_json(const BasicJsonType& j, CompatibleObjectType& obj)
//
// note: Is it really necessary to provide explicit overloads for boolean_t etc..
// in case of a custom BooleanType which is not an arithmetic type?
template <
typename BasicJsonType, typename ArithmeticType,
template<typename BasicJsonType, typename ArithmeticType,
enable_if_t <
std::is_arithmetic<ArithmeticType>::value and
not std::is_same<ArithmeticType,
typename BasicJsonType::number_unsigned_t>::value and
not std::is_same<ArithmeticType,
typename BasicJsonType::number_integer_t>::value and
not std::is_same<ArithmeticType,
typename BasicJsonType::number_float_t>::value and
not std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value and
not std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value and
not std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value and
not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
int> = 0>
void from_json(const BasicJsonType& j, ArithmeticType& val)
@ -783,34 +805,27 @@ void from_json(const BasicJsonType& j, ArithmeticType& val)
switch (static_cast<value_t>(j))
{
case value_t::number_unsigned:
val = static_cast<ArithmeticType>(
*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
break;
case value_t::number_integer:
val = static_cast<ArithmeticType>(
*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
break;
case value_t::number_float:
val = static_cast<ArithmeticType>(
*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
break;
case value_t::boolean:
val = static_cast<ArithmeticType>(
*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
break;
default:
JSON_THROW(
std::domain_error("type must be number, but is " + j.type_name()));
JSON_THROW(std::domain_error("type must be number, but is " + j.type_name()));
}
}
struct to_json_fn
{
template<typename BasicJsonType, typename T>
auto call(BasicJsonType& j, T&& val, priority_tag<1>) const
noexcept(noexcept(to_json(j, std::forward<T>(val))))
-> decltype(to_json(j, std::forward<T>(val)),
void())
auto call(BasicJsonType& j, T&& val, priority_tag<1>) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
-> decltype(to_json(j, std::forward<T>(val)), void())
{
return to_json(j, std::forward<T>(val));
}
@ -866,6 +881,7 @@ struct static_const
template<typename T>
constexpr T static_const<T>::value;
/*!
@brief helper class to create locales with decimal point
@ -885,7 +901,8 @@ struct DecimalSeparator : std::numpunct<char>
return '.';
}
};
}
} // namespace detail
namespace
{
@ -912,6 +929,7 @@ struct adl_serializer
}
};
/*!
@brief a class to store JSON values
@ -5714,6 +5732,13 @@ class basic_json
/// @}
public:
//////////////////////////////////////////
// lexicographical comparison operators //
//////////////////////////////////////////
/// @name lexicographical comparison operators
/// @{
/*!
@brief comparison: equal
@ -9945,7 +9970,7 @@ class basic_json
for (; curptr < m_cursor; curptr++)
{
// quickly skip tests if a digit
if (*curptr < '0' || *curptr > '9')
if (*curptr < '0' or* curptr > '9')
{
if (*curptr == '.')
{