29 struct ordered_map : std::vector<std::pair<const Key, T>, Allocator>
32 using mapped_type = T;
33 using Container = std::vector<std::pair<const Key, T>, Allocator>;
34 using iterator =
typename Container::iterator;
35 using const_iterator =
typename Container::const_iterator;
36 using size_type =
typename Container::size_type;
37 using value_type =
typename Container::value_type;
39 using key_compare = std::equal_to<>;
41 using key_compare = std::equal_to<Key>;
46 ordered_map()
noexcept(
noexcept(Container())) : Container{} {}
47 explicit ordered_map(
const Allocator& alloc)
noexcept(
noexcept(Container(alloc))) : Container{alloc} {}
49 ordered_map(It first, It last,
const Allocator& alloc = Allocator())
50 : Container{first, last, alloc} {}
51 ordered_map(std::initializer_list<value_type> init,
const Allocator& alloc = Allocator() )
52 : Container{init, alloc} {}
54 std::pair<iterator, bool> emplace(
const key_type& key, T&& t)
56 for (
auto it = this->begin(); it != this->end(); ++it)
58 if (m_compare(it->first, key))
63 Container::emplace_back(key, std::forward<T>(t));
64 return {std::prev(this->end()),
true};
67 template<
class KeyType, detail::enable_if_t<
68 detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value,
int> = 0>
69 std::pair<iterator, bool> emplace(KeyType && key, T && t)
71 for (
auto it = this->begin(); it != this->end(); ++it)
73 if (m_compare(it->first, key))
78 Container::emplace_back(std::forward<KeyType>(key), std::forward<T>(t));
79 return {std::prev(this->end()),
true};
82 T& operator[](
const key_type& key)
84 return emplace(key, T{}).first->second;
87 template<
class KeyType, detail::enable_if_t<
88 detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value,
int> = 0>
89 T & operator[](KeyType && key)
91 return emplace(std::forward<KeyType>(key), T{}).first->second;
94 const T& operator[](
const key_type& key)
const
99 template<
class KeyType, detail::enable_if_t<
100 detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value,
int> = 0>
101 const T & operator[](KeyType && key)
const
103 return at(std::forward<KeyType>(key));
106 T& at(
const key_type& key)
108 for (
auto it = this->begin(); it != this->end(); ++it)
110 if (m_compare(it->first, key))
116 JSON_THROW(std::out_of_range(
"key not found"));
119 template<
class KeyType, detail::enable_if_t<
120 detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value,
int> = 0>
121 T & at(KeyType && key)
123 for (
auto it = this->begin(); it != this->end(); ++it)
125 if (m_compare(it->first, key))
131 JSON_THROW(std::out_of_range(
"key not found"));
134 const T& at(
const key_type& key)
const
136 for (
auto it = this->begin(); it != this->end(); ++it)
138 if (m_compare(it->first, key))
144 JSON_THROW(std::out_of_range(
"key not found"));
147 template<
class KeyType, detail::enable_if_t<
148 detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value,
int> = 0>
149 const T & at(KeyType && key)
const
151 for (
auto it = this->begin(); it != this->end(); ++it)
153 if (m_compare(it->first, key))
159 JSON_THROW(std::out_of_range(
"key not found"));
162 size_type erase(
const key_type& key)
164 for (
auto it = this->begin(); it != this->end(); ++it)
166 if (m_compare(it->first, key))
169 for (
auto next = it; ++next != this->end(); ++it)
172 new (&*it) value_type{std::move(*next)};
174 Container::pop_back();
181 template<
class KeyType, detail::enable_if_t<
182 detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value,
int> = 0>
183 size_type erase(KeyType && key)
185 for (
auto it = this->begin(); it != this->end(); ++it)
187 if (m_compare(it->first, key))
190 for (
auto next = it; ++next != this->end(); ++it)
193 new (&*it) value_type{std::move(*next)};
195 Container::pop_back();
202 iterator erase(iterator pos)
204 return erase(pos, std::next(pos));
207 iterator erase(iterator first, iterator last)
214 const auto elements_affected = std::distance(first, last);
215 const auto offset = std::distance(Container::begin(), first);
237 for (
auto it = first; std::next(it, elements_affected) != Container::end(); ++it)
240 new (&*it) value_type{std::move(*std::next(it, elements_affected))};
248 Container::resize(this->size() -
static_cast<size_type
>(elements_affected));
257 return Container::begin() + offset;
260 size_type count(
const key_type& key)
const
262 for (
auto it = this->begin(); it != this->end(); ++it)
264 if (m_compare(it->first, key))
272 template<
class KeyType, detail::enable_if_t<
273 detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value,
int> = 0>
274 size_type count(KeyType && key)
const
276 for (
auto it = this->begin(); it != this->end(); ++it)
278 if (m_compare(it->first, key))
286 iterator find(
const key_type& key)
288 for (
auto it = this->begin(); it != this->end(); ++it)
290 if (m_compare(it->first, key))
295 return Container::end();
298 template<
class KeyType, detail::enable_if_t<
299 detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value,
int> = 0>
300 iterator find(KeyType && key)
302 for (
auto it = this->begin(); it != this->end(); ++it)
304 if (m_compare(it->first, key))
309 return Container::end();
312 const_iterator find(
const key_type& key)
const
314 for (
auto it = this->begin(); it != this->end(); ++it)
316 if (m_compare(it->first, key))
321 return Container::end();
324 std::pair<iterator, bool> insert( value_type&& value )
326 return emplace(value.first, std::move(value.second));
329 std::pair<iterator, bool> insert(
const value_type& value )
331 for (
auto it = this->begin(); it != this->end(); ++it)
333 if (m_compare(it->first, value.first))
338 Container::push_back(value);
339 return {--this->end(),
true};
342 template<
typename InputIt>
343 using require_input_iter =
typename std::enable_if<std::is_convertible<typename std::iterator_traits<InputIt>::iterator_category,
344 std::input_iterator_tag>::value>::type;
346 template<
typename InputIt,
typename = require_input_iter<InputIt>>
347 void insert(InputIt first, InputIt last)
349 for (
auto it = first; it != last; ++it)
356 JSON_NO_UNIQUE_ADDRESS key_compare m_compare = key_compare();