🎨 use Clang-Format

This commit is contained in:
Niels Lohmann
2023-11-29 15:02:51 +01:00
parent 9cca280a4d
commit 311ad0b877
123 changed files with 17740 additions and 15765 deletions

View File

@@ -24,9 +24,9 @@ struct adl_serializer
/// @brief convert a JSON value to any value type
/// @sa https://json.nlohmann.me/api/adl_serializer/from_json/
template<typename BasicJsonType, typename TargetType = ValueType>
static auto from_json(BasicJsonType && j, TargetType& val) noexcept(
static auto from_json(BasicJsonType&& j, TargetType& val) noexcept(
noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
-> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void())
-> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void())
{
::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
}
@@ -34,19 +34,19 @@ struct adl_serializer
/// @brief convert a JSON value to any value type
/// @sa https://json.nlohmann.me/api/adl_serializer/from_json/
template<typename BasicJsonType, typename TargetType = ValueType>
static auto from_json(BasicJsonType && j) noexcept(
noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {})))
-> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {}))
static auto from_json(BasicJsonType&& j) noexcept(
noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType>{})))
-> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType>{}))
{
return ::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {});
return ::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType>{});
}
/// @brief convert any value type to a JSON value
/// @sa https://json.nlohmann.me/api/adl_serializer/to_json/
template<typename BasicJsonType, typename TargetType = ValueType>
static auto to_json(BasicJsonType& j, TargetType && val) noexcept(
static auto to_json(BasicJsonType& j, TargetType&& val) noexcept(
noexcept(::nlohmann::to_json(j, std::forward<TargetType>(val))))
-> decltype(::nlohmann::to_json(j, std::forward<TargetType>(val)), void())
-> decltype(::nlohmann::to_json(j, std::forward<TargetType>(val)), void())
{
::nlohmann::to_json(j, std::forward<TargetType>(val));
}

View File

@@ -8,9 +8,9 @@
#pragma once
#include <cstdint> // uint8_t, uint64_t
#include <tuple> // tie
#include <utility> // move
#include <cstdint> // uint8_t, uint64_t
#include <tuple> // tie
#include <utility> // move
#include <nlohmann/detail/abi_macros.hpp>
@@ -27,31 +27,31 @@ class byte_container_with_subtype : public BinaryType
/// @sa https://json.nlohmann.me/api/byte_container_with_subtype/byte_container_with_subtype/
byte_container_with_subtype() noexcept(noexcept(container_type()))
: container_type()
: container_type()
{}
/// @sa https://json.nlohmann.me/api/byte_container_with_subtype/byte_container_with_subtype/
byte_container_with_subtype(const container_type& b) noexcept(noexcept(container_type(b)))
: container_type(b)
: container_type(b)
{}
/// @sa https://json.nlohmann.me/api/byte_container_with_subtype/byte_container_with_subtype/
byte_container_with_subtype(container_type&& b) noexcept(noexcept(container_type(std::move(b))))
: container_type(std::move(b))
: container_type(std::move(b))
{}
/// @sa https://json.nlohmann.me/api/byte_container_with_subtype/byte_container_with_subtype/
byte_container_with_subtype(const container_type& b, subtype_type subtype_) noexcept(noexcept(container_type(b)))
: container_type(b)
, m_subtype(subtype_)
, m_has_subtype(true)
: container_type(b)
, m_subtype(subtype_)
, m_has_subtype(true)
{}
/// @sa https://json.nlohmann.me/api/byte_container_with_subtype/byte_container_with_subtype/
byte_container_with_subtype(container_type&& b, subtype_type subtype_) noexcept(noexcept(container_type(std::move(b))))
: container_type(std::move(b))
, m_subtype(subtype_)
, m_has_subtype(true)
: container_type(std::move(b))
, m_subtype(subtype_)
, m_has_subtype(true)
{}
bool operator==(const byte_container_with_subtype& rhs) const

View File

@@ -47,54 +47,52 @@
#endif
// Construct the namespace ABI tags component
#define NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b) json_abi ## a ## b
#define NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b) json_abi##a##b
#define NLOHMANN_JSON_ABI_TAGS_CONCAT(a, b) \
NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b)
#define NLOHMANN_JSON_ABI_TAGS \
NLOHMANN_JSON_ABI_TAGS_CONCAT( \
NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS, \
NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON)
#define NLOHMANN_JSON_ABI_TAGS \
NLOHMANN_JSON_ABI_TAGS_CONCAT( \
NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS, \
NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON)
// Construct the namespace version component
#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) \
_v ## major ## _ ## minor ## _ ## patch
_v##major##_##minor##_##patch
#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(major, minor, patch) \
NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch)
#if NLOHMANN_JSON_NAMESPACE_NO_VERSION
#define NLOHMANN_JSON_NAMESPACE_VERSION
#define NLOHMANN_JSON_NAMESPACE_VERSION
#else
#define NLOHMANN_JSON_NAMESPACE_VERSION \
NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(NLOHMANN_JSON_VERSION_MAJOR, \
NLOHMANN_JSON_VERSION_MINOR, \
NLOHMANN_JSON_VERSION_PATCH)
#define NLOHMANN_JSON_NAMESPACE_VERSION \
NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(NLOHMANN_JSON_VERSION_MAJOR, \
NLOHMANN_JSON_VERSION_MINOR, \
NLOHMANN_JSON_VERSION_PATCH)
#endif
// Combine namespace components
#define NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b) a ## b
#define NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b) a##b
#define NLOHMANN_JSON_NAMESPACE_CONCAT(a, b) \
NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b)
#ifndef NLOHMANN_JSON_NAMESPACE
#define NLOHMANN_JSON_NAMESPACE \
nlohmann::NLOHMANN_JSON_NAMESPACE_CONCAT( \
NLOHMANN_JSON_ABI_TAGS, \
#define NLOHMANN_JSON_NAMESPACE \
nlohmann::NLOHMANN_JSON_NAMESPACE_CONCAT( \
NLOHMANN_JSON_ABI_TAGS, \
NLOHMANN_JSON_NAMESPACE_VERSION)
#endif
#ifndef NLOHMANN_JSON_NAMESPACE_BEGIN
#define NLOHMANN_JSON_NAMESPACE_BEGIN \
namespace nlohmann \
{ \
inline namespace NLOHMANN_JSON_NAMESPACE_CONCAT( \
NLOHMANN_JSON_ABI_TAGS, \
NLOHMANN_JSON_NAMESPACE_VERSION) \
{
#define NLOHMANN_JSON_NAMESPACE_BEGIN \
namespace nlohmann { \
inline namespace NLOHMANN_JSON_NAMESPACE_CONCAT( \
NLOHMANN_JSON_ABI_TAGS, \
NLOHMANN_JSON_NAMESPACE_VERSION) {
#endif
#ifndef NLOHMANN_JSON_NAMESPACE_END
#define NLOHMANN_JSON_NAMESPACE_END \
} /* namespace (inline namespace) NOLINT(readability/namespace) */ \
} // namespace nlohmann
#define NLOHMANN_JSON_NAMESPACE_END \
} /* namespace (inline namespace) NOLINT(readability/namespace) */ \
} // namespace nlohmann
#endif

View File

@@ -8,17 +8,17 @@
#pragma once
#include <algorithm> // transform
#include <array> // array
#include <forward_list> // forward_list
#include <iterator> // inserter, front_inserter, end
#include <map> // map
#include <string> // string
#include <tuple> // tuple, make_tuple
#include <type_traits> // is_arithmetic, is_same, is_enum, underlying_type, is_convertible
#include <unordered_map> // unordered_map
#include <utility> // pair, declval
#include <valarray> // valarray
#include <algorithm> // transform
#include <array> // array
#include <forward_list> // forward_list
#include <iterator> // inserter, front_inserter, end
#include <map> // map
#include <string> // string
#include <tuple> // tuple, make_tuple
#include <type_traits> // is_arithmetic, is_same, is_enum, underlying_type, is_convertible
#include <unordered_map> // unordered_map
#include <utility> // pair, declval
#include <valarray> // valarray
#include <nlohmann/detail/exceptions.hpp>
#include <nlohmann/detail/macro_scope.hpp>
@@ -30,8 +30,7 @@
#include <nlohmann/detail/value_t.hpp>
NLOHMANN_JSON_NAMESPACE_BEGIN
namespace detail
{
namespace detail {
template<typename BasicJsonType>
inline void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
@@ -44,10 +43,7 @@ inline void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
}
// overloads for basic_json template parameters
template < typename BasicJsonType, typename ArithmeticType,
enable_if_t < std::is_arithmetic<ArithmeticType>::value&&
!std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
int > = 0 >
template<typename BasicJsonType, typename ArithmeticType, enable_if_t<std::is_arithmetic<ArithmeticType>::value && !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))
@@ -100,13 +96,12 @@ inline void from_json(const BasicJsonType& j, typename BasicJsonType::string_t&
s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
}
template <
typename BasicJsonType, typename StringType,
enable_if_t <
std::is_assignable<StringType&, const typename BasicJsonType::string_t>::value
&& is_detected_exact<typename BasicJsonType::string_t::value_type, value_type_t, StringType>::value
&& !std::is_same<typename BasicJsonType::string_t, StringType>::value
&& !is_json_ref<StringType>::value, int > = 0 >
template<
typename BasicJsonType,
typename StringType,
enable_if_t<
std::is_assignable<StringType&, const typename BasicJsonType::string_t>::value && is_detected_exact<typename BasicJsonType::string_t::value_type, value_type_t, StringType>::value && !std::is_same<typename BasicJsonType::string_t, StringType>::value && !is_json_ref<StringType>::value,
int> = 0>
inline void from_json(const BasicJsonType& j, StringType& s)
{
if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
@@ -136,8 +131,7 @@ inline void from_json(const BasicJsonType& j, typename BasicJsonType::number_int
}
#if !JSON_DISABLE_ENUM_SERIALIZATION
template<typename BasicJsonType, typename EnumType,
enable_if_t<std::is_enum<EnumType>::value, int> = 0>
template<typename BasicJsonType, typename EnumType, enable_if_t<std::is_enum<EnumType>::value, int> = 0>
inline void from_json(const BasicJsonType& j, EnumType& e)
{
typename std::underlying_type<EnumType>::type val;
@@ -147,8 +141,7 @@ inline void from_json(const BasicJsonType& j, EnumType& e)
#endif // JSON_DISABLE_ENUM_SERIALIZATION
// forward_list doesn't have an insert method
template<typename BasicJsonType, typename T, typename Allocator,
enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
template<typename BasicJsonType, typename T, typename Allocator, enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
inline void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
{
if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
@@ -156,16 +149,13 @@ inline void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l
JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
}
l.clear();
std::transform(j.rbegin(), j.rend(),
std::front_inserter(l), [](const BasicJsonType & i)
{
std::transform(j.rbegin(), j.rend(), std::front_inserter(l), [](const BasicJsonType& i) {
return i.template get<T>();
});
}
// valarray doesn't have an insert method
template<typename BasicJsonType, typename T,
enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
template<typename BasicJsonType, typename T, enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
inline void from_json(const BasicJsonType& j, std::valarray<T>& l)
{
if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
@@ -173,16 +163,14 @@ inline void from_json(const BasicJsonType& j, std::valarray<T>& l)
JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
}
l.resize(j.size());
std::transform(j.begin(), j.end(), std::begin(l),
[](const BasicJsonType & elem)
{
std::transform(j.begin(), j.end(), std::begin(l), [](const BasicJsonType& elem) {
return elem.template get<T>();
});
}
template<typename BasicJsonType, typename T, std::size_t N>
auto from_json(const BasicJsonType& j, T (&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
-> decltype(j.template get<T>(), void())
-> decltype(j.template get<T>(), void())
{
for (std::size_t i = 0; i < N; ++i)
{
@@ -197,9 +185,8 @@ inline void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType:
}
template<typename BasicJsonType, typename T, std::size_t N>
auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr,
priority_tag<2> /*unused*/)
-> decltype(j.template get<T>(), void())
auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr, priority_tag<2> /*unused*/)
-> decltype(j.template get<T>(), void())
{
for (std::size_t i = 0; i < N; ++i)
{
@@ -207,23 +194,17 @@ auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr,
}
}
template<typename BasicJsonType, typename ConstructibleArrayType,
enable_if_t<
std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
int> = 0>
template<typename BasicJsonType, typename ConstructibleArrayType, enable_if_t<std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value, int> = 0>
auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> /*unused*/)
-> decltype(
arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()),
j.template get<typename ConstructibleArrayType::value_type>(),
void())
-> decltype(arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()),
j.template get<typename ConstructibleArrayType::value_type>(),
void())
{
using std::end;
ConstructibleArrayType ret;
ret.reserve(j.size());
std::transform(j.begin(), j.end(),
std::inserter(ret, end(ret)), [](const BasicJsonType & i)
{
std::transform(j.begin(), j.end(), std::inserter(ret, end(ret)), [](const BasicJsonType& i) {
// get<BasicJsonType>() returns *this, this won't call a from_json
// method when value_type is BasicJsonType
return i.template get<typename ConstructibleArrayType::value_type>();
@@ -231,65 +212,56 @@ auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, p
arr = std::move(ret);
}
template<typename BasicJsonType, typename ConstructibleArrayType,
enable_if_t<
std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
int> = 0>
inline void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr,
priority_tag<0> /*unused*/)
template<typename BasicJsonType, typename ConstructibleArrayType, enable_if_t<std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value, int> = 0>
inline void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<0> /*unused*/)
{
using std::end;
ConstructibleArrayType ret;
std::transform(
j.begin(), j.end(), std::inserter(ret, end(ret)),
[](const BasicJsonType & i)
{
// get<BasicJsonType>() returns *this, this won't call a from_json
// method when value_type is BasicJsonType
return i.template get<typename ConstructibleArrayType::value_type>();
});
j.begin(),
j.end(),
std::inserter(ret, end(ret)),
[](const BasicJsonType& i) {
// get<BasicJsonType>() returns *this, this won't call a from_json
// method when value_type is BasicJsonType
return i.template get<typename ConstructibleArrayType::value_type>();
});
arr = std::move(ret);
}
template < typename BasicJsonType, typename ConstructibleArrayType,
enable_if_t <
is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value&&
!is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value&&
!is_constructible_string_type<BasicJsonType, ConstructibleArrayType>::value&&
!std::is_same<ConstructibleArrayType, typename BasicJsonType::binary_t>::value&&
!is_basic_json<ConstructibleArrayType>::value,
int > = 0 >
template<typename BasicJsonType, typename ConstructibleArrayType, enable_if_t<is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value && !is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value && !is_constructible_string_type<BasicJsonType, ConstructibleArrayType>::value && !std::is_same<ConstructibleArrayType, typename BasicJsonType::binary_t>::value && !is_basic_json<ConstructibleArrayType>::value, int> = 0>
auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)
-> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
j.template get<typename ConstructibleArrayType::value_type>(),
void())
-> decltype(from_json_array_impl(j, arr, priority_tag<3>{}),
j.template get<typename ConstructibleArrayType::value_type>(),
void())
{
if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
{
JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
}
from_json_array_impl(j, arr, priority_tag<3> {});
from_json_array_impl(j, arr, priority_tag<3>{});
}
template < typename BasicJsonType, typename T, std::size_t... Idx >
template<typename BasicJsonType, typename T, std::size_t... Idx>
std::array<T, sizeof...(Idx)> from_json_inplace_array_impl(BasicJsonType&& j,
identity_tag<std::array<T, sizeof...(Idx)>> /*unused*/, index_sequence<Idx...> /*unused*/)
identity_tag<std::array<T, sizeof...(Idx)>> /*unused*/,
index_sequence<Idx...> /*unused*/)
{
return { { std::forward<BasicJsonType>(j).at(Idx).template get<T>()... } };
return {{std::forward<BasicJsonType>(j).at(Idx).template get<T>()...}};
}
template < typename BasicJsonType, typename T, std::size_t N >
template<typename BasicJsonType, typename T, std::size_t N>
auto from_json(BasicJsonType&& j, identity_tag<std::array<T, N>> tag)
-> decltype(from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {}))
-> decltype(from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N>{}))
{
if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
{
JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
}
return from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {});
return from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N>{});
}
template<typename BasicJsonType>
@@ -303,8 +275,7 @@ inline void from_json(const BasicJsonType& j, typename BasicJsonType::binary_t&
bin = *j.template get_ptr<const typename BasicJsonType::binary_t*>();
}
template<typename BasicJsonType, typename ConstructibleObjectType,
enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int> = 0>
template<typename BasicJsonType, typename ConstructibleObjectType, enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int> = 0>
inline void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
{
if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
@@ -316,12 +287,12 @@ inline void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
const auto* inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
using value_type = typename ConstructibleObjectType::value_type;
std::transform(
inner_object->begin(), inner_object->end(),
inner_object->begin(),
inner_object->end(),
std::inserter(ret, ret.begin()),
[](typename BasicJsonType::object_t::value_type const & p)
{
return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
});
[](typename BasicJsonType::object_t::value_type const& p) {
return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
});
obj = std::move(ret);
}
@@ -329,14 +300,7 @@ inline void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
// (BooleanType, etc..); 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,
enable_if_t <
std::is_arithmetic<ArithmeticType>::value&&
!std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value&&
!std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value&&
!std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value&&
!std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
int > = 0 >
template<typename BasicJsonType, typename ArithmeticType, enable_if_t<std::is_arithmetic<ArithmeticType>::value && !std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value && !std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value && !std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value && !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value, int> = 0>
inline void from_json(const BasicJsonType& j, ArithmeticType& val)
{
switch (static_cast<value_t>(j))
@@ -379,7 +343,7 @@ std::tuple<Args...> from_json_tuple_impl_base(BasicJsonType&& j, index_sequence<
return std::make_tuple(std::forward<BasicJsonType>(j).at(Idx).template get<Args>()...);
}
template < typename BasicJsonType, class A1, class A2 >
template<typename BasicJsonType, class A1, class A2>
std::pair<A1, A2> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::pair<A1, A2>> /*unused*/, priority_tag<0> /*unused*/)
{
return {std::forward<BasicJsonType>(j).at(0).template get<A1>(),
@@ -389,36 +353,34 @@ std::pair<A1, A2> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::pair
template<typename BasicJsonType, typename A1, typename A2>
inline void from_json_tuple_impl(BasicJsonType&& j, std::pair<A1, A2>& p, priority_tag<1> /*unused*/)
{
p = from_json_tuple_impl(std::forward<BasicJsonType>(j), identity_tag<std::pair<A1, A2>> {}, priority_tag<0> {});
p = from_json_tuple_impl(std::forward<BasicJsonType>(j), identity_tag<std::pair<A1, A2>>{}, priority_tag<0>{});
}
template<typename BasicJsonType, typename... Args>
std::tuple<Args...> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::tuple<Args...>> /*unused*/, priority_tag<2> /*unused*/)
{
return from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
return from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...>{});
}
template<typename BasicJsonType, typename... Args>
inline void from_json_tuple_impl(BasicJsonType&& j, std::tuple<Args...>& t, priority_tag<3> /*unused*/)
{
t = from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
t = from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...>{});
}
template<typename BasicJsonType, typename TupleRelated>
auto from_json(BasicJsonType&& j, TupleRelated&& t)
-> decltype(from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {}))
-> decltype(from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3>{}))
{
if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
{
JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
}
return from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {});
return from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3>{});
}
template < typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
typename = enable_if_t < !std::is_constructible <
typename BasicJsonType::string_t, Key >::value >>
template<typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator, typename = enable_if_t<!std::is_constructible<typename BasicJsonType::string_t, Key>::value>>
inline void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
{
if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
@@ -436,9 +398,7 @@ inline void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allo
}
}
template < typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator,
typename = enable_if_t < !std::is_constructible <
typename BasicJsonType::string_t, Key >::value >>
template<typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator, typename = enable_if_t<!std::is_constructible<typename BasicJsonType::string_t, Key>::value>>
inline void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
{
if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
@@ -472,8 +432,8 @@ struct from_json_fn
{
template<typename BasicJsonType, typename T>
auto operator()(const BasicJsonType& j, T&& val) const
noexcept(noexcept(from_json(j, std::forward<T>(val))))
-> decltype(from_json(j, std::forward<T>(val)))
noexcept(noexcept(from_json(j, std::forward<T>(val))))
-> decltype(from_json(j, std::forward<T>(val)))
{
return from_json(j, std::forward<T>(val));
}
@@ -485,10 +445,10 @@ struct from_json_fn
/// namespace to hold default `from_json` function
/// to see why this is required:
/// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html
namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
{
#endif
JSON_INLINE_VARIABLE constexpr const auto& from_json = // NOLINT(misc-definitions-in-headers)
JSON_INLINE_VARIABLE constexpr const auto& from_json = // NOLINT(misc-definitions-in-headers)
detail::static_const<detail::from_json_fn>::value;
#ifndef JSON_HAS_CPP_17
} // namespace

View File

@@ -9,18 +9,17 @@
#pragma once
#include <array> // array
#include <cmath> // signbit, isfinite
#include <cstdint> // intN_t, uintN_t
#include <cstring> // memcpy, memmove
#include <limits> // numeric_limits
#include <type_traits> // conditional
#include <array> // array
#include <cmath> // signbit, isfinite
#include <cstdint> // intN_t, uintN_t
#include <cstring> // memcpy, memmove
#include <limits> // numeric_limits
#include <type_traits> // conditional
#include <nlohmann/detail/macro_scope.hpp>
NLOHMANN_JSON_NAMESPACE_BEGIN
namespace detail
{
namespace detail {
/*!
@brief implements the Grisu2 algorithm for binary to decimal floating-point
@@ -41,8 +40,7 @@ For a detailed description of the algorithm see:
Proceedings of the ACM SIGPLAN 1996 Conference on Programming Language
Design and Implementation, PLDI 1996
*/
namespace dtoa_impl
{
namespace dtoa_impl {
template<typename Target, typename Source>
Target reinterpret_bits(const Source source)
@@ -54,14 +52,17 @@ Target reinterpret_bits(const Source source)
return target;
}
struct diyfp // f * 2^e
struct diyfp // f * 2^e
{
static constexpr int kPrecision = 64; // = q
static constexpr int kPrecision = 64; // = q
std::uint64_t f = 0;
int e = 0;
constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_) {}
constexpr diyfp(std::uint64_t f_, int e_) noexcept
: f(f_)
, e(e_)
{}
/*!
@brief returns x - y
@@ -133,7 +134,7 @@ struct diyfp // f * 2^e
// Effectively we only need to add the highest bit in p_lo to p_hi (and
// Q_hi + 1 does not overflow).
Q += std::uint64_t{1} << (64u - 32u - 1u); // round, ties up
Q += std::uint64_t{1} << (64u - 32u - 1u); // round, ties up
const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u);
@@ -201,12 +202,12 @@ boundaries compute_boundaries(FloatType value)
static_assert(std::numeric_limits<FloatType>::is_iec559,
"internal error: dtoa_short requires an IEEE-754 floating-point implementation");
constexpr int kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)
constexpr int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
constexpr int kMinExp = 1 - kBias;
constexpr std::uint64_t kHiddenBit = std::uint64_t{1} << (kPrecision - 1); // = 2^(p-1)
constexpr int kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)
constexpr int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
constexpr int kMinExp = 1 - kBias;
constexpr std::uint64_t kHiddenBit = std::uint64_t{1} << (kPrecision - 1); // = 2^(p-1)
using bits_type = typename std::conditional<kPrecision == 24, std::uint32_t, std::uint64_t >::type;
using bits_type = typename std::conditional<kPrecision == 24, std::uint32_t, std::uint64_t>::type;
const auto bits = static_cast<std::uint64_t>(reinterpret_bits<bits_type>(value));
const std::uint64_t E = bits >> (kPrecision - 1);
@@ -214,8 +215,8 @@ boundaries compute_boundaries(FloatType value)
const bool is_denormal = E == 0;
const diyfp v = is_denormal
? diyfp(F, kMinExp)
: diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
? diyfp(F, kMinExp)
: diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
// Compute the boundaries m- and m+ of the floating-point value
// v = f * 2^e.
@@ -241,8 +242,8 @@ boundaries compute_boundaries(FloatType value)
const bool lower_boundary_is_closer = F == 0 && E > 1;
const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
const diyfp m_minus = lower_boundary_is_closer
? diyfp(4 * v.f - 1, v.e - 2) // (B)
: diyfp(2 * v.f - 1, v.e - 1); // (A)
? diyfp(4 * v.f - 1, v.e - 2) // (B)
: diyfp(2 * v.f - 1, v.e - 1); // (A)
// Determine the normalized w+ = m+.
const diyfp w_plus = diyfp::normalize(m_plus);
@@ -311,7 +312,7 @@ boundaries compute_boundaries(FloatType value)
constexpr int kAlpha = -60;
constexpr int kGamma = -32;
struct cached_power // c = f * 2^e ~= 10^k
struct cached_power // c = f * 2^e ~= 10^k
{
std::uint64_t f;
int e;
@@ -381,96 +382,95 @@ inline cached_power get_cached_power_for_binary_exponent(int e)
constexpr int kCachedPowersDecStep = 8;
static constexpr std::array<cached_power, 79> kCachedPowers =
{
{
{ 0xAB70FE17C79AC6CA, -1060, -300 },
{ 0xFF77B1FCBEBCDC4F, -1034, -292 },
{ 0xBE5691EF416BD60C, -1007, -284 },
{ 0x8DD01FAD907FFC3C, -980, -276 },
{ 0xD3515C2831559A83, -954, -268 },
{ 0x9D71AC8FADA6C9B5, -927, -260 },
{ 0xEA9C227723EE8BCB, -901, -252 },
{ 0xAECC49914078536D, -874, -244 },
{ 0x823C12795DB6CE57, -847, -236 },
{ 0xC21094364DFB5637, -821, -228 },
{ 0x9096EA6F3848984F, -794, -220 },
{ 0xD77485CB25823AC7, -768, -212 },
{ 0xA086CFCD97BF97F4, -741, -204 },
{ 0xEF340A98172AACE5, -715, -196 },
{ 0xB23867FB2A35B28E, -688, -188 },
{ 0x84C8D4DFD2C63F3B, -661, -180 },
{ 0xC5DD44271AD3CDBA, -635, -172 },
{ 0x936B9FCEBB25C996, -608, -164 },
{ 0xDBAC6C247D62A584, -582, -156 },
{ 0xA3AB66580D5FDAF6, -555, -148 },
{ 0xF3E2F893DEC3F126, -529, -140 },
{ 0xB5B5ADA8AAFF80B8, -502, -132 },
{ 0x87625F056C7C4A8B, -475, -124 },
{ 0xC9BCFF6034C13053, -449, -116 },
{ 0x964E858C91BA2655, -422, -108 },
{ 0xDFF9772470297EBD, -396, -100 },
{ 0xA6DFBD9FB8E5B88F, -369, -92 },
{ 0xF8A95FCF88747D94, -343, -84 },
{ 0xB94470938FA89BCF, -316, -76 },
{ 0x8A08F0F8BF0F156B, -289, -68 },
{ 0xCDB02555653131B6, -263, -60 },
{ 0x993FE2C6D07B7FAC, -236, -52 },
{ 0xE45C10C42A2B3B06, -210, -44 },
{ 0xAA242499697392D3, -183, -36 },
{ 0xFD87B5F28300CA0E, -157, -28 },
{ 0xBCE5086492111AEB, -130, -20 },
{ 0x8CBCCC096F5088CC, -103, -12 },
{ 0xD1B71758E219652C, -77, -4 },
{ 0x9C40000000000000, -50, 4 },
{ 0xE8D4A51000000000, -24, 12 },
{ 0xAD78EBC5AC620000, 3, 20 },
{ 0x813F3978F8940984, 30, 28 },
{ 0xC097CE7BC90715B3, 56, 36 },
{ 0x8F7E32CE7BEA5C70, 83, 44 },
{ 0xD5D238A4ABE98068, 109, 52 },
{ 0x9F4F2726179A2245, 136, 60 },
{ 0xED63A231D4C4FB27, 162, 68 },
{ 0xB0DE65388CC8ADA8, 189, 76 },
{ 0x83C7088E1AAB65DB, 216, 84 },
{ 0xC45D1DF942711D9A, 242, 92 },
{ 0x924D692CA61BE758, 269, 100 },
{ 0xDA01EE641A708DEA, 295, 108 },
{ 0xA26DA3999AEF774A, 322, 116 },
{ 0xF209787BB47D6B85, 348, 124 },
{ 0xB454E4A179DD1877, 375, 132 },
{ 0x865B86925B9BC5C2, 402, 140 },
{ 0xC83553C5C8965D3D, 428, 148 },
{ 0x952AB45CFA97A0B3, 455, 156 },
{ 0xDE469FBD99A05FE3, 481, 164 },
{ 0xA59BC234DB398C25, 508, 172 },
{ 0xF6C69A72A3989F5C, 534, 180 },
{ 0xB7DCBF5354E9BECE, 561, 188 },
{ 0x88FCF317F22241E2, 588, 196 },
{ 0xCC20CE9BD35C78A5, 614, 204 },
{ 0x98165AF37B2153DF, 641, 212 },
{ 0xE2A0B5DC971F303A, 667, 220 },
{ 0xA8D9D1535CE3B396, 694, 228 },
{ 0xFB9B7CD9A4A7443C, 720, 236 },
{ 0xBB764C4CA7A44410, 747, 244 },
{ 0x8BAB8EEFB6409C1A, 774, 252 },
{ 0xD01FEF10A657842C, 800, 260 },
{ 0x9B10A4E5E9913129, 827, 268 },
{ 0xE7109BFBA19C0C9D, 853, 276 },
{ 0xAC2820D9623BF429, 880, 284 },
{ 0x80444B5E7AA7CF85, 907, 292 },
{ 0xBF21E44003ACDD2D, 933, 300 },
{ 0x8E679C2F5E44FF8F, 960, 308 },
{ 0xD433179D9C8CB841, 986, 316 },
{ 0x9E19DB92B4E31BA9, 1013, 324 },
}
};
{
{0xAB70FE17C79AC6CA, -1060, -300},
{0xFF77B1FCBEBCDC4F, -1034, -292},
{0xBE5691EF416BD60C, -1007, -284},
{0x8DD01FAD907FFC3C, -980, -276},
{0xD3515C2831559A83, -954, -268},
{0x9D71AC8FADA6C9B5, -927, -260},
{0xEA9C227723EE8BCB, -901, -252},
{0xAECC49914078536D, -874, -244},
{0x823C12795DB6CE57, -847, -236},
{0xC21094364DFB5637, -821, -228},
{0x9096EA6F3848984F, -794, -220},
{0xD77485CB25823AC7, -768, -212},
{0xA086CFCD97BF97F4, -741, -204},
{0xEF340A98172AACE5, -715, -196},
{0xB23867FB2A35B28E, -688, -188},
{0x84C8D4DFD2C63F3B, -661, -180},
{0xC5DD44271AD3CDBA, -635, -172},
{0x936B9FCEBB25C996, -608, -164},
{0xDBAC6C247D62A584, -582, -156},
{0xA3AB66580D5FDAF6, -555, -148},
{0xF3E2F893DEC3F126, -529, -140},
{0xB5B5ADA8AAFF80B8, -502, -132},
{0x87625F056C7C4A8B, -475, -124},
{0xC9BCFF6034C13053, -449, -116},
{0x964E858C91BA2655, -422, -108},
{0xDFF9772470297EBD, -396, -100},
{0xA6DFBD9FB8E5B88F, -369, -92},
{0xF8A95FCF88747D94, -343, -84},
{0xB94470938FA89BCF, -316, -76},
{0x8A08F0F8BF0F156B, -289, -68},
{0xCDB02555653131B6, -263, -60},
{0x993FE2C6D07B7FAC, -236, -52},
{0xE45C10C42A2B3B06, -210, -44},
{0xAA242499697392D3, -183, -36},
{0xFD87B5F28300CA0E, -157, -28},
{0xBCE5086492111AEB, -130, -20},
{0x8CBCCC096F5088CC, -103, -12},
{0xD1B71758E219652C, -77, -4},
{0x9C40000000000000, -50, 4},
{0xE8D4A51000000000, -24, 12},
{0xAD78EBC5AC620000, 3, 20},
{0x813F3978F8940984, 30, 28},
{0xC097CE7BC90715B3, 56, 36},
{0x8F7E32CE7BEA5C70, 83, 44},
{0xD5D238A4ABE98068, 109, 52},
{0x9F4F2726179A2245, 136, 60},
{0xED63A231D4C4FB27, 162, 68},
{0xB0DE65388CC8ADA8, 189, 76},
{0x83C7088E1AAB65DB, 216, 84},
{0xC45D1DF942711D9A, 242, 92},
{0x924D692CA61BE758, 269, 100},
{0xDA01EE641A708DEA, 295, 108},
{0xA26DA3999AEF774A, 322, 116},
{0xF209787BB47D6B85, 348, 124},
{0xB454E4A179DD1877, 375, 132},
{0x865B86925B9BC5C2, 402, 140},
{0xC83553C5C8965D3D, 428, 148},
{0x952AB45CFA97A0B3, 455, 156},
{0xDE469FBD99A05FE3, 481, 164},
{0xA59BC234DB398C25, 508, 172},
{0xF6C69A72A3989F5C, 534, 180},
{0xB7DCBF5354E9BECE, 561, 188},
{0x88FCF317F22241E2, 588, 196},
{0xCC20CE9BD35C78A5, 614, 204},
{0x98165AF37B2153DF, 641, 212},
{0xE2A0B5DC971F303A, 667, 220},
{0xA8D9D1535CE3B396, 694, 228},
{0xFB9B7CD9A4A7443C, 720, 236},
{0xBB764C4CA7A44410, 747, 244},
{0x8BAB8EEFB6409C1A, 774, 252},
{0xD01FEF10A657842C, 800, 260},
{0x9B10A4E5E9913129, 827, 268},
{0xE7109BFBA19C0C9D, 853, 276},
{0xAC2820D9623BF429, 880, 284},
{0x80444B5E7AA7CF85, 907, 292},
{0xBF21E44003ACDD2D, 933, 300},
{0x8E679C2F5E44FF8F, 960, 308},
{0xD433179D9C8CB841, 986, 316},
{0x9E19DB92B4E31BA9, 1013, 324},
}};
// This computation gives exactly the same results for k as
// k = ceil((kAlpha - e - 1) * 0.30102999566398114)
// for |e| <= 1500, but doesn't require floating-point operations.
// NB: log_10(2) ~= 78913 / 2^18
JSON_ASSERT(e >= -1500);
JSON_ASSERT(e <= 1500);
JSON_ASSERT(e <= 1500);
const int f = kAlpha - e - 1;
const int k = (f * 78913) / (1 << 18) + static_cast<int>(f > 0);
@@ -501,50 +501,49 @@ inline int find_largest_pow10(const std::uint32_t n, std::uint32_t& pow10)
if (n >= 100000000)
{
pow10 = 100000000;
return 9;
return 9;
}
if (n >= 10000000)
{
pow10 = 10000000;
return 8;
return 8;
}
if (n >= 1000000)
{
pow10 = 1000000;
return 7;
return 7;
}
if (n >= 100000)
{
pow10 = 100000;
return 6;
return 6;
}
if (n >= 10000)
{
pow10 = 10000;
return 5;
return 5;
}
if (n >= 1000)
{
pow10 = 1000;
return 4;
return 4;
}
if (n >= 100)
{
pow10 = 100;
return 3;
return 3;
}
if (n >= 10)
{
pow10 = 10;
return 2;
return 2;
}
pow10 = 1;
return 1;
}
inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta,
std::uint64_t rest, std::uint64_t ten_k)
inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta, std::uint64_t rest, std::uint64_t ten_k)
{
JSON_ASSERT(len >= 1);
JSON_ASSERT(dist <= delta);
@@ -570,9 +569,7 @@ inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t d
// The tests are written in this order to avoid overflow in unsigned
// integer arithmetic.
while (rest < dist
&& delta - rest >= ten_k
&& (rest + ten_k < dist || dist - rest > rest + ten_k - dist))
while (rest < dist && delta - rest >= ten_k && (rest + ten_k < dist || dist - rest > rest + ten_k - dist))
{
JSON_ASSERT(buf[len - 1] != '0');
buf[len - 1]--;
@@ -584,8 +581,7 @@ inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t d
Generates V = buffer * 10^decimal_exponent, such that M- <= V <= M+.
M- and M+ must be normalized and share the same exponent -60 <= e <= -32.
*/
inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
diyfp M_minus, diyfp w, diyfp M_plus)
inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent, diyfp M_minus, diyfp w, diyfp M_plus)
{
static_assert(kAlpha >= -60, "internal error");
static_assert(kGamma <= -32, "internal error");
@@ -605,8 +601,8 @@ inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
JSON_ASSERT(M_plus.e >= kAlpha);
JSON_ASSERT(M_plus.e <= kGamma);
std::uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)
std::uint64_t dist = diyfp::sub(M_plus, w ).f; // (significand of (M+ - w ), implicit exponent is e)
std::uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)
std::uint64_t dist = diyfp::sub(M_plus, w).f; // (significand of (M+ - w ), implicit exponent is e)
// Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0):
//
@@ -617,8 +613,8 @@ inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
const diyfp one(std::uint64_t{1} << -M_plus.e, M_plus.e);
auto p1 = static_cast<std::uint32_t>(M_plus.f >> -one.e); // p1 = f div 2^-e (Since -e >= 32, p1 fits into a 32-bit int.)
std::uint64_t p2 = M_plus.f & (one.f - 1); // p2 = f mod 2^-e
auto p1 = static_cast<std::uint32_t>(M_plus.f >> -one.e); // p1 = f div 2^-e (Since -e >= 32, p1 fits into a 32-bit int.)
std::uint64_t p2 = M_plus.f & (one.f - 1); // p2 = f mod 2^-e
// 1)
//
@@ -661,7 +657,7 @@ inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
// = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e)
//
JSON_ASSERT(d <= 9);
buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
//
// M+ = buffer * 10^(n-1) + (r + p2 * 2^e)
//
@@ -760,15 +756,15 @@ inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
//
JSON_ASSERT(p2 <= (std::numeric_limits<std::uint64_t>::max)() / 10);
p2 *= 10;
const std::uint64_t d = p2 >> -one.e; // d = (10 * p2) div 2^-e
const std::uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e
const std::uint64_t d = p2 >> -one.e; // d = (10 * p2) div 2^-e
const std::uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e
//
// M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e
// = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e))
// = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e
//
JSON_ASSERT(d <= 9);
buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
//
// M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e
//
@@ -784,7 +780,7 @@ inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
// p2 * 2^e <= 10^m * delta * 2^e
// p2 <= 10^m * delta
delta *= 10;
dist *= 10;
dist *= 10;
if (p2 <= delta)
{
break;
@@ -825,8 +821,7 @@ len is the length of the buffer (number of decimal digits)
The buffer must be large enough, i.e. >= max_digits10.
*/
JSON_HEDLEY_NON_NULL(1)
inline void grisu2(char* buf, int& len, int& decimal_exponent,
diyfp m_minus, diyfp v, diyfp m_plus)
inline void grisu2(char* buf, int& len, int& decimal_exponent, diyfp m_minus, diyfp v, diyfp m_plus)
{
JSON_ASSERT(m_plus.e == m_minus.e);
JSON_ASSERT(m_plus.e == v.e);
@@ -842,12 +837,12 @@ inline void grisu2(char* buf, int& len, int& decimal_exponent,
const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k
const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k
// The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma]
const diyfp w = diyfp::mul(v, c_minus_k);
const diyfp w = diyfp::mul(v, c_minus_k);
const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
const diyfp w_plus = diyfp::mul(m_plus, c_minus_k);
const diyfp w_plus = diyfp::mul(m_plus, c_minus_k);
// ----(---+---)---------------(---+---)---------------(---+---)----
// w- w w+
@@ -871,9 +866,9 @@ inline void grisu2(char* buf, int& len, int& decimal_exponent,
// Note that this does not mean that Grisu2 always generates the shortest
// possible number in the interval (m-, m+).
const diyfp M_minus(w_minus.f + 1, w_minus.e);
const diyfp M_plus (w_plus.f - 1, w_plus.e );
const diyfp M_plus(w_plus.f - 1, w_plus.e);
decimal_exponent = -cached.k; // = -(-k) = k
decimal_exponent = -cached.k; // = -(-k) = k
grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
}
@@ -909,7 +904,7 @@ void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)
// NB: If the neighbors are computed for single-precision numbers, there is a single float
// (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision
// value is off by 1 ulp.
#if 0 // NOLINT(readability-avoid-unconditional-preprocessor-if)
#if 0 // NOLINT(readability-avoid-unconditional-preprocessor-if)
const boundaries w = compute_boundaries(static_cast<double>(value));
#else
const boundaries w = compute_boundaries(value);
@@ -928,7 +923,7 @@ JSON_HEDLEY_RETURNS_NON_NULL
inline char* append_exponent(char* buf, int e)
{
JSON_ASSERT(e > -1000);
JSON_ASSERT(e < 1000);
JSON_ASSERT(e < 1000);
if (e < 0)
{
@@ -977,8 +972,7 @@ notation. Otherwise it will be printed in exponential notation.
*/
JSON_HEDLEY_NON_NULL(1)
JSON_HEDLEY_RETURNS_NON_NULL
inline char* format_buffer(char* buf, int len, int decimal_exponent,
int min_exp, int max_exp)
inline char* format_buffer(char* buf, int len, int decimal_exponent, int min_exp, int max_exp)
{
JSON_ASSERT(min_exp < 0);
JSON_ASSERT(max_exp > 0);
@@ -1062,9 +1056,9 @@ format. Returns an iterator pointing past-the-end of the decimal representation.
template<typename FloatType>
JSON_HEDLEY_NON_NULL(1, 2)
JSON_HEDLEY_RETURNS_NON_NULL
char* to_chars(char* first, const char* last, FloatType value)
char* to_chars(char* first, const char* last, FloatType value)
{
static_cast<void>(last); // maybe unused - fix warning
static_cast<void>(last); // maybe unused - fix warning
JSON_ASSERT(std::isfinite(value));
// Use signbit(value) instead of (value < 0) since signbit works for -0.
@@ -1075,10 +1069,10 @@ char* to_chars(char* first, const char* last, FloatType value)
}
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
if (value == 0) // +-0
if (value == 0) // +-0
{
*first++ = '0';
// Make it look like a floating-point number (#362, #378)
@@ -1087,7 +1081,7 @@ char* to_chars(char* first, const char* last, FloatType value)
return first;
}
#ifdef __GNUC__
#pragma GCC diagnostic pop
#pragma GCC diagnostic pop
#endif
JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10);

View File

@@ -8,14 +8,14 @@
#pragma once
#include <algorithm> // copy
#include <iterator> // begin, end
#include <string> // string
#include <tuple> // tuple, get
#include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type
#include <utility> // move, forward, declval, pair
#include <valarray> // valarray
#include <vector> // vector
#include <algorithm> // copy
#include <iterator> // begin, end
#include <string> // string
#include <tuple> // tuple, get
#include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type
#include <utility> // move, forward, declval, pair
#include <valarray> // valarray
#include <vector> // vector
#include <nlohmann/detail/iterators/iteration_proxy.hpp>
#include <nlohmann/detail/macro_scope.hpp>
@@ -25,8 +25,7 @@
#include <nlohmann/detail/value_t.hpp>
NLOHMANN_JSON_NAMESPACE_BEGIN
namespace detail
{
namespace detail {
//////////////////
// constructors //
@@ -39,7 +38,8 @@ namespace detail
* https://github.com/nlohmann/json/issues/2865 for more information.
*/
template<value_t> struct external_constructor;
template<value_t>
struct external_constructor;
template<>
struct external_constructor<value_t::boolean>
@@ -75,9 +75,7 @@ struct external_constructor<value_t::string>
j.assert_invariant();
}
template < typename BasicJsonType, typename CompatibleStringType,
enable_if_t < !std::is_same<CompatibleStringType, typename BasicJsonType::string_t>::value,
int > = 0 >
template<typename BasicJsonType, typename CompatibleStringType, enable_if_t<!std::is_same<CompatibleStringType, typename BasicJsonType::string_t>::value, int> = 0>
static void construct(BasicJsonType& j, const CompatibleStringType& str)
{
j.m_data.m_value.destroy(j.m_data.m_type);
@@ -171,9 +169,7 @@ struct external_constructor<value_t::array>
j.assert_invariant();
}
template < typename BasicJsonType, typename CompatibleArrayType,
enable_if_t < !std::is_same<CompatibleArrayType, typename BasicJsonType::array_t>::value,
int > = 0 >
template<typename BasicJsonType, typename CompatibleArrayType, enable_if_t<!std::is_same<CompatibleArrayType, typename BasicJsonType::array_t>::value, int> = 0>
static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
{
using std::begin;
@@ -201,8 +197,7 @@ struct external_constructor<value_t::array>
j.assert_invariant();
}
template<typename BasicJsonType, typename T,
enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
template<typename BasicJsonType, typename T, enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
static void construct(BasicJsonType& j, const std::valarray<T>& arr)
{
j.m_data.m_value.destroy(j.m_data.m_type);
@@ -241,8 +236,7 @@ struct external_constructor<value_t::object>
j.assert_invariant();
}
template < typename BasicJsonType, typename CompatibleObjectType,
enable_if_t < !std::is_same<CompatibleObjectType, typename BasicJsonType::object_t>::value, int > = 0 >
template<typename BasicJsonType, typename CompatibleObjectType, enable_if_t<!std::is_same<CompatibleObjectType, typename BasicJsonType::object_t>::value, int> = 0>
static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
{
using std::begin;
@@ -260,28 +254,19 @@ struct external_constructor<value_t::object>
// to_json //
/////////////
template<typename BasicJsonType, typename T,
enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
template<typename BasicJsonType, typename T, enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
inline void to_json(BasicJsonType& j, T b) noexcept
{
external_constructor<value_t::boolean>::construct(j, b);
}
template < typename BasicJsonType, typename BoolRef,
enable_if_t <
((std::is_same<std::vector<bool>::reference, BoolRef>::value
&& !std::is_same <std::vector<bool>::reference, typename BasicJsonType::boolean_t&>::value)
|| (std::is_same<std::vector<bool>::const_reference, BoolRef>::value
&& !std::is_same <detail::uncvref_t<std::vector<bool>::const_reference>,
typename BasicJsonType::boolean_t >::value))
&& std::is_convertible<const BoolRef&, typename BasicJsonType::boolean_t>::value, int > = 0 >
template<typename BasicJsonType, typename BoolRef, enable_if_t<((std::is_same<std::vector<bool>::reference, BoolRef>::value && !std::is_same<std::vector<bool>::reference, typename BasicJsonType::boolean_t&>::value) || (std::is_same<std::vector<bool>::const_reference, BoolRef>::value && !std::is_same<detail::uncvref_t<std::vector<bool>::const_reference>, typename BasicJsonType::boolean_t>::value)) && std::is_convertible<const BoolRef&, typename BasicJsonType::boolean_t>::value, int> = 0>
inline void to_json(BasicJsonType& j, const BoolRef& b) noexcept
{
external_constructor<value_t::boolean>::construct(j, static_cast<typename BasicJsonType::boolean_t>(b));
}
template<typename BasicJsonType, typename CompatibleString,
enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0>
template<typename BasicJsonType, typename CompatibleString, enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0>
inline void to_json(BasicJsonType& j, const CompatibleString& s)
{
external_constructor<value_t::string>::construct(j, s);
@@ -293,30 +278,26 @@ inline void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
external_constructor<value_t::string>::construct(j, std::move(s));
}
template<typename BasicJsonType, typename FloatType,
enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
template<typename BasicJsonType, typename FloatType, enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
inline 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, CompatibleNumberUnsignedType>::value, int> = 0>
template<typename BasicJsonType, typename CompatibleNumberUnsignedType, enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value, int> = 0>
inline void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
{
external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
}
template<typename BasicJsonType, typename CompatibleNumberIntegerType,
enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0>
template<typename BasicJsonType, typename CompatibleNumberIntegerType, enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0>
inline void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
{
external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
}
#if !JSON_DISABLE_ENUM_SERIALIZATION
template<typename BasicJsonType, typename EnumType,
enable_if_t<std::is_enum<EnumType>::value, int> = 0>
template<typename BasicJsonType, typename EnumType, enable_if_t<std::is_enum<EnumType>::value, int> = 0>
inline void to_json(BasicJsonType& j, EnumType e) noexcept
{
using underlying_type = typename std::underlying_type<EnumType>::type;
@@ -330,14 +311,7 @@ inline void to_json(BasicJsonType& j, const std::vector<bool>& e)
external_constructor<value_t::array>::construct(j, e);
}
template < typename BasicJsonType, typename CompatibleArrayType,
enable_if_t < is_compatible_array_type<BasicJsonType,
CompatibleArrayType>::value&&
!is_compatible_object_type<BasicJsonType, CompatibleArrayType>::value&&
!is_compatible_string_type<BasicJsonType, CompatibleArrayType>::value&&
!std::is_same<typename BasicJsonType::binary_t, CompatibleArrayType>::value&&
!is_basic_json<CompatibleArrayType>::value,
int > = 0 >
template<typename BasicJsonType, typename CompatibleArrayType, enable_if_t<is_compatible_array_type<BasicJsonType, CompatibleArrayType>::value && !is_compatible_object_type<BasicJsonType, CompatibleArrayType>::value && !is_compatible_string_type<BasicJsonType, CompatibleArrayType>::value && !std::is_same<typename BasicJsonType::binary_t, CompatibleArrayType>::value && !is_basic_json<CompatibleArrayType>::value, int> = 0>
inline void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
{
external_constructor<value_t::array>::construct(j, arr);
@@ -349,8 +323,7 @@ inline void to_json(BasicJsonType& j, const typename BasicJsonType::binary_t& bi
external_constructor<value_t::binary>::construct(j, bin);
}
template<typename BasicJsonType, typename T,
enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
template<typename BasicJsonType, typename T, enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
inline void to_json(BasicJsonType& j, const std::valarray<T>& arr)
{
external_constructor<value_t::array>::construct(j, std::move(arr));
@@ -362,8 +335,7 @@ inline void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
external_constructor<value_t::array>::construct(j, std::move(arr));
}
template < typename BasicJsonType, typename CompatibleObjectType,
enable_if_t < is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value&& !is_basic_json<CompatibleObjectType>::value, int > = 0 >
template<typename BasicJsonType, typename CompatibleObjectType, enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value && !is_basic_json<CompatibleObjectType>::value, int> = 0>
inline void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
{
external_constructor<value_t::object>::construct(j, obj);
@@ -375,40 +347,41 @@ inline void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
external_constructor<value_t::object>::construct(j, std::move(obj));
}
template <
typename BasicJsonType, typename T, std::size_t N,
enable_if_t < !std::is_constructible<typename BasicJsonType::string_t,
const T(&)[N]>::value, // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
int > = 0 >
inline void to_json(BasicJsonType& j, const T(&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
template<
typename BasicJsonType,
typename T,
std::size_t N,
enable_if_t<!std::is_constructible<typename BasicJsonType::string_t,
const T (&)[N]>::value, // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
int> = 0>
inline void to_json(BasicJsonType& j, const T (&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
{
external_constructor<value_t::array>::construct(j, arr);
}
template < typename BasicJsonType, typename T1, typename T2, enable_if_t < std::is_constructible<BasicJsonType, T1>::value&& std::is_constructible<BasicJsonType, T2>::value, int > = 0 >
template<typename BasicJsonType, typename T1, typename T2, enable_if_t<std::is_constructible<BasicJsonType, T1>::value && std::is_constructible<BasicJsonType, T2>::value, int> = 0>
inline void to_json(BasicJsonType& j, const std::pair<T1, T2>& p)
{
j = { p.first, p.second };
j = {p.first, p.second};
}
// for https://github.com/nlohmann/json/pull/1134
template<typename BasicJsonType, typename T,
enable_if_t<std::is_same<T, iteration_proxy_value<typename BasicJsonType::iterator>>::value, int> = 0>
template<typename BasicJsonType, typename T, enable_if_t<std::is_same<T, iteration_proxy_value<typename BasicJsonType::iterator>>::value, int> = 0>
inline void to_json(BasicJsonType& j, const T& b)
{
j = { {b.key(), b.value()} };
j = {{b.key(), b.value()}};
}
template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
inline void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...> /*unused*/)
{
j = { std::get<Idx>(t)... };
j = {std::get<Idx>(t)...};
}
template<typename BasicJsonType, typename T, enable_if_t<is_constructible_tuple<BasicJsonType, T>::value, int > = 0>
template<typename BasicJsonType, typename T, enable_if_t<is_constructible_tuple<BasicJsonType, T>::value, int> = 0>
inline void to_json(BasicJsonType& j, const T& t)
{
to_json_tuple_impl(j, t, make_index_sequence<std::tuple_size<T>::value> {});
to_json_tuple_impl(j, t, make_index_sequence<std::tuple_size<T>::value>{});
}
#if JSON_HAS_FILESYSTEM || JSON_HAS_EXPERIMENTAL_FILESYSTEM
@@ -423,7 +396,7 @@ struct to_json_fn
{
template<typename BasicJsonType, typename T>
auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
-> decltype(to_json(j, std::forward<T>(val)), void())
-> decltype(to_json(j, std::forward<T>(val)), void())
{
return to_json(j, std::forward<T>(val));
}
@@ -434,10 +407,10 @@ struct to_json_fn
/// namespace to hold default `to_json` function
/// to see why this is required:
/// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html
namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
{
#endif
JSON_INLINE_VARIABLE constexpr const auto& to_json = // NOLINT(misc-definitions-in-headers)
JSON_INLINE_VARIABLE constexpr const auto& to_json = // NOLINT(misc-definitions-in-headers)
detail::static_const<detail::to_json_fn>::value;
#ifndef JSON_HAS_CPP_17
} // namespace

View File

@@ -8,26 +8,25 @@
#pragma once
#include <cstddef> // nullptr_t
#include <exception> // exception
#include <cstddef> // nullptr_t
#include <exception> // exception
#if JSON_DIAGNOSTICS
#include <numeric> // accumulate
#include <numeric> // accumulate
#endif
#include <stdexcept> // runtime_error
#include <string> // to_string
#include <vector> // vector
#include <stdexcept> // runtime_error
#include <string> // to_string
#include <vector> // vector
#include <nlohmann/detail/value_t.hpp>
#include <nlohmann/detail/string_escape.hpp>
#include <nlohmann/detail/input/position_t.hpp>
#include <nlohmann/detail/macro_scope.hpp>
#include <nlohmann/detail/meta/cpp_future.hpp>
#include <nlohmann/detail/meta/type_traits.hpp>
#include <nlohmann/detail/string_concat.hpp>
#include <nlohmann/detail/string_escape.hpp>
#include <nlohmann/detail/value_t.hpp>
NLOHMANN_JSON_NAMESPACE_BEGIN
namespace detail
{
namespace detail {
////////////////
// exceptions //
@@ -45,11 +44,14 @@ class exception : public std::exception
}
/// the id of the exception
const int id; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes)
const int id; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes)
protected:
JSON_HEDLEY_NON_NULL(3)
exception(int id_, const char* what_arg) : id(id_), m(what_arg) {} // NOLINT(bugprone-throw-keyword-missing)
exception(int id_, const char* what_arg)
: id(id_)
, m(what_arg)
{} // NOLINT(bugprone-throw-keyword-missing)
static std::string name(const std::string& ename, int id_)
{
@@ -96,16 +98,16 @@ class exception : public std::exception
break;
}
case value_t::null: // LCOV_EXCL_LINE
case value_t::string: // LCOV_EXCL_LINE
case value_t::boolean: // LCOV_EXCL_LINE
case value_t::number_integer: // LCOV_EXCL_LINE
case value_t::number_unsigned: // LCOV_EXCL_LINE
case value_t::number_float: // LCOV_EXCL_LINE
case value_t::binary: // LCOV_EXCL_LINE
case value_t::discarded: // LCOV_EXCL_LINE
default: // LCOV_EXCL_LINE
break; // LCOV_EXCL_LINE
case value_t::null: // LCOV_EXCL_LINE
case value_t::string: // LCOV_EXCL_LINE
case value_t::boolean: // LCOV_EXCL_LINE
case value_t::number_integer: // LCOV_EXCL_LINE
case value_t::number_unsigned: // LCOV_EXCL_LINE
case value_t::number_float: // LCOV_EXCL_LINE
case value_t::binary: // LCOV_EXCL_LINE
case value_t::discarded: // LCOV_EXCL_LINE
default: // LCOV_EXCL_LINE
break; // LCOV_EXCL_LINE
}
}
@@ -114,9 +116,7 @@ class exception : public std::exception
return "";
}
auto str = std::accumulate(tokens.rbegin(), tokens.rend(), std::string{},
[](const std::string & a, const std::string & b)
{
auto str = std::accumulate(tokens.rbegin(), tokens.rend(), std::string{}, [](const std::string& a, const std::string& b) {
return concat(a, '/', detail::escape(b));
});
return concat('(', str, ") ");
@@ -148,17 +148,14 @@ class parse_error : public exception
template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
static parse_error create(int id_, const position_t& pos, const std::string& what_arg, BasicJsonContext context)
{
const std::string w = concat(exception::name("parse_error", id_), "parse error",
position_string(pos), ": ", exception::diagnostics(context), what_arg);
const std::string w = concat(exception::name("parse_error", id_), "parse error", position_string(pos), ": ", exception::diagnostics(context), what_arg);
return {id_, pos.chars_read_total, w.c_str()};
}
template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
static parse_error create(int id_, std::size_t byte_, const std::string& what_arg, BasicJsonContext context)
{
const std::string w = concat(exception::name("parse_error", id_), "parse error",
(byte_ != 0 ? (concat(" at byte ", std::to_string(byte_))) : ""),
": ", exception::diagnostics(context), what_arg);
const std::string w = concat(exception::name("parse_error", id_), "parse error", (byte_ != 0 ? (concat(" at byte ", std::to_string(byte_))) : ""), ": ", exception::diagnostics(context), what_arg);
return {id_, byte_, w.c_str()};
}
@@ -175,12 +172,13 @@ class parse_error : public exception
private:
parse_error(int id_, std::size_t byte_, const char* what_arg)
: exception(id_, what_arg), byte(byte_) {}
: exception(id_, what_arg)
, byte(byte_)
{}
static std::string position_string(const position_t& pos)
{
return concat(" at line ", std::to_string(pos.lines_read + 1),
", column ", std::to_string(pos.chars_read_current_line));
return concat(" at line ", std::to_string(pos.lines_read + 1), ", column ", std::to_string(pos.chars_read_current_line));
}
};
@@ -199,7 +197,8 @@ class invalid_iterator : public exception
private:
JSON_HEDLEY_NON_NULL(3)
invalid_iterator(int id_, const char* what_arg)
: exception(id_, what_arg) {}
: exception(id_, what_arg)
{}
};
/// @brief exception indicating executing a member function with a wrong type
@@ -216,7 +215,9 @@ class type_error : public exception
private:
JSON_HEDLEY_NON_NULL(3)
type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
type_error(int id_, const char* what_arg)
: exception(id_, what_arg)
{}
};
/// @brief exception indicating access out of the defined range
@@ -233,7 +234,9 @@ class out_of_range : public exception
private:
JSON_HEDLEY_NON_NULL(3)
out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}
out_of_range(int id_, const char* what_arg)
: exception(id_, what_arg)
{}
};
/// @brief exception indicating other library errors
@@ -250,7 +253,9 @@ class other_error : public exception
private:
JSON_HEDLEY_NON_NULL(3)
other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
other_error(int id_, const char* what_arg)
: exception(id_, what_arg)
{}
};
} // namespace detail

View File

@@ -8,16 +8,15 @@
#pragma once
#include <cstdint> // uint8_t
#include <cstddef> // size_t
#include <functional> // hash
#include <cstddef> // size_t
#include <cstdint> // uint8_t
#include <functional> // hash
#include <nlohmann/detail/abi_macros.hpp>
#include <nlohmann/detail/value_t.hpp>
NLOHMANN_JSON_NAMESPACE_BEGIN
namespace detail
{
namespace detail {
// boost::hash_combine
inline std::size_t combine(std::size_t seed, std::size_t h) noexcept
@@ -59,7 +58,7 @@ std::size_t hash(const BasicJsonType& j)
auto seed = combine(type, j.size());
for (const auto& element : j.items())
{
const auto h = std::hash<string_t> {}(element.key());
const auto h = std::hash<string_t>{}(element.key());
seed = combine(seed, h);
seed = combine(seed, hash(element.value()));
}
@@ -78,50 +77,50 @@ std::size_t hash(const BasicJsonType& j)
case BasicJsonType::value_t::string:
{
const auto h = std::hash<string_t> {}(j.template get_ref<const string_t&>());
const auto h = std::hash<string_t>{}(j.template get_ref<const string_t&>());
return combine(type, h);
}
case BasicJsonType::value_t::boolean:
{
const auto h = std::hash<bool> {}(j.template get<bool>());
const auto h = std::hash<bool>{}(j.template get<bool>());
return combine(type, h);
}
case BasicJsonType::value_t::number_integer:
{
const auto h = std::hash<number_integer_t> {}(j.template get<number_integer_t>());
const auto h = std::hash<number_integer_t>{}(j.template get<number_integer_t>());
return combine(type, h);
}
case BasicJsonType::value_t::number_unsigned:
{
const auto h = std::hash<number_unsigned_t> {}(j.template get<number_unsigned_t>());
const auto h = std::hash<number_unsigned_t>{}(j.template get<number_unsigned_t>());
return combine(type, h);
}
case BasicJsonType::value_t::number_float:
{
const auto h = std::hash<number_float_t> {}(j.template get<number_float_t>());
const auto h = std::hash<number_float_t>{}(j.template get<number_float_t>());
return combine(type, h);
}
case BasicJsonType::value_t::binary:
{
auto seed = combine(type, j.get_binary().size());
const auto h = std::hash<bool> {}(j.get_binary().has_subtype());
const auto h = std::hash<bool>{}(j.get_binary().has_subtype());
seed = combine(seed, h);
seed = combine(seed, static_cast<std::size_t>(j.get_binary().subtype()));
for (const auto byte : j.get_binary())
{
seed = combine(seed, std::hash<std::uint8_t> {}(byte));
seed = combine(seed, std::hash<std::uint8_t>{}(byte));
}
return seed;
}
default: // LCOV_EXCL_LINE
JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
return 0; // LCOV_EXCL_LINE
default: // LCOV_EXCL_LINE
JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
return 0; // LCOV_EXCL_LINE
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -8,15 +8,15 @@
#pragma once
#include <array> // array
#include <cstddef> // size_t
#include <cstring> // strlen
#include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next
#include <memory> // shared_ptr, make_shared, addressof
#include <numeric> // accumulate
#include <string> // string, char_traits
#include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer
#include <utility> // pair, declval
#include <array> // array
#include <cstddef> // size_t
#include <cstring> // strlen
#include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next
#include <memory> // shared_ptr, make_shared, addressof
#include <numeric> // accumulate
#include <string> // string, char_traits
#include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer
#include <utility> // pair, declval
#ifndef JSON_NO_IO
#include <cstdio> // FILE *
@@ -28,11 +28,18 @@
#include <nlohmann/detail/meta/type_traits.hpp>
NLOHMANN_JSON_NAMESPACE_BEGIN
namespace detail
{
namespace detail {
/// the supported input formats
enum class input_format_t { json, cbor, msgpack, ubjson, bson, bjdata };
enum class input_format_t
{
json,
cbor,
msgpack,
ubjson,
bson,
bjdata
};
////////////////////
// input adapters //
@@ -50,7 +57,7 @@ class file_input_adapter
JSON_HEDLEY_NON_NULL(2)
explicit file_input_adapter(std::FILE* f) noexcept
: m_file(f)
: m_file(f)
{
JSON_ASSERT(m_file != nullptr);
}
@@ -97,7 +104,8 @@ class input_stream_adapter
}
explicit input_stream_adapter(std::istream& i)
: is(&i), sb(i.rdbuf())
: is(&i)
, sb(i.rdbuf())
{}
// delete because of pointer members
@@ -106,7 +114,8 @@ class input_stream_adapter
input_stream_adapter& operator=(input_stream_adapter&&) = delete;
input_stream_adapter(input_stream_adapter&& rhs) noexcept
: is(rhs.is), sb(rhs.sb)
: is(rhs.is)
, sb(rhs.sb)
{
rhs.is = nullptr;
rhs.sb = nullptr;
@@ -142,7 +151,8 @@ class iterator_input_adapter
using char_type = typename std::iterator_traits<IteratorType>::value_type;
iterator_input_adapter(IteratorType first, IteratorType last)
: current(std::move(first)), end(std::move(last))
: current(std::move(first))
, end(std::move(last))
{}
typename char_traits<char_type>::int_type get_character()
@@ -301,7 +311,8 @@ class wide_string_input_adapter
using char_type = char;
wide_string_input_adapter(BaseInputAdapter base)
: base_adapter(base) {}
: base_adapter(base)
{}
typename std::char_traits<char>::int_type get_character() noexcept
{
@@ -387,26 +398,26 @@ typename iterator_input_adapter_factory<IteratorType>::adapter_type input_adapte
// Enables ADL on begin(container) and end(container)
// Encloses the using declarations in namespace for not to leak them to outside scope
namespace container_input_adapter_factory_impl
{
namespace container_input_adapter_factory_impl {
using std::begin;
using std::end;
template<typename ContainerType, typename Enable = void>
struct container_input_adapter_factory {};
struct container_input_adapter_factory
{};
template<typename ContainerType>
struct container_input_adapter_factory< ContainerType,
void_t<decltype(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>()))>>
{
using adapter_type = decltype(input_adapter(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>())));
static adapter_type create(const ContainerType& container)
struct container_input_adapter_factory<ContainerType,
void_t<decltype(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>()))>>
{
return input_adapter(begin(container), end(container));
}
};
using adapter_type = decltype(input_adapter(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>())));
static adapter_type create(const ContainerType& container)
{
return input_adapter(begin(container), end(container));
}
};
} // namespace container_input_adapter_factory_impl
@@ -437,13 +448,13 @@ inline input_stream_adapter input_adapter(std::istream&& stream)
using contiguous_bytes_input_adapter = decltype(input_adapter(std::declval<const char*>(), std::declval<const char*>()));
// Null-delimited strings, and the like.
template < typename CharT,
typename std::enable_if <
std::is_pointer<CharT>::value&&
!std::is_array<CharT>::value&&
std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
sizeof(typename std::remove_pointer<CharT>::type) == 1,
int >::type = 0 >
template<typename CharT,
typename std::enable_if<
std::is_pointer<CharT>::value &&
!std::is_array<CharT>::value &&
std::is_integral<typename std::remove_pointer<CharT>::type>::value &&
sizeof(typename std::remove_pointer<CharT>::type) == 1,
int>::type = 0>
contiguous_bytes_input_adapter input_adapter(CharT b)
{
auto length = std::strlen(reinterpret_cast<const char*>(b));
@@ -452,7 +463,7 @@ contiguous_bytes_input_adapter input_adapter(CharT b)
}
template<typename T, std::size_t N>
auto input_adapter(T (&array)[N]) -> decltype(input_adapter(array, array + N)) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
auto input_adapter(T (&array)[N]) -> decltype(input_adapter(array, array + N)) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
{
return input_adapter(array, array + N);
}
@@ -463,25 +474,27 @@ auto input_adapter(T (&array)[N]) -> decltype(input_adapter(array, array + N)) /
class span_input_adapter
{
public:
template < typename CharT,
typename std::enable_if <
std::is_pointer<CharT>::value&&
std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
sizeof(typename std::remove_pointer<CharT>::type) == 1,
int >::type = 0 >
template<typename CharT,
typename std::enable_if<
std::is_pointer<CharT>::value &&
std::is_integral<typename std::remove_pointer<CharT>::type>::value &&
sizeof(typename std::remove_pointer<CharT>::type) == 1,
int>::type = 0>
span_input_adapter(CharT b, std::size_t l)
: ia(reinterpret_cast<const char*>(b), reinterpret_cast<const char*>(b) + l) {}
: ia(reinterpret_cast<const char*>(b), reinterpret_cast<const char*>(b) + l)
{}
template<class IteratorType,
typename std::enable_if<
std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
int>::type = 0>
span_input_adapter(IteratorType first, IteratorType last)
: ia(input_adapter(first, last)) {}
: ia(input_adapter(first, last))
{}
contiguous_bytes_input_adapter&& get()
{
return std::move(ia); // NOLINT(hicpp-move-const-arg,performance-move-const-arg)
return std::move(ia); // NOLINT(hicpp-move-const-arg,performance-move-const-arg)
}
private:

View File

@@ -9,9 +9,9 @@
#pragma once
#include <cstddef>
#include <string> // string
#include <utility> // move
#include <vector> // vector
#include <string> // string
#include <utility> // move
#include <vector> // vector
#include <nlohmann/detail/exceptions.hpp>
#include <nlohmann/detail/macro_scope.hpp>
@@ -142,8 +142,7 @@ struct json_sax
virtual ~json_sax() = default;
};
namespace detail
{
namespace detail {
/*!
@brief SAX implementation to create a JSON value from SAX events
@@ -173,14 +172,15 @@ class json_sax_dom_parser
@param[in] allow_exceptions_ whether parse errors yield exceptions
*/
explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true)
: root(r), allow_exceptions(allow_exceptions_)
: root(r)
, allow_exceptions(allow_exceptions_)
{}
// make class move-only
json_sax_dom_parser(const json_sax_dom_parser&) = delete;
json_sax_dom_parser(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
json_sax_dom_parser(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
json_sax_dom_parser& operator=(const json_sax_dom_parser&) = delete;
json_sax_dom_parser& operator=(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
json_sax_dom_parser& operator=(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
~json_sax_dom_parser() = default;
bool null()
@@ -280,8 +280,7 @@ class json_sax_dom_parser
}
template<class Exception>
bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
const Exception& ex)
bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const Exception& ex)
{
errored = true;
static_cast<void>(ex);
@@ -306,7 +305,8 @@ class json_sax_dom_parser
*/
template<typename Value>
JSON_HEDLEY_RETURNS_NON_NULL
BasicJsonType* handle_value(Value&& v)
BasicJsonType*
handle_value(Value&& v)
{
if (ref_stack.empty())
{
@@ -331,7 +331,7 @@ class json_sax_dom_parser
/// the parsed JSON value
BasicJsonType& root;
/// stack to model hierarchy of values
std::vector<BasicJsonType*> ref_stack {};
std::vector<BasicJsonType*> ref_stack{};
/// helper to hold the reference for the next object element
BasicJsonType* object_element = nullptr;
/// whether a syntax error occurred
@@ -355,16 +355,18 @@ class json_sax_dom_callback_parser
json_sax_dom_callback_parser(BasicJsonType& r,
const parser_callback_t cb,
const bool allow_exceptions_ = true)
: root(r), callback(cb), allow_exceptions(allow_exceptions_)
: root(r)
, callback(cb)
, allow_exceptions(allow_exceptions_)
{
keep_stack.push_back(true);
}
// make class move-only
json_sax_dom_callback_parser(const json_sax_dom_callback_parser&) = delete;
json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
json_sax_dom_callback_parser& operator=(const json_sax_dom_callback_parser&) = delete;
json_sax_dom_callback_parser& operator=(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
json_sax_dom_callback_parser& operator=(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
~json_sax_dom_callback_parser() = default;
bool null()
@@ -530,8 +532,7 @@ class json_sax_dom_callback_parser
}
template<class Exception>
bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
const Exception& ex)
bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const Exception& ex)
{
errored = true;
static_cast<void>(ex);
@@ -590,7 +591,7 @@ class json_sax_dom_callback_parser
if (ref_stack.empty())
{
root = std::move(value);
return {true, & root};
return {true, &root};
}
// skip this value if we already decided to skip the parent
@@ -607,7 +608,7 @@ class json_sax_dom_callback_parser
if (ref_stack.back()->is_array())
{
ref_stack.back()->m_data.m_value.array->emplace_back(std::move(value));
return {true, & (ref_stack.back()->m_data.m_value.array->back())};
return {true, &(ref_stack.back()->m_data.m_value.array->back())};
}
// object
@@ -630,11 +631,11 @@ class json_sax_dom_callback_parser
/// the parsed JSON value
BasicJsonType& root;
/// stack to model hierarchy of values
std::vector<BasicJsonType*> ref_stack {};
std::vector<BasicJsonType*> ref_stack{};
/// stack to manage which values to keep
std::vector<bool> keep_stack {};
std::vector<bool> keep_stack{};
/// stack to manage which object keys to keep
std::vector<bool> key_keep_stack {};
std::vector<bool> key_keep_stack{};
/// helper to hold the reference for the next object element
BasicJsonType* object_element = nullptr;
/// whether a syntax error occurred

View File

@@ -8,15 +8,15 @@
#pragma once
#include <array> // array
#include <clocale> // localeconv
#include <cstddef> // size_t
#include <cstdio> // snprintf
#include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull
#include <initializer_list> // initializer_list
#include <string> // char_traits, string
#include <utility> // move
#include <vector> // vector
#include <array> // array
#include <clocale> // localeconv
#include <cstddef> // size_t
#include <cstdio> // snprintf
#include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull
#include <initializer_list> // initializer_list
#include <string> // char_traits, string
#include <utility> // move
#include <vector> // vector
#include <nlohmann/detail/input/input_adapters.hpp>
#include <nlohmann/detail/input/position_t.hpp>
@@ -24,8 +24,7 @@
#include <nlohmann/detail/meta/type_traits.hpp>
NLOHMANN_JSON_NAMESPACE_BEGIN
namespace detail
{
namespace detail {
///////////
// lexer //
@@ -97,7 +96,7 @@ class lexer_base
case token_type::literal_or_value:
return "'[', '{', or a literal";
// LCOV_EXCL_START
default: // catch non-enum values
default: // catch non-enum values
return "unknown token";
// LCOV_EXCL_STOP
}
@@ -122,16 +121,16 @@ class lexer : public lexer_base<BasicJsonType>
using token_type = typename lexer_base<BasicJsonType>::token_type;
explicit lexer(InputAdapterType&& adapter, bool ignore_comments_ = false) noexcept
: ia(std::move(adapter))
, ignore_comments(ignore_comments_)
, decimal_point_char(static_cast<char_int_type>(get_decimal_point()))
: ia(std::move(adapter))
, ignore_comments(ignore_comments_)
, decimal_point_char(static_cast<char_int_type>(get_decimal_point()))
{}
// delete because of pointer members
lexer(const lexer&) = delete;
lexer(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
lexer(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
lexer& operator=(lexer&) = delete;
lexer& operator=(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
lexer& operator=(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
~lexer() = default;
private:
@@ -173,7 +172,7 @@ class lexer : public lexer_base<BasicJsonType>
JSON_ASSERT(current == 'u');
int codepoint = 0;
const auto factors = { 12u, 8u, 4u, 0u };
const auto factors = {12u, 8u, 4u, 0u};
for (const auto factor : factors)
{
get();
@@ -223,7 +222,7 @@ class lexer : public lexer_base<BasicJsonType>
for (auto range = ranges.begin(); range != ranges.end(); ++range)
{
get();
if (JSON_HEDLEY_LIKELY(*range <= current && current <= *(++range))) // NOLINT(bugprone-inc-dec-in-conditions)
if (JSON_HEDLEY_LIKELY(*range <= current && current <= *(++range))) // NOLINT(bugprone-inc-dec-in-conditions)
{
add(current);
}
@@ -320,7 +319,7 @@ class lexer : public lexer_base<BasicJsonType>
case 'u':
{
const int codepoint1 = get_codepoint();
int codepoint = codepoint1; // start with codepoint1
int codepoint = codepoint1; // start with codepoint1
if (JSON_HEDLEY_UNLIKELY(codepoint1 == -1))
{
@@ -347,14 +346,14 @@ class lexer : public lexer_base<BasicJsonType>
{
// overwrite codepoint
codepoint = static_cast<int>(
// high surrogate occupies the most significant 22 bits
(static_cast<unsigned int>(codepoint1) << 10u)
// low surrogate occupies the least significant 15 bits
+ static_cast<unsigned int>(codepoint2)
// there is still the 0xD800, 0xDC00 and 0x10000 noise
// in the result, so we have to subtract with:
// (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
- 0x35FDC00u);
// high surrogate occupies the most significant 22 bits
(static_cast<unsigned int>(codepoint1) << 10u)
// low surrogate occupies the least significant 15 bits
+ static_cast<unsigned int>(codepoint2)
// there is still the 0xD800, 0xDC00 and 0x10000 noise
// in the result, so we have to subtract with:
// (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
- 0x35FDC00u);
}
else
{
@@ -1006,8 +1005,8 @@ class lexer : public lexer_base<BasicJsonType>
}
// all other characters are rejected outside scan_number()
default: // LCOV_EXCL_LINE
JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
default: // LCOV_EXCL_LINE
JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
}
scan_number_minus:
@@ -1245,7 +1244,7 @@ scan_number_done:
// we are done scanning a number)
unget();
char* endptr = nullptr; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
char* endptr = nullptr; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
errno = 0;
// try to parse integers first and fall back to floats
@@ -1298,8 +1297,7 @@ scan_number_done:
@param[in] return_type the token type to return on success
*/
JSON_HEDLEY_NON_NULL(2)
token_type scan_literal(const char_type* literal_text, const std::size_t length,
token_type return_type)
token_type scan_literal(const char_type* literal_text, const std::size_t length, token_type return_type)
{
JSON_ASSERT(char_traits<char_type>::to_char_type(current) == literal_text[0]);
for (std::size_t i = 1; i < length; ++i)
@@ -1456,7 +1454,7 @@ scan_number_done:
{
// escape control characters
std::array<char, 9> cs{{}};
static_cast<void>((std::snprintf)(cs.data(), cs.size(), "<U+%.4X>", static_cast<unsigned char>(c))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
static_cast<void>((std::snprintf)(cs.data(), cs.size(), "<U+%.4X>", static_cast<unsigned char>(c))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
result += cs.data();
}
else
@@ -1503,8 +1501,7 @@ scan_number_done:
do
{
get();
}
while (current == ' ' || current == '\t' || current == '\n' || current == '\r');
} while (current == ' ' || current == '\t' || current == '\n' || current == '\r');
}
token_type scan()
@@ -1609,13 +1606,13 @@ scan_number_done:
bool next_unget = false;
/// the start position of the current token
position_t position {};
position_t position{};
/// raw input token string (for error messages)
std::vector<char_type> token_string {};
std::vector<char_type> token_string{};
/// buffer for variable-length tokens (numbers, strings)
string_t token_buffer {};
string_t token_buffer{};
/// a description of occurred lexer errors
const char* error_message = "";

View File

@@ -8,12 +8,12 @@
#pragma once
#include <cmath> // isfinite
#include <cstdint> // uint8_t
#include <functional> // function
#include <string> // string
#include <utility> // move
#include <vector> // vector
#include <cmath> // isfinite
#include <cstdint> // uint8_t
#include <functional> // function
#include <string> // string
#include <utility> // move
#include <vector> // vector
#include <nlohmann/detail/exceptions.hpp>
#include <nlohmann/detail/input/input_adapters.hpp>
@@ -25,8 +25,7 @@
#include <nlohmann/detail/value_t.hpp>
NLOHMANN_JSON_NAMESPACE_BEGIN
namespace detail
{
namespace detail {
////////////
// parser //
////////////
@@ -72,9 +71,9 @@ class parser
const parser_callback_t<BasicJsonType> cb = nullptr,
const bool allow_exceptions_ = true,
const bool skip_comments = false)
: callback(cb)
, m_lexer(std::move(adapter), skip_comments)
, allow_exceptions(allow_exceptions_)
: callback(cb)
, m_lexer(std::move(adapter), skip_comments)
, allow_exceptions(allow_exceptions_)
{
// read first token
get_token();
@@ -102,8 +101,7 @@ class parser
{
sdp.parse_error(m_lexer.get_position(),
m_lexer.get_token_string(),
parse_error::create(101, m_lexer.get_position(),
exception_message(token_type::end_of_input, "value"), nullptr));
parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), nullptr));
}
// in case of an error, return discarded value
@@ -160,7 +158,7 @@ class parser
JSON_HEDLEY_NON_NULL(2)
bool sax_parse(SAX* sax, const bool strict = true)
{
(void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
(void)detail::is_sax_static_asserts<SAX, BasicJsonType>{};
const bool result = sax_parse_internal(sax);
// strict mode: next byte must be EOF
@@ -347,8 +345,7 @@ class parser
{
return sax->parse_error(m_lexer.get_position(),
m_lexer.get_token_string(),
parse_error::create(101, m_lexer.get_position(),
"attempting to parse an empty input; check that your input string or stream contains the expected JSON", nullptr));
parse_error::create(101, m_lexer.get_position(), "attempting to parse an empty input; check that your input string or stream contains the expected JSON", nullptr));
}
return sax->parse_error(m_lexer.get_position(),
@@ -361,7 +358,7 @@ class parser
case token_type::name_separator:
case token_type::value_separator:
case token_type::literal_or_value:
default: // the last token was unexpected
default: // the last token was unexpected
{
return sax->parse_error(m_lexer.get_position(),
m_lexer.get_token_string(),
@@ -488,8 +485,7 @@ class parser
if (last_token == token_type::parse_error)
{
error_msg += concat(m_lexer.get_error_message(), "; last read: '",
m_lexer.get_token_string(), '\'');
error_msg += concat(m_lexer.get_error_message(), "; last read: '", m_lexer.get_token_string(), '\'');
}
else
{

View File

@@ -8,13 +8,12 @@
#pragma once
#include <cstddef> // size_t
#include <cstddef> // size_t
#include <nlohmann/detail/abi_macros.hpp>
NLOHMANN_JSON_NAMESPACE_BEGIN
namespace detail
{
namespace detail {
/// struct to capture the start position of the current token
struct position_t

View File

@@ -12,8 +12,7 @@
#include <nlohmann/detail/iterators/primitive_iterator.hpp>
NLOHMANN_JSON_NAMESPACE_BEGIN
namespace detail
{
namespace detail {
/*!
@brief an iterator value
@@ -21,14 +20,15 @@ namespace detail
@note This structure could easily be a union, but MSVC currently does not allow
unions members with complex constructors, see https://github.com/nlohmann/json/pull/105.
*/
template<typename BasicJsonType> struct internal_iterator
template<typename BasicJsonType>
struct internal_iterator
{
/// iterator for JSON objects
typename BasicJsonType::object_t::iterator object_iterator {};
typename BasicJsonType::object_t::iterator object_iterator{};
/// iterator for JSON arrays
typename BasicJsonType::array_t::iterator array_iterator {};
typename BasicJsonType::array_t::iterator array_iterator{};
/// generic iterator for all other types
primitive_iterator_t primitive_iterator {};
primitive_iterator_t primitive_iterator{};
};
} // namespace detail

View File

@@ -8,8 +8,8 @@
#pragma once
#include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next
#include <type_traits> // conditional, is_const, remove_const
#include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next
#include <type_traits> // conditional, is_const, remove_const
#include <nlohmann/detail/exceptions.hpp>
#include <nlohmann/detail/iterators/internal_iterator.hpp>
@@ -20,12 +20,13 @@
#include <nlohmann/detail/value_t.hpp>
NLOHMANN_JSON_NAMESPACE_BEGIN
namespace detail
{
namespace detail {
// forward declare, to be able to friend it later on
template<typename IteratorType> class iteration_proxy;
template<typename IteratorType> class iteration_proxy_value;
template<typename IteratorType>
class iteration_proxy;
template<typename IteratorType>
class iteration_proxy_value;
/*!
@brief a template for a bidirectional iterator for the @ref basic_json class
@@ -44,7 +45,7 @@ This class implements a both iterators (iterator and const_iterator) for the
iterators in version 3.0.0 (see https://github.com/nlohmann/json/issues/593)
*/
template<typename BasicJsonType>
class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
{
/// the iterator with BasicJsonType of different const-ness
using other_iter_impl = iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
@@ -60,8 +61,7 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
static_assert(is_basic_json<typename std::remove_const<BasicJsonType>::type>::value,
"iter_impl only accepts (const) basic_json");
// superficial check for the LegacyBidirectionalIterator named requirement
static_assert(std::is_base_of<std::bidirectional_iterator_tag, std::bidirectional_iterator_tag>::value
&& std::is_base_of<std::bidirectional_iterator_tag, typename std::iterator_traits<typename array_t::iterator>::iterator_category>::value,
static_assert(std::is_base_of<std::bidirectional_iterator_tag, std::bidirectional_iterator_tag>::value && std::is_base_of<std::bidirectional_iterator_tag, typename std::iterator_traits<typename array_t::iterator>::iterator_category>::value,
"basic_json iterator assumes array and object type iterators satisfy the LegacyBidirectionalIterator named requirement.");
public:
@@ -78,13 +78,13 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
using difference_type = typename BasicJsonType::difference_type;
/// defines a pointer to the type iterated over (value_type)
using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,
typename BasicJsonType::const_pointer,
typename BasicJsonType::pointer>::type;
typename BasicJsonType::const_pointer,
typename BasicJsonType::pointer>::type;
/// defines a reference to the type iterated over (value_type)
using reference =
typename std::conditional<std::is_const<BasicJsonType>::value,
typename BasicJsonType::const_reference,
typename BasicJsonType::reference>::type;
typename BasicJsonType::const_reference,
typename BasicJsonType::reference>::type;
iter_impl() = default;
~iter_impl() = default;
@@ -97,7 +97,8 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
@pre object != nullptr
@post The iterator is initialized; i.e. `m_object != nullptr`.
*/
explicit iter_impl(pointer object) noexcept : m_object(object)
explicit iter_impl(pointer object) noexcept
: m_object(object)
{
JSON_ASSERT(m_object != nullptr);
@@ -148,7 +149,8 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
information refer to: https://github.com/nlohmann/json/issues/1608
*/
iter_impl(const iter_impl<const BasicJsonType>& other) noexcept
: m_object(other.m_object), m_it(other.m_it)
: m_object(other.m_object)
, m_it(other.m_it)
{}
/*!
@@ -173,7 +175,8 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
@note It is not checked whether @a other is initialized.
*/
iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
: m_object(other.m_object), m_it(other.m_it)
: m_object(other.m_object)
, m_it(other.m_it)
{}
/*!
@@ -182,19 +185,20 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
@return const/non-const iterator
@note It is not checked whether @a other is initialized.
*/
iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept // NOLINT(cert-oop54-cpp)
iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept // NOLINT(cert-oop54-cpp)
{
m_object = other.m_object;
m_it = other.m_it;
return *this;
}
JSON_PRIVATE_UNLESS_TESTED:
/*!
JSON_PRIVATE_UNLESS_TESTED :
/*!
@brief set the iterator to the first value
@pre The iterator is initialized; i.e. `m_object != nullptr`.
*/
void set_begin() noexcept
void
set_begin() noexcept
{
JSON_ASSERT(m_object != nullptr);
@@ -363,7 +367,7 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
@brief post-increment (it++)
@pre The iterator is initialized; i.e. `m_object != nullptr`.
*/
iter_impl operator++(int)& // NOLINT(cert-dcl21-cpp)
iter_impl operator++(int) & // NOLINT(cert-dcl21-cpp)
{
auto result = *this;
++(*this);
@@ -414,7 +418,7 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
@brief post-decrement (it--)
@pre The iterator is initialized; i.e. `m_object != nullptr`.
*/
iter_impl operator--(int)& // NOLINT(cert-dcl21-cpp)
iter_impl operator--(int) & // NOLINT(cert-dcl21-cpp)
{
auto result = *this;
--(*this);
@@ -465,7 +469,7 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
@brief comparison: equal
@pre The iterator is initialized; i.e. `m_object != nullptr`.
*/
template < typename IterImpl, detail::enable_if_t < (std::is_same<IterImpl, iter_impl>::value || std::is_same<IterImpl, other_iter_impl>::value), std::nullptr_t > = nullptr >
template<typename IterImpl, detail::enable_if_t<(std::is_same<IterImpl, iter_impl>::value || std::is_same<IterImpl, other_iter_impl>::value), std::nullptr_t> = nullptr>
bool operator==(const IterImpl& other) const
{
// if objects are not the same, the comparison is undefined
@@ -501,7 +505,7 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
@brief comparison: not equal
@pre The iterator is initialized; i.e. `m_object != nullptr`.
*/
template < typename IterImpl, detail::enable_if_t < (std::is_same<IterImpl, iter_impl>::value || std::is_same<IterImpl, other_iter_impl>::value), std::nullptr_t > = nullptr >
template<typename IterImpl, detail::enable_if_t<(std::is_same<IterImpl, iter_impl>::value || std::is_same<IterImpl, other_iter_impl>::value), std::nullptr_t> = nullptr>
bool operator!=(const IterImpl& other) const
{
return !operator==(other);
@@ -548,7 +552,7 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
*/
bool operator<=(const iter_impl& other) const
{
return !other.operator < (*this);
return !other.operator<(*this);
}
/*!
@@ -740,11 +744,11 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
return operator*();
}
JSON_PRIVATE_UNLESS_TESTED:
/// associated JSON instance
pointer m_object = nullptr;
JSON_PRIVATE_UNLESS_TESTED :
/// associated JSON instance
pointer m_object = nullptr;
/// the actual iterator of the associated instance
internal_iterator<typename std::remove_const<BasicJsonType>::type> m_it {};
internal_iterator<typename std::remove_const<BasicJsonType>::type> m_it{};
};
} // namespace detail

View File

@@ -8,14 +8,14 @@
#pragma once
#include <cstddef> // size_t
#include <iterator> // input_iterator_tag
#include <string> // string, to_string
#include <tuple> // tuple_size, get, tuple_element
#include <utility> // move
#include <cstddef> // size_t
#include <iterator> // input_iterator_tag
#include <string> // string, to_string
#include <tuple> // tuple_size, get, tuple_element
#include <utility> // move
#if JSON_HAS_RANGES
#include <ranges> // enable_borrowed_range
#include <ranges> // enable_borrowed_range
#endif
#include <nlohmann/detail/abi_macros.hpp>
@@ -23,25 +23,25 @@
#include <nlohmann/detail/value_t.hpp>
NLOHMANN_JSON_NAMESPACE_BEGIN
namespace detail
{
namespace detail {
template<typename string_type>
void int_to_string( string_type& target, std::size_t value )
void int_to_string(string_type& target, std::size_t value)
{
// For ADL
using std::to_string;
target = to_string(value);
}
template<typename IteratorType> class iteration_proxy_value
template<typename IteratorType>
class iteration_proxy_value
{
public:
using difference_type = std::ptrdiff_t;
using value_type = iteration_proxy_value;
using pointer = value_type *;
using reference = value_type &;
using pointer = value_type*;
using reference = value_type&;
using iterator_category = std::input_iterator_tag;
using string_type = typename std::remove_cv< typename std::remove_reference<decltype( std::declval<IteratorType>().key() ) >::type >::type;
using string_type = typename std::remove_cv<typename std::remove_reference<decltype(std::declval<IteratorType>().key())>::type>::type;
private:
/// the iterator
@@ -57,22 +57,16 @@ template<typename IteratorType> class iteration_proxy_value
public:
explicit iteration_proxy_value() = default;
explicit iteration_proxy_value(IteratorType it, std::size_t array_index_ = 0)
noexcept(std::is_nothrow_move_constructible<IteratorType>::value
&& std::is_nothrow_default_constructible<string_type>::value)
: anchor(std::move(it))
, array_index(array_index_)
explicit iteration_proxy_value(IteratorType it, std::size_t array_index_ = 0) noexcept(std::is_nothrow_move_constructible<IteratorType>::value && std::is_nothrow_default_constructible<string_type>::value)
: anchor(std::move(it))
, array_index(array_index_)
{}
iteration_proxy_value(iteration_proxy_value const&) = default;
iteration_proxy_value& operator=(iteration_proxy_value const&) = default;
// older GCCs are a bit fussy and require explicit noexcept specifiers on defaulted functions
iteration_proxy_value(iteration_proxy_value&&)
noexcept(std::is_nothrow_move_constructible<IteratorType>::value
&& std::is_nothrow_move_constructible<string_type>::value) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor,cppcoreguidelines-noexcept-move-operations)
iteration_proxy_value& operator=(iteration_proxy_value&&)
noexcept(std::is_nothrow_move_assignable<IteratorType>::value
&& std::is_nothrow_move_assignable<string_type>::value) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor,cppcoreguidelines-noexcept-move-operations)
iteration_proxy_value(iteration_proxy_value&&) noexcept(std::is_nothrow_move_constructible<IteratorType>::value && std::is_nothrow_move_constructible<string_type>::value) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor,cppcoreguidelines-noexcept-move-operations)
iteration_proxy_value& operator=(iteration_proxy_value&&) noexcept(std::is_nothrow_move_assignable<IteratorType>::value && std::is_nothrow_move_assignable<string_type>::value) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor,cppcoreguidelines-noexcept-move-operations)
~iteration_proxy_value() = default;
/// dereference operator (needed for range-based for)
@@ -90,7 +84,7 @@ template<typename IteratorType> class iteration_proxy_value
return *this;
}
iteration_proxy_value operator++(int)& // NOLINT(cert-dcl21-cpp)
iteration_proxy_value operator++(int) & // NOLINT(cert-dcl21-cpp)
{
auto tmp = iteration_proxy_value(anchor, array_index);
++anchor;
@@ -122,7 +116,7 @@ template<typename IteratorType> class iteration_proxy_value
{
if (array_index != array_index_last)
{
int_to_string( array_index_str, array_index );
int_to_string(array_index_str, array_index);
array_index_last = array_index;
}
return array_index_str;
@@ -154,7 +148,8 @@ template<typename IteratorType> class iteration_proxy_value
};
/// proxy class for the items() function
template<typename IteratorType> class iteration_proxy
template<typename IteratorType>
class iteration_proxy
{
private:
/// the container to iterate
@@ -165,7 +160,8 @@ template<typename IteratorType> class iteration_proxy
/// construct iteration proxy from a container
explicit iteration_proxy(typename IteratorType::reference cont) noexcept
: container(&cont) {}
: container(&cont)
{}
iteration_proxy(iteration_proxy const&) = default;
iteration_proxy& operator=(iteration_proxy const&) = default;
@@ -210,8 +206,7 @@ NLOHMANN_JSON_NAMESPACE_END
// Structured Bindings Support to the iteration_proxy_value class
// For further reference see https://blog.tartanllama.xyz/structured-bindings/
// And see https://github.com/nlohmann/json/pull/1391
namespace std
{
namespace std {
#if defined(__clang__)
// Fix: https://github.com/nlohmann/json/issues/1401
@@ -219,16 +214,16 @@ namespace std
#pragma clang diagnostic ignored "-Wmismatched-tags"
#endif
template<typename IteratorType>
class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>> // NOLINT(cert-dcl58-cpp)
: public std::integral_constant<std::size_t, 2> {};
class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>> // NOLINT(cert-dcl58-cpp)
: public std::integral_constant<std::size_t, 2>
{};
template<std::size_t N, typename IteratorType>
class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >> // NOLINT(cert-dcl58-cpp)
class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType>> // NOLINT(cert-dcl58-cpp)
{
public:
using type = decltype(
get<N>(std::declval <
::nlohmann::detail::iteration_proxy_value<IteratorType >> ()));
using type = decltype(get<N>(std::declval<
::nlohmann::detail::iteration_proxy_value<IteratorType>>()));
};
#if defined(__clang__)
#pragma clang diagnostic pop
@@ -237,6 +232,6 @@ class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >>
} // namespace std
#if JSON_HAS_RANGES
template <typename IteratorType>
inline constexpr bool ::std::ranges::enable_borrowed_range<::nlohmann::detail::iteration_proxy<IteratorType>> = true;
template<typename IteratorType>
inline constexpr bool ::std::ranges::enable_borrowed_range<::nlohmann::detail::iteration_proxy<IteratorType>> = true;
#endif

View File

@@ -8,24 +8,23 @@
#pragma once
#include <iterator> // random_access_iterator_tag
#include <iterator> // random_access_iterator_tag
#include <nlohmann/detail/abi_macros.hpp>
#include <nlohmann/detail/meta/void_t.hpp>
#include <nlohmann/detail/meta/cpp_future.hpp>
#include <nlohmann/detail/meta/void_t.hpp>
NLOHMANN_JSON_NAMESPACE_BEGIN
namespace detail
{
namespace detail {
template<typename It, typename = void>
struct iterator_types {};
struct iterator_types
{};
template<typename It>
struct iterator_types <
struct iterator_types<
It,
void_t<typename It::difference_type, typename It::value_type, typename It::pointer,
typename It::reference, typename It::iterator_category >>
void_t<typename It::difference_type, typename It::value_type, typename It::pointer, typename It::reference, typename It::iterator_category>>
{
using difference_type = typename It::difference_type;
using value_type = typename It::value_type;
@@ -42,8 +41,8 @@ struct iterator_traits
};
template<typename T>
struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >>
: iterator_types<T>
struct iterator_traits<T, enable_if_t<!std::is_pointer<T>::value>>
: iterator_types<T>
{
};

View File

@@ -8,15 +8,14 @@
#pragma once
#include <cstddef> // ptrdiff_t
#include <iterator> // reverse_iterator
#include <utility> // declval
#include <cstddef> // ptrdiff_t
#include <iterator> // reverse_iterator
#include <utility> // declval
#include <nlohmann/detail/abi_macros.hpp>
NLOHMANN_JSON_NAMESPACE_BEGIN
namespace detail
{
namespace detail {
//////////////////////
// reverse_iterator //
@@ -52,13 +51,16 @@ class json_reverse_iterator : public std::reverse_iterator<Base>
/// create reverse iterator from iterator
explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
: base_iterator(it) {}
: base_iterator(it)
{}
/// create reverse iterator from base class
explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
explicit json_reverse_iterator(const base_iterator& it) noexcept
: base_iterator(it)
{}
/// post-increment (it++)
json_reverse_iterator operator++(int)& // NOLINT(cert-dcl21-cpp)
json_reverse_iterator operator++(int) & // NOLINT(cert-dcl21-cpp)
{
return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
}
@@ -70,7 +72,7 @@ class json_reverse_iterator : public std::reverse_iterator<Base>
}
/// post-decrement (it--)
json_reverse_iterator operator--(int)& // NOLINT(cert-dcl21-cpp)
json_reverse_iterator operator--(int) & // NOLINT(cert-dcl21-cpp)
{
return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
}
@@ -122,7 +124,7 @@ class json_reverse_iterator : public std::reverse_iterator<Base>
reference value() const
{
auto it = --this->base();
return it.operator * ();
return it.operator*();
}
};

View File

@@ -8,14 +8,13 @@
#pragma once
#include <cstddef> // ptrdiff_t
#include <limits> // numeric_limits
#include <cstddef> // ptrdiff_t
#include <limits> // numeric_limits
#include <nlohmann/detail/macro_scope.hpp>
NLOHMANN_JSON_NAMESPACE_BEGIN
namespace detail
{
namespace detail {
/*
@brief an iterator for primitive JSON types
@@ -33,9 +32,9 @@ class primitive_iterator_t
static constexpr difference_type begin_value = 0;
static constexpr difference_type end_value = begin_value + 1;
JSON_PRIVATE_UNLESS_TESTED:
/// iterator as signed integer type
difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
JSON_PRIVATE_UNLESS_TESTED :
/// iterator as signed integer type
difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
public:
constexpr difference_type get_value() const noexcept
@@ -95,7 +94,7 @@ class primitive_iterator_t
return *this;
}
primitive_iterator_t operator++(int)& noexcept // NOLINT(cert-dcl21-cpp)
primitive_iterator_t operator++(int) & noexcept // NOLINT(cert-dcl21-cpp)
{
auto result = *this;
++m_it;
@@ -108,7 +107,7 @@ class primitive_iterator_t
return *this;
}
primitive_iterator_t operator--(int)& noexcept // NOLINT(cert-dcl21-cpp)
primitive_iterator_t operator--(int) & noexcept // NOLINT(cert-dcl21-cpp)
{
auto result = *this;
--m_it;

View File

@@ -8,13 +8,12 @@
#pragma once
#include <type_traits> // conditional, is_same
#include <type_traits> // conditional, is_same
#include <nlohmann/detail/abi_macros.hpp>
NLOHMANN_JSON_NAMESPACE_BEGIN
namespace detail
{
namespace detail {
/*!
@brief Default base class of the @ref basic_json class.
@@ -26,14 +25,14 @@ of @ref basic_json do not require complex case distinctions
By default, this class is used because it is empty and thus has no effect
on the behavior of @ref basic_json.
*/
struct json_default_base {};
struct json_default_base
{};
template<class T>
using json_base_class = typename std::conditional <
std::is_same<T, void>::value,
json_default_base,
T
>::type;
using json_base_class = typename std::conditional<
std::is_same<T, void>::value,
json_default_base,
T>::type;
} // namespace detail
NLOHMANN_JSON_NAMESPACE_END

View File

@@ -8,18 +8,18 @@
#pragma once
#include <algorithm> // all_of
#include <cctype> // isdigit
#include <cerrno> // errno, ERANGE
#include <cstdlib> // strtoull
#include <algorithm> // all_of
#include <cctype> // isdigit
#include <cerrno> // errno, ERANGE
#include <cstdlib> // strtoull
#ifndef JSON_NO_IO
#include <iosfwd> // ostream
#endif // JSON_NO_IO
#include <limits> // max
#include <numeric> // accumulate
#include <string> // string
#include <utility> // move
#include <vector> // vector
#include <iosfwd> // ostream
#endif // JSON_NO_IO
#include <limits> // max
#include <numeric> // accumulate
#include <string> // string
#include <utility> // move
#include <vector> // vector
#include <nlohmann/detail/exceptions.hpp>
#include <nlohmann/detail/macro_scope.hpp>
@@ -60,17 +60,14 @@ class json_pointer
/// @brief create JSON pointer
/// @sa https://json.nlohmann.me/api/json_pointer/json_pointer/
explicit json_pointer(const string_t& s = "")
: reference_tokens(split(s))
: reference_tokens(split(s))
{}
/// @brief return a string representation of the JSON pointer
/// @sa https://json.nlohmann.me/api/json_pointer/to_string/
string_t to_string() const
{
return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
string_t{},
[](const string_t& a, const string_t& b)
{
return std::accumulate(reference_tokens.begin(), reference_tokens.end(), string_t{}, [](const string_t& a, const string_t& b) {
return detail::concat(a, '/', detail::escape(b));
});
}
@@ -128,7 +125,7 @@ class json_pointer
/// @brief create a new JSON pointer by appending the unescaped token at the end of the JSON pointer
/// @sa https://json.nlohmann.me/api/json_pointer/operator_slash/
friend json_pointer operator/(const json_pointer& lhs, string_t token) // NOLINT(performance-unnecessary-value-param)
friend json_pointer operator/(const json_pointer& lhs, string_t token) // NOLINT(performance-unnecessary-value-param)
{
return json_pointer(lhs) /= std::move(token);
}
@@ -229,11 +226,11 @@ class json_pointer
const char* p = s.c_str();
char* p_end = nullptr;
errno = 0; // strtoull doesn't reset errno
const unsigned long long res = std::strtoull(p, &p_end, 10); // NOLINT(runtime/int)
if (p == p_end // invalid input or empty string
|| errno == ERANGE // out of range
|| JSON_HEDLEY_UNLIKELY(static_cast<std::size_t>(p_end - p) != s.size())) // incomplete read
errno = 0; // strtoull doesn't reset errno
const unsigned long long res = std::strtoull(p, &p_end, 10); // NOLINT(runtime/int)
if (p == p_end // invalid input or empty string
|| errno == ERANGE // out of range
|| JSON_HEDLEY_UNLIKELY(static_cast<std::size_t>(p_end - p) != s.size())) // incomplete read
{
JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", s, "'"), nullptr));
}
@@ -242,14 +239,13 @@ class json_pointer
// https://github.com/nlohmann/json/pull/2203
if (res >= static_cast<unsigned long long>((std::numeric_limits<size_type>::max)())) // NOLINT(runtime/int)
{
JSON_THROW(detail::out_of_range::create(410, detail::concat("array index ", s, " exceeds size_type"), nullptr)); // LCOV_EXCL_LINE
JSON_THROW(detail::out_of_range::create(410, detail::concat("array index ", s, " exceeds size_type"), nullptr)); // LCOV_EXCL_LINE
}
return static_cast<size_type>(res);
}
JSON_PRIVATE_UNLESS_TESTED:
json_pointer top() const
JSON_PRIVATE_UNLESS_TESTED : json_pointer top() const
{
if (JSON_HEDLEY_UNLIKELY(empty()))
{
@@ -360,16 +356,14 @@ class json_pointer
{
// check if reference token is a number
const bool nums =
std::all_of(reference_token.begin(), reference_token.end(),
[](const unsigned char x)
{
return std::isdigit(x);
});
std::all_of(reference_token.begin(), reference_token.end(), [](const unsigned char x) {
return std::isdigit(x);
});
// change value to array for numbers or "-" or to object otherwise
*ptr = (nums || reference_token == "-")
? detail::value_t::array
: detail::value_t::object;
? detail::value_t::array
: detail::value_t::object;
}
switch (ptr->type())
@@ -437,9 +431,7 @@ class json_pointer
if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
{
// "-" always fails the range check
JSON_THROW(detail::out_of_range::create(402, detail::concat(
"array index '-' (", std::to_string(ptr->m_data.m_value.array->size()),
") is out of range"), ptr));
JSON_THROW(detail::out_of_range::create(402, detail::concat("array index '-' (", std::to_string(ptr->m_data.m_value.array->size()), ") is out of range"), ptr));
}
// note: at performs range check
@@ -544,9 +536,7 @@ class json_pointer
if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
{
// "-" always fails the range check
JSON_THROW(detail::out_of_range::create(402, detail::concat(
"array index '-' (", std::to_string(ptr->m_data.m_value.array->size()),
") is out of range"), ptr));
JSON_THROW(detail::out_of_range::create(402, detail::concat("array index '-' (", std::to_string(ptr->m_data.m_value.array->size()), ") is out of range"), ptr));
}
// note: at performs range check
@@ -685,14 +675,14 @@ class json_pointer
for (
// search for the first slash after the first character
std::size_t slash = reference_string.find_first_of('/', 1),
// set the beginning of the first reference token
// set the beginning of the first reference token
start = 1;
// we can stop if start == 0 (if slash == string_t::npos)
start != 0;
// set the beginning of the next reference token
// (will eventually be 0 if slash == string_t::npos)
start = (slash == string_t::npos) ? 0 : slash + 1,
// find next slash
// find next slash
slash = reference_string.find_first_of('/', start))
{
// use the text between the beginning of the reference token
@@ -701,8 +691,8 @@ class json_pointer
// check reference tokens are properly escaped
for (std::size_t pos = reference_token.find_first_of('~');
pos != string_t::npos;
pos = reference_token.find_first_of('~', pos + 1))
pos != string_t::npos;
pos = reference_token.find_first_of('~', pos + 1))
{
JSON_ASSERT(reference_token[pos] == '~');
@@ -751,7 +741,8 @@ class json_pointer
for (std::size_t i = 0; i < value.m_data.m_value.array->size(); ++i)
{
flatten(detail::concat(reference_string, '/', std::to_string(i)),
value.m_data.m_value.array->operator[](i), result);
value.m_data.m_value.array->operator[](i),
result);
}
}
break;
@@ -839,7 +830,7 @@ class json_pointer
return result;
}
json_pointer<string_t> convert()&&
json_pointer<string_t> convert() &&
{
json_pointer<string_t> result;
result.reference_tokens = std::move(reference_tokens);
@@ -866,9 +857,9 @@ class json_pointer
/// @brief 3-way compares two JSON pointers
template<typename RefStringTypeRhs>
std::strong_ordering operator<=>(const json_pointer<RefStringTypeRhs>& rhs) const noexcept // *NOPAD*
std::strong_ordering operator<= > (const json_pointer<RefStringTypeRhs>& rhs) const noexcept // *NOPAD*
{
return reference_tokens <=> rhs.reference_tokens; // *NOPAD*
return reference_tokens <= > rhs.reference_tokens; // *NOPAD*
}
#else
/// @brief compares two JSON pointers for equality

View File

@@ -15,8 +15,7 @@
#include <nlohmann/detail/meta/type_traits.hpp>
NLOHMANN_JSON_NAMESPACE_BEGIN
namespace detail
{
namespace detail {
template<typename BasicJsonType>
class json_ref
@@ -25,22 +24,22 @@ class json_ref
using value_type = BasicJsonType;
json_ref(value_type&& value)
: owned_value(std::move(value))
: owned_value(std::move(value))
{}
json_ref(const value_type& value)
: value_ref(&value)
: value_ref(&value)
{}
json_ref(std::initializer_list<json_ref> init)
: owned_value(init)
: owned_value(init)
{}
template <
template<
class... Args,
enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0 >
json_ref(Args && ... args)
: owned_value(std::forward<Args>(args)...)
enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0>
json_ref(Args&&... args)
: owned_value(std::forward<Args>(args)...)
{}
// class should be movable only
@@ -66,7 +65,7 @@ class json_ref
value_type const* operator->() const
{
return &** this;
return &**this;
}
private:

View File

@@ -8,9 +8,9 @@
#pragma once
#include <utility> // declval, pair
#include <nlohmann/detail/meta/detected.hpp>
#include <nlohmann/thirdparty/hedley/hedley.hpp>
#include <utility> // declval, pair
// This file contains all internal macro definitions (except those affecting ABI)
// You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them
@@ -37,7 +37,7 @@
#define JSON_HAS_CPP_20
#define JSON_HAS_CPP_17
#define JSON_HAS_CPP_14
#elif (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
#elif (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
#define JSON_HAS_CPP_17
#define JSON_HAS_CPP_14
#elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
@@ -114,8 +114,7 @@
#endif
#ifndef JSON_HAS_THREE_WAY_COMPARISON
#if defined(__cpp_impl_three_way_comparison) && __cpp_impl_three_way_comparison >= 201907L \
&& defined(__cpp_lib_three_way_comparison) && __cpp_lib_three_way_comparison >= 201907L
#if defined(__cpp_impl_three_way_comparison) && __cpp_impl_three_way_comparison >= 201907L && defined(__cpp_lib_three_way_comparison) && __cpp_lib_three_way_comparison >= 201907L
#define JSON_HAS_THREE_WAY_COMPARISON 1
#else
#define JSON_HAS_THREE_WAY_COMPARISON 0
@@ -164,14 +163,14 @@
#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
#define JSON_THROW(exception) throw exception
#define JSON_TRY try
#define JSON_CATCH(exception) catch(exception)
#define JSON_INTERNAL_CATCH(exception) catch(exception)
#define JSON_CATCH(exception) catch (exception)
#define JSON_INTERNAL_CATCH(exception) catch (exception)
#else
#include <cstdlib>
#define JSON_THROW(exception) std::abort()
#define JSON_TRY if(true)
#define JSON_CATCH(exception) if(false)
#define JSON_INTERNAL_CATCH(exception) if(false)
#define JSON_TRY if (true)
#define JSON_CATCH(exception) if (false)
#define JSON_INTERNAL_CATCH(exception) if (false)
#endif
// override exception macros
@@ -196,7 +195,7 @@
// allow overriding assert
#if !defined(JSON_ASSERT)
#include <cassert> // assert
#include <cassert> // assert
#define JSON_ASSERT(x) assert(x)
#endif
@@ -212,119 +211,119 @@
@def NLOHMANN_JSON_SERIALIZE_ENUM
@since version 3.4.0
*/
#define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \
template<typename BasicJsonType> \
inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \
{ \
static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
auto it = std::find_if(std::begin(m), std::end(m), \
[e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
{ \
return ej_pair.first == e; \
}); \
j = ((it != std::end(m)) ? it : std::begin(m))->second; \
} \
template<typename BasicJsonType> \
inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \
{ \
static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
auto it = std::find_if(std::begin(m), std::end(m), \
[&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
{ \
return ej_pair.second == j; \
}); \
e = ((it != std::end(m)) ? it : std::begin(m))->first; \
#define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \
template<typename BasicJsonType> \
inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \
{ \
static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
auto it = std::find_if(std::begin(m), std::end(m), [e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool { \
return ej_pair.first == e; \
}); \
j = ((it != std::end(m)) ? it : std::begin(m))->second; \
} \
template<typename BasicJsonType> \
inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \
{ \
static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
auto it = std::find_if(std::begin(m), std::end(m), [&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool { \
return ej_pair.second == j; \
}); \
e = ((it != std::end(m)) ? it : std::begin(m))->first; \
}
// Ugly macros to avoid uglier copy-paste when specializing basic_json. They
// may be removed in the future once the class is split.
#define NLOHMANN_BASIC_JSON_TPL_DECLARATION \
template<template<typename, typename, typename...> class ObjectType, \
template<typename, typename...> class ArrayType, \
class StringType, class BooleanType, class NumberIntegerType, \
class NumberUnsignedType, class NumberFloatType, \
template<typename> class AllocatorType, \
template<typename, typename = void> class JSONSerializer, \
class BinaryType, \
#define NLOHMANN_BASIC_JSON_TPL_DECLARATION \
template<template<typename, typename, typename...> class ObjectType, \
template<typename, typename...> \
class ArrayType, \
class StringType, \
class BooleanType, \
class NumberIntegerType, \
class NumberUnsignedType, \
class NumberFloatType, \
template<typename> \
class AllocatorType, \
template<typename, typename = void> \
class JSONSerializer, \
class BinaryType, \
class CustomBaseClass>
#define NLOHMANN_BASIC_JSON_TPL \
basic_json<ObjectType, ArrayType, StringType, BooleanType, \
NumberIntegerType, NumberUnsignedType, NumberFloatType, \
AllocatorType, JSONSerializer, BinaryType, CustomBaseClass>
#define NLOHMANN_BASIC_JSON_TPL \
basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer, BinaryType, CustomBaseClass>
// Macros to simplify conversion from/to types
#define NLOHMANN_JSON_EXPAND( x ) x
#define NLOHMANN_JSON_GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, NAME,...) NAME
#define NLOHMANN_JSON_PASTE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_GET_MACRO(__VA_ARGS__, \
NLOHMANN_JSON_PASTE64, \
NLOHMANN_JSON_PASTE63, \
NLOHMANN_JSON_PASTE62, \
NLOHMANN_JSON_PASTE61, \
NLOHMANN_JSON_PASTE60, \
NLOHMANN_JSON_PASTE59, \
NLOHMANN_JSON_PASTE58, \
NLOHMANN_JSON_PASTE57, \
NLOHMANN_JSON_PASTE56, \
NLOHMANN_JSON_PASTE55, \
NLOHMANN_JSON_PASTE54, \
NLOHMANN_JSON_PASTE53, \
NLOHMANN_JSON_PASTE52, \
NLOHMANN_JSON_PASTE51, \
NLOHMANN_JSON_PASTE50, \
NLOHMANN_JSON_PASTE49, \
NLOHMANN_JSON_PASTE48, \
NLOHMANN_JSON_PASTE47, \
NLOHMANN_JSON_PASTE46, \
NLOHMANN_JSON_PASTE45, \
NLOHMANN_JSON_PASTE44, \
NLOHMANN_JSON_PASTE43, \
NLOHMANN_JSON_PASTE42, \
NLOHMANN_JSON_PASTE41, \
NLOHMANN_JSON_PASTE40, \
NLOHMANN_JSON_PASTE39, \
NLOHMANN_JSON_PASTE38, \
NLOHMANN_JSON_PASTE37, \
NLOHMANN_JSON_PASTE36, \
NLOHMANN_JSON_PASTE35, \
NLOHMANN_JSON_PASTE34, \
NLOHMANN_JSON_PASTE33, \
NLOHMANN_JSON_PASTE32, \
NLOHMANN_JSON_PASTE31, \
NLOHMANN_JSON_PASTE30, \
NLOHMANN_JSON_PASTE29, \
NLOHMANN_JSON_PASTE28, \
NLOHMANN_JSON_PASTE27, \
NLOHMANN_JSON_PASTE26, \
NLOHMANN_JSON_PASTE25, \
NLOHMANN_JSON_PASTE24, \
NLOHMANN_JSON_PASTE23, \
NLOHMANN_JSON_PASTE22, \
NLOHMANN_JSON_PASTE21, \
NLOHMANN_JSON_PASTE20, \
NLOHMANN_JSON_PASTE19, \
NLOHMANN_JSON_PASTE18, \
NLOHMANN_JSON_PASTE17, \
NLOHMANN_JSON_PASTE16, \
NLOHMANN_JSON_PASTE15, \
NLOHMANN_JSON_PASTE14, \
NLOHMANN_JSON_PASTE13, \
NLOHMANN_JSON_PASTE12, \
NLOHMANN_JSON_PASTE11, \
NLOHMANN_JSON_PASTE10, \
NLOHMANN_JSON_PASTE9, \
NLOHMANN_JSON_PASTE8, \
NLOHMANN_JSON_PASTE7, \
NLOHMANN_JSON_PASTE6, \
NLOHMANN_JSON_PASTE5, \
NLOHMANN_JSON_PASTE4, \
NLOHMANN_JSON_PASTE3, \
NLOHMANN_JSON_PASTE2, \
NLOHMANN_JSON_PASTE1)(__VA_ARGS__))
#define NLOHMANN_JSON_EXPAND(x) x
#define NLOHMANN_JSON_GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, NAME, ...) NAME
#define NLOHMANN_JSON_PASTE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_GET_MACRO(__VA_ARGS__, \
NLOHMANN_JSON_PASTE64, \
NLOHMANN_JSON_PASTE63, \
NLOHMANN_JSON_PASTE62, \
NLOHMANN_JSON_PASTE61, \
NLOHMANN_JSON_PASTE60, \
NLOHMANN_JSON_PASTE59, \
NLOHMANN_JSON_PASTE58, \
NLOHMANN_JSON_PASTE57, \
NLOHMANN_JSON_PASTE56, \
NLOHMANN_JSON_PASTE55, \
NLOHMANN_JSON_PASTE54, \
NLOHMANN_JSON_PASTE53, \
NLOHMANN_JSON_PASTE52, \
NLOHMANN_JSON_PASTE51, \
NLOHMANN_JSON_PASTE50, \
NLOHMANN_JSON_PASTE49, \
NLOHMANN_JSON_PASTE48, \
NLOHMANN_JSON_PASTE47, \
NLOHMANN_JSON_PASTE46, \
NLOHMANN_JSON_PASTE45, \
NLOHMANN_JSON_PASTE44, \
NLOHMANN_JSON_PASTE43, \
NLOHMANN_JSON_PASTE42, \
NLOHMANN_JSON_PASTE41, \
NLOHMANN_JSON_PASTE40, \
NLOHMANN_JSON_PASTE39, \
NLOHMANN_JSON_PASTE38, \
NLOHMANN_JSON_PASTE37, \
NLOHMANN_JSON_PASTE36, \
NLOHMANN_JSON_PASTE35, \
NLOHMANN_JSON_PASTE34, \
NLOHMANN_JSON_PASTE33, \
NLOHMANN_JSON_PASTE32, \
NLOHMANN_JSON_PASTE31, \
NLOHMANN_JSON_PASTE30, \
NLOHMANN_JSON_PASTE29, \
NLOHMANN_JSON_PASTE28, \
NLOHMANN_JSON_PASTE27, \
NLOHMANN_JSON_PASTE26, \
NLOHMANN_JSON_PASTE25, \
NLOHMANN_JSON_PASTE24, \
NLOHMANN_JSON_PASTE23, \
NLOHMANN_JSON_PASTE22, \
NLOHMANN_JSON_PASTE21, \
NLOHMANN_JSON_PASTE20, \
NLOHMANN_JSON_PASTE19, \
NLOHMANN_JSON_PASTE18, \
NLOHMANN_JSON_PASTE17, \
NLOHMANN_JSON_PASTE16, \
NLOHMANN_JSON_PASTE15, \
NLOHMANN_JSON_PASTE14, \
NLOHMANN_JSON_PASTE13, \
NLOHMANN_JSON_PASTE12, \
NLOHMANN_JSON_PASTE11, \
NLOHMANN_JSON_PASTE10, \
NLOHMANN_JSON_PASTE9, \
NLOHMANN_JSON_PASTE8, \
NLOHMANN_JSON_PASTE7, \
NLOHMANN_JSON_PASTE6, \
NLOHMANN_JSON_PASTE5, \
NLOHMANN_JSON_PASTE4, \
NLOHMANN_JSON_PASTE3, \
NLOHMANN_JSON_PASTE2, \
NLOHMANN_JSON_PASTE1)(__VA_ARGS__))
#define NLOHMANN_JSON_PASTE2(func, v1) func(v1)
#define NLOHMANN_JSON_PASTE3(func, v1, v2) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE2(func, v2)
#define NLOHMANN_JSON_PASTE4(func, v1, v2, v3) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE3(func, v2, v3)
@@ -398,32 +397,64 @@
@def NLOHMANN_DEFINE_TYPE_INTRUSIVE
@since version 3.9.0
*/
#define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...) \
friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
#define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...) \
friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) \
{ \
NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) \
} \
friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) \
{ \
NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) \
}
#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Type, ...) \
friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) }
#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Type, ...) \
friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) \
{ \
NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) \
} \
friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) \
{ \
const Type nlohmann_json_default_obj{}; \
NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) \
}
#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE(Type, ...) \
friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) }
#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE(Type, ...) \
friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) \
{ \
NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) \
}
/*!
@brief macro
@def NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE
@since version 3.9.0
*/
#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...) \
inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...) \
inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) \
{ \
NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) \
} \
inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) \
{ \
NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) \
}
#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE(Type, ...) \
inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) }
#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE(Type, ...) \
inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) \
{ \
NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) \
}
#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(Type, ...) \
inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) }
#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(Type, ...) \
inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) \
{ \
NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) \
} \
inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) \
{ \
const Type nlohmann_json_default_obj{}; \
NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) \
}
// inspired from https://stackoverflow.com/a/26745591
// allows to call any std function as if (e.g. with begin):
@@ -434,30 +465,30 @@
#define NLOHMANN_CAN_CALL_STD_FUNC_IMPL(std_name) \
namespace detail { \
using std::std_name; \
\
\
template<typename... T> \
using result_of_##std_name = decltype(std_name(std::declval<T>()...)); \
} \
\
\
namespace detail2 { \
struct std_name##_tag \
{ \
}; \
\
\
template<typename... T> \
std_name##_tag std_name(T&&...); \
\
\
template<typename... T> \
using result_of_##std_name = decltype(std_name(std::declval<T>()...)); \
\
\
template<typename... T> \
struct would_call_std_##std_name \
{ \
static constexpr auto const value = ::nlohmann::detail:: \
is_detected_exact<std_name##_tag, result_of_##std_name, T...>::value; \
is_detected_exact<std_name##_tag, result_of_##std_name, T...>::value; \
}; \
} /* namespace detail2 */ \
\
} /* namespace detail2 */ \
\
template<typename... T> \
struct would_call_std_##std_name : detail2::would_call_std_##std_name<T...> \
{ \

View File

@@ -9,16 +9,15 @@
#pragma once
#include <array> // array
#include <cstddef> // size_t
#include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type
#include <utility> // index_sequence, make_index_sequence, index_sequence_for
#include <array> // array
#include <cstddef> // size_t
#include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type
#include <utility> // index_sequence, make_index_sequence, index_sequence_for
#include <nlohmann/detail/macro_scope.hpp>
NLOHMANN_JSON_NAMESPACE_BEGIN
namespace detail
{
namespace detail {
template<typename T>
using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
@@ -28,8 +27,8 @@ using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::typ
// the following utilities are natively available in C++14
using std::enable_if_t;
using std::index_sequence;
using std::make_index_sequence;
using std::index_sequence_for;
using std::make_index_sequence;
#else
@@ -61,7 +60,7 @@ using enable_if_t = typename std::enable_if<B, T>::type;
// // will be deduced to `0, 1, 2, 3, 4`.
// user_function(make_integer_sequence<int, 5>());
// }
template <typename T, T... Ints>
template<typename T, T... Ints>
struct integer_sequence
{
using value_type = T;
@@ -76,38 +75,37 @@ struct integer_sequence
// A helper template for an `integer_sequence` of `size_t`,
// `absl::index_sequence` is designed to be a drop-in replacement for C++14's
// `std::index_sequence`.
template <size_t... Ints>
template<size_t... Ints>
using index_sequence = integer_sequence<size_t, Ints...>;
namespace utility_internal
{
namespace utility_internal {
template <typename Seq, size_t SeqSize, size_t Rem>
template<typename Seq, size_t SeqSize, size_t Rem>
struct Extend;
// Note that SeqSize == sizeof...(Ints). It's passed explicitly for efficiency.
template <typename T, T... Ints, size_t SeqSize>
template<typename T, T... Ints, size_t SeqSize>
struct Extend<integer_sequence<T, Ints...>, SeqSize, 0>
{
using type = integer_sequence < T, Ints..., (Ints + SeqSize)... >;
using type = integer_sequence<T, Ints..., (Ints + SeqSize)...>;
};
template <typename T, T... Ints, size_t SeqSize>
template<typename T, T... Ints, size_t SeqSize>
struct Extend<integer_sequence<T, Ints...>, SeqSize, 1>
{
using type = integer_sequence < T, Ints..., (Ints + SeqSize)..., 2 * SeqSize >;
using type = integer_sequence<T, Ints..., (Ints + SeqSize)..., 2 * SeqSize>;
};
// Recursion helper for 'make_integer_sequence<T, N>'.
// 'Gen<T, N>::type' is an alias for 'integer_sequence<T, 0, 1, ... N-1>'.
template <typename T, size_t N>
template<typename T, size_t N>
struct Gen
{
using type =
typename Extend < typename Gen < T, N / 2 >::type, N / 2, N % 2 >::type;
typename Extend<typename Gen<T, N / 2>::type, N / 2, N % 2>::type;
};
template <typename T>
template<typename T>
struct Gen<T, 0>
{
using type = integer_sequence<T>;
@@ -122,7 +120,7 @@ struct Gen<T, 0>
// This template alias is equivalent to
// `integer_sequence<int, 0, 1, ..., N-1>`, and is designed to be a drop-in
// replacement for C++14's `std::make_integer_sequence`.
template <typename T, T N>
template<typename T, T N>
using make_integer_sequence = typename utility_internal::Gen<T, N>::type;
// make_index_sequence
@@ -130,7 +128,7 @@ using make_integer_sequence = typename utility_internal::Gen<T, N>::type;
// This template alias is equivalent to `index_sequence<0, 1, ..., N-1>`,
// and is designed to be a drop-in replacement for C++14's
// `std::make_index_sequence`.
template <size_t N>
template<size_t N>
using make_index_sequence = make_integer_sequence<size_t, N>;
// index_sequence_for
@@ -138,7 +136,7 @@ using make_index_sequence = make_integer_sequence<size_t, N>;
// Converts a typename pack into an index sequence of the same length, and
// is designed to be a drop-in replacement for C++14's
// `std::index_sequence_for()`
template <typename... Ts>
template<typename... Ts>
using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
//// END OF CODE FROM GOOGLE ABSEIL
@@ -146,8 +144,12 @@ using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
#endif
// dispatch utility (taken from ranges-v3)
template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
template<> struct priority_tag<0> {};
template<unsigned N>
struct priority_tag : priority_tag<N - 1>
{};
template<>
struct priority_tag<0>
{};
// taken from ranges-v3
template<typename T>
@@ -157,14 +159,14 @@ struct static_const
};
#ifndef JSON_HAS_CPP_17
template<typename T>
constexpr T static_const<T>::value;
template<typename T>
constexpr T static_const<T>::value;
#endif
template<typename T, typename... Args>
inline constexpr std::array<T, sizeof...(Args)> make_array(Args&& ... args)
inline constexpr std::array<T, sizeof...(Args)> make_array(Args&&... args)
{
return std::array<T, sizeof...(Args)> {{static_cast<T>(std::forward<Args>(args))...}};
return std::array<T, sizeof...(Args)>{{static_cast<T>(std::forward<Args>(args))...}};
}
} // namespace detail

View File

@@ -13,8 +13,7 @@
#include <nlohmann/detail/meta/void_t.hpp>
NLOHMANN_JSON_NAMESPACE_BEGIN
namespace detail
{
namespace detail {
// https://en.cppreference.com/w/cpp/experimental/is_detected
struct nonesuch
@@ -29,7 +28,8 @@ struct nonesuch
template<class Default,
class AlwaysVoid,
template<class...> class Op,
template<class...>
class Op,
class... Args>
struct detector
{
@@ -48,7 +48,8 @@ template<template<class...> class Op, class... Args>
using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;
template<template<class...> class Op, class... Args>
struct is_detected_lazy : is_detected<Op, Args...> { };
struct is_detected_lazy : is_detected<Op, Args...>
{};
template<template<class...> class Op, class... Args>
using detected_t = typename detector<nonesuch, void, Op, Args...>::type;

View File

@@ -11,11 +11,12 @@
#include <nlohmann/detail/abi_macros.hpp>
NLOHMANN_JSON_NAMESPACE_BEGIN
namespace detail
{
namespace detail {
// dispatching helper struct
template <class T> struct identity_tag {};
template<class T>
struct identity_tag
{};
} // namespace detail
NLOHMANN_JSON_NAMESPACE_END

View File

@@ -8,17 +8,16 @@
#pragma once
#include <cstdint> // size_t
#include <utility> // declval
#include <string> // string
#include <cstdint> // size_t
#include <string> // string
#include <utility> // declval
#include <nlohmann/detail/abi_macros.hpp>
#include <nlohmann/detail/meta/detected.hpp>
#include <nlohmann/detail/meta/type_traits.hpp>
NLOHMANN_JSON_NAMESPACE_BEGIN
namespace detail
{
namespace detail {
template<typename T>
using null_function_t = decltype(std::declval<T&>().null());
@@ -37,7 +36,8 @@ using number_unsigned_function_t =
template<typename T, typename Float, typename String>
using number_float_function_t = decltype(std::declval<T&>().number_float(
std::declval<Float>(), std::declval<const String&>()));
std::declval<Float>(),
std::declval<const String&>()));
template<typename T, typename String>
using string_function_t =
@@ -67,8 +67,9 @@ using end_array_function_t = decltype(std::declval<T&>().end_array());
template<typename T, typename Exception>
using parse_error_function_t = decltype(std::declval<T&>().parse_error(
std::declval<std::size_t>(), std::declval<const std::string&>(),
std::declval<const Exception&>()));
std::declval<std::size_t>(),
std::declval<const std::string&>(),
std::declval<const Exception&>()));
template<typename SAX, typename BasicJsonType>
struct is_sax
@@ -123,15 +124,12 @@ struct is_sax_static_asserts
static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
"Missing/invalid function: bool boolean(bool)");
static_assert(
is_detected_exact<bool, number_integer_function_t, SAX,
number_integer_t>::value,
is_detected_exact<bool, number_integer_function_t, SAX, number_integer_t>::value,
"Missing/invalid function: bool number_integer(number_integer_t)");
static_assert(
is_detected_exact<bool, number_unsigned_function_t, SAX,
number_unsigned_t>::value,
is_detected_exact<bool, number_unsigned_function_t, SAX, number_unsigned_t>::value,
"Missing/invalid function: bool number_unsigned(number_unsigned_t)");
static_assert(is_detected_exact<bool, number_float_function_t, SAX,
number_float_t, string_t>::value,
static_assert(is_detected_exact<bool, number_float_function_t, SAX, number_float_t, string_t>::value,
"Missing/invalid function: bool number_float(number_float_t, const string_t&)");
static_assert(
is_detected_exact<bool, string_function_t, SAX, string_t>::value,

View File

@@ -11,18 +11,16 @@
#include <nlohmann/detail/macro_scope.hpp>
#if JSON_HAS_EXPERIMENTAL_FILESYSTEM
#include <experimental/filesystem>
#include <experimental/filesystem>
NLOHMANN_JSON_NAMESPACE_BEGIN
namespace detail
{
namespace detail {
namespace std_fs = std::experimental::filesystem;
} // namespace detail
NLOHMANN_JSON_NAMESPACE_END
#elif JSON_HAS_FILESYSTEM
#include <filesystem>
#include <filesystem>
NLOHMANN_JSON_NAMESPACE_BEGIN
namespace detail
{
namespace detail {
namespace std_fs = std::filesystem;
} // namespace detail
NLOHMANN_JSON_NAMESPACE_END

View File

@@ -8,11 +8,11 @@
#pragma once
#include <limits> // numeric_limits
#include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
#include <utility> // declval
#include <tuple> // tuple
#include <string> // char_traits
#include <limits> // numeric_limits
#include <string> // char_traits
#include <tuple> // tuple
#include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
#include <utility> // declval
#include <nlohmann/detail/iterators/iterator_traits.hpp>
#include <nlohmann/detail/macro_scope.hpp>
@@ -31,8 +31,7 @@ implementations of some @ref basic_json methods, and meta-programming helpers.
@since version 2.1.0
*/
namespace detail
{
namespace detail {
/////////////
// helpers //
@@ -47,19 +46,20 @@ namespace detail
// In this case, T has to be properly CV-qualified to constraint the function arguments
// (e.g. to_json(BasicJsonType&, const T&))
template<typename> struct is_basic_json : std::false_type {};
template<typename>
struct is_basic_json : std::false_type
{};
NLOHMANN_BASIC_JSON_TPL_DECLARATION
struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type
{};
// used by exceptions create() member functions
// true_type for pointer to possibly cv-qualified basic_json or std::nullptr_t
// false_type otherwise
template<typename BasicJsonContext>
struct is_basic_json_context :
std::integral_constant < bool,
is_basic_json<typename std::remove_cv<typename std::remove_pointer<BasicJsonContext>::type>::type>::value
|| std::is_same<BasicJsonContext, std::nullptr_t>::value >
struct is_basic_json_context : std::integral_constant<bool,
is_basic_json<typename std::remove_cv<typename std::remove_pointer<BasicJsonContext>::type>::type>::value || std::is_same<BasicJsonContext, std::nullptr_t>::value>
{};
//////////////////////
@@ -70,10 +70,12 @@ template<typename>
class json_ref;
template<typename>
struct is_json_ref : std::false_type {};
struct is_json_ref : std::false_type
{};
template<typename T>
struct is_json_ref<json_ref<T>> : std::true_type {};
struct is_json_ref<json_ref<T>> : std::true_type
{};
//////////////////////////
// aliases for detected //
@@ -111,63 +113,64 @@ using get_template_function = decltype(std::declval<T>().template get<U>());
// trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
template<typename BasicJsonType, typename T, typename = void>
struct has_from_json : std::false_type {};
struct has_from_json : std::false_type
{};
// trait checking if j.get<T> is valid
// use this trait instead of std::is_constructible or std::is_convertible,
// both rely on, or make use of implicit conversions, and thus fail when T
// has several constructors/operator= (see https://github.com/nlohmann/json/issues/958)
template <typename BasicJsonType, typename T>
template<typename BasicJsonType, typename T>
struct is_getable
{
static constexpr bool value = is_detected<get_template_function, const BasicJsonType&, T>::value;
};
template<typename BasicJsonType, typename T>
struct has_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
struct has_from_json<BasicJsonType, T, enable_if_t<!is_basic_json<T>::value>>
{
using serializer = typename BasicJsonType::template json_serializer<T, void>;
static constexpr bool value =
is_detected_exact<void, from_json_function, serializer,
const BasicJsonType&, T&>::value;
is_detected_exact<void, from_json_function, serializer, const BasicJsonType&, T&>::value;
};
// This trait checks if JSONSerializer<T>::from_json(json const&) exists
// this overload is used for non-default-constructible user-defined-types
template<typename BasicJsonType, typename T, typename = void>
struct has_non_default_from_json : std::false_type {};
struct has_non_default_from_json : std::false_type
{};
template<typename BasicJsonType, typename T>
struct has_non_default_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
struct has_non_default_from_json<BasicJsonType, T, enable_if_t<!is_basic_json<T>::value>>
{
using serializer = typename BasicJsonType::template json_serializer<T, void>;
static constexpr bool value =
is_detected_exact<T, from_json_function, serializer,
const BasicJsonType&>::value;
is_detected_exact<T, from_json_function, serializer, const BasicJsonType&>::value;
};
// This trait checks if BasicJsonType::json_serializer<T>::to_json exists
// Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion.
template<typename BasicJsonType, typename T, typename = void>
struct has_to_json : std::false_type {};
struct has_to_json : std::false_type
{};
template<typename BasicJsonType, typename T>
struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
struct has_to_json<BasicJsonType, T, enable_if_t<!is_basic_json<T>::value>>
{
using serializer = typename BasicJsonType::template json_serializer<T, void>;
static constexpr bool value =
is_detected_exact<void, to_json_function, serializer, BasicJsonType&,
T>::value;
is_detected_exact<void, to_json_function, serializer, BasicJsonType&, T>::value;
};
template<typename T>
using detect_key_compare = typename T::key_compare;
template<typename T>
struct has_key_compare : std::integral_constant<bool, is_detected<detect_key_compare, T>::value> {};
struct has_key_compare : std::integral_constant<bool, is_detected<detect_key_compare, T>::value>
{};
// obtains the actual object key comparator
template<typename BasicJsonType>
@@ -175,8 +178,9 @@ struct actual_object_comparator
{
using object_t = typename BasicJsonType::object_t;
using object_comparator_t = typename BasicJsonType::default_object_comparator_t;
using type = typename std::conditional < has_key_compare<object_t>::value,
typename object_t::key_compare, object_comparator_t>::type;
using type = typename std::conditional<has_key_compare<object_t>::value,
typename object_t::key_compare,
object_comparator_t>::type;
};
template<typename BasicJsonType>
@@ -244,54 +248,72 @@ struct char_traits<signed char> : std::char_traits<char>
///////////////////
// https://en.cppreference.com/w/cpp/types/conjunction
template<class...> struct conjunction : std::true_type { };
template<class B> struct conjunction<B> : B { };
template<class...>
struct conjunction : std::true_type
{};
template<class B>
struct conjunction<B> : B
{};
template<class B, class... Bn>
struct conjunction<B, Bn...>
: std::conditional<static_cast<bool>(B::value), conjunction<Bn...>, B>::type {};
: std::conditional<static_cast<bool>(B::value), conjunction<Bn...>, B>::type
{};
// https://en.cppreference.com/w/cpp/types/negation
template<class B> struct negation : std::integral_constant < bool, !B::value > { };
template<class B>
struct negation : std::integral_constant<bool, !B::value>
{};
// Reimplementation of is_constructible and is_default_constructible, due to them being broken for
// std::pair and std::tuple until LWG 2367 fix (see https://cplusplus.github.io/LWG/lwg-defects.html#2367).
// This causes compile errors in e.g. clang 3.5 or gcc 4.9.
template <typename T>
struct is_default_constructible : std::is_default_constructible<T> {};
template<typename T>
struct is_default_constructible : std::is_default_constructible<T>
{};
template <typename T1, typename T2>
template<typename T1, typename T2>
struct is_default_constructible<std::pair<T1, T2>>
: conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
: conjunction<is_default_constructible<T1>, is_default_constructible<T2>>
{};
template <typename T1, typename T2>
template<typename T1, typename T2>
struct is_default_constructible<const std::pair<T1, T2>>
: conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
: conjunction<is_default_constructible<T1>, is_default_constructible<T2>>
{};
template <typename... Ts>
template<typename... Ts>
struct is_default_constructible<std::tuple<Ts...>>
: conjunction<is_default_constructible<Ts>...> {};
: conjunction<is_default_constructible<Ts>...>
{};
template <typename... Ts>
template<typename... Ts>
struct is_default_constructible<const std::tuple<Ts...>>
: conjunction<is_default_constructible<Ts>...> {};
: conjunction<is_default_constructible<Ts>...>
{};
template <typename T, typename... Args>
struct is_constructible : std::is_constructible<T, Args...> {};
template<typename T, typename... Args>
struct is_constructible : std::is_constructible<T, Args...>
{};
template <typename T1, typename T2>
struct is_constructible<std::pair<T1, T2>> : is_default_constructible<std::pair<T1, T2>> {};
template<typename T1, typename T2>
struct is_constructible<std::pair<T1, T2>> : is_default_constructible<std::pair<T1, T2>>
{};
template <typename T1, typename T2>
struct is_constructible<const std::pair<T1, T2>> : is_default_constructible<const std::pair<T1, T2>> {};
template<typename T1, typename T2>
struct is_constructible<const std::pair<T1, T2>> : is_default_constructible<const std::pair<T1, T2>>
{};
template <typename... Ts>
struct is_constructible<std::tuple<Ts...>> : is_default_constructible<std::tuple<Ts...>> {};
template<typename... Ts>
struct is_constructible<std::tuple<Ts...>> : is_default_constructible<std::tuple<Ts...>>
{};
template <typename... Ts>
struct is_constructible<const std::tuple<Ts...>> : is_default_constructible<const std::tuple<Ts...>> {};
template<typename... Ts>
struct is_constructible<const std::tuple<Ts...>> : is_default_constructible<const std::tuple<Ts...>>
{};
template<typename T, typename = void>
struct is_iterator_traits : std::false_type {};
struct is_iterator_traits : std::false_type
{};
template<typename T>
struct is_iterator_traits<iterator_traits<T>>
@@ -338,44 +360,49 @@ using range_value_t = value_type_t<iterator_traits<iterator_t<T>>>;
// and is written by Xiang Fan who agreed to using it in this library.
template<typename T, typename = void>
struct is_complete_type : std::false_type {};
struct is_complete_type : std::false_type
{};
template<typename T>
struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type
{};
template<typename BasicJsonType, typename CompatibleObjectType,
typename = void>
struct is_compatible_object_type_impl : std::false_type {};
template<typename BasicJsonType, typename CompatibleObjectType, typename = void>
struct is_compatible_object_type_impl : std::false_type
{};
template<typename BasicJsonType, typename CompatibleObjectType>
struct is_compatible_object_type_impl <
BasicJsonType, CompatibleObjectType,
enable_if_t < is_detected<mapped_type_t, CompatibleObjectType>::value&&
is_detected<key_type_t, CompatibleObjectType>::value >>
struct is_compatible_object_type_impl<
BasicJsonType,
CompatibleObjectType,
enable_if_t<is_detected<mapped_type_t, CompatibleObjectType>::value &&
is_detected<key_type_t, CompatibleObjectType>::value>>
{
using object_t = typename BasicJsonType::object_t;
// macOS's is_constructible does not play well with nonesuch...
static constexpr bool value =
is_constructible<typename object_t::key_type,
typename CompatibleObjectType::key_type>::value &&
typename CompatibleObjectType::key_type>::value &&
is_constructible<typename object_t::mapped_type,
typename CompatibleObjectType::mapped_type>::value;
typename CompatibleObjectType::mapped_type>::value;
};
template<typename BasicJsonType, typename CompatibleObjectType>
struct is_compatible_object_type
: is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};
: is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType>
{};
template<typename BasicJsonType, typename ConstructibleObjectType,
typename = void>
struct is_constructible_object_type_impl : std::false_type {};
template<typename BasicJsonType, typename ConstructibleObjectType, typename = void>
struct is_constructible_object_type_impl : std::false_type
{};
template<typename BasicJsonType, typename ConstructibleObjectType>
struct is_constructible_object_type_impl <
BasicJsonType, ConstructibleObjectType,
enable_if_t < is_detected<mapped_type_t, ConstructibleObjectType>::value&&
is_detected<key_type_t, ConstructibleObjectType>::value >>
struct is_constructible_object_type_impl<
BasicJsonType,
ConstructibleObjectType,
enable_if_t<is_detected<mapped_type_t, ConstructibleObjectType>::value &&
is_detected<key_type_t, ConstructibleObjectType>::value>>
{
using object_t = typename BasicJsonType::object_t;
@@ -384,21 +411,22 @@ struct is_constructible_object_type_impl <
(std::is_move_assignable<ConstructibleObjectType>::value ||
std::is_copy_assignable<ConstructibleObjectType>::value) &&
(is_constructible<typename ConstructibleObjectType::key_type,
typename object_t::key_type>::value &&
std::is_same <
typename object_t::mapped_type,
typename ConstructibleObjectType::mapped_type >::value)) ||
typename object_t::key_type>::value &&
std::is_same<
typename object_t::mapped_type,
typename ConstructibleObjectType::mapped_type>::value)) ||
(has_from_json<BasicJsonType,
typename ConstructibleObjectType::mapped_type>::value ||
has_non_default_from_json <
BasicJsonType,
typename ConstructibleObjectType::mapped_type >::value);
typename ConstructibleObjectType::mapped_type>::value ||
has_non_default_from_json<
BasicJsonType,
typename ConstructibleObjectType::mapped_type>::value);
};
template<typename BasicJsonType, typename ConstructibleObjectType>
struct is_constructible_object_type
: is_constructible_object_type_impl<BasicJsonType,
ConstructibleObjectType> {};
: is_constructible_object_type_impl<BasicJsonType,
ConstructibleObjectType>
{};
template<typename BasicJsonType, typename CompatibleStringType>
struct is_compatible_string_type
@@ -418,88 +446,98 @@ struct is_constructible_string_type
#endif
static constexpr auto value =
conjunction <
is_constructible<laundered_type, typename BasicJsonType::string_t>,
is_detected_exact<typename BasicJsonType::string_t::value_type,
value_type_t, laundered_type >>::value;
conjunction<
is_constructible<laundered_type, typename BasicJsonType::string_t>,
is_detected_exact<typename BasicJsonType::string_t::value_type,
value_type_t,
laundered_type>>::value;
};
template<typename BasicJsonType, typename CompatibleArrayType, typename = void>
struct is_compatible_array_type_impl : std::false_type {};
struct is_compatible_array_type_impl : std::false_type
{};
template<typename BasicJsonType, typename CompatibleArrayType>
struct is_compatible_array_type_impl <
BasicJsonType, CompatibleArrayType,
enable_if_t <
is_detected<iterator_t, CompatibleArrayType>::value&&
is_iterator_traits<iterator_traits<detected_t<iterator_t, CompatibleArrayType>>>::value&&
// special case for types like std::filesystem::path whose iterator's value_type are themselves
// c.f. https://github.com/nlohmann/json/pull/3073
!std::is_same<CompatibleArrayType, detected_t<range_value_t, CompatibleArrayType>>::value >>
struct is_compatible_array_type_impl<
BasicJsonType,
CompatibleArrayType,
enable_if_t<
is_detected<iterator_t, CompatibleArrayType>::value &&
is_iterator_traits<iterator_traits<detected_t<iterator_t, CompatibleArrayType>>>::value &&
// special case for types like std::filesystem::path whose iterator's value_type are themselves
// c.f. https://github.com/nlohmann/json/pull/3073
!std::is_same<CompatibleArrayType, detected_t<range_value_t, CompatibleArrayType>>::value>>
{
static constexpr bool value =
is_constructible<BasicJsonType,
range_value_t<CompatibleArrayType>>::value;
range_value_t<CompatibleArrayType>>::value;
};
template<typename BasicJsonType, typename CompatibleArrayType>
struct is_compatible_array_type
: is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {};
: is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType>
{};
template<typename BasicJsonType, typename ConstructibleArrayType, typename = void>
struct is_constructible_array_type_impl : std::false_type {};
struct is_constructible_array_type_impl : std::false_type
{};
template<typename BasicJsonType, typename ConstructibleArrayType>
struct is_constructible_array_type_impl <
BasicJsonType, ConstructibleArrayType,
struct is_constructible_array_type_impl<
BasicJsonType,
ConstructibleArrayType,
enable_if_t<std::is_same<ConstructibleArrayType,
typename BasicJsonType::value_type>::value >>
: std::true_type {};
typename BasicJsonType::value_type>::value>>
: std::true_type
{};
template<typename BasicJsonType, typename ConstructibleArrayType>
struct is_constructible_array_type_impl <
BasicJsonType, ConstructibleArrayType,
enable_if_t < !std::is_same<ConstructibleArrayType,
typename BasicJsonType::value_type>::value&&
!is_compatible_string_type<BasicJsonType, ConstructibleArrayType>::value&&
is_default_constructible<ConstructibleArrayType>::value&&
(std::is_move_assignable<ConstructibleArrayType>::value ||
std::is_copy_assignable<ConstructibleArrayType>::value)&&
is_detected<iterator_t, ConstructibleArrayType>::value&&
is_iterator_traits<iterator_traits<detected_t<iterator_t, ConstructibleArrayType>>>::value&&
is_detected<range_value_t, ConstructibleArrayType>::value&&
// special case for types like std::filesystem::path whose iterator's value_type are themselves
// c.f. https://github.com/nlohmann/json/pull/3073
!std::is_same<ConstructibleArrayType, detected_t<range_value_t, ConstructibleArrayType>>::value&&
is_complete_type <
detected_t<range_value_t, ConstructibleArrayType >>::value >>
struct is_constructible_array_type_impl<
BasicJsonType,
ConstructibleArrayType,
enable_if_t<!std::is_same<ConstructibleArrayType,
typename BasicJsonType::value_type>::value &&
!is_compatible_string_type<BasicJsonType, ConstructibleArrayType>::value &&
is_default_constructible<ConstructibleArrayType>::value &&
(std::is_move_assignable<ConstructibleArrayType>::value ||
std::is_copy_assignable<ConstructibleArrayType>::value) &&
is_detected<iterator_t, ConstructibleArrayType>::value &&
is_iterator_traits<iterator_traits<detected_t<iterator_t, ConstructibleArrayType>>>::value &&
is_detected<range_value_t, ConstructibleArrayType>::value &&
// special case for types like std::filesystem::path whose iterator's value_type are themselves
// c.f. https://github.com/nlohmann/json/pull/3073
!std::is_same<ConstructibleArrayType, detected_t<range_value_t, ConstructibleArrayType>>::value &&
is_complete_type<
detected_t<range_value_t, ConstructibleArrayType>>::value>>
{
using value_type = range_value_t<ConstructibleArrayType>;
static constexpr bool value =
std::is_same<value_type,
typename BasicJsonType::array_t::value_type>::value ||
typename BasicJsonType::array_t::value_type>::value ||
has_from_json<BasicJsonType,
value_type>::value ||
has_non_default_from_json <
BasicJsonType,
value_type >::value;
value_type>::value ||
has_non_default_from_json<
BasicJsonType,
value_type>::value;
};
template<typename BasicJsonType, typename ConstructibleArrayType>
struct is_constructible_array_type
: is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {};
: is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType>
{};
template<typename RealIntegerType, typename CompatibleNumberIntegerType,
typename = void>
struct is_compatible_integer_type_impl : std::false_type {};
template<typename RealIntegerType, typename CompatibleNumberIntegerType, typename = void>
struct is_compatible_integer_type_impl : std::false_type
{};
template<typename RealIntegerType, typename CompatibleNumberIntegerType>
struct is_compatible_integer_type_impl <
RealIntegerType, CompatibleNumberIntegerType,
enable_if_t < std::is_integral<RealIntegerType>::value&&
std::is_integral<CompatibleNumberIntegerType>::value&&
!std::is_same<bool, CompatibleNumberIntegerType>::value >>
struct is_compatible_integer_type_impl<
RealIntegerType,
CompatibleNumberIntegerType,
enable_if_t<std::is_integral<RealIntegerType>::value &&
std::is_integral<CompatibleNumberIntegerType>::value &&
!std::is_same<bool, CompatibleNumberIntegerType>::value>>
{
// is there an assert somewhere on overflows?
using RealLimits = std::numeric_limits<RealIntegerType>;
@@ -507,23 +545,26 @@ struct is_compatible_integer_type_impl <
static constexpr auto value =
is_constructible<RealIntegerType,
CompatibleNumberIntegerType>::value &&
CompatibleNumberIntegerType>::value &&
CompatibleLimits::is_integer &&
RealLimits::is_signed == CompatibleLimits::is_signed;
};
template<typename RealIntegerType, typename CompatibleNumberIntegerType>
struct is_compatible_integer_type
: is_compatible_integer_type_impl<RealIntegerType,
CompatibleNumberIntegerType> {};
: is_compatible_integer_type_impl<RealIntegerType,
CompatibleNumberIntegerType>
{};
template<typename BasicJsonType, typename CompatibleType, typename = void>
struct is_compatible_type_impl: std::false_type {};
struct is_compatible_type_impl : std::false_type
{};
template<typename BasicJsonType, typename CompatibleType>
struct is_compatible_type_impl <
BasicJsonType, CompatibleType,
enable_if_t<is_complete_type<CompatibleType>::value >>
struct is_compatible_type_impl<
BasicJsonType,
CompatibleType,
enable_if_t<is_complete_type<CompatibleType>::value>>
{
static constexpr bool value =
has_to_json<BasicJsonType, CompatibleType>::value;
@@ -531,60 +572,60 @@ struct is_compatible_type_impl <
template<typename BasicJsonType, typename CompatibleType>
struct is_compatible_type
: is_compatible_type_impl<BasicJsonType, CompatibleType> {};
: is_compatible_type_impl<BasicJsonType, CompatibleType>
{};
template<typename T1, typename T2>
struct is_constructible_tuple : std::false_type {};
struct is_constructible_tuple : std::false_type
{};
template<typename T1, typename... Args>
struct is_constructible_tuple<T1, std::tuple<Args...>> : conjunction<is_constructible<T1, Args>...> {};
struct is_constructible_tuple<T1, std::tuple<Args...>> : conjunction<is_constructible<T1, Args>...>
{};
template<typename BasicJsonType, typename T>
struct is_json_iterator_of : std::false_type {};
struct is_json_iterator_of : std::false_type
{};
template<typename BasicJsonType>
struct is_json_iterator_of<BasicJsonType, typename BasicJsonType::iterator> : std::true_type {};
struct is_json_iterator_of<BasicJsonType, typename BasicJsonType::iterator> : std::true_type
{};
template<typename BasicJsonType>
struct is_json_iterator_of<BasicJsonType, typename BasicJsonType::const_iterator> : std::true_type
{};
// checks if a given type T is a template specialization of Primary
template<template <typename...> class Primary, typename T>
struct is_specialization_of : std::false_type {};
template<template<typename...> class Primary, typename T>
struct is_specialization_of : std::false_type
{};
template<template <typename...> class Primary, typename... Args>
struct is_specialization_of<Primary, Primary<Args...>> : std::true_type {};
template<template<typename...> class Primary, typename... Args>
struct is_specialization_of<Primary, Primary<Args...>> : std::true_type
{};
template<typename T>
using is_json_pointer = is_specialization_of<::nlohmann::json_pointer, uncvref_t<T>>;
// checks if A and B are comparable using Compare functor
template<typename Compare, typename A, typename B, typename = void>
struct is_comparable : std::false_type {};
struct is_comparable : std::false_type
{};
template<typename Compare, typename A, typename B>
struct is_comparable<Compare, A, B, void_t<
decltype(std::declval<Compare>()(std::declval<A>(), std::declval<B>())),
decltype(std::declval<Compare>()(std::declval<B>(), std::declval<A>()))
>> : std::true_type {};
struct is_comparable<Compare, A, B, void_t<decltype(std::declval<Compare>()(std::declval<A>(), std::declval<B>())), decltype(std::declval<Compare>()(std::declval<B>(), std::declval<A>()))>> : std::true_type
{};
template<typename T>
using detect_is_transparent = typename T::is_transparent;
// type trait to check if KeyType can be used as object key (without a BasicJsonType)
// see is_usable_as_basic_json_key_type below
template<typename Comparator, typename ObjectKeyType, typename KeyTypeCVRef, bool RequireTransparentComparator = true,
bool ExcludeObjectKeyType = RequireTransparentComparator, typename KeyType = uncvref_t<KeyTypeCVRef>>
using is_usable_as_key_type = typename std::conditional <
is_comparable<Comparator, ObjectKeyType, KeyTypeCVRef>::value
&& !(ExcludeObjectKeyType && std::is_same<KeyType,
ObjectKeyType>::value)
&& (!RequireTransparentComparator
|| is_detected <detect_is_transparent, Comparator>::value)
&& !is_json_pointer<KeyType>::value,
std::true_type,
std::false_type >::type;
template<typename Comparator, typename ObjectKeyType, typename KeyTypeCVRef, bool RequireTransparentComparator = true, bool ExcludeObjectKeyType = RequireTransparentComparator, typename KeyType = uncvref_t<KeyTypeCVRef>>
using is_usable_as_key_type = typename std::conditional<
is_comparable<Comparator, ObjectKeyType, KeyTypeCVRef>::value && !(ExcludeObjectKeyType && std::is_same<KeyType, ObjectKeyType>::value) && (!RequireTransparentComparator || is_detected<detect_is_transparent, Comparator>::value) && !is_json_pointer<KeyType>::value,
std::true_type,
std::false_type>::type;
// type trait to check if KeyType can be used as object key
// true if:
@@ -592,48 +633,55 @@ using is_usable_as_key_type = typename std::conditional <
// - if ExcludeObjectKeyType is true, KeyType is not BasicJsonType::object_t::key_type
// - the comparator is transparent or RequireTransparentComparator is false
// - KeyType is not a JSON iterator or json_pointer
template<typename BasicJsonType, typename KeyTypeCVRef, bool RequireTransparentComparator = true,
bool ExcludeObjectKeyType = RequireTransparentComparator, typename KeyType = uncvref_t<KeyTypeCVRef>>
using is_usable_as_basic_json_key_type = typename std::conditional <
is_usable_as_key_type<typename BasicJsonType::object_comparator_t,
typename BasicJsonType::object_t::key_type, KeyTypeCVRef,
RequireTransparentComparator, ExcludeObjectKeyType>::value
&& !is_json_iterator_of<BasicJsonType, KeyType>::value,
std::true_type,
std::false_type >::type;
template<typename BasicJsonType, typename KeyTypeCVRef, bool RequireTransparentComparator = true, bool ExcludeObjectKeyType = RequireTransparentComparator, typename KeyType = uncvref_t<KeyTypeCVRef>>
using is_usable_as_basic_json_key_type = typename std::conditional<
is_usable_as_key_type<typename BasicJsonType::object_comparator_t,
typename BasicJsonType::object_t::key_type,
KeyTypeCVRef,
RequireTransparentComparator,
ExcludeObjectKeyType>::value &&
!is_json_iterator_of<BasicJsonType, KeyType>::value,
std::true_type,
std::false_type>::type;
template<typename ObjectType, typename KeyType>
using detect_erase_with_key_type = decltype(std::declval<ObjectType&>().erase(std::declval<KeyType>()));
// type trait to check if object_t has an erase() member functions accepting KeyType
template<typename BasicJsonType, typename KeyType>
using has_erase_with_key_type = typename std::conditional <
is_detected <
detect_erase_with_key_type,
typename BasicJsonType::object_t, KeyType >::value,
std::true_type,
std::false_type >::type;
using has_erase_with_key_type = typename std::conditional<
is_detected<
detect_erase_with_key_type,
typename BasicJsonType::object_t,
KeyType>::value,
std::true_type,
std::false_type>::type;
// a naive helper to check if a type is an ordered_map (exploits the fact that
// ordered_map inherits capacity() from std::vector)
template <typename T>
template<typename T>
struct is_ordered_map
{
using one = char;
struct two
{
char x[2]; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
char x[2]; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
};
template <typename C> static one test( decltype(&C::capacity) ) ;
template <typename C> static two test(...);
template<typename C>
static one test(decltype(&C::capacity));
template<typename C>
static two test(...);
enum { value = sizeof(test<T>(nullptr)) == sizeof(char) }; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
enum
{
value = sizeof(test<T>(nullptr)) == sizeof(char)
}; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
};
// to avoid useless casts (see https://github.com/nlohmann/json/issues/2893#issuecomment-889152324)
template < typename T, typename U, enable_if_t < !std::is_same<T, U>::value, int > = 0 >
template<typename T, typename U, enable_if_t<!std::is_same<T, U>::value, int> = 0>
T conditional_static_cast(U value)
{
return static_cast<T>(value);
@@ -656,17 +704,14 @@ using all_unsigned = conjunction<std::is_unsigned<Types>...>;
// there's a disjunction trait in another PR; replace when merged
template<typename... Types>
using same_sign = std::integral_constant < bool,
all_signed<Types...>::value || all_unsigned<Types...>::value >;
using same_sign = std::integral_constant<bool,
all_signed<Types...>::value || all_unsigned<Types...>::value>;
template<typename OfType, typename T>
using never_out_of_range = std::integral_constant < bool,
(std::is_signed<OfType>::value && (sizeof(T) < sizeof(OfType)))
|| (same_sign<OfType, T>::value && sizeof(OfType) == sizeof(T)) >;
using never_out_of_range = std::integral_constant<bool,
(std::is_signed<OfType>::value && (sizeof(T) < sizeof(OfType))) || (same_sign<OfType, T>::value && sizeof(OfType) == sizeof(T))>;
template<typename OfType, typename T,
bool OfTypeSigned = std::is_signed<OfType>::value,
bool TSigned = std::is_signed<T>::value>
template<typename OfType, typename T, bool OfTypeSigned = std::is_signed<OfType>::value, bool TSigned = std::is_signed<T>::value>
struct value_in_range_of_impl2;
template<typename OfType, typename T>
@@ -705,14 +750,11 @@ struct value_in_range_of_impl2<OfType, T, true, true>
static constexpr bool test(T val)
{
using CommonType = typename std::common_type<OfType, T>::type;
return static_cast<CommonType>(val) >= static_cast<CommonType>((std::numeric_limits<OfType>::min)())
&& static_cast<CommonType>(val) <= static_cast<CommonType>((std::numeric_limits<OfType>::max)());
return static_cast<CommonType>(val) >= static_cast<CommonType>((std::numeric_limits<OfType>::min)()) && static_cast<CommonType>(val) <= static_cast<CommonType>((std::numeric_limits<OfType>::max)());
}
};
template<typename OfType, typename T,
bool NeverOutOfRange = never_out_of_range<OfType, T>::value,
typename = detail::enable_if_t<all_integral<OfType, T>::value>>
template<typename OfType, typename T, bool NeverOutOfRange = never_out_of_range<OfType, T>::value, typename = detail::enable_if_t<all_integral<OfType, T>::value>>
struct value_in_range_of_impl1;
template<typename OfType, typename T>
@@ -746,8 +788,7 @@ using bool_constant = std::integral_constant<bool, Value>;
// is_c_string
///////////////////////////////////////////////////////////////////////////////
namespace impl
{
namespace impl {
template<typename T>
inline constexpr bool is_c_string()
@@ -756,16 +797,15 @@ inline constexpr bool is_c_string()
using TUnCVExt = typename std::remove_cv<TUnExt>::type;
using TUnPtr = typename std::remove_pointer<T>::type;
using TUnCVPtr = typename std::remove_cv<TUnPtr>::type;
return
(std::is_array<T>::value && std::is_same<TUnCVExt, char>::value)
|| (std::is_pointer<T>::value && std::is_same<TUnCVPtr, char>::value);
return (std::is_array<T>::value && std::is_same<TUnCVExt, char>::value) || (std::is_pointer<T>::value && std::is_same<TUnCVPtr, char>::value);
}
} // namespace impl
// checks whether T is a [cv] char */[cv] char[] C string
template<typename T>
struct is_c_string : bool_constant<impl::is_c_string<T>()> {};
struct is_c_string : bool_constant<impl::is_c_string<T>()>
{};
template<typename T>
using is_c_string_uncvref = is_c_string<uncvref_t<T>>;
@@ -774,8 +814,7 @@ using is_c_string_uncvref = is_c_string<uncvref_t<T>>;
// is_transparent
///////////////////////////////////////////////////////////////////////////////
namespace impl
{
namespace impl {
template<typename T>
inline constexpr bool is_transparent()
@@ -787,7 +826,8 @@ inline constexpr bool is_transparent()
// checks whether T has a member named is_transparent
template<typename T>
struct is_transparent : bool_constant<impl::is_transparent<T>()> {};
struct is_transparent : bool_constant<impl::is_transparent<T>()>
{};
///////////////////////////////////////////////////////////////////////////////

View File

@@ -11,14 +11,15 @@
#include <nlohmann/detail/abi_macros.hpp>
NLOHMANN_JSON_NAMESPACE_BEGIN
namespace detail
{
namespace detail {
template<typename ...Ts> struct make_void
template<typename... Ts>
struct make_void
{
using type = void;
};
template<typename ...Ts> using void_t = typename make_void<Ts...>::type;
template<typename... Ts>
using void_t = typename make_void<Ts...>::type;
} // namespace detail
NLOHMANN_JSON_NAMESPACE_END

View File

@@ -8,16 +8,16 @@
#pragma once
#include <algorithm> // reverse
#include <array> // array
#include <map> // map
#include <cmath> // isnan, isinf
#include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
#include <cstring> // memcpy
#include <limits> // numeric_limits
#include <string> // string
#include <utility> // move
#include <vector> // vector
#include <algorithm> // reverse
#include <array> // array
#include <cmath> // isnan, isinf
#include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
#include <cstring> // memcpy
#include <limits> // numeric_limits
#include <map> // map
#include <string> // string
#include <utility> // move
#include <vector> // vector
#include <nlohmann/detail/input/binary_reader.hpp>
#include <nlohmann/detail/macro_scope.hpp>
@@ -25,8 +25,7 @@
#include <nlohmann/detail/string_concat.hpp>
NLOHMANN_JSON_NAMESPACE_BEGIN
namespace detail
{
namespace detail {
///////////////////
// binary writer //
@@ -48,7 +47,8 @@ class binary_writer
@param[in] adapter output adapter to write to
*/
explicit binary_writer(output_adapter_t<CharType> adapter) : oa(std::move(adapter))
explicit binary_writer(output_adapter_t<CharType> adapter)
: oa(std::move(adapter))
{
JSON_ASSERT(oa);
}
@@ -99,8 +99,8 @@ class binary_writer
case value_t::boolean:
{
oa->write_character(j.m_data.m_value.boolean
? to_char_type(0xF5)
: to_char_type(0xF4));
? to_char_type(0xF5)
: to_char_type(0xF4));
break;
}
@@ -414,17 +414,17 @@ class binary_writer
{
switch (j.type())
{
case value_t::null: // nil
case value_t::null: // nil
{
oa->write_character(to_char_type(0xC0));
break;
}
case value_t::boolean: // true and false
case value_t::boolean: // true and false
{
oa->write_character(j.m_data.m_value.boolean
? to_char_type(0xC3)
: to_char_type(0xC2));
? to_char_type(0xC3)
: to_char_type(0xC2));
break;
}
@@ -626,30 +626,29 @@ class binary_writer
switch (N)
{
case 1:
output_type = 0xD4; // fixext 1
output_type = 0xD4; // fixext 1
break;
case 2:
output_type = 0xD5; // fixext 2
output_type = 0xD5; // fixext 2
break;
case 4:
output_type = 0xD6; // fixext 4
output_type = 0xD6; // fixext 4
break;
case 8:
output_type = 0xD7; // fixext 8
output_type = 0xD7; // fixext 8
break;
case 16:
output_type = 0xD8; // fixext 16
output_type = 0xD8; // fixext 16
break;
default:
output_type = 0xC7; // ext 8
output_type = 0xC7; // ext 8
fixed = false;
break;
}
}
else
{
output_type = 0xC4; // bin 8
output_type = 0xC4; // bin 8
fixed = false;
}
@@ -662,8 +661,8 @@ class binary_writer
else if (N <= (std::numeric_limits<std::uint16_t>::max)())
{
const std::uint8_t output_type = use_ext
? 0xC8 // ext 16
: 0xC5; // bin 16
? 0xC8 // ext 16
: 0xC5; // bin 16
oa->write_character(to_char_type(output_type));
write_number(static_cast<std::uint16_t>(N));
@@ -671,8 +670,8 @@ class binary_writer
else if (N <= (std::numeric_limits<std::uint32_t>::max)())
{
const std::uint8_t output_type = use_ext
? 0xC9 // ext 32
: 0xC6; // bin 32
? 0xC9 // ext 32
: 0xC6; // bin 32
oa->write_character(to_char_type(output_type));
write_number(static_cast<std::uint32_t>(N));
@@ -736,9 +735,7 @@ class binary_writer
@param[in] add_prefix whether prefixes need to be used for this value
@param[in] use_bjdata whether write in BJData format, default is false
*/
void write_ubjson(const BasicJsonType& j, const bool use_count,
const bool use_type, const bool add_prefix = true,
const bool use_bjdata = false)
void write_ubjson(const BasicJsonType& j, const bool use_count, const bool use_type, const bool add_prefix = true, const bool use_bjdata = false)
{
switch (j.type())
{
@@ -756,8 +753,8 @@ class binary_writer
if (add_prefix)
{
oa->write_character(j.m_data.m_value.boolean
? to_char_type('T')
: to_char_type('F'));
? to_char_type('T')
: to_char_type('F'));
}
break;
}
@@ -805,13 +802,11 @@ class binary_writer
{
JSON_ASSERT(use_count);
const CharType first_prefix = ubjson_prefix(j.front(), use_bjdata);
const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
[this, first_prefix, use_bjdata](const BasicJsonType & v)
{
const bool same_prefix = std::all_of(j.begin() + 1, j.end(), [this, first_prefix, use_bjdata](const BasicJsonType& v) {
return ubjson_prefix(v, use_bjdata) == first_prefix;
});
std::vector<CharType> bjdx = {'[', '{', 'S', 'H', 'T', 'F', 'N', 'Z'}; // excluded markers in bjdata optimized type
std::vector<CharType> bjdx = {'[', '{', 'S', 'H', 'T', 'F', 'N', 'Z'}; // excluded markers in bjdata optimized type
if (same_prefix && !(use_bjdata && std::find(bjdx.begin(), bjdx.end(), first_prefix) != bjdx.end()))
{
@@ -903,13 +898,11 @@ class binary_writer
{
JSON_ASSERT(use_count);
const CharType first_prefix = ubjson_prefix(j.front(), use_bjdata);
const bool same_prefix = std::all_of(j.begin(), j.end(),
[this, first_prefix, use_bjdata](const BasicJsonType & v)
{
const bool same_prefix = std::all_of(j.begin(), j.end(), [this, first_prefix, use_bjdata](const BasicJsonType& v) {
return ubjson_prefix(v, use_bjdata) == first_prefix;
});
std::vector<CharType> bjdx = {'[', '{', 'S', 'H', 'T', 'F', 'N', 'Z'}; // excluded markers in bjdata optimized type
std::vector<CharType> bjdx = {'[', '{', 'S', 'H', 'T', 'F', 'N', 'Z'}; // excluded markers in bjdata optimized type
if (same_prefix && !(use_bjdata && std::find(bjdx.begin(), bjdx.end(), first_prefix) != bjdx.end()))
{
@@ -966,7 +959,7 @@ class binary_writer
static_cast<void>(j);
}
return /*id*/ 1ul + name.size() + /*zero-terminator*/1u;
return /*id*/ 1ul + name.size() + /*zero-terminator*/ 1u;
}
/*!
@@ -975,7 +968,7 @@ class binary_writer
void write_bson_entry_header(const string_t& name,
const std::uint8_t element_type)
{
oa->write_character(to_char_type(element_type)); // boolean
oa->write_character(to_char_type(element_type)); // boolean
oa->write_characters(
reinterpret_cast<const CharType*>(name.c_str()),
name.size() + 1u);
@@ -1037,8 +1030,8 @@ class binary_writer
static std::size_t calc_bson_integer_size(const std::int64_t value)
{
return (std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)()
? sizeof(std::int32_t)
: sizeof(std::int64_t);
? sizeof(std::int32_t)
: sizeof(std::int64_t);
}
/*!
@@ -1049,12 +1042,12 @@ class binary_writer
{
if ((std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)())
{
write_bson_entry_header(name, 0x10); // int32
write_bson_entry_header(name, 0x10); // int32
write_number<std::int32_t>(static_cast<std::int32_t>(value), true);
}
else
{
write_bson_entry_header(name, 0x12); // int64
write_bson_entry_header(name, 0x12); // int64
write_number<std::int64_t>(static_cast<std::int64_t>(value), true);
}
}
@@ -1065,8 +1058,8 @@ class binary_writer
static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
{
return (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
? sizeof(std::int32_t)
: sizeof(std::int64_t);
? sizeof(std::int32_t)
: sizeof(std::int64_t);
}
/*!
@@ -1097,7 +1090,7 @@ class binary_writer
void write_bson_object_entry(const string_t& name,
const typename BasicJsonType::object_t& value)
{
write_bson_entry_header(name, 0x03); // object
write_bson_entry_header(name, 0x03); // object
write_bson_object(value);
}
@@ -1108,8 +1101,7 @@ class binary_writer
{
std::size_t array_index = 0ul;
const std::size_t embedded_document_size = std::accumulate(std::begin(value), std::end(value), static_cast<std::size_t>(0), [&array_index](std::size_t result, const typename BasicJsonType::array_t::value_type & el)
{
const std::size_t embedded_document_size = std::accumulate(std::begin(value), std::end(value), static_cast<std::size_t>(0), [&array_index](std::size_t result, const typename BasicJsonType::array_t::value_type& el) {
return result + calc_bson_element_size(std::to_string(array_index++), el);
});
@@ -1130,7 +1122,7 @@ class binary_writer
void write_bson_array(const string_t& name,
const typename BasicJsonType::array_t& value)
{
write_bson_entry_header(name, 0x04); // array
write_bson_entry_header(name, 0x04); // array
write_number<std::int32_t>(static_cast<std::int32_t>(calc_bson_array_size(value)), true);
std::size_t array_index = 0ul;
@@ -1162,7 +1154,7 @@ class binary_writer
@return The calculated size for the BSON document entry for @a j with the given @a name.
*/
static std::size_t calc_bson_element_size(const string_t& name,
const BasicJsonType& j)
const BasicJsonType& j)
{
const auto header_size = calc_bson_entry_header_size(name, j);
switch (j.type())
@@ -1197,7 +1189,7 @@ class binary_writer
// LCOV_EXCL_START
case value_t::discarded:
default:
JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
return 0ul;
// LCOV_EXCL_STOP
}
@@ -1244,7 +1236,7 @@ class binary_writer
// LCOV_EXCL_START
case value_t::discarded:
default:
JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
return;
// LCOV_EXCL_STOP
}
@@ -1258,9 +1250,7 @@ class binary_writer
*/
static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t& value)
{
const std::size_t document_size = std::accumulate(value.begin(), value.end(), static_cast<std::size_t>(0),
[](size_t result, const typename BasicJsonType::object_t::value_type & el)
{
const std::size_t document_size = std::accumulate(value.begin(), value.end(), static_cast<std::size_t>(0), [](size_t result, const typename BasicJsonType::object_t::value_type& el) {
return result += calc_bson_element_size(el.first, el.second);
});
@@ -1316,8 +1306,7 @@ class binary_writer
////////////
// UBJSON: write number (floating point)
template<typename NumberType, typename std::enable_if<
std::is_floating_point<NumberType>::value, int>::type = 0>
template<typename NumberType, typename std::enable_if<std::is_floating_point<NumberType>::value, int>::type = 0>
void write_number_with_ubjson_prefix(const NumberType n,
const bool add_prefix,
const bool use_bjdata)
@@ -1330,8 +1319,7 @@ class binary_writer
}
// UBJSON: write number (unsigned integer)
template<typename NumberType, typename std::enable_if<
std::is_unsigned<NumberType>::value, int>::type = 0>
template<typename NumberType, typename std::enable_if<std::is_unsigned<NumberType>::value, int>::type = 0>
void write_number_with_ubjson_prefix(const NumberType n,
const bool add_prefix,
const bool use_bjdata)
@@ -1417,9 +1405,7 @@ class binary_writer
}
// UBJSON: write number (signed integer)
template < typename NumberType, typename std::enable_if <
std::is_signed<NumberType>::value&&
!std::is_floating_point<NumberType>::value, int >::type = 0 >
template<typename NumberType, typename std::enable_if<std::is_signed<NumberType>::value && !std::is_floating_point<NumberType>::value, int>::type = 0>
void write_number_with_ubjson_prefix(const NumberType n,
const bool add_prefix,
const bool use_bjdata)
@@ -1542,7 +1528,7 @@ class binary_writer
return 'L';
}
// anything else is treated as high-precision number
return 'H'; // LCOV_EXCL_LINE
return 'H'; // LCOV_EXCL_LINE
}
case value_t::number_unsigned:
@@ -1580,7 +1566,7 @@ class binary_writer
return 'M';
}
// anything else is treated as high-precision number
return 'H'; // LCOV_EXCL_LINE
return 'H'; // LCOV_EXCL_LINE
}
case value_t::number_float:
@@ -1589,7 +1575,7 @@ class binary_writer
case value_t::string:
return 'S';
case value_t::array: // fallthrough
case value_t::array: // fallthrough
case value_t::binary:
return '[';
@@ -1617,9 +1603,7 @@ class binary_writer
*/
bool write_bjdata_ndarray(const typename BasicJsonType::object_t& value, const bool use_count, const bool use_type)
{
std::map<string_t, CharType> bjdtype = {{"uint8", 'U'}, {"int8", 'i'}, {"uint16", 'u'}, {"int16", 'I'},
{"uint32", 'm'}, {"int32", 'l'}, {"uint64", 'M'}, {"int64", 'L'}, {"single", 'd'}, {"double", 'D'}, {"char", 'C'}
};
std::map<string_t, CharType> bjdtype = {{"uint8", 'U'}, {"int8", 'i'}, {"uint16", 'u'}, {"int16", 'I'}, {"uint32", 'm'}, {"int32", 'l'}, {"uint64", 'M'}, {"int64", 'L'}, {"single", 'd'}, {"double", 'D'}, {"char", 'C'}};
string_t key = "_ArrayType_";
auto it = bjdtype.find(static_cast<string_t>(value.at(key)));
@@ -1648,7 +1632,7 @@ class binary_writer
oa->write_character('#');
key = "_ArraySize_";
write_ubjson(value.at(key), use_count, use_type, true, true);
write_ubjson(value.at(key), use_count, use_type, true, true);
key = "_ArrayData_";
if (dtype == 'U' || dtype == 'C')
@@ -1761,27 +1745,27 @@ class binary_writer
void write_compact_float(const number_float_t n, detail::input_format_t format)
{
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
if (static_cast<double>(n) >= static_cast<double>(std::numeric_limits<float>::lowest()) &&
static_cast<double>(n) <= static_cast<double>((std::numeric_limits<float>::max)()) &&
static_cast<double>(static_cast<float>(n)) == static_cast<double>(n))
static_cast<double>(n) <= static_cast<double>((std::numeric_limits<float>::max)()) &&
static_cast<double>(static_cast<float>(n)) == static_cast<double>(n))
{
oa->write_character(format == detail::input_format_t::cbor
? get_cbor_float_prefix(static_cast<float>(n))
: get_msgpack_float_prefix(static_cast<float>(n)));
? get_cbor_float_prefix(static_cast<float>(n))
: get_msgpack_float_prefix(static_cast<float>(n)));
write_number(static_cast<float>(n));
}
else
{
oa->write_character(format == detail::input_format_t::cbor
? get_cbor_float_prefix(n)
: get_msgpack_float_prefix(n));
? get_cbor_float_prefix(n)
: get_msgpack_float_prefix(n));
write_number(n);
}
#ifdef __GNUC__
#pragma GCC diagnostic pop
#pragma GCC diagnostic pop
#endif
}
@@ -1790,15 +1774,15 @@ class binary_writer
// between uint8_t and CharType. In case CharType is not unsigned,
// such a conversion is required to allow values greater than 128.
// See <https://github.com/nlohmann/json/issues/1286> for a discussion.
template < typename C = CharType,
enable_if_t < std::is_signed<C>::value && std::is_signed<char>::value > * = nullptr >
template<typename C = CharType,
enable_if_t<std::is_signed<C>::value && std::is_signed<char>::value>* = nullptr>
static constexpr CharType to_char_type(std::uint8_t x) noexcept
{
return *reinterpret_cast<char*>(&x);
}
template < typename C = CharType,
enable_if_t < std::is_signed<C>::value && std::is_unsigned<char>::value > * = nullptr >
template<typename C = CharType,
enable_if_t<std::is_signed<C>::value && std::is_unsigned<char>::value>* = nullptr>
static CharType to_char_type(std::uint8_t x) noexcept
{
static_assert(sizeof(std::uint8_t) == sizeof(CharType), "size of CharType must be equal to std::uint8_t");
@@ -1815,12 +1799,7 @@ class binary_writer
return x;
}
template < typename InputCharType, typename C = CharType,
enable_if_t <
std::is_signed<C>::value &&
std::is_signed<char>::value &&
std::is_same<char, typename std::remove_cv<InputCharType>::type>::value
> * = nullptr >
template<typename InputCharType, typename C = CharType, enable_if_t<std::is_signed<C>::value && std::is_signed<char>::value && std::is_same<char, typename std::remove_cv<InputCharType>::type>::value>* = nullptr>
static constexpr CharType to_char_type(InputCharType x) noexcept
{
return x;

View File

@@ -8,26 +8,26 @@
#pragma once
#include <algorithm> // copy
#include <cstddef> // size_t
#include <iterator> // back_inserter
#include <memory> // shared_ptr, make_shared
#include <string> // basic_string
#include <vector> // vector
#include <algorithm> // copy
#include <cstddef> // size_t
#include <iterator> // back_inserter
#include <memory> // shared_ptr, make_shared
#include <string> // basic_string
#include <vector> // vector
#ifndef JSON_NO_IO
#include <ios> // streamsize
#include <ostream> // basic_ostream
#endif // JSON_NO_IO
#endif // JSON_NO_IO
#include <nlohmann/detail/macro_scope.hpp>
NLOHMANN_JSON_NAMESPACE_BEGIN
namespace detail
{
namespace detail {
/// abstract output adapter interface
template<typename CharType> struct output_adapter_protocol
template<typename CharType>
struct output_adapter_protocol
{
virtual void write_character(CharType c) = 0;
virtual void write_characters(const CharType* s, std::size_t length) = 0;
@@ -50,7 +50,7 @@ class output_vector_adapter : public output_adapter_protocol<CharType>
{
public:
explicit output_vector_adapter(std::vector<CharType, AllocatorType>& vec) noexcept
: v(vec)
: v(vec)
{}
void write_character(CharType c) override
@@ -75,7 +75,7 @@ class output_stream_adapter : public output_adapter_protocol<CharType>
{
public:
explicit output_stream_adapter(std::basic_ostream<CharType>& s) noexcept
: stream(s)
: stream(s)
{}
void write_character(CharType c) override
@@ -100,7 +100,7 @@ class output_string_adapter : public output_adapter_protocol<CharType>
{
public:
explicit output_string_adapter(StringType& s) noexcept
: str(s)
: str(s)
{}
void write_character(CharType c) override
@@ -124,15 +124,18 @@ class output_adapter
public:
template<typename AllocatorType = std::allocator<CharType>>
output_adapter(std::vector<CharType, AllocatorType>& vec)
: oa(std::make_shared<output_vector_adapter<CharType, AllocatorType>>(vec)) {}
: oa(std::make_shared<output_vector_adapter<CharType, AllocatorType>>(vec))
{}
#ifndef JSON_NO_IO
output_adapter(std::basic_ostream<CharType>& s)
: oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
: oa(std::make_shared<output_stream_adapter<CharType>>(s))
{}
#endif // JSON_NO_IO
output_adapter(StringType& s)
: oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
: oa(std::make_shared<output_string_adapter<CharType, StringType>>(s))
{}
operator output_adapter_t<CharType>()
{

View File

@@ -9,18 +9,18 @@
#pragma once
#include <algorithm> // reverse, remove, fill, find, none_of
#include <array> // array
#include <clocale> // localeconv, lconv
#include <cmath> // labs, isfinite, isnan, signbit
#include <cstddef> // size_t, ptrdiff_t
#include <cstdint> // uint8_t
#include <cstdio> // snprintf
#include <limits> // numeric_limits
#include <string> // string, char_traits
#include <iomanip> // setfill, setw
#include <type_traits> // is_same
#include <utility> // move
#include <algorithm> // reverse, remove, fill, find, none_of
#include <array> // array
#include <clocale> // localeconv, lconv
#include <cmath> // labs, isfinite, isnan, signbit
#include <cstddef> // size_t, ptrdiff_t
#include <cstdint> // uint8_t
#include <cstdio> // snprintf
#include <iomanip> // setfill, setw
#include <limits> // numeric_limits
#include <string> // string, char_traits
#include <type_traits> // is_same
#include <utility> // move
#include <nlohmann/detail/conversions/to_chars.hpp>
#include <nlohmann/detail/exceptions.hpp>
@@ -32,8 +32,7 @@
#include <nlohmann/detail/value_t.hpp>
NLOHMANN_JSON_NAMESPACE_BEGIN
namespace detail
{
namespace detail {
///////////////////
// serialization //
@@ -42,9 +41,9 @@ namespace detail
/// how to treat decoding errors
enum class error_handler_t
{
strict, ///< throw a type_error exception in case of invalid UTF-8
replace, ///< replace invalid UTF-8 sequences with U+FFFD
ignore ///< ignore invalid UTF-8 sequences
strict, ///< throw a type_error exception in case of invalid UTF-8
replace, ///< replace invalid UTF-8 sequences with U+FFFD
ignore ///< ignore invalid UTF-8 sequences
};
template<typename BasicJsonType>
@@ -64,15 +63,14 @@ class serializer
@param[in] ichar indentation character to use
@param[in] error_handler_ how to react on decoding errors
*/
serializer(output_adapter_t<char> s, const char ichar,
error_handler_t error_handler_ = error_handler_t::strict)
: o(std::move(s))
, loc(std::localeconv())
, thousands_sep(loc->thousands_sep == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->thousands_sep)))
, decimal_point(loc->decimal_point == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->decimal_point)))
, indent_char(ichar)
, indent_string(512, indent_char)
, error_handler(error_handler_)
serializer(output_adapter_t<char> s, const char ichar, error_handler_t error_handler_ = error_handler_t::strict)
: o(std::move(s))
, loc(std::localeconv())
, thousands_sep(loc->thousands_sep == nullptr ? '\0' : std::char_traits<char>::to_char_type(*(loc->thousands_sep)))
, decimal_point(loc->decimal_point == nullptr ? '\0' : std::char_traits<char>::to_char_type(*(loc->decimal_point)))
, indent_char(ichar)
, indent_string(512, indent_char)
, error_handler(error_handler_)
{}
// delete because of pointer members
@@ -206,7 +204,8 @@ class serializer
// first n-1 elements
for (auto i = val.m_data.m_value.array->cbegin();
i != val.m_data.m_value.array->cend() - 1; ++i)
i != val.m_data.m_value.array->cend() - 1;
++i)
{
o->write_characters(indent_string.c_str(), new_indent);
dump(*i, true, ensure_ascii, indent_step, new_indent);
@@ -228,7 +227,8 @@ class serializer
// first n-1 elements
for (auto i = val.m_data.m_value.array->cbegin();
i != val.m_data.m_value.array->cend() - 1; ++i)
i != val.m_data.m_value.array->cend() - 1;
++i)
{
dump(*i, false, ensure_ascii, indent_step, current_indent);
o->write_character(',');
@@ -272,7 +272,8 @@ class serializer
if (!val.m_data.m_value.binary->empty())
{
for (auto i = val.m_data.m_value.binary->cbegin();
i != val.m_data.m_value.binary->cend() - 1; ++i)
i != val.m_data.m_value.binary->cend() - 1;
++i)
{
dump_integer(*i);
o->write_characters(", ", 2);
@@ -303,7 +304,8 @@ class serializer
if (!val.m_data.m_value.binary->empty())
{
for (auto i = val.m_data.m_value.binary->cbegin();
i != val.m_data.m_value.binary->cend() - 1; ++i)
i != val.m_data.m_value.binary->cend() - 1;
++i)
{
dump_integer(*i);
o->write_character(',');
@@ -368,13 +370,13 @@ class serializer
return;
}
default: // LCOV_EXCL_LINE
JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
default: // LCOV_EXCL_LINE
JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
}
}
JSON_PRIVATE_UNLESS_TESTED:
/*!
JSON_PRIVATE_UNLESS_TESTED :
/*!
@brief dump escaped string
Escape a string by replacing certain special characters by a sequence of an
@@ -388,7 +390,8 @@ class serializer
@complexity Linear in the length of string @a s.
*/
void dump_escaped(const string_t& s, const bool ensure_ascii)
void
dump_escaped(const string_t& s, const bool ensure_ascii)
{
std::uint32_t codepoint{};
std::uint8_t state = UTF8_ACCEPT;
@@ -408,49 +411,49 @@ class serializer
{
switch (codepoint)
{
case 0x08: // backspace
case 0x08: // backspace
{
string_buffer[bytes++] = '\\';
string_buffer[bytes++] = 'b';
break;
}
case 0x09: // horizontal tab
case 0x09: // horizontal tab
{
string_buffer[bytes++] = '\\';
string_buffer[bytes++] = 't';
break;
}
case 0x0A: // newline
case 0x0A: // newline
{
string_buffer[bytes++] = '\\';
string_buffer[bytes++] = 'n';
break;
}
case 0x0C: // formfeed
case 0x0C: // formfeed
{
string_buffer[bytes++] = '\\';
string_buffer[bytes++] = 'f';
break;
}
case 0x0D: // carriage return
case 0x0D: // carriage return
{
string_buffer[bytes++] = '\\';
string_buffer[bytes++] = 'r';
break;
}
case 0x22: // quotation mark
case 0x22: // quotation mark
{
string_buffer[bytes++] = '\\';
string_buffer[bytes++] = '\"';
break;
}
case 0x5C: // reverse solidus
case 0x5C: // reverse solidus
{
string_buffer[bytes++] = '\\';
string_buffer[bytes++] = '\\';
@@ -466,16 +469,13 @@ class serializer
if (codepoint <= 0xFFFF)
{
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
static_cast<void>((std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x",
static_cast<std::uint16_t>(codepoint)));
static_cast<void>((std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x", static_cast<std::uint16_t>(codepoint)));
bytes += 6;
}
else
{
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
static_cast<void>((std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x",
static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)),
static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu))));
static_cast<void>((std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x", static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)), static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu))));
bytes += 12;
}
}
@@ -567,8 +567,8 @@ class serializer
break;
}
default: // LCOV_EXCL_LINE
JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
default: // LCOV_EXCL_LINE
JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
}
break;
}
@@ -628,8 +628,8 @@ class serializer
break;
}
default: // LCOV_EXCL_LINE
JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
default: // LCOV_EXCL_LINE
JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
}
}
}
@@ -684,13 +684,13 @@ class serializer
}
// templates to avoid warnings about useless casts
template <typename NumberType, enable_if_t<std::is_signed<NumberType>::value, int> = 0>
template<typename NumberType, enable_if_t<std::is_signed<NumberType>::value, int> = 0>
bool is_negative_number(NumberType x)
{
return x < 0;
}
template < typename NumberType, enable_if_t <std::is_unsigned<NumberType>::value, int > = 0 >
template<typename NumberType, enable_if_t<std::is_unsigned<NumberType>::value, int> = 0>
bool is_negative_number(NumberType /*unused*/)
{
return false;
@@ -705,29 +705,112 @@ class serializer
@param[in] x integer number (signed or unsigned) to dump
@tparam NumberType either @a number_integer_t or @a number_unsigned_t
*/
template < typename NumberType, detail::enable_if_t <
std::is_integral<NumberType>::value ||
std::is_same<NumberType, number_unsigned_t>::value ||
std::is_same<NumberType, number_integer_t>::value ||
std::is_same<NumberType, binary_char_t>::value,
int > = 0 >
template<typename NumberType, detail::enable_if_t<std::is_integral<NumberType>::value || std::is_same<NumberType, number_unsigned_t>::value || std::is_same<NumberType, number_integer_t>::value || std::is_same<NumberType, binary_char_t>::value, int> = 0>
void dump_integer(NumberType x)
{
static constexpr std::array<std::array<char, 2>, 100> digits_to_99
{
static constexpr std::array<std::array<char, 2>, 100> digits_to_99{
{
{{'0', '0'}}, {{'0', '1'}}, {{'0', '2'}}, {{'0', '3'}}, {{'0', '4'}}, {{'0', '5'}}, {{'0', '6'}}, {{'0', '7'}}, {{'0', '8'}}, {{'0', '9'}},
{{'1', '0'}}, {{'1', '1'}}, {{'1', '2'}}, {{'1', '3'}}, {{'1', '4'}}, {{'1', '5'}}, {{'1', '6'}}, {{'1', '7'}}, {{'1', '8'}}, {{'1', '9'}},
{{'2', '0'}}, {{'2', '1'}}, {{'2', '2'}}, {{'2', '3'}}, {{'2', '4'}}, {{'2', '5'}}, {{'2', '6'}}, {{'2', '7'}}, {{'2', '8'}}, {{'2', '9'}},
{{'3', '0'}}, {{'3', '1'}}, {{'3', '2'}}, {{'3', '3'}}, {{'3', '4'}}, {{'3', '5'}}, {{'3', '6'}}, {{'3', '7'}}, {{'3', '8'}}, {{'3', '9'}},
{{'4', '0'}}, {{'4', '1'}}, {{'4', '2'}}, {{'4', '3'}}, {{'4', '4'}}, {{'4', '5'}}, {{'4', '6'}}, {{'4', '7'}}, {{'4', '8'}}, {{'4', '9'}},
{{'5', '0'}}, {{'5', '1'}}, {{'5', '2'}}, {{'5', '3'}}, {{'5', '4'}}, {{'5', '5'}}, {{'5', '6'}}, {{'5', '7'}}, {{'5', '8'}}, {{'5', '9'}},
{{'6', '0'}}, {{'6', '1'}}, {{'6', '2'}}, {{'6', '3'}}, {{'6', '4'}}, {{'6', '5'}}, {{'6', '6'}}, {{'6', '7'}}, {{'6', '8'}}, {{'6', '9'}},
{{'7', '0'}}, {{'7', '1'}}, {{'7', '2'}}, {{'7', '3'}}, {{'7', '4'}}, {{'7', '5'}}, {{'7', '6'}}, {{'7', '7'}}, {{'7', '8'}}, {{'7', '9'}},
{{'8', '0'}}, {{'8', '1'}}, {{'8', '2'}}, {{'8', '3'}}, {{'8', '4'}}, {{'8', '5'}}, {{'8', '6'}}, {{'8', '7'}}, {{'8', '8'}}, {{'8', '9'}},
{{'9', '0'}}, {{'9', '1'}}, {{'9', '2'}}, {{'9', '3'}}, {{'9', '4'}}, {{'9', '5'}}, {{'9', '6'}}, {{'9', '7'}}, {{'9', '8'}}, {{'9', '9'}},
}
};
{{'0', '0'}},
{{'0', '1'}},
{{'0', '2'}},
{{'0', '3'}},
{{'0', '4'}},
{{'0', '5'}},
{{'0', '6'}},
{{'0', '7'}},
{{'0', '8'}},
{{'0', '9'}},
{{'1', '0'}},
{{'1', '1'}},
{{'1', '2'}},
{{'1', '3'}},
{{'1', '4'}},
{{'1', '5'}},
{{'1', '6'}},
{{'1', '7'}},
{{'1', '8'}},
{{'1', '9'}},
{{'2', '0'}},
{{'2', '1'}},
{{'2', '2'}},
{{'2', '3'}},
{{'2', '4'}},
{{'2', '5'}},
{{'2', '6'}},
{{'2', '7'}},
{{'2', '8'}},
{{'2', '9'}},
{{'3', '0'}},
{{'3', '1'}},
{{'3', '2'}},
{{'3', '3'}},
{{'3', '4'}},
{{'3', '5'}},
{{'3', '6'}},
{{'3', '7'}},
{{'3', '8'}},
{{'3', '9'}},
{{'4', '0'}},
{{'4', '1'}},
{{'4', '2'}},
{{'4', '3'}},
{{'4', '4'}},
{{'4', '5'}},
{{'4', '6'}},
{{'4', '7'}},
{{'4', '8'}},
{{'4', '9'}},
{{'5', '0'}},
{{'5', '1'}},
{{'5', '2'}},
{{'5', '3'}},
{{'5', '4'}},
{{'5', '5'}},
{{'5', '6'}},
{{'5', '7'}},
{{'5', '8'}},
{{'5', '9'}},
{{'6', '0'}},
{{'6', '1'}},
{{'6', '2'}},
{{'6', '3'}},
{{'6', '4'}},
{{'6', '5'}},
{{'6', '6'}},
{{'6', '7'}},
{{'6', '8'}},
{{'6', '9'}},
{{'7', '0'}},
{{'7', '1'}},
{{'7', '2'}},
{{'7', '3'}},
{{'7', '4'}},
{{'7', '5'}},
{{'7', '6'}},
{{'7', '7'}},
{{'7', '8'}},
{{'7', '9'}},
{{'8', '0'}},
{{'8', '1'}},
{{'8', '2'}},
{{'8', '3'}},
{{'8', '4'}},
{{'8', '5'}},
{{'8', '6'}},
{{'8', '7'}},
{{'8', '8'}},
{{'8', '9'}},
{{'9', '0'}},
{{'9', '1'}},
{{'9', '2'}},
{{'9', '3'}},
{{'9', '4'}},
{{'9', '5'}},
{{'9', '6'}},
{{'9', '7'}},
{{'9', '8'}},
{{'9', '9'}},
}};
// special case for "0"
if (x == 0)
@@ -737,7 +820,7 @@ class serializer
}
// use a pointer to fill the buffer
auto buffer_ptr = number_buffer.begin(); // NOLINT(llvm-qualified-auto,readability-qualified-auto,cppcoreguidelines-pro-type-vararg,hicpp-vararg)
auto buffer_ptr = number_buffer.begin(); // NOLINT(llvm-qualified-auto,readability-qualified-auto,cppcoreguidelines-pro-type-vararg,hicpp-vararg)
number_unsigned_t abs_value;
@@ -810,9 +893,8 @@ class serializer
// guaranteed to round-trip, using strtof and strtod, resp.
//
// NB: The test below works if <long double> == <double>.
static constexpr bool is_ieee_single_or_double
= (std::numeric_limits<number_float_t>::is_iec559 && std::numeric_limits<number_float_t>::digits == 24 && std::numeric_limits<number_float_t>::max_exponent == 128) ||
(std::numeric_limits<number_float_t>::is_iec559 && std::numeric_limits<number_float_t>::digits == 53 && std::numeric_limits<number_float_t>::max_exponent == 1024);
static constexpr bool is_ieee_single_or_double = (std::numeric_limits<number_float_t>::is_iec559 && std::numeric_limits<number_float_t>::digits == 24 && std::numeric_limits<number_float_t>::max_exponent == 128) ||
(std::numeric_limits<number_float_t>::is_iec559 && std::numeric_limits<number_float_t>::digits == 53 && std::numeric_limits<number_float_t>::max_exponent == 1024);
dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
}
@@ -864,11 +946,9 @@ class serializer
// determine if we need to append ".0"
const bool value_is_int_like =
std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
[](char c)
{
return c == '.' || c == 'e';
});
std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1, [](char c) {
return c == '.' || c == 'e';
});
if (value_is_int_like)
{
@@ -900,31 +980,416 @@ class serializer
static std::uint8_t decode(std::uint8_t& state, std::uint32_t& codep, const std::uint8_t byte) noexcept
{
static const std::array<std::uint8_t, 400> utf8d =
{
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 00..1F
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20..3F
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 40..5F
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 60..7F
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // 80..9F
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // A0..BF
8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // C0..DF
0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF
0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF
0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, // s1..s2
1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, // s3..s4
1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, // s5..s6
1, 3, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // s7..s8
}
};
{
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0, // 00..1F
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0, // 20..3F
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0, // 40..5F
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0, // 60..7F
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
9,
9,
9,
9,
9,
9,
9,
9,
9,
9,
9,
9,
9,
9,
9,
9, // 80..9F
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7, // A0..BF
8,
8,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2, // C0..DF
0xA,
0x3,
0x3,
0x3,
0x3,
0x3,
0x3,
0x3,
0x3,
0x3,
0x3,
0x3,
0x3,
0x4,
0x3,
0x3, // E0..EF
0xB,
0x6,
0x6,
0x6,
0x5,
0x8,
0x8,
0x8,
0x8,
0x8,
0x8,
0x8,
0x8,
0x8,
0x8,
0x8, // F0..FF
0x0,
0x1,
0x2,
0x3,
0x5,
0x8,
0x7,
0x1,
0x1,
0x1,
0x4,
0x6,
0x1,
0x1,
0x1,
0x1, // s0..s0
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
0,
1,
1,
1,
1,
1,
0,
1,
0,
1,
1,
1,
1,
1,
1, // s1..s2
1,
2,
1,
1,
1,
1,
1,
2,
1,
2,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
2,
1,
1,
1,
1,
1,
1,
1,
1, // s3..s4
1,
2,
1,
1,
1,
1,
1,
1,
1,
2,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
3,
1,
3,
1,
1,
1,
1,
1,
1, // s5..s6
1,
3,
1,
1,
1,
1,
1,
3,
1,
3,
1,
1,
1,
1,
1,
1,
1,
3,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1 // s7..s8
}};
JSON_ASSERT(byte < utf8d.size());
const std::uint8_t type = utf8d[byte];
codep = (state != UTF8_ACCEPT)
? (byte & 0x3fu) | (codep << 6u)
: (0xFFu >> type) & (byte);
? (byte & 0x3fu) | (codep << 6u)
: (0xFFu >> type) & (byte);
const std::size_t index = 256u + static_cast<size_t>(state) * 16u + static_cast<size_t>(type);
JSON_ASSERT(index < utf8d.size());
@@ -939,8 +1404,8 @@ class serializer
*/
number_unsigned_t remove_sign(number_unsigned_t x)
{
JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
return x; // LCOV_EXCL_LINE
JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
return x; // LCOV_EXCL_LINE
}
/*
@@ -954,7 +1419,7 @@ class serializer
*/
inline number_unsigned_t remove_sign(number_integer_t x) noexcept
{
JSON_ASSERT(x < 0 && x < (std::numeric_limits<number_integer_t>::max)()); // NOLINT(misc-redundant-expression)
JSON_ASSERT(x < 0 && x < (std::numeric_limits<number_integer_t>::max)()); // NOLINT(misc-redundant-expression)
return static_cast<number_unsigned_t>(-(x + 1)) + 1;
}

View File

@@ -8,16 +8,15 @@
#pragma once
#include <cstring> // strlen
#include <string> // string
#include <utility> // forward
#include <cstring> // strlen
#include <string> // string
#include <utility> // forward
#include <nlohmann/detail/meta/cpp_future.hpp>
#include <nlohmann/detail/meta/detected.hpp>
NLOHMANN_JSON_NAMESPACE_BEGIN
namespace detail
{
namespace detail {
inline std::size_t concat_length()
{
@@ -25,26 +24,26 @@ inline std::size_t concat_length()
}
template<typename... Args>
inline std::size_t concat_length(const char* cstr, const Args& ... rest);
inline std::size_t concat_length(const char* cstr, const Args&... rest);
template<typename StringType, typename... Args>
inline std::size_t concat_length(const StringType& str, const Args& ... rest);
inline std::size_t concat_length(const StringType& str, const Args&... rest);
template<typename... Args>
inline std::size_t concat_length(const char /*c*/, const Args& ... rest)
inline std::size_t concat_length(const char /*c*/, const Args&... rest)
{
return 1 + concat_length(rest...);
}
template<typename... Args>
inline std::size_t concat_length(const char* cstr, const Args& ... rest)
inline std::size_t concat_length(const char* cstr, const Args&... rest)
{
// cppcheck-suppress ignoredReturnValue
return ::strlen(cstr) + concat_length(rest...);
}
template<typename StringType, typename... Args>
inline std::size_t concat_length(const StringType& str, const Args& ... rest)
inline std::size_t concat_length(const StringType& str, const Args&... rest)
{
return str.size() + concat_length(rest...);
}
@@ -54,13 +53,13 @@ inline void concat_into(OutStringType& /*out*/)
{}
template<typename StringType, typename Arg>
using string_can_append = decltype(std::declval<StringType&>().append(std::declval < Arg && > ()));
using string_can_append = decltype(std::declval<StringType&>().append(std::declval<Arg&&>()));
template<typename StringType, typename Arg>
using detect_string_can_append = is_detected<string_can_append, StringType, Arg>;
template<typename StringType, typename Arg>
using string_can_append_op = decltype(std::declval<StringType&>() += std::declval < Arg && > ());
using string_can_append_op = decltype(std::declval<StringType&>() += std::declval<Arg&&>());
template<typename StringType, typename Arg>
using detect_string_can_append_op = is_detected<string_can_append_op, StringType, Arg>;
@@ -77,64 +76,45 @@ using string_can_append_data = decltype(std::declval<StringType&>().append(std::
template<typename StringType, typename Arg>
using detect_string_can_append_data = is_detected<string_can_append_data, StringType, Arg>;
template < typename OutStringType, typename Arg, typename... Args,
enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
&& detect_string_can_append_op<OutStringType, Arg>::value, int > = 0 >
inline void concat_into(OutStringType& out, Arg && arg, Args && ... rest);
template<typename OutStringType, typename Arg, typename... Args, enable_if_t<!detect_string_can_append<OutStringType, Arg>::value && detect_string_can_append_op<OutStringType, Arg>::value, int> = 0>
inline void concat_into(OutStringType& out, Arg&& arg, Args&&... rest);
template < typename OutStringType, typename Arg, typename... Args,
enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
&& !detect_string_can_append_op<OutStringType, Arg>::value
&& detect_string_can_append_iter<OutStringType, Arg>::value, int > = 0 >
inline void concat_into(OutStringType& out, const Arg& arg, Args && ... rest);
template<typename OutStringType, typename Arg, typename... Args, enable_if_t<!detect_string_can_append<OutStringType, Arg>::value && !detect_string_can_append_op<OutStringType, Arg>::value && detect_string_can_append_iter<OutStringType, Arg>::value, int> = 0>
inline void concat_into(OutStringType& out, const Arg& arg, Args&&... rest);
template < typename OutStringType, typename Arg, typename... Args,
enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
&& !detect_string_can_append_op<OutStringType, Arg>::value
&& !detect_string_can_append_iter<OutStringType, Arg>::value
&& detect_string_can_append_data<OutStringType, Arg>::value, int > = 0 >
inline void concat_into(OutStringType& out, const Arg& arg, Args && ... rest);
template<typename OutStringType, typename Arg, typename... Args, enable_if_t<!detect_string_can_append<OutStringType, Arg>::value && !detect_string_can_append_op<OutStringType, Arg>::value && !detect_string_can_append_iter<OutStringType, Arg>::value && detect_string_can_append_data<OutStringType, Arg>::value, int> = 0>
inline void concat_into(OutStringType& out, const Arg& arg, Args&&... rest);
template<typename OutStringType, typename Arg, typename... Args,
enable_if_t<detect_string_can_append<OutStringType, Arg>::value, int> = 0>
inline void concat_into(OutStringType& out, Arg && arg, Args && ... rest)
template<typename OutStringType, typename Arg, typename... Args, enable_if_t<detect_string_can_append<OutStringType, Arg>::value, int> = 0>
inline void concat_into(OutStringType& out, Arg&& arg, Args&&... rest)
{
out.append(std::forward<Arg>(arg));
concat_into(out, std::forward<Args>(rest)...);
}
template < typename OutStringType, typename Arg, typename... Args,
enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
&& detect_string_can_append_op<OutStringType, Arg>::value, int > >
inline void concat_into(OutStringType& out, Arg&& arg, Args&& ... rest)
template<typename OutStringType, typename Arg, typename... Args, enable_if_t<!detect_string_can_append<OutStringType, Arg>::value && detect_string_can_append_op<OutStringType, Arg>::value, int>>
inline void concat_into(OutStringType& out, Arg&& arg, Args&&... rest)
{
out += std::forward<Arg>(arg);
concat_into(out, std::forward<Args>(rest)...);
}
template < typename OutStringType, typename Arg, typename... Args,
enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
&& !detect_string_can_append_op<OutStringType, Arg>::value
&& detect_string_can_append_iter<OutStringType, Arg>::value, int > >
inline void concat_into(OutStringType& out, const Arg& arg, Args&& ... rest)
template<typename OutStringType, typename Arg, typename... Args, enable_if_t<!detect_string_can_append<OutStringType, Arg>::value && !detect_string_can_append_op<OutStringType, Arg>::value && detect_string_can_append_iter<OutStringType, Arg>::value, int>>
inline void concat_into(OutStringType& out, const Arg& arg, Args&&... rest)
{
out.append(arg.begin(), arg.end());
concat_into(out, std::forward<Args>(rest)...);
}
template < typename OutStringType, typename Arg, typename... Args,
enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
&& !detect_string_can_append_op<OutStringType, Arg>::value
&& !detect_string_can_append_iter<OutStringType, Arg>::value
&& detect_string_can_append_data<OutStringType, Arg>::value, int > >
inline void concat_into(OutStringType& out, const Arg& arg, Args&& ... rest)
template<typename OutStringType, typename Arg, typename... Args, enable_if_t<!detect_string_can_append<OutStringType, Arg>::value && !detect_string_can_append_op<OutStringType, Arg>::value && !detect_string_can_append_iter<OutStringType, Arg>::value && detect_string_can_append_data<OutStringType, Arg>::value, int>>
inline void concat_into(OutStringType& out, const Arg& arg, Args&&... rest)
{
out.append(arg.data(), arg.size());
concat_into(out, std::forward<Args>(rest)...);
}
template<typename OutStringType = std::string, typename... Args>
inline OutStringType concat(Args && ... args)
inline OutStringType concat(Args&&... args)
{
OutStringType str;
str.reserve(concat_length(args...));

View File

@@ -11,8 +11,7 @@
#include <nlohmann/detail/abi_macros.hpp>
NLOHMANN_JSON_NAMESPACE_BEGIN
namespace detail
{
namespace detail {
/*!
@brief replace all occurrences of a substring by another string
@@ -28,14 +27,13 @@ enforced with an assertion.**
@since version 2.0.0
*/
template<typename StringType>
inline void replace_substring(StringType& s, const StringType& f,
const StringType& t)
inline void replace_substring(StringType& s, const StringType& f, const StringType& t)
{
JSON_ASSERT(!f.empty());
for (auto pos = s.find(f); // find first occurrence of f
pos != StringType::npos; // make sure f was found
s.replace(pos, f.size(), t), // replace with t, and
pos = s.find(f, pos + t.size())) // find next occurrence of f
for (auto pos = s.find(f); // find first occurrence of f
pos != StringType::npos; // make sure f was found
s.replace(pos, f.size(), t), // replace with t, and
pos = s.find(f, pos + t.size())) // find next occurrence of f
{}
}

View File

@@ -8,19 +8,18 @@
#pragma once
#include <array> // array
#include <cstddef> // size_t
#include <cstdint> // uint8_t
#include <string> // string
#include <array> // array
#include <cstddef> // size_t
#include <cstdint> // uint8_t
#include <string> // string
#include <nlohmann/detail/macro_scope.hpp>
#if JSON_HAS_THREE_WAY_COMPARISON
#include <compare> // partial_ordering
#include <compare> // partial_ordering
#endif
NLOHMANN_JSON_NAMESPACE_BEGIN
namespace detail
{
namespace detail {
///////////////////////////
// JSON type enumeration //
@@ -78,24 +77,29 @@ Returns an ordering that is similar to Python:
@since version 1.0.0
*/
#if JSON_HAS_THREE_WAY_COMPARISON
inline std::partial_ordering operator<=>(const value_t lhs, const value_t rhs) noexcept // *NOPAD*
inline std::partial_ordering operator<= > (const value_t lhs, const value_t rhs) noexcept // *NOPAD*
#else
inline bool operator<(const value_t lhs, const value_t rhs) noexcept
inline bool operator<(const value_t lhs, const value_t rhs) noexcept
#endif
{
static constexpr std::array<std::uint8_t, 9> order = {{
0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */,
1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */,
6 /* binary */
}
};
0 /* null */,
3 /* object */,
4 /* array */,
5 /* string */,
1 /* boolean */,
2 /* integer */,
2 /* unsigned */,
2 /* float */,
6 /* binary */
}};
const auto l_index = static_cast<std::size_t>(lhs);
const auto r_index = static_cast<std::size_t>(rhs);
#if JSON_HAS_THREE_WAY_COMPARISON
if (l_index < order.size() && r_index < order.size())
{
return order[l_index] <=> order[r_index]; // *NOPAD*
return order[l_index] <= > order[r_index]; // *NOPAD*
}
return std::partial_ordering::unordered;
#else
@@ -110,7 +114,7 @@ Returns an ordering that is similar to Python:
#if JSON_HAS_THREE_WAY_COMPARISON && defined(__GNUC__)
inline bool operator<(const value_t lhs, const value_t rhs) noexcept
{
return std::is_lt(lhs <=> rhs); // *NOPAD*
return std::is_lt(lhs <= > rhs); // *NOPAD*
}
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -9,11 +9,11 @@
#ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_
#define INCLUDE_NLOHMANN_JSON_FWD_HPP_
#include <cstdint> // int64_t, uint64_t
#include <map> // map
#include <memory> // allocator
#include <string> // string
#include <vector> // vector
#include <cstdint> // int64_t, uint64_t
#include <map> // map
#include <memory> // allocator
#include <string> // string
#include <vector> // vector
#include <nlohmann/detail/abi_macros.hpp>
@@ -37,16 +37,17 @@ struct adl_serializer;
/// a class to store JSON values
/// @sa https://json.nlohmann.me/api/basic_json/
template<template<typename U, typename V, typename... Args> class ObjectType =
std::map,
std::map,
template<typename U, typename... Args> class ArrayType = std::vector,
class StringType = std::string, class BooleanType = bool,
class StringType = std::string,
class BooleanType = bool,
class NumberIntegerType = std::int64_t,
class NumberUnsignedType = std::uint64_t,
class NumberFloatType = double,
template<typename U> class AllocatorType = std::allocator,
template<typename T, typename SFINAE = void> class JSONSerializer =
adl_serializer,
class BinaryType = std::vector<std::uint8_t>, // cppcheck-suppress syntaxError
adl_serializer,
class BinaryType = std::vector<std::uint8_t>, // cppcheck-suppress syntaxError
class CustomBaseClass = void>
class basic_json;

View File

@@ -8,14 +8,14 @@
#pragma once
#include <functional> // equal_to, less
#include <initializer_list> // initializer_list
#include <iterator> // input_iterator_tag, iterator_traits
#include <memory> // allocator
#include <stdexcept> // for out_of_range
#include <type_traits> // enable_if, is_convertible
#include <utility> // pair
#include <vector> // vector
#include <functional> // equal_to, less
#include <initializer_list> // initializer_list
#include <iterator> // input_iterator_tag, iterator_traits
#include <memory> // allocator
#include <stdexcept> // for out_of_range
#include <type_traits> // enable_if, is_convertible
#include <utility> // pair
#include <vector> // vector
#include <nlohmann/detail/macro_scope.hpp>
#include <nlohmann/detail/meta/type_traits.hpp>
@@ -24,9 +24,8 @@ NLOHMANN_JSON_NAMESPACE_BEGIN
/// ordered_map: a minimal map-like container that preserves insertion order
/// for use within nlohmann::basic_json<ordered_map>
template <class Key, class T, class IgnoredLess = std::less<Key>,
class Allocator = std::allocator<std::pair<const Key, T>>>
struct ordered_map : std::vector<std::pair<const Key, T>, Allocator>
template<class Key, class T, class IgnoredLess = std::less<Key>, class Allocator = std::allocator<std::pair<const Key, T>>>
struct ordered_map : std::vector<std::pair<const Key, T>, Allocator>
{
using key_type = Key;
using mapped_type = T;
@@ -43,13 +42,19 @@ template <class Key, class T, class IgnoredLess = std::less<Key>,
// Explicit constructors instead of `using Container::Container`
// otherwise older compilers choke on it (GCC <= 5.5, xcode <= 9.4)
ordered_map() noexcept(noexcept(Container())) : Container{} {}
explicit ordered_map(const Allocator& alloc) noexcept(noexcept(Container(alloc))) : Container{alloc} {}
template <class It>
ordered_map() noexcept(noexcept(Container()))
: Container{}
{}
explicit ordered_map(const Allocator& alloc) noexcept(noexcept(Container(alloc)))
: Container{alloc}
{}
template<class It>
ordered_map(It first, It last, const Allocator& alloc = Allocator())
: Container{first, last, alloc} {}
ordered_map(std::initializer_list<value_type> init, const Allocator& alloc = Allocator() )
: Container{init, alloc} {}
: Container{first, last, alloc}
{}
ordered_map(std::initializer_list<value_type> init, const Allocator& alloc = Allocator())
: Container{init, alloc}
{}
std::pair<iterator, bool> emplace(const key_type& key, T&& t)
{
@@ -64,9 +69,8 @@ template <class Key, class T, class IgnoredLess = std::less<Key>,
return {std::prev(this->end()), true};
}
template<class KeyType, detail::enable_if_t<
detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
std::pair<iterator, bool> emplace(KeyType && key, T && t)
template<class KeyType, detail::enable_if_t<detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
std::pair<iterator, bool> emplace(KeyType&& key, T&& t)
{
for (auto it = this->begin(); it != this->end(); ++it)
{
@@ -84,9 +88,8 @@ template <class Key, class T, class IgnoredLess = std::less<Key>,
return emplace(key, T{}).first->second;
}
template<class KeyType, detail::enable_if_t<
detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
T & operator[](KeyType && key)
template<class KeyType, detail::enable_if_t<detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
T& operator[](KeyType&& key)
{
return emplace(std::forward<KeyType>(key), T{}).first->second;
}
@@ -96,9 +99,8 @@ template <class Key, class T, class IgnoredLess = std::less<Key>,
return at(key);
}
template<class KeyType, detail::enable_if_t<
detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
const T & operator[](KeyType && key) const
template<class KeyType, detail::enable_if_t<detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
const T& operator[](KeyType&& key) const
{
return at(std::forward<KeyType>(key));
}
@@ -116,9 +118,8 @@ template <class Key, class T, class IgnoredLess = std::less<Key>,
JSON_THROW(std::out_of_range("key not found"));
}
template<class KeyType, detail::enable_if_t<
detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
T & at(KeyType && key) // NOLINT(cppcoreguidelines-missing-std-forward)
template<class KeyType, detail::enable_if_t<detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
T& at(KeyType&& key) // NOLINT(cppcoreguidelines-missing-std-forward)
{
for (auto it = this->begin(); it != this->end(); ++it)
{
@@ -144,9 +145,8 @@ template <class Key, class T, class IgnoredLess = std::less<Key>,
JSON_THROW(std::out_of_range("key not found"));
}
template<class KeyType, detail::enable_if_t<
detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
const T & at(KeyType && key) const // NOLINT(cppcoreguidelines-missing-std-forward)
template<class KeyType, detail::enable_if_t<detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
const T& at(KeyType&& key) const // NOLINT(cppcoreguidelines-missing-std-forward)
{
for (auto it = this->begin(); it != this->end(); ++it)
{
@@ -168,7 +168,7 @@ template <class Key, class T, class IgnoredLess = std::less<Key>,
// Since we cannot move const Keys, re-construct them in place
for (auto next = it; ++next != this->end(); ++it)
{
it->~value_type(); // Destroy but keep allocation
it->~value_type(); // Destroy but keep allocation
new (&*it) value_type{std::move(*next)};
}
Container::pop_back();
@@ -178,9 +178,8 @@ template <class Key, class T, class IgnoredLess = std::less<Key>,
return 0;
}
template<class KeyType, detail::enable_if_t<
detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
size_type erase(KeyType && key) // NOLINT(cppcoreguidelines-missing-std-forward)
template<class KeyType, detail::enable_if_t<detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
size_type erase(KeyType&& key) // NOLINT(cppcoreguidelines-missing-std-forward)
{
for (auto it = this->begin(); it != this->end(); ++it)
{
@@ -189,7 +188,7 @@ template <class Key, class T, class IgnoredLess = std::less<Key>,
// Since we cannot move const Keys, re-construct them in place
for (auto next = it; ++next != this->end(); ++it)
{
it->~value_type(); // Destroy but keep allocation
it->~value_type(); // Destroy but keep allocation
new (&*it) value_type{std::move(*next)};
}
Container::pop_back();
@@ -236,8 +235,8 @@ template <class Key, class T, class IgnoredLess = std::less<Key>,
for (auto it = first; std::next(it, elements_affected) != Container::end(); ++it)
{
it->~value_type(); // destroy but keep allocation
new (&*it) value_type{std::move(*std::next(it, elements_affected))}; // "move" next element to it
it->~value_type(); // destroy but keep allocation
new (&*it) value_type{std::move(*std::next(it, elements_affected))}; // "move" next element to it
}
// [ a, b, c, d, h, i, j, h, i, j ]
@@ -269,9 +268,8 @@ template <class Key, class T, class IgnoredLess = std::less<Key>,
return 0;
}
template<class KeyType, detail::enable_if_t<
detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
size_type count(KeyType && key) const // NOLINT(cppcoreguidelines-missing-std-forward)
template<class KeyType, detail::enable_if_t<detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
size_type count(KeyType&& key) const // NOLINT(cppcoreguidelines-missing-std-forward)
{
for (auto it = this->begin(); it != this->end(); ++it)
{
@@ -295,9 +293,8 @@ template <class Key, class T, class IgnoredLess = std::less<Key>,
return Container::end();
}
template<class KeyType, detail::enable_if_t<
detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
iterator find(KeyType && key) // NOLINT(cppcoreguidelines-missing-std-forward)
template<class KeyType, detail::enable_if_t<detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
iterator find(KeyType&& key) // NOLINT(cppcoreguidelines-missing-std-forward)
{
for (auto it = this->begin(); it != this->end(); ++it)
{
@@ -321,12 +318,12 @@ template <class Key, class T, class IgnoredLess = std::less<Key>,
return Container::end();
}
std::pair<iterator, bool> insert( value_type&& value )
std::pair<iterator, bool> insert(value_type&& value)
{
return emplace(value.first, std::move(value.second));
}
std::pair<iterator, bool> insert( const value_type& value )
std::pair<iterator, bool> insert(const value_type& value)
{
for (auto it = this->begin(); it != this->end(); ++it)
{
@@ -341,7 +338,7 @@ template <class Key, class T, class IgnoredLess = std::less<Key>,
template<typename InputIt>
using require_input_iter = typename std::enable_if<std::is_convertible<typename std::iterator_traits<InputIt>::iterator_category,
std::input_iterator_tag>::value>::type;
std::input_iterator_tag>::value>::type;
template<typename InputIt, typename = require_input_iter<InputIt>>
void insert(InputIt first, InputIt last)
@@ -352,7 +349,7 @@ template <class Key, class T, class IgnoredLess = std::less<Key>,
}
}
private:
private:
JSON_NO_UNIQUE_ADDRESS key_compare m_compare = key_compare();
};

File diff suppressed because it is too large Load Diff