Warning, file /include/nlohmann/ordered_map.hpp was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include <functional> // equal_to, less
0012 #include <initializer_list> // initializer_list
0013 #include <iterator> // input_iterator_tag, iterator_traits
0014 #include <memory> // allocator
0015 #include <stdexcept> // for out_of_range
0016 #include <type_traits> // enable_if, is_convertible
0017 #include <utility> // pair
0018 #include <vector> // vector
0019
0020 #include <nlohmann/detail/macro_scope.hpp>
0021 #include <nlohmann/detail/meta/type_traits.hpp>
0022
0023 NLOHMANN_JSON_NAMESPACE_BEGIN
0024
0025
0026
0027 template <class Key, class T, class IgnoredLess = std::less<Key>,
0028 class Allocator = std::allocator<std::pair<const Key, T>>>
0029 struct ordered_map : std::vector<std::pair<const Key, T>, Allocator>
0030 {
0031 using key_type = Key;
0032 using mapped_type = T;
0033 using Container = std::vector<std::pair<const Key, T>, Allocator>;
0034 using iterator = typename Container::iterator;
0035 using const_iterator = typename Container::const_iterator;
0036 using size_type = typename Container::size_type;
0037 using value_type = typename Container::value_type;
0038 #ifdef JSON_HAS_CPP_14
0039 using key_compare = std::equal_to<>;
0040 #else
0041 using key_compare = std::equal_to<Key>;
0042 #endif
0043
0044
0045
0046 ordered_map() noexcept(noexcept(Container())) : Container{} {}
0047 explicit ordered_map(const Allocator& alloc) noexcept(noexcept(Container(alloc))) : Container{alloc} {}
0048 template <class It>
0049 ordered_map(It first, It last, const Allocator& alloc = Allocator())
0050 : Container{first, last, alloc} {}
0051 ordered_map(std::initializer_list<value_type> init, const Allocator& alloc = Allocator() )
0052 : Container{init, alloc} {}
0053
0054 std::pair<iterator, bool> emplace(const key_type& key, T&& t)
0055 {
0056 for (auto it = this->begin(); it != this->end(); ++it)
0057 {
0058 if (m_compare(it->first, key))
0059 {
0060 return {it, false};
0061 }
0062 }
0063 Container::emplace_back(key, std::forward<T>(t));
0064 return {std::prev(this->end()), true};
0065 }
0066
0067 template<class KeyType, detail::enable_if_t<
0068 detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
0069 std::pair<iterator, bool> emplace(KeyType && key, T && t)
0070 {
0071 for (auto it = this->begin(); it != this->end(); ++it)
0072 {
0073 if (m_compare(it->first, key))
0074 {
0075 return {it, false};
0076 }
0077 }
0078 Container::emplace_back(std::forward<KeyType>(key), std::forward<T>(t));
0079 return {std::prev(this->end()), true};
0080 }
0081
0082 T& operator[](const key_type& key)
0083 {
0084 return emplace(key, T{}).first->second;
0085 }
0086
0087 template<class KeyType, detail::enable_if_t<
0088 detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
0089 T & operator[](KeyType && key)
0090 {
0091 return emplace(std::forward<KeyType>(key), T{}).first->second;
0092 }
0093
0094 const T& operator[](const key_type& key) const
0095 {
0096 return at(key);
0097 }
0098
0099 template<class KeyType, detail::enable_if_t<
0100 detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
0101 const T & operator[](KeyType && key) const
0102 {
0103 return at(std::forward<KeyType>(key));
0104 }
0105
0106 T& at(const key_type& key)
0107 {
0108 for (auto it = this->begin(); it != this->end(); ++it)
0109 {
0110 if (m_compare(it->first, key))
0111 {
0112 return it->second;
0113 }
0114 }
0115
0116 JSON_THROW(std::out_of_range("key not found"));
0117 }
0118
0119 template<class KeyType, detail::enable_if_t<
0120 detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
0121 T & at(KeyType && key)
0122 {
0123 for (auto it = this->begin(); it != this->end(); ++it)
0124 {
0125 if (m_compare(it->first, key))
0126 {
0127 return it->second;
0128 }
0129 }
0130
0131 JSON_THROW(std::out_of_range("key not found"));
0132 }
0133
0134 const T& at(const key_type& key) const
0135 {
0136 for (auto it = this->begin(); it != this->end(); ++it)
0137 {
0138 if (m_compare(it->first, key))
0139 {
0140 return it->second;
0141 }
0142 }
0143
0144 JSON_THROW(std::out_of_range("key not found"));
0145 }
0146
0147 template<class KeyType, detail::enable_if_t<
0148 detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
0149 const T & at(KeyType && key) const
0150 {
0151 for (auto it = this->begin(); it != this->end(); ++it)
0152 {
0153 if (m_compare(it->first, key))
0154 {
0155 return it->second;
0156 }
0157 }
0158
0159 JSON_THROW(std::out_of_range("key not found"));
0160 }
0161
0162 size_type erase(const key_type& key)
0163 {
0164 for (auto it = this->begin(); it != this->end(); ++it)
0165 {
0166 if (m_compare(it->first, key))
0167 {
0168
0169 for (auto next = it; ++next != this->end(); ++it)
0170 {
0171 it->~value_type();
0172 new (&*it) value_type{std::move(*next)};
0173 }
0174 Container::pop_back();
0175 return 1;
0176 }
0177 }
0178 return 0;
0179 }
0180
0181 template<class KeyType, detail::enable_if_t<
0182 detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
0183 size_type erase(KeyType && key)
0184 {
0185 for (auto it = this->begin(); it != this->end(); ++it)
0186 {
0187 if (m_compare(it->first, key))
0188 {
0189
0190 for (auto next = it; ++next != this->end(); ++it)
0191 {
0192 it->~value_type();
0193 new (&*it) value_type{std::move(*next)};
0194 }
0195 Container::pop_back();
0196 return 1;
0197 }
0198 }
0199 return 0;
0200 }
0201
0202 iterator erase(iterator pos)
0203 {
0204 return erase(pos, std::next(pos));
0205 }
0206
0207 iterator erase(iterator first, iterator last)
0208 {
0209 if (first == last)
0210 {
0211 return first;
0212 }
0213
0214 const auto elements_affected = std::distance(first, last);
0215 const auto offset = std::distance(Container::begin(), first);
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234
0235
0236
0237 for (auto it = first; std::next(it, elements_affected) != Container::end(); ++it)
0238 {
0239 it->~value_type();
0240 new (&*it) value_type{std::move(*std::next(it, elements_affected))};
0241 }
0242
0243
0244
0245
0246
0247
0248 Container::resize(this->size() - static_cast<size_type>(elements_affected));
0249
0250
0251
0252
0253
0254
0255
0256
0257 return Container::begin() + offset;
0258 }
0259
0260 size_type count(const key_type& key) const
0261 {
0262 for (auto it = this->begin(); it != this->end(); ++it)
0263 {
0264 if (m_compare(it->first, key))
0265 {
0266 return 1;
0267 }
0268 }
0269 return 0;
0270 }
0271
0272 template<class KeyType, detail::enable_if_t<
0273 detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
0274 size_type count(KeyType && key) const
0275 {
0276 for (auto it = this->begin(); it != this->end(); ++it)
0277 {
0278 if (m_compare(it->first, key))
0279 {
0280 return 1;
0281 }
0282 }
0283 return 0;
0284 }
0285
0286 iterator find(const key_type& key)
0287 {
0288 for (auto it = this->begin(); it != this->end(); ++it)
0289 {
0290 if (m_compare(it->first, key))
0291 {
0292 return it;
0293 }
0294 }
0295 return Container::end();
0296 }
0297
0298 template<class KeyType, detail::enable_if_t<
0299 detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
0300 iterator find(KeyType && key)
0301 {
0302 for (auto it = this->begin(); it != this->end(); ++it)
0303 {
0304 if (m_compare(it->first, key))
0305 {
0306 return it;
0307 }
0308 }
0309 return Container::end();
0310 }
0311
0312 const_iterator find(const key_type& key) const
0313 {
0314 for (auto it = this->begin(); it != this->end(); ++it)
0315 {
0316 if (m_compare(it->first, key))
0317 {
0318 return it;
0319 }
0320 }
0321 return Container::end();
0322 }
0323
0324 std::pair<iterator, bool> insert( value_type&& value )
0325 {
0326 return emplace(value.first, std::move(value.second));
0327 }
0328
0329 std::pair<iterator, bool> insert( const value_type& value )
0330 {
0331 for (auto it = this->begin(); it != this->end(); ++it)
0332 {
0333 if (m_compare(it->first, value.first))
0334 {
0335 return {it, false};
0336 }
0337 }
0338 Container::push_back(value);
0339 return {--this->end(), true};
0340 }
0341
0342 template<typename InputIt>
0343 using require_input_iter = typename std::enable_if<std::is_convertible<typename std::iterator_traits<InputIt>::iterator_category,
0344 std::input_iterator_tag>::value>::type;
0345
0346 template<typename InputIt, typename = require_input_iter<InputIt>>
0347 void insert(InputIt first, InputIt last)
0348 {
0349 for (auto it = first; it != last; ++it)
0350 {
0351 insert(*it);
0352 }
0353 }
0354
0355 private:
0356 JSON_NO_UNIQUE_ADDRESS key_compare m_compare = key_compare();
0357 };
0358
0359 NLOHMANN_JSON_NAMESPACE_END