Try amalgamate again.

There seems to be some issues or inconsistencies with the astyle
version 3.2.1 from the AUR versus 3.2.1-build from apt:
   * --squeeze-lines is not defined in the one from Arch, so I had to
     comment that one out in order to make the amalgamate step run.
   * A bunch of files are affected by the amalgamate, which does not
     seem right.
This commit is contained in:
Fredrik Sandhei 2023-10-09 18:30:11 +02:00
parent 828bac981a
commit ca407117ed
11 changed files with 683 additions and 640 deletions

View File

@ -115,7 +115,7 @@ class exception : public std::exception
} }
auto str = std::accumulate(tokens.rbegin(), tokens.rend(), std::string{}, 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)); return concat(a, '/', detail::escape(b));
}); });

View File

@ -43,7 +43,7 @@ struct iterator_traits
template<typename T> template<typename T>
struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >> 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> template<typename SAX, typename BasicJsonType>
struct is_sax struct is_sax
{ {
private: private:
static_assert(is_basic_json<BasicJsonType>::value, static_assert(is_basic_json<BasicJsonType>::value,
"BasicJsonType must be of type basic_json<...>"); "BasicJsonType must be of type basic_json<...>");
@ -84,7 +84,7 @@ struct is_sax
using binary_t = typename BasicJsonType::binary_t; using binary_t = typename BasicJsonType::binary_t;
using exception_t = typename BasicJsonType::exception; using exception_t = typename BasicJsonType::exception;
public: public:
static constexpr bool value = static constexpr bool value =
is_detected_exact<bool, null_function_t, SAX>::value && is_detected_exact<bool, null_function_t, SAX>::value &&
is_detected_exact<bool, boolean_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> template<typename SAX, typename BasicJsonType>
struct is_sax_static_asserts struct is_sax_static_asserts
{ {
private: private:
static_assert(is_basic_json<BasicJsonType>::value, static_assert(is_basic_json<BasicJsonType>::value,
"BasicJsonType must be of type basic_json<...>"); "BasicJsonType must be of type basic_json<...>");
@ -115,7 +115,7 @@ struct is_sax_static_asserts
using binary_t = typename BasicJsonType::binary_t; using binary_t = typename BasicJsonType::binary_t;
using exception_t = typename BasicJsonType::exception; using exception_t = typename BasicJsonType::exception;
public: public:
static_assert(is_detected_exact<bool, null_function_t, SAX>::value, static_assert(is_detected_exact<bool, null_function_t, SAX>::value,
"Missing/invalid function: bool null()"); "Missing/invalid function: bool null()");
static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value, 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> struct conjunction<B> : B { };
template<class B, class... Bn> template<class B, class... Bn>
struct conjunction<B, 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 // 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 > { };
@ -203,19 +203,19 @@ 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>> 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>> 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...>> 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...>> struct is_default_constructible<const std::tuple<Ts...>>
: conjunction<is_default_constructible<Ts>...> {}; : conjunction<is_default_constructible<Ts>...> {};
template <typename T, typename... Args> template <typename T, typename... Args>
struct is_constructible : std::is_constructible<T, Args...> {}; struct is_constructible : std::is_constructible<T, Args...> {};
@ -238,10 +238,10 @@ struct is_iterator_traits : std::false_type {};
template<typename T> template<typename T>
struct is_iterator_traits<iterator_traits<T>> struct is_iterator_traits<iterator_traits<T>>
{ {
private: private:
using traits = iterator_traits<T>; using traits = iterator_traits<T>;
public: public:
static constexpr auto value = static constexpr auto value =
is_detected<value_type_t, traits>::value && is_detected<value_type_t, traits>::value &&
is_detected<difference_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> template<typename T>
struct is_range struct is_range
{ {
private: private:
using t_ref = typename std::add_lvalue_reference<T>::type; using t_ref = typename std::add_lvalue_reference<T>::type;
using iterator = detected_t<result_of_begin, t_ref>; using iterator = detected_t<result_of_begin, t_ref>;
@ -265,7 +265,7 @@ struct is_range
static constexpr auto is_iterator_begin = static constexpr auto is_iterator_begin =
is_iterator_traits<iterator_traits<iterator>>::value; 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; 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> template<typename BasicJsonType, typename CompatibleObjectType>
struct is_compatible_object_type struct is_compatible_object_type
: is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {}; : is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};
template<typename BasicJsonType, typename ConstructibleObjectType, template<typename BasicJsonType, typename ConstructibleObjectType,
typename = void> typename = void>
@ -339,8 +339,8 @@ struct is_constructible_object_type_impl <
template<typename BasicJsonType, typename ConstructibleObjectType> template<typename BasicJsonType, typename ConstructibleObjectType>
struct is_constructible_object_type struct is_constructible_object_type
: is_constructible_object_type_impl<BasicJsonType, : is_constructible_object_type_impl<BasicJsonType,
ConstructibleObjectType> {}; ConstructibleObjectType> {};
template<typename BasicJsonType, typename CompatibleStringType> template<typename BasicJsonType, typename CompatibleStringType>
struct is_compatible_string_type struct is_compatible_string_type
@ -386,7 +386,7 @@ struct is_compatible_array_type_impl <
template<typename BasicJsonType, typename CompatibleArrayType> template<typename BasicJsonType, typename CompatibleArrayType>
struct is_compatible_array_type 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> 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 {};
@ -396,7 +396,7 @@ struct is_constructible_array_type_impl <
BasicJsonType, ConstructibleArrayType, BasicJsonType, ConstructibleArrayType,
enable_if_t<std::is_same<ConstructibleArrayType, enable_if_t<std::is_same<ConstructibleArrayType,
typename BasicJsonType::value_type>::value >> typename BasicJsonType::value_type>::value >>
: std::true_type {}; : std::true_type {};
template<typename BasicJsonType, typename ConstructibleArrayType> template<typename BasicJsonType, typename ConstructibleArrayType>
struct is_constructible_array_type_impl < 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&& !std::is_same<ConstructibleArrayType, detected_t<range_value_t, ConstructibleArrayType>>::value&&
is_complete_type < is_complete_type <
detected_t<range_value_t, ConstructibleArrayType >>::value >> 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 = static constexpr bool value =
std::is_same<value_type, std::is_same<value_type,
typename BasicJsonType::array_t::value_type>::value || typename BasicJsonType::array_t::value_type>::value ||
has_from_json<BasicJsonType, has_from_json<BasicJsonType,
value_type>::value || value_type>::value ||
has_non_default_from_json < has_non_default_from_json <
BasicJsonType, BasicJsonType,
value_type >::value; value_type >::value;
}; };
template<typename BasicJsonType, typename ConstructibleArrayType> template<typename BasicJsonType, typename ConstructibleArrayType>
struct is_constructible_array_type struct is_constructible_array_type
: is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {}; : is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {};
template<typename RealIntegerType, typename CompatibleNumberIntegerType, template<typename RealIntegerType, typename CompatibleNumberIntegerType,
typename = void> typename = void>
@ -456,8 +456,8 @@ struct is_compatible_integer_type_impl <
template<typename RealIntegerType, typename CompatibleNumberIntegerType> template<typename RealIntegerType, typename CompatibleNumberIntegerType>
struct is_compatible_integer_type struct is_compatible_integer_type
: is_compatible_integer_type_impl<RealIntegerType, : is_compatible_integer_type_impl<RealIntegerType,
CompatibleNumberIntegerType> {}; CompatibleNumberIntegerType> {};
template<typename BasicJsonType, typename CompatibleType, typename = void> template<typename BasicJsonType, typename CompatibleType, typename = void>
struct is_compatible_type_impl: std::false_type {}; struct is_compatible_type_impl: std::false_type {};
@ -473,7 +473,7 @@ struct is_compatible_type_impl <
template<typename BasicJsonType, typename CompatibleType> template<typename BasicJsonType, typename CompatibleType>
struct is_compatible_type struct is_compatible_type
: is_compatible_type_impl<BasicJsonType, CompatibleType> {}; : is_compatible_type_impl<BasicJsonType, CompatibleType> {};
template<typename T1, typename T2> template<typename T1, typename T2>
struct is_constructible_tuple : std::false_type {}; 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< struct is_comparable<Compare, A, B, void_t<
decltype(std::declval<Compare>()(std::declval<A>(), std::declval<B>())), decltype(std::declval<Compare>()(std::declval<A>(), std::declval<B>())),
decltype(std::declval<Compare>()(std::declval<B>(), std::declval<A>())) decltype(std::declval<Compare>()(std::declval<B>(), std::declval<A>()))
>> : std::true_type {}; >> : std::true_type {};
template<typename T> template<typename T>
using detect_is_transparent = typename T::is_transparent; 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 // the valid JSON Patch operations
enum class patch_operations {add, remove, replace, move, copy, test, invalid}; 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") if (op == "add")
{ {
@ -4838,8 +4838,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
for (const auto& val : json_patch) for (const auto& val : json_patch)
{ {
// wrapper to get a value for an operation // wrapper to get a value for an operation
const auto get_value = [&val](const std::string & op, const auto get_value = [&val](const std::string& op,
const std::string & member, const std::string& member,
bool string_type) -> basic_json & bool string_type) -> basic_json &
{ {
// find value // 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, bool operator()(::nlohmann::detail::value_t lhs,
::nlohmann::detail::value_t rhs) const noexcept ::nlohmann::detail::value_t rhs) const noexcept
{ {
#if JSON_HAS_THREE_WAY_COMPARISON #if JSON_HAS_THREE_WAY_COMPARISON
return std::is_lt(lhs <=> rhs); // *NOPAD* return std::is_lt(lhs <=> rhs); // *NOPAD*
#else #else
return ::nlohmann::detail::operator<(lhs, rhs); return ::nlohmann::detail::operator<(lhs, rhs);
#endif #endif
} }
}; };
// C++20 prohibit function specialization in the std namespace. // C++20 prohibit function specialization in the std namespace.
#ifndef JSON_HAS_CPP_20 #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>, template <class Key, class T, class IgnoredLess = std::less<Key>,
class Allocator = std::allocator<std::pair<const Key, T>>> class Allocator = std::allocator<std::pair<const Key, T>>>
struct ordered_map : std::vector<std::pair<const Key, T>, Allocator> struct ordered_map : std::vector<std::pair<const Key, T>, Allocator>
{ {
using key_type = Key; using key_type = Key;
using mapped_type = T; using mapped_type = T;
using Container = std::vector<std::pair<const Key, T>, Allocator>; using Container = std::vector<std::pair<const Key, T>, Allocator>;
using iterator = typename Container::iterator; using iterator = typename Container::iterator;
using const_iterator = typename Container::const_iterator; using const_iterator = typename Container::const_iterator;
using size_type = typename Container::size_type; using size_type = typename Container::size_type;
using value_type = typename Container::value_type; using value_type = typename Container::value_type;
#ifdef JSON_HAS_CPP_14 #ifdef JSON_HAS_CPP_14
using key_compare = std::equal_to<>; using key_compare = std::equal_to<>;
#else #else
using key_compare = std::equal_to<Key>; using key_compare = std::equal_to<Key>;
#endif #endif
// Explicit constructors instead of `using Container::Container` // Explicit constructors instead of `using Container::Container`
// otherwise older compilers choke on it (GCC <= 5.5, xcode <= 9.4) // otherwise older compilers choke on it (GCC <= 5.5, xcode <= 9.4)
ordered_map() noexcept(noexcept(Container())) : Container{} {} ordered_map() noexcept(noexcept(Container())) : Container{} {}
explicit ordered_map(const Allocator& alloc) noexcept(noexcept(Container(alloc))) : Container{alloc} {} explicit ordered_map(const Allocator& alloc) noexcept(noexcept(Container(alloc))) : Container{alloc} {}
template <class It> template <class It>
ordered_map(It first, It last, const Allocator& alloc = Allocator()) ordered_map(It first, It last, const Allocator& alloc = Allocator())
: Container{first, last, alloc} {} : Container{first, last, alloc} {}
ordered_map(std::initializer_list<value_type> init, const Allocator& alloc = Allocator() ) ordered_map(std::initializer_list<value_type> init, const Allocator& alloc = Allocator() )
: Container{init, alloc} {} : Container{init, alloc} {}
std::pair<iterator, bool> emplace(const key_type& key, T&& t) std::pair<iterator, bool> emplace(const key_type& key, T&& t)
{
for (auto it = this->begin(); it != this->end(); ++it)
{ {
for (auto it = this->begin(); it != this->end(); ++it) if (m_compare(it->first, key))
{ {
if (m_compare(it->first, key)) 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)
{ {
return {it, false}; it->~value_type(); // Destroy but keep allocation
new (&*it) value_type{std::move(*next)};
} }
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< template<class KeyType, detail::enable_if_t<
detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0> detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
std::pair<iterator, bool> emplace(KeyType && key, T && t) size_type erase(KeyType && key) // NOLINT(cppcoreguidelines-missing-std-forward)
{
for (auto it = this->begin(); it != this->end(); ++it)
{ {
for (auto it = this->begin(); it != this->end(); ++it) if (m_compare(it->first, key))
{ {
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)
{ {
return {it, false}; it->~value_type(); // Destroy but keep allocation
new (&*it) value_type{std::move(*next)};
} }
Container::pop_back();
return 1;
} }
Container::emplace_back(std::forward<KeyType>(key), std::forward<T>(t)); }
return {std::prev(this->end()), true}; return 0;
}
iterator erase(iterator pos)
{
return erase(pos, std::next(pos));
}
iterator erase(iterator first, iterator last)
{
if (first == last)
{
return first;
} }
T& operator[](const key_type& key) 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)
{ {
return emplace(key, T{}).first->second; it->~value_type(); // destroy but keep allocation
new (&*it) value_type{std::move(*std::next(it, elements_affected))}; // "move" next element to it
} }
template<class KeyType, detail::enable_if_t< // [ a, b, c, d, h, i, j, h, i, j ]
detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0> // ^ ^
T & operator[](KeyType && key) // first last
{
return emplace(std::forward<KeyType>(key), T{}).first->second;
}
const T& operator[](const key_type& key) const // remove the unneeded elements at the end of the vector
{ Container::resize(this->size() - static_cast<size_type>(elements_affected));
return at(key);
}
template<class KeyType, detail::enable_if_t< // [ a, b, c, d, h, i, j ]
detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0> // ^ ^
const T & operator[](KeyType && key) const // first last
{
return at(std::forward<KeyType>(key));
}
T& at(const key_type& key) // 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)
{ {
for (auto it = this->begin(); it != this->end(); ++it) if (m_compare(it->first, key))
{ {
if (m_compare(it->first, key)) return 1;
{
return it->second;
}
} }
JSON_THROW(std::out_of_range("key not found"));
} }
return 0;
}
template<class KeyType, detail::enable_if_t< template<class KeyType, detail::enable_if_t<
detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0> detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
T & at(KeyType && key) // NOLINT(cppcoreguidelines-missing-std-forward) size_type count(KeyType && key) const // NOLINT(cppcoreguidelines-missing-std-forward)
{
for (auto it = this->begin(); it != this->end(); ++it)
{ {
for (auto it = this->begin(); it != this->end(); ++it) if (m_compare(it->first, key))
{ {
if (m_compare(it->first, key)) return 1;
{
return it->second;
}
} }
JSON_THROW(std::out_of_range("key not found"));
} }
return 0;
}
const T& at(const key_type& key) const iterator find(const key_type& key)
{
for (auto it = this->begin(); it != this->end(); ++it)
{ {
for (auto it = this->begin(); it != this->end(); ++it) if (m_compare(it->first, key))
{ {
if (m_compare(it->first, key)) return it;
{
return it->second;
}
} }
JSON_THROW(std::out_of_range("key not found"));
} }
return Container::end();
}
template<class KeyType, detail::enable_if_t< template<class KeyType, detail::enable_if_t<
detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0> 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) iterator find(KeyType && key) // NOLINT(cppcoreguidelines-missing-std-forward)
{
for (auto it = this->begin(); it != this->end(); ++it)
{ {
for (auto it = this->begin(); it != this->end(); ++it) if (m_compare(it->first, key))
{ {
if (m_compare(it->first, key)) return it;
{
return it->second;
}
} }
JSON_THROW(std::out_of_range("key not found"));
} }
return Container::end();
}
size_type erase(const key_type& key) const_iterator find(const key_type& key) const
{
for (auto it = this->begin(); it != this->end(); ++it)
{ {
for (auto it = this->begin(); it != this->end(); ++it) if (m_compare(it->first, key))
{ {
if (m_compare(it->first, key)) return it;
{
// 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();
}
template<class KeyType, detail::enable_if_t< std::pair<iterator, bool> insert( value_type&& value )
detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0> {
size_type erase(KeyType && key) // NOLINT(cppcoreguidelines-missing-std-forward) 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)
{ {
for (auto it = this->begin(); it != this->end(); ++it) if (m_compare(it->first, value.first))
{ {
if (m_compare(it->first, key)) return {it, false};
{
// 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: 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 NLOHMANN_JSON_NAMESPACE_END

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

@ -106,7 +106,7 @@ TEST_CASE("compliance tests from nativejson-benchmark")
SECTION("doubles") 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(json_string)
CAPTURE(expected) CAPTURE(expected)
@ -238,7 +238,7 @@ TEST_CASE("compliance tests from nativejson-benchmark")
SECTION("strings") 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(json_string)
CAPTURE(expected) CAPTURE(expected)

View File

@ -126,7 +126,7 @@ TEST_CASE("digit gen")
{ {
SECTION("single precision") 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(number)
CAPTURE(digits) CAPTURE(digits)
@ -190,7 +190,7 @@ TEST_CASE("digit gen")
SECTION("double precision") 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(number)
CAPTURE(digits) CAPTURE(digits)
@ -336,7 +336,7 @@ TEST_CASE("formatting")
{ {
SECTION("single precision") 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{}; std::array<char, 33> buf{};
char* end = nlohmann::detail::to_chars(buf.data(), buf.data() + 32, number); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg) 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") 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{}; std::array<char, 33> buf{};
char* end = nlohmann::detail::to_chars(buf.data(), buf.data() + 32, number); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg) 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") 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; const nlohmann::json j = number;
CHECK(j.dump() == expected); CHECK(j.dump() == expected);