diff --git a/include/nlohmann/ordered_map.hpp b/include/nlohmann/ordered_map.hpp index 5d28cdf20..62c48a303 100644 --- a/include/nlohmann/ordered_map.hpp +++ b/include/nlohmann/ordered_map.hpp @@ -8,14 +8,14 @@ #pragma once -#include // equal_to, less -#include // initializer_list -#include // input_iterator_tag, iterator_traits -#include // allocator -#include // for out_of_range -#include // enable_if, is_convertible -#include // pair -#include // vector +#include // equal_to, less +#include // initializer_list +#include // input_iterator_tag, iterator_traits +#include // allocator +#include // for out_of_range +#include // enable_if, is_convertible +#include // pair +#include // vector #include #include @@ -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 -template , - class Allocator = std::allocator>> - struct ordered_map : std::vector, Allocator> +template, class Allocator = std::allocator>> + struct ordered_map : std::vector, Allocator> { using key_type = Key; using mapped_type = T; @@ -43,17 +42,24 @@ template , // 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 + ordered_map() noexcept(noexcept(Container())) + : Container{} + {} + explicit ordered_map(const Allocator& alloc) noexcept(noexcept(Container(alloc))) + : Container{alloc} + {} + template ordered_map(It first, It last, const Allocator& alloc = Allocator()) - : Container{first, last, alloc} {} - ordered_map(std::initializer_list init, const Allocator& alloc = Allocator() ) - : Container{init, alloc} {} + : Container{first, last, alloc} + {} + ordered_map(std::initializer_list init, const Allocator& alloc = Allocator()) + : Container{init, alloc} + {} std::pair emplace(const key_type& key, T&& t) { - for (auto it = this->begin(); it != this->end(); ++it) + auto endItr = this->end(); + for (auto it = this->begin(); it != endItr; ++it) { if (m_compare(it->first, key)) { @@ -64,11 +70,11 @@ template , return {std::prev(this->end()), true}; } - template::value, int> = 0> + template::value, int> = 0> std::pair emplace(KeyType && key, T && t) { - for (auto it = this->begin(); it != this->end(); ++it) + auto endItr = this->end(); + for (auto it = this->begin(); it != endItr; ++it) { if (m_compare(it->first, key)) { @@ -84,8 +90,7 @@ template , return emplace(key, T{}).first->second; } - template::value, int> = 0> + template::value, int> = 0> T & operator[](KeyType && key) { return emplace(std::forward(key), T{}).first->second; @@ -96,8 +101,7 @@ template , return at(key); } - template::value, int> = 0> + template::value, int> = 0> const T & operator[](KeyType && key) const { return at(std::forward(key)); @@ -105,22 +109,15 @@ template , 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")); + const ordered_map& cThis = *this; + return const_cast(cThis.at(key)); } - template::value, int> = 0> + template::value, int> = 0> T & at(KeyType && key) // NOLINT(cppcoreguidelines-missing-std-forward) { - for (auto it = this->begin(); it != this->end(); ++it) + auto endItr = this->end(); + for (auto it = this->begin(); it != endItr; ++it) { if (m_compare(it->first, key)) { @@ -133,7 +130,8 @@ template , const T& at(const key_type& key) const { - for (auto it = this->begin(); it != this->end(); ++it) + auto endItr = this->end(); + for (auto it = this->begin(); it != endItr; ++it) { if (m_compare(it->first, key)) { @@ -144,11 +142,11 @@ template , JSON_THROW(std::out_of_range("key not found")); } - template::value, int> = 0> + template::value, int> = 0> const T & at(KeyType && key) const // NOLINT(cppcoreguidelines-missing-std-forward) { - for (auto it = this->begin(); it != this->end(); ++it) + auto endItr = this->end(); + for (auto it = this->begin(); it != endItr; ++it) { if (m_compare(it->first, key)) { @@ -161,14 +159,15 @@ template , size_type erase(const key_type& key) { - for (auto it = this->begin(); it != this->end(); ++it) + auto endItr = this->end(); + for (auto it = this->begin(); it != endItr; ++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) + for (auto next = it; ++next != endItr; ++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,18 +177,18 @@ template , return 0; } - template::value, int> = 0> + template::value, int> = 0> size_type erase(KeyType && key) // NOLINT(cppcoreguidelines-missing-std-forward) { - for (auto it = this->begin(); it != this->end(); ++it) + auto endItr = this->end(); + for (auto it = this->begin(); it != endItr; ++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) + for (auto next = it; ++next != endItr; ++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 , 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 ] @@ -259,7 +258,8 @@ template , size_type count(const key_type& key) const { - for (auto it = this->begin(); it != this->end(); ++it) + auto endItr = this->end(); + for (auto it = this->begin(); it != endItr; ++it) { if (m_compare(it->first, key)) { @@ -269,11 +269,11 @@ template , return 0; } - template::value, int> = 0> + template::value, int> = 0> size_type count(KeyType && key) const // NOLINT(cppcoreguidelines-missing-std-forward) { - for (auto it = this->begin(); it != this->end(); ++it) + auto endItr = this->end(); + for (auto it = this->begin(); it != endItr; ++it) { if (m_compare(it->first, key)) { @@ -285,7 +285,8 @@ template , iterator find(const key_type& key) { - for (auto it = this->begin(); it != this->end(); ++it) + auto endItr = this->end(); + for (auto it = this->begin(); it != endItr; ++it) { if (m_compare(it->first, key)) { @@ -295,11 +296,11 @@ template , return Container::end(); } - template::value, int> = 0> + template::value, int> = 0> iterator find(KeyType && key) // NOLINT(cppcoreguidelines-missing-std-forward) { - for (auto it = this->begin(); it != this->end(); ++it) + auto endItr = this->end(); + for (auto it = this->begin(); it != endItr; ++it) { if (m_compare(it->first, key)) { @@ -311,7 +312,8 @@ template , const_iterator find(const key_type& key) const { - for (auto it = this->begin(); it != this->end(); ++it) + auto endItr = this->end(); + for (auto it = this->begin(); it != endItr; ++it) { if (m_compare(it->first, key)) { @@ -321,14 +323,15 @@ template , return Container::end(); } - std::pair insert( value_type&& value ) + std::pair insert(value_type&& value) { return emplace(value.first, std::move(value.second)); } - std::pair insert( const value_type& value ) + std::pair insert(const value_type& value) { - for (auto it = this->begin(); it != this->end(); ++it) + auto endItr = this->end(); + for (auto it = this->begin(); it != endItr; ++it) { if (m_compare(it->first, value.first)) {