Revert "Try amalgamate again."

This reverts commit ca407117ed.
This commit is contained in:
Fredrik Sandhei 2023-10-09 20:39:30 +02:00
parent ca407117ed
commit d4f9594315
11 changed files with 654 additions and 697 deletions

View File

@ -115,7 +115,7 @@ class exception : public std::exception
}
auto str = std::accumulate(tokens.rbegin(), tokens.rend(), std::string{},
[](const std::string& a, const std::string& b)
[](const std::string & a, const std::string & b)
{
return concat(a, '/', detail::escape(b));
});

View File

@ -43,7 +43,7 @@ struct iterator_traits
template<typename T>
struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >>
: iterator_types<T>
: iterator_types<T>
{
};

View File

@ -73,7 +73,7 @@ using parse_error_function_t = decltype(std::declval<T&>().parse_error(
template<typename SAX, typename BasicJsonType>
struct is_sax
{
private:
private:
static_assert(is_basic_json<BasicJsonType>::value,
"BasicJsonType must be of type basic_json<...>");
@ -84,7 +84,7 @@ struct is_sax
using binary_t = typename BasicJsonType::binary_t;
using exception_t = typename BasicJsonType::exception;
public:
public:
static constexpr bool value =
is_detected_exact<bool, null_function_t, SAX>::value &&
is_detected_exact<bool, boolean_function_t, SAX>::value &&
@ -104,7 +104,7 @@ struct is_sax
template<typename SAX, typename BasicJsonType>
struct is_sax_static_asserts
{
private:
private:
static_assert(is_basic_json<BasicJsonType>::value,
"BasicJsonType must be of type basic_json<...>");
@ -115,7 +115,7 @@ struct is_sax_static_asserts
using binary_t = typename BasicJsonType::binary_t;
using exception_t = typename BasicJsonType::exception;
public:
public:
static_assert(is_detected_exact<bool, null_function_t, SAX>::value,
"Missing/invalid function: bool null()");
static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,

View File

@ -190,7 +190,7 @@ 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 > { };
@ -203,19 +203,19 @@ struct is_default_constructible : std::is_default_constructible<T> {};
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>
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>
struct is_default_constructible<std::tuple<Ts...>>
: conjunction<is_default_constructible<Ts>...> {};
: conjunction<is_default_constructible<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...> {};
@ -238,10 +238,10 @@ struct is_iterator_traits : std::false_type {};
template<typename T>
struct is_iterator_traits<iterator_traits<T>>
{
private:
private:
using traits = iterator_traits<T>;
public:
public:
static constexpr auto value =
is_detected<value_type_t, traits>::value &&
is_detected<difference_type_t, traits>::value &&
@ -253,7 +253,7 @@ struct is_iterator_traits<iterator_traits<T>>
template<typename T>
struct is_range
{
private:
private:
using t_ref = typename std::add_lvalue_reference<T>::type;
using iterator = detected_t<result_of_begin, t_ref>;
@ -265,7 +265,7 @@ struct is_range
static constexpr auto is_iterator_begin =
is_iterator_traits<iterator_traits<iterator>>::value;
public:
public:
static constexpr bool value = !std::is_same<iterator, nonesuch>::value && !std::is_same<sentinel, nonesuch>::value && is_iterator_begin;
};
@ -307,7 +307,7 @@ struct is_compatible_object_type_impl <
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>
@ -339,8 +339,8 @@ struct is_constructible_object_type_impl <
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
@ -386,7 +386,7 @@ struct is_compatible_array_type_impl <
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 {};
@ -396,7 +396,7 @@ struct is_constructible_array_type_impl <
BasicJsonType, ConstructibleArrayType,
enable_if_t<std::is_same<ConstructibleArrayType,
typename BasicJsonType::value_type>::value >>
: std::true_type {};
: std::true_type {};
template<typename BasicJsonType, typename ConstructibleArrayType>
struct is_constructible_array_type_impl <
@ -415,22 +415,22 @@ is_detected<range_value_t, ConstructibleArrayType>::value&&
!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>;
{
using value_type = range_value_t<ConstructibleArrayType>;
static constexpr bool value =
std::is_same<value_type,
typename BasicJsonType::array_t::value_type>::value ||
has_from_json<BasicJsonType,
value_type>::value ||
has_non_default_from_json <
BasicJsonType,
value_type >::value;
};
static constexpr bool value =
std::is_same<value_type,
typename BasicJsonType::array_t::value_type>::value ||
has_from_json<BasicJsonType,
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>
@ -456,8 +456,8 @@ struct is_compatible_integer_type_impl <
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 {};
@ -473,7 +473,7 @@ 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 {};
@ -509,7 +509,7 @@ 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 {};
>> : std::true_type {};
template<typename T>
using detect_is_transparent = typename T::is_transparent;

View File

@ -4701,7 +4701,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
// the valid JSON Patch operations
enum class patch_operations {add, remove, replace, move, copy, test, invalid};
const auto get_op = [](const std::string& op)
const auto get_op = [](const std::string & op)
{
if (op == "add")
{
@ -4838,8 +4838,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
for (const auto& val : json_patch)
{
// wrapper to get a value for an operation
const auto get_value = [&val](const std::string& op,
const std::string& member,
const auto get_value = [&val](const std::string & op,
const std::string & member,
bool string_type) -> basic_json &
{
// find value
@ -5216,14 +5216,14 @@ struct less< ::nlohmann::detail::value_t> // do not remove the space after '<',
*/
bool operator()(::nlohmann::detail::value_t lhs,
::nlohmann::detail::value_t rhs) const noexcept
{
{
#if JSON_HAS_THREE_WAY_COMPARISON
return std::is_lt(lhs <=> rhs); // *NOPAD*
return std::is_lt(lhs <=> rhs); // *NOPAD*
#else
return ::nlohmann::detail::operator<(lhs, rhs);
return ::nlohmann::detail::operator<(lhs, rhs);
#endif
}
};
}
};
// C++20 prohibit function specialization in the std namespace.
#ifndef JSON_HAS_CPP_20

View File

@ -27,333 +27,333 @@ NLOHMANN_JSON_NAMESPACE_BEGIN
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;
using Container = std::vector<std::pair<const Key, T>, Allocator>;
using iterator = typename Container::iterator;
using const_iterator = typename Container::const_iterator;
using size_type = typename Container::size_type;
using value_type = typename Container::value_type;
{
using key_type = Key;
using mapped_type = T;
using Container = std::vector<std::pair<const Key, T>, Allocator>;
using iterator = typename Container::iterator;
using const_iterator = typename Container::const_iterator;
using size_type = typename Container::size_type;
using value_type = typename Container::value_type;
#ifdef JSON_HAS_CPP_14
using key_compare = std::equal_to<>;
using key_compare = std::equal_to<>;
#else
using key_compare = std::equal_to<Key>;
using key_compare = std::equal_to<Key>;
#endif
// 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(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} {}
// 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(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} {}
std::pair<iterator, bool> emplace(const key_type& key, T&& t)
{
for (auto it = this->begin(); it != this->end(); ++it)
std::pair<iterator, bool> emplace(const key_type& key, T&& t)
{
if (m_compare(it->first, key))
for (auto it = this->begin(); it != this->end(); ++it)
{
return {it, false};
}
}
Container::emplace_back(key, std::forward<T>(t));
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)
{
for (auto it = this->begin(); it != this->end(); ++it)
{
if (m_compare(it->first, key))
{
return {it, false};
}
}
Container::emplace_back(std::forward<KeyType>(key), std::forward<T>(t));
return {std::prev(this->end()), true};
}
T& operator[](const key_type& 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)
{
return emplace(std::forward<KeyType>(key), T{}).first->second;
}
const T& operator[](const key_type& key) const
{
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
{
return at(std::forward<KeyType>(key));
}
T& at(const key_type& key)
{
for (auto it = this->begin(); it != this->end(); ++it)
{
if (m_compare(it->first, key))
{
return it->second;
}
}
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)
{
for (auto it = this->begin(); it != this->end(); ++it)
{
if (m_compare(it->first, key))
{
return it->second;
}
}
JSON_THROW(std::out_of_range("key not found"));
}
const T& at(const key_type& key) const
{
for (auto it = this->begin(); it != this->end(); ++it)
{
if (m_compare(it->first, key))
{
return it->second;
}
}
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)
{
for (auto it = this->begin(); it != this->end(); ++it)
{
if (m_compare(it->first, key))
{
return it->second;
}
}
JSON_THROW(std::out_of_range("key not found"));
}
size_type erase(const key_type& key)
{
for (auto it = this->begin(); it != this->end(); ++it)
{
if (m_compare(it->first, key))
{
// Since we cannot move const Keys, re-construct them in place
for (auto next = it; ++next != this->end(); ++it)
if (m_compare(it->first, key))
{
it->~value_type(); // Destroy but keep allocation
new (&*it) value_type{std::move(*next)};
return {it, false};
}
Container::pop_back();
return 1;
}
Container::emplace_back(key, std::forward<T>(t));
return {std::prev(this->end()), true};
}
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)
{
for (auto it = this->begin(); it != this->end(); ++it)
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)
{
if (m_compare(it->first, key))
for (auto it = this->begin(); it != this->end(); ++it)
{
// Since we cannot move const Keys, re-construct them in place
for (auto next = it; ++next != this->end(); ++it)
if (m_compare(it->first, key))
{
it->~value_type(); // Destroy but keep allocation
new (&*it) value_type{std::move(*next)};
return {it, false};
}
Container::pop_back();
return 1;
}
}
return 0;
}
iterator erase(iterator pos)
{
return erase(pos, std::next(pos));
}
iterator erase(iterator first, iterator last)
{
if (first == last)
{
return first;
Container::emplace_back(std::forward<KeyType>(key), std::forward<T>(t));
return {std::prev(this->end()), true};
}
const auto elements_affected = std::distance(first, last);
const auto offset = std::distance(Container::begin(), first);
// This is the start situation. We need to delete elements_affected
// elements (3 in this example: e, f, g), and need to return an
// iterator past the last deleted element (h in this example).
// Note that offset is the distance from the start of the vector
// to first. We will need this later.
// [ a, b, c, d, e, f, g, h, i, j ]
// ^ ^
// first last
// Since we cannot move const Keys, we re-construct them in place.
// We start at first and re-construct (viz. copy) the elements from
// the back of the vector. Example for first iteration:
// ,--------.
// v | destroy e and re-construct with h
// [ a, b, c, d, e, f, g, h, i, j ]
// ^ ^
// it it + elements_affected
for (auto it = first; std::next(it, elements_affected) != Container::end(); ++it)
T& operator[](const key_type& key)
{
it->~value_type(); // destroy but keep allocation
new (&*it) value_type{std::move(*std::next(it, elements_affected))}; // "move" next element to it
return emplace(key, T{}).first->second;
}
// [ a, b, c, d, h, i, j, h, i, j ]
// ^ ^
// first last
// remove the unneeded elements at the end of the vector
Container::resize(this->size() - static_cast<size_type>(elements_affected));
// [ a, b, c, d, h, i, j ]
// ^ ^
// first last
// first is now pointing past the last deleted element, but we cannot
// use this iterator, because it may have been invalidated by the
// resize call. Instead, we can return begin() + offset.
return Container::begin() + offset;
}
size_type count(const key_type& key) const
{
for (auto it = this->begin(); it != this->end(); ++it)
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)
{
if (m_compare(it->first, key))
return emplace(std::forward<KeyType>(key), T{}).first->second;
}
const T& operator[](const key_type& key) const
{
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
{
return at(std::forward<KeyType>(key));
}
T& at(const key_type& key)
{
for (auto it = this->begin(); it != this->end(); ++it)
{
return 1;
if (m_compare(it->first, key))
{
return it->second;
}
}
}
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)
{
for (auto it = this->begin(); it != this->end(); ++it)
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)
{
if (m_compare(it->first, key))
for (auto it = this->begin(); it != this->end(); ++it)
{
return 1;
if (m_compare(it->first, key))
{
return it->second;
}
}
}
return 0;
}
iterator find(const key_type& key)
{
for (auto it = this->begin(); it != this->end(); ++it)
JSON_THROW(std::out_of_range("key not found"));
}
const T& at(const key_type& key) const
{
if (m_compare(it->first, key))
for (auto it = this->begin(); it != this->end(); ++it)
{
return it;
if (m_compare(it->first, key))
{
return it->second;
}
}
}
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)
{
for (auto it = this->begin(); it != this->end(); ++it)
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)
{
if (m_compare(it->first, key))
for (auto it = this->begin(); it != this->end(); ++it)
{
return it;
if (m_compare(it->first, key))
{
return it->second;
}
}
}
return Container::end();
}
const_iterator find(const key_type& key) const
{
for (auto it = this->begin(); it != this->end(); ++it)
JSON_THROW(std::out_of_range("key not found"));
}
size_type erase(const key_type& key)
{
if (m_compare(it->first, key))
for (auto it = this->begin(); it != this->end(); ++it)
{
return it;
if (m_compare(it->first, 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
new (&*it) value_type{std::move(*next)};
}
Container::pop_back();
return 1;
}
}
return 0;
}
return Container::end();
}
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 )
{
for (auto it = this->begin(); it != this->end(); ++it)
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)
{
if (m_compare(it->first, value.first))
for (auto it = this->begin(); it != this->end(); ++it)
{
return {it, false};
if (m_compare(it->first, 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
new (&*it) value_type{std::move(*next)};
}
Container::pop_back();
return 1;
}
}
return 0;
}
iterator erase(iterator pos)
{
return erase(pos, std::next(pos));
}
iterator erase(iterator first, iterator last)
{
if (first == last)
{
return first;
}
const auto elements_affected = std::distance(first, last);
const auto offset = std::distance(Container::begin(), first);
// This is the start situation. We need to delete elements_affected
// elements (3 in this example: e, f, g), and need to return an
// iterator past the last deleted element (h in this example).
// Note that offset is the distance from the start of the vector
// to first. We will need this later.
// [ a, b, c, d, e, f, g, h, i, j ]
// ^ ^
// first last
// Since we cannot move const Keys, we re-construct them in place.
// We start at first and re-construct (viz. copy) the elements from
// the back of the vector. Example for first iteration:
// ,--------.
// v | destroy e and re-construct with h
// [ a, b, c, d, e, f, g, h, i, j ]
// ^ ^
// it it + elements_affected
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
}
// [ a, b, c, d, h, i, j, h, i, j ]
// ^ ^
// first last
// remove the unneeded elements at the end of the vector
Container::resize(this->size() - static_cast<size_type>(elements_affected));
// [ a, b, c, d, h, i, j ]
// ^ ^
// first last
// first is now pointing past the last deleted element, but we cannot
// use this iterator, because it may have been invalidated by the
// resize call. Instead, we can return begin() + offset.
return Container::begin() + offset;
}
size_type count(const key_type& key) const
{
for (auto it = this->begin(); it != this->end(); ++it)
{
if (m_compare(it->first, key))
{
return 1;
}
}
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)
{
for (auto it = this->begin(); it != this->end(); ++it)
{
if (m_compare(it->first, key))
{
return 1;
}
}
return 0;
}
iterator find(const key_type& key)
{
for (auto it = this->begin(); it != this->end(); ++it)
{
if (m_compare(it->first, key))
{
return it;
}
}
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)
{
for (auto it = this->begin(); it != this->end(); ++it)
{
if (m_compare(it->first, key))
{
return it;
}
}
return Container::end();
}
const_iterator find(const key_type& key) const
{
for (auto it = this->begin(); it != this->end(); ++it)
{
if (m_compare(it->first, key))
{
return it;
}
}
return Container::end();
}
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 )
{
for (auto it = this->begin(); it != this->end(); ++it)
{
if (m_compare(it->first, value.first))
{
return {it, false};
}
}
Container::push_back(value);
return {--this->end(), true};
}
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;
template<typename InputIt, typename = require_input_iter<InputIt>>
void insert(InputIt first, InputIt last)
{
for (auto it = first; it != last; ++it)
{
insert(*it);
}
}
Container::push_back(value);
return {--this->end(), true};
}
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;
template<typename InputIt, typename = require_input_iter<InputIt>>
void insert(InputIt first, InputIt last)
{
for (auto it = first; it != last; ++it)
{
insert(*it);
}
}
private:
JSON_NO_UNIQUE_ADDRESS key_compare m_compare = key_compare();
};
JSON_NO_UNIQUE_ADDRESS key_compare m_compare = key_compare();
};
NLOHMANN_JSON_NAMESPACE_END

