VectorMap.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. // Description : std::map replacement implemented using sorted vector.
  9. #ifndef CRYINCLUDE_CRYCOMMON_VECTORMAP_H
  10. #define CRYINCLUDE_CRYCOMMON_VECTORMAP_H
  11. #pragma once
  12. #include <CryCommon/StlUtils.h>
  13. //--------------------------------------------------------------------------
  14. // VectorMap
  15. //
  16. // Usage Notes:
  17. // This class is designed to be an (almost, see below) drop-in replacement
  18. // for std::map. It features an almost identical interface, but it is
  19. // implemented using a sorted vector rather than a tree. This is in most
  20. // cases more efficient, as there is less dynamic memory allocation and
  21. // pointer dereferencing.
  22. //
  23. // *************************************************************************
  24. // PLEASE NOTE: There is one vital difference between std::map and VectorMap
  25. // that you will need to note before trying to replace std::map. Since
  26. // VectorMap is implemented using a vector, iterators can and will be
  27. // invalidated by many operations, such as insertions and deletions, and
  28. // due to sorting potentially even normal lookups. Please Please PLEASE make
  29. // sure that you are not storing any iterators to this class.
  30. // *************************************************************************
  31. //
  32. // The class varies from the std::set API in that two of the erase methods
  33. // methods are not of void return type but return an iterator - this is
  34. // required in practice because they invalidate iterators, as noted above.
  35. //
  36. // * iterator erase(iterator where);
  37. // * iterator erase(iterator first, iterator last);
  38. //
  39. //
  40. // Performance Notes:
  41. //
  42. // This class uses the empty base optimization hack to allow comparison
  43. // predicate objects that have no state to take up no space in the object.
  44. // As a result the size of the overall VectorMap instance is the same as
  45. // that of the std::vector it uses to store the elements.
  46. //
  47. // In addition to the normal map interface, this class provides the
  48. // following members that can be used to manage memory requirements:
  49. //
  50. // * void reserve(size_type count);
  51. // Allocate enough space for count elements (see vector::reserve()).
  52. //
  53. // * size_type capacity() const;
  54. // Report how many elements can be stored without reallocating (see
  55. // vector::capacity()).
  56. //
  57. //--------------------------------------------------------------------------
  58. template <typename K, typename V, typename T = std::less<K>, typename A = std::allocator<std::pair <K, V> > >
  59. class VectorMap
  60. : private T // Empty base optimization
  61. {
  62. public:
  63. typedef K key_type;
  64. typedef V mapped_type;
  65. typedef A allocator_type;
  66. typedef std::pair</*const */ key_type, mapped_type> value_type;
  67. typedef T key_compare;
  68. class FirstLess
  69. {
  70. public:
  71. FirstLess(const key_compare& comp)
  72. : m_comp(comp) {}
  73. bool operator()(const value_type& left, const value_type& right) const
  74. {
  75. return m_comp(left.first, right.first);
  76. }
  77. private:
  78. const key_compare& m_comp;
  79. };
  80. typedef std::vector<value_type, allocator_type> container_type;
  81. typedef typename container_type::iterator iterator;
  82. typedef typename container_type::const_iterator const_iterator;
  83. typedef typename container_type::reverse_iterator reverse_iterator;
  84. typedef typename container_type::const_reverse_iterator const_reverse_iterator;
  85. typedef value_type& reference;
  86. typedef const value_type& const_reference;
  87. typedef value_type* pointer;
  88. typedef const value_type* const_pointer;
  89. typedef typename std::allocator_traits<allocator_type>::size_type size_type;
  90. VectorMap();
  91. explicit VectorMap(const key_compare& comp);
  92. explicit VectorMap(const key_compare& comp, const allocator_type& alloc);
  93. VectorMap(const VectorMap& right);
  94. template <class InputIterator>
  95. VectorMap(InputIterator first, InputIterator last);
  96. template <class InputIterator>
  97. VectorMap(InputIterator first, InputIterator last, const key_compare& comp);
  98. template <class InputIterator>
  99. VectorMap(InputIterator first, InputIterator last, const key_compare& comp, const allocator_type& alloc);
  100. void SwapElementsWithVector(container_type& elementVector);
  101. iterator begin();
  102. const_iterator begin() const;
  103. size_type capacity() const;
  104. void clear();
  105. void clearAndFreeMemory();
  106. size_type count(const key_type& key) const;
  107. bool empty() const;
  108. iterator end();
  109. const_iterator end() const;
  110. std::pair<iterator, iterator> equal_range(const key_type& key);
  111. std::pair<const_iterator, const_iterator> equal_range(const key_type& key) const;
  112. iterator erase(iterator where); // See documentation above
  113. iterator erase(iterator first, iterator last); // See documentation above
  114. void erase(const key_type& key);
  115. template <typename Predicate>
  116. void erase_if(const Predicate& predicate);
  117. iterator find(const key_type& key);
  118. const_iterator find(const key_type& key) const;
  119. allocator_type get_allocator() const;
  120. std::pair<iterator, bool> insert(const value_type& val);
  121. iterator insert(iterator where, const value_type& val);
  122. template <class InputIterator>
  123. void insert(InputIterator first, InputIterator last);
  124. key_compare key_comp() const;
  125. iterator lower_bound(const key_type& key);
  126. const_iterator lower_bound(const key_type& key) const;
  127. size_type max_size() const;
  128. reverse_iterator rbegin();
  129. const_reverse_iterator rbegin() const;
  130. reverse_iterator rend();
  131. const_reverse_iterator rend() const;
  132. void reserve(size_type count);
  133. size_type size() const;
  134. void swap(VectorMap& other);
  135. iterator upper_bound(const key_type& key);
  136. const_iterator upper_bound(const key_type& key) const;
  137. mapped_type& operator[](const key_type& key);
  138. template<typename Sizer>
  139. void GetMemoryUsage(Sizer* pSizer) const
  140. {
  141. pSizer->AddObject(m_entries);
  142. }
  143. private:
  144. container_type m_entries;
  145. };
  146. template <typename K, typename V, typename T, typename A>
  147. VectorMap<K, V, T, A>::VectorMap()
  148. {
  149. }
  150. template <typename K, typename V, typename T, typename A>
  151. VectorMap<K, V, T, A>::VectorMap(const key_compare& comp)
  152. : key_compare(comp)
  153. {
  154. }
  155. template <typename K, typename V, typename T, typename A>
  156. VectorMap<K, V, T, A>::VectorMap(const key_compare& comp, const allocator_type& alloc)
  157. : key_compare(comp)
  158. , m_entries(alloc)
  159. {
  160. }
  161. template <typename K, typename V, typename T, typename A>
  162. VectorMap<K, V, T, A>::VectorMap(const VectorMap& right)
  163. : key_compare(right)
  164. , m_entries(right.m_entries)
  165. {
  166. }
  167. template <typename K, typename V, typename T, typename A>
  168. template <class InputIterator>
  169. VectorMap<K, V, T, A>::VectorMap(InputIterator first, InputIterator last)
  170. {
  171. for (; first != last; ++first)
  172. {
  173. m_entries.push_back(*first);
  174. }
  175. std::sort(m_entries.begin(), m_entries.end(), FirstLess(static_cast<key_compare>(*this)));
  176. }
  177. template <typename K, typename V, typename T, typename A>
  178. template <class InputIterator>
  179. VectorMap<K, V, T, A>::VectorMap(InputIterator first, InputIterator last, const key_compare& comp)
  180. : key_compare(comp)
  181. {
  182. for (; first != last; ++first)
  183. {
  184. m_entries.push_back(*first);
  185. }
  186. std::sort(m_entries.begin(), m_entries.end(), FirstLess(static_cast<key_compare>(*this)));
  187. }
  188. template <typename K, typename V, typename T, typename A>
  189. template <class InputIterator>
  190. VectorMap<K, V, T, A>::VectorMap(InputIterator first, InputIterator last, const key_compare& comp, const allocator_type& alloc)
  191. : key_compare(comp)
  192. , m_entries(alloc)
  193. {
  194. for (; first != last; ++first)
  195. {
  196. m_entries.push_back(*first);
  197. }
  198. std::sort(m_entries.begin(), m_entries.end(), FirstLess(static_cast<key_compare>(*this)));
  199. }
  200. template <typename K, typename V, typename T, typename A>
  201. void VectorMap<K, V, T, A>::SwapElementsWithVector(typename VectorMap<K, V, T, A>::container_type& elementVector)
  202. {
  203. m_entries.swap(elementVector);
  204. std::sort(m_entries.begin(), m_entries.end(), FirstLess(static_cast<key_compare>(*this)));
  205. }
  206. template <typename K, typename V, typename T, typename A>
  207. typename VectorMap<K, V, T, A>::iterator VectorMap<K, V, T, A>::begin()
  208. {
  209. return m_entries.begin();
  210. }
  211. template <typename K, typename V, typename T, typename A>
  212. typename VectorMap<K, V, T, A>::const_iterator VectorMap<K, V, T, A>::begin() const
  213. {
  214. return m_entries.begin();
  215. }
  216. template <typename K, typename V, typename T, typename A>
  217. void VectorMap<K, V, T, A>::clear()
  218. {
  219. m_entries.resize(0);
  220. }
  221. template <typename K, typename V, typename T, typename A>
  222. void VectorMap<K, V, T, A>::clearAndFreeMemory()
  223. {
  224. stl::free_container(m_entries);
  225. }
  226. template <typename K, typename V, typename T, typename A>
  227. typename VectorMap<K, V, T, A>::size_type VectorMap<K, V, T, A>::capacity() const
  228. {
  229. return m_entries.capacity();
  230. }
  231. template <typename K, typename V, typename T, typename A>
  232. typename VectorMap<K, V, T, A>::size_type VectorMap<K, V, T, A>::count(const key_type& key) const
  233. {
  234. return size_type(std::binary_search(m_entries.begin(), m_entries.end(), value_type(key, mapped_type()), static_cast<key_compare>(*this)));
  235. }
  236. template <typename K, typename V, typename T, typename A>
  237. bool VectorMap<K, V, T, A>::empty() const
  238. {
  239. return m_entries.empty();
  240. }
  241. template <typename K, typename V, typename T, typename A>
  242. typename VectorMap<K, V, T, A>::iterator VectorMap<K, V, T, A>::end()
  243. {
  244. return m_entries.end();
  245. }
  246. template <typename K, typename V, typename T, typename A>
  247. typename VectorMap<K, V, T, A>::const_iterator VectorMap<K, V, T, A>::end() const
  248. {
  249. return m_entries.end();
  250. }
  251. template <typename K, typename V, typename T, typename A>
  252. std::pair<typename VectorMap<K, V, T, A>::iterator, typename VectorMap<K, V, T, A>::iterator> VectorMap<K, V, T, A>::equal_range(const key_type& key)
  253. {
  254. iterator lower = lower_bound(key);
  255. if (lower != m_entries.end() && key_compare::operator()(key, (*lower).first))
  256. {
  257. lower = m_entries.end();
  258. }
  259. iterator upper = lower;
  260. if (upper != m_entries.end())
  261. {
  262. ++upper;
  263. }
  264. return std::make_pair(lower, upper);
  265. }
  266. template <typename K, typename V, typename T, typename A>
  267. std::pair<typename VectorMap<K, V, T, A>::const_iterator, typename VectorMap<K, V, T, A>::const_iterator> VectorMap<K, V, T, A>::equal_range(const key_type& key) const
  268. {
  269. const_iterator lower = lower_bound(key);
  270. if (lower != m_entries.end() && key_compare::operator()(key, (*lower).first))
  271. {
  272. lower = m_entries.end();
  273. }
  274. const_iterator upper = lower;
  275. if (upper != m_entries.end())
  276. {
  277. ++upper;
  278. }
  279. return std::make_pair(lower, upper);
  280. }
  281. template <typename K, typename V, typename T, typename A>
  282. typename VectorMap<K, V, T, A>::iterator VectorMap<K, V, T, A>::erase(iterator where)
  283. {
  284. return m_entries.erase(where);
  285. }
  286. template <typename K, typename V, typename T, typename A>
  287. template <typename Predicate>
  288. void VectorMap<K, V, T, A>::erase_if(const Predicate& predicate)
  289. {
  290. m_entries.erase(std::remove_if(m_entries.begin(), m_entries.end(), predicate), m_entries.end());
  291. std::sort(m_entries.begin(), m_entries.end(), FirstLess(static_cast<key_compare>(*this)));
  292. }
  293. template <typename K, typename V, typename T, typename A>
  294. typename VectorMap<K, V, T, A>::iterator VectorMap<K, V, T, A>::erase(iterator first, iterator last)
  295. {
  296. return m_entries.erase(first, last);
  297. }
  298. template <typename K, typename V, typename T, typename A>
  299. void VectorMap<K, V, T, A>::erase(const key_type& key)
  300. {
  301. iterator where = find(key);
  302. if (where != m_entries.end())
  303. {
  304. m_entries.erase(where);
  305. }
  306. }
  307. template <typename K, typename V, typename T, typename A>
  308. typename VectorMap<K, V, T, A>::iterator VectorMap<K, V, T, A>::find(const key_type& key)
  309. {
  310. iterator it = lower_bound(key);
  311. if (it != m_entries.end() && key_compare::operator()(key, (*it).first))
  312. {
  313. it = m_entries.end();
  314. }
  315. return it;
  316. }
  317. template <typename K, typename V, typename T, typename A>
  318. typename VectorMap<K, V, T, A>::const_iterator VectorMap<K, V, T, A>::find(const key_type& key) const
  319. {
  320. const_iterator it = lower_bound(key);
  321. if (it != m_entries.end() && key_compare::operator()(key, (*it).first))
  322. {
  323. it = m_entries.end();
  324. }
  325. return it;
  326. }
  327. template <typename K, typename V, typename T, typename A>
  328. typename VectorMap<K, V, T, A>::allocator_type VectorMap<K, V, T, A>::get_allocator() const
  329. {
  330. return m_entries.get_allocator();
  331. }
  332. template <typename K, typename V, typename T, typename A>
  333. std::pair<typename VectorMap<K, V, T, A>::iterator, bool> VectorMap<K, V, T, A>::insert(const value_type& val)
  334. {
  335. iterator it = lower_bound(val.first);
  336. bool insertionMade = false;
  337. if (it == m_entries.end() || key_compare::operator()(val.first, (*it).first))
  338. {
  339. it = m_entries.insert(it, val), insertionMade = true;
  340. }
  341. return std::make_pair(it, insertionMade);
  342. }
  343. template <typename K, typename V, typename T, typename A>
  344. typename VectorMap<K, V, T, A>::iterator VectorMap<K, V, T, A>::insert(iterator where, const value_type& val)
  345. {
  346. return insert(val);
  347. }
  348. template <typename K, typename V, typename T, typename A>
  349. template <class InputIterator>
  350. void VectorMap<K, V, T, A>::insert(InputIterator first, InputIterator last)
  351. {
  352. for (; first != last; ++first)
  353. {
  354. insert(*first);
  355. }
  356. }
  357. template <typename K, typename V, typename T, typename A>
  358. typename VectorMap<K, V, T, A>::key_compare VectorMap<K, V, T, A>::key_comp() const
  359. {
  360. return static_cast<key_compare>(*this);
  361. }
  362. template <typename K, typename V, typename T, typename A>
  363. typename VectorMap<K, V, T, A>::iterator VectorMap<K, V, T, A>::lower_bound(const key_type& key)
  364. {
  365. int count = static_cast<int>(m_entries.size());
  366. iterator first = m_entries.begin();
  367. for (; 0 < count; )
  368. { // divide and conquer, find half that contains answer
  369. int count2 = count / 2;
  370. iterator mid = first + count2;
  371. if (key_compare::operator()(mid->first, key))
  372. {
  373. first = ++mid, count -= count2 + 1;
  374. }
  375. else
  376. {
  377. count = count2;
  378. }
  379. }
  380. return first;
  381. }
  382. template <typename K, typename V, typename T, typename A>
  383. typename VectorMap<K, V, T, A>::const_iterator VectorMap<K, V, T, A>::lower_bound(const key_type& key) const
  384. {
  385. int count = static_cast<int>(m_entries.size());
  386. const_iterator first = m_entries.begin();
  387. for (; 0 < count; )
  388. { // divide and conquer, find half that contains answer
  389. int count2 = count / 2;
  390. const_iterator mid = first + count2;
  391. if (key_compare::operator()(mid->first, key))
  392. {
  393. first = ++mid, count -= count2 + 1;
  394. }
  395. else
  396. {
  397. count = count2;
  398. }
  399. }
  400. return first;
  401. }
  402. template <typename K, typename V, typename T, typename A>
  403. typename VectorMap<K, V, T, A>::size_type VectorMap<K, V, T, A>::max_size() const
  404. {
  405. return m_entries.max_size();
  406. }
  407. template <typename K, typename V, typename T, typename A>
  408. typename VectorMap<K, V, T, A>::reverse_iterator VectorMap<K, V, T, A>::rbegin()
  409. {
  410. return m_entries.rbegin();
  411. }
  412. template <typename K, typename V, typename T, typename A>
  413. typename VectorMap<K, V, T, A>::const_reverse_iterator VectorMap<K, V, T, A>::rbegin() const
  414. {
  415. return m_entries.rbegin();
  416. }
  417. template <typename K, typename V, typename T, typename A>
  418. typename VectorMap<K, V, T, A>::reverse_iterator VectorMap<K, V, T, A>::rend()
  419. {
  420. return m_entries.rend();
  421. }
  422. template <typename K, typename V, typename T, typename A>
  423. typename VectorMap<K, V, T, A>::const_reverse_iterator VectorMap<K, V, T, A>::rend() const
  424. {
  425. return m_entries.rend();
  426. }
  427. template <typename K, typename V, typename T, typename A>
  428. void VectorMap<K, V, T, A>::reserve(size_type count)
  429. {
  430. m_entries.reserve(count);
  431. }
  432. template <typename K, typename V, typename T, typename A>
  433. typename VectorMap<K, V, T, A>::size_type VectorMap<K, V, T, A>::size() const
  434. {
  435. return m_entries.size();
  436. }
  437. template <typename K, typename V, typename T, typename A>
  438. void VectorMap<K, V, T, A>::swap(VectorMap& other)
  439. {
  440. m_entries.swap(other.m_entries);
  441. std::swap(static_cast<key_compare&>(*this), static_cast<key_compare&>(other));
  442. }
  443. template <typename K, typename V, typename T, typename A>
  444. typename VectorMap<K, V, T, A>::iterator VectorMap<K, V, T, A>::upper_bound(const key_type& key)
  445. {
  446. iterator upper = lower_bound(key);
  447. if (upper != m_entries.end() && !key_compare::operator()(key, (*upper).first))
  448. {
  449. ++upper;
  450. }
  451. return upper;
  452. }
  453. template <typename K, typename V, typename T, typename A>
  454. typename VectorMap<K, V, T, A>::const_iterator VectorMap<K, V, T, A>::upper_bound(const key_type& key) const
  455. {
  456. iterator upper = lower_bound(key);
  457. if (upper != m_entries.end() && !key_compare::operator()(key, (*upper).first))
  458. {
  459. ++upper;
  460. }
  461. return upper;
  462. }
  463. template <typename K, typename V, typename T, typename A>
  464. typename VectorMap<K, V, T, A>::mapped_type& VectorMap<K, V, T, A>::operator[](const key_type& key)
  465. {
  466. iterator it = find(key);
  467. if (it == m_entries.end())
  468. {
  469. it = insert(value_type(key, mapped_type())).first;
  470. }
  471. return (*it).second;
  472. }
  473. #endif // CRYINCLUDE_CRYCOMMON_VECTORMAP_H