ordered_map.hpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  1. // __ _____ _____ _____
  2. // __| | __| | | | JSON for Modern C++
  3. // | | |__ | | | | | | version 3.11.2
  4. // |_____|_____|_____|_|___| https://github.com/nlohmann/json
  5. //
  6. // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
  7. // SPDX-License-Identifier: MIT
  8. #pragma once
  9. #include <functional> // equal_to, less
  10. #include <initializer_list> // initializer_list
  11. #include <iterator> // input_iterator_tag, iterator_traits
  12. #include <memory> // allocator
  13. #include <stdexcept> // for out_of_range
  14. #include <type_traits> // enable_if, is_convertible
  15. #include <utility> // pair
  16. #include <vector> // vector
  17. #include <nlohmann/detail/macro_scope.hpp>
  18. #include <nlohmann/detail/meta/type_traits.hpp>
  19. NLOHMANN_JSON_NAMESPACE_BEGIN
  20. /// ordered_map: a minimal map-like container that preserves insertion order
  21. /// for use within nlohmann::basic_json<ordered_map>
  22. template <class Key, class T, class IgnoredLess = std::less<Key>,
  23. class Allocator = std::allocator<std::pair<const Key, T>>>
  24. struct ordered_map : std::vector<std::pair<const Key, T>, Allocator>
  25. {
  26. using key_type = Key;
  27. using mapped_type = T;
  28. using Container = std::vector<std::pair<const Key, T>, Allocator>;
  29. using iterator = typename Container::iterator;
  30. using const_iterator = typename Container::const_iterator;
  31. using size_type = typename Container::size_type;
  32. using value_type = typename Container::value_type;
  33. #ifdef JSON_HAS_CPP_14
  34. using key_compare = std::equal_to<>;
  35. #else
  36. using key_compare = std::equal_to<Key>;
  37. #endif
  38. // Explicit constructors instead of `using Container::Container`
  39. // otherwise older compilers choke on it (GCC <= 5.5, xcode <= 9.4)
  40. ordered_map() noexcept(noexcept(Container())) : Container{} {}
  41. explicit ordered_map(const Allocator& alloc) noexcept(noexcept(Container(alloc))) : Container{alloc} {}
  42. template <class It>
  43. ordered_map(It first, It last, const Allocator& alloc = Allocator())
  44. : Container{first, last, alloc} {}
  45. ordered_map(std::initializer_list<value_type> init, const Allocator& alloc = Allocator() )
  46. : Container{init, alloc} {}
  47. std::pair<iterator, bool> emplace(const key_type& key, T&& t)
  48. {
  49. for (auto it = this->begin(); it != this->end(); ++it)
  50. {
  51. if (m_compare(it->first, key))
  52. {
  53. return {it, false};
  54. }
  55. }
  56. Container::emplace_back(key, std::forward<T>(t));
  57. return {std::prev(this->end()), true};
  58. }
  59. template<class KeyType, detail::enable_if_t<
  60. detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
  61. std::pair<iterator, bool> emplace(KeyType && key, T && t)
  62. {
  63. for (auto it = this->begin(); it != this->end(); ++it)
  64. {
  65. if (m_compare(it->first, key))
  66. {
  67. return {it, false};
  68. }
  69. }
  70. Container::emplace_back(std::forward<KeyType>(key), std::forward<T>(t));
  71. return {std::prev(this->end()), true};
  72. }
  73. T& operator[](const key_type& key)
  74. {
  75. return emplace(key, T{}).first->second;
  76. }
  77. template<class KeyType, detail::enable_if_t<
  78. detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
  79. T & operator[](KeyType && key)
  80. {
  81. return emplace(std::forward<KeyType>(key), T{}).first->second;
  82. }
  83. const T& operator[](const key_type& key) const
  84. {
  85. return at(key);
  86. }
  87. template<class KeyType, detail::enable_if_t<
  88. detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
  89. const T & operator[](KeyType && key) const
  90. {
  91. return at(std::forward<KeyType>(key));
  92. }
  93. T& at(const key_type& key)
  94. {
  95. for (auto it = this->begin(); it != this->end(); ++it)
  96. {
  97. if (m_compare(it->first, key))
  98. {
  99. return it->second;
  100. }
  101. }
  102. JSON_THROW(std::out_of_range("key not found"));
  103. }
  104. template<class KeyType, detail::enable_if_t<
  105. detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
  106. T & at(KeyType && key)
  107. {
  108. for (auto it = this->begin(); it != this->end(); ++it)
  109. {
  110. if (m_compare(it->first, key))
  111. {
  112. return it->second;
  113. }
  114. }
  115. JSON_THROW(std::out_of_range("key not found"));
  116. }
  117. const T& at(const key_type& key) const
  118. {
  119. for (auto it = this->begin(); it != this->end(); ++it)
  120. {
  121. if (m_compare(it->first, key))
  122. {
  123. return it->second;
  124. }
  125. }
  126. JSON_THROW(std::out_of_range("key not found"));
  127. }
  128. template<class KeyType, detail::enable_if_t<
  129. detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
  130. const T & at(KeyType && key) const
  131. {
  132. for (auto it = this->begin(); it != this->end(); ++it)
  133. {
  134. if (m_compare(it->first, key))
  135. {
  136. return it->second;
  137. }
  138. }
  139. JSON_THROW(std::out_of_range("key not found"));
  140. }
  141. size_type erase(const key_type& key)
  142. {
  143. for (auto it = this->begin(); it != this->end(); ++it)
  144. {
  145. if (m_compare(it->first, key))
  146. {
  147. // Since we cannot move const Keys, re-construct them in place
  148. for (auto next = it; ++next != this->end(); ++it)
  149. {
  150. it->~value_type(); // Destroy but keep allocation
  151. new (&*it) value_type{std::move(*next)};
  152. }
  153. Container::pop_back();
  154. return 1;
  155. }
  156. }
  157. return 0;
  158. }
  159. template<class KeyType, detail::enable_if_t<
  160. detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
  161. size_type erase(KeyType && key)
  162. {
  163. for (auto it = this->begin(); it != this->end(); ++it)
  164. {
  165. if (m_compare(it->first, key))
  166. {
  167. // Since we cannot move const Keys, re-construct them in place
  168. for (auto next = it; ++next != this->end(); ++it)
  169. {
  170. it->~value_type(); // Destroy but keep allocation
  171. new (&*it) value_type{std::move(*next)};
  172. }
  173. Container::pop_back();
  174. return 1;
  175. }
  176. }
  177. return 0;
  178. }
  179. iterator erase(iterator pos)
  180. {
  181. return erase(pos, std::next(pos));
  182. }
  183. iterator erase(iterator first, iterator last)
  184. {
  185. if (first == last)
  186. {
  187. return first;
  188. }
  189. const auto elements_affected = std::distance(first, last);
  190. const auto offset = std::distance(Container::begin(), first);
  191. // This is the start situation. We need to delete elements_affected
  192. // elements (3 in this example: e, f, g), and need to return an
  193. // iterator past the last deleted element (h in this example).
  194. // Note that offset is the distance from the start of the vector
  195. // to first. We will need this later.
  196. // [ a, b, c, d, e, f, g, h, i, j ]
  197. // ^ ^
  198. // first last
  199. // Since we cannot move const Keys, we re-construct them in place.
  200. // We start at first and re-construct (viz. copy) the elements from
  201. // the back of the vector. Example for first iteration:
  202. // ,--------.
  203. // v | destroy e and re-construct with h
  204. // [ a, b, c, d, e, f, g, h, i, j ]
  205. // ^ ^
  206. // it it + elements_affected
  207. for (auto it = first; std::next(it, elements_affected) != Container::end(); ++it)
  208. {
  209. it->~value_type(); // destroy but keep allocation
  210. new (&*it) value_type{std::move(*std::next(it, elements_affected))}; // "move" next element to it
  211. }
  212. // [ a, b, c, d, h, i, j, h, i, j ]
  213. // ^ ^
  214. // first last
  215. // remove the unneeded elements at the end of the vector
  216. Container::resize(this->size() - static_cast<size_type>(elements_affected));
  217. // [ a, b, c, d, h, i, j ]
  218. // ^ ^
  219. // first last
  220. // first is now pointing past the last deleted element, but we cannot
  221. // use this iterator, because it may have been invalidated by the
  222. // resize call. Instead, we can return begin() + offset.
  223. return Container::begin() + offset;
  224. }
  225. size_type count(const key_type& key) const
  226. {
  227. for (auto it = this->begin(); it != this->end(); ++it)
  228. {
  229. if (m_compare(it->first, key))
  230. {
  231. return 1;
  232. }
  233. }
  234. return 0;
  235. }
  236. template<class KeyType, detail::enable_if_t<
  237. detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
  238. size_type count(KeyType && key) const
  239. {
  240. for (auto it = this->begin(); it != this->end(); ++it)
  241. {
  242. if (m_compare(it->first, key))
  243. {
  244. return 1;
  245. }
  246. }
  247. return 0;
  248. }
  249. iterator find(const key_type& key)
  250. {
  251. for (auto it = this->begin(); it != this->end(); ++it)
  252. {
  253. if (m_compare(it->first, key))
  254. {
  255. return it;
  256. }
  257. }
  258. return Container::end();
  259. }
  260. template<class KeyType, detail::enable_if_t<
  261. detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
  262. iterator find(KeyType && key)
  263. {
  264. for (auto it = this->begin(); it != this->end(); ++it)
  265. {
  266. if (m_compare(it->first, key))
  267. {
  268. return it;
  269. }
  270. }
  271. return Container::end();
  272. }
  273. const_iterator find(const key_type& key) const
  274. {
  275. for (auto it = this->begin(); it != this->end(); ++it)
  276. {
  277. if (m_compare(it->first, key))
  278. {
  279. return it;
  280. }
  281. }
  282. return Container::end();
  283. }
  284. std::pair<iterator, bool> insert( value_type&& value )
  285. {
  286. return emplace(value.first, std::move(value.second));
  287. }
  288. std::pair<iterator, bool> insert( const value_type& value )
  289. {
  290. for (auto it = this->begin(); it != this->end(); ++it)
  291. {
  292. if (m_compare(it->first, value.first))
  293. {
  294. return {it, false};
  295. }
  296. }
  297. Container::push_back(value);
  298. return {--this->end(), true};
  299. }
  300. template<typename InputIt>
  301. using require_input_iter = typename std::enable_if<std::is_convertible<typename std::iterator_traits<InputIt>::iterator_category,
  302. std::input_iterator_tag>::value>::type;
  303. template<typename InputIt, typename = require_input_iter<InputIt>>
  304. void insert(InputIt first, InputIt last)
  305. {
  306. for (auto it = first; it != last; ++it)
  307. {
  308. insert(*it);
  309. }
  310. }
  311. private:
  312. JSON_NO_UNIQUE_ADDRESS key_compare m_compare = key_compare();
  313. };
  314. NLOHMANN_JSON_NAMESPACE_END