File diff suppressed because it is too large Load Diff

View File

@ -25,7 +25,6 @@
// SPDX-License-Identifier: MIT
// This file contains all macro definitions affecting or depending on the ABI
#ifndef JSON_SKIP_LIBRARY_VERSION_CHECK

View File

@ -88,7 +88,7 @@ struct Data
Data() = default;
Data(std::string a_, std::string b_)
: a(std::move(a_))
, b(std::move(b_))
, b(std::move(b_))
{}
std::string a{};
std::string b{};

View File

@ -106,7 +106,7 @@ TEST_CASE("compliance tests from nativejson-benchmark")
SECTION("doubles")
{
auto TEST_DOUBLE = [](const std::string& json_string, const double expected)
auto TEST_DOUBLE = [](const std::string & json_string, const double expected)
{
CAPTURE(json_string)
CAPTURE(expected)
@ -238,7 +238,7 @@ TEST_CASE("compliance tests from nativejson-benchmark")
SECTION("strings")
{
auto TEST_STRING = [](const std::string& json_string, const std::string& expected)
auto TEST_STRING = [](const std::string & json_string, const std::string & expected)
{
CAPTURE(json_string)
CAPTURE(expected)

View File

@ -126,7 +126,7 @@ TEST_CASE("digit gen")
{
SECTION("single precision")
{
auto check_float = [](float number, const std::string& digits, int expected_exponent)
auto check_float = [](float number, const std::string & digits, int expected_exponent)
{
CAPTURE(number)
CAPTURE(digits)
@ -190,7 +190,7 @@ TEST_CASE("digit gen")
SECTION("double precision")
{
auto check_double = [](double number, const std::string& digits, int expected_exponent)
auto check_double = [](double number, const std::string & digits, int expected_exponent)
{
CAPTURE(number)
CAPTURE(digits)
@ -336,7 +336,7 @@ TEST_CASE("formatting")
{
SECTION("single precision")
{
auto check_float = [](float number, const std::string& expected)
auto check_float = [](float number, const std::string & expected)
{
std::array<char, 33> buf{};
char* end = nlohmann::detail::to_chars(buf.data(), buf.data() + 32, number); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
@ -396,7 +396,7 @@ TEST_CASE("formatting")
SECTION("double precision")
{
auto check_double = [](double number, const std::string& expected)
auto check_double = [](double number, const std::string & expected)
{
std::array<char, 33> buf{};
char* end = nlohmann::detail::to_chars(buf.data(), buf.data() + 32, number); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
@ -456,7 +456,7 @@ TEST_CASE("formatting")
SECTION("integer")
{
auto check_integer = [](std::int64_t number, const std::string& expected)
auto check_integer = [](std::int64_t number, const std::string & expected)
{
const nlohmann::json j = number;
CHECK(j.dump() == expected);