HashMap.h 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. // Copyright (C) 2014, Panagiotis Christopoulos Charitos.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #ifndef ANKI_UTIL_HASH_MAP_H
  6. #define ANKI_UTIL_HASH_MAP_H
  7. #include "anki/util/Allocator.h"
  8. #include "anki/util/NonCopyable.h"
  9. /// @addtogroup util_private
  10. /// @{
  11. /// HashMap node.
  12. template<typename T>
  13. class HashMapNode
  14. {
  15. public:
  16. using Value = T;
  17. Value m_value;
  18. U64 m_hash;
  19. HashMapNode* m_prev = nullptr;
  20. HashMapNode* m_next = nullptr;
  21. template<typename... TArgs>
  22. HashMapNode(TArgs&&... args)
  23. : m_value(std::forward<TArgs>(args)...)
  24. {}
  25. };
  26. /// HashMap bidirectional iterator.
  27. template<typename TNodePointer, typename TValuePointer,
  28. typename TValueReference, typename THashMapPointer>
  29. class HashMapIterator
  30. {
  31. public:
  32. TNodePointer m_node = nullptr;
  33. THashMapPointer m_map = nullptr; ///< Used to go back from the end
  34. HashMapIterator() = default;
  35. HashMapIterator(const HashMapIterator& b)
  36. : m_node(b.m_node),
  37. m_map(b.m_map)
  38. {}
  39. /// Allow conversion from iterator to const iterator.
  40. template<typename YNodePointer, typename YValuePointer,
  41. typename YValueReference, typename YHashMap>
  42. HashMapIterator(const HashMapIterator<YNodePointer,
  43. YValuePointer, YValueReference, YHashMap>& b)
  44. : m_node(b.m_node),
  45. m_map(b.m_map)
  46. {}
  47. HashMapIterator(TNodePointer node, THashMapPointer list)
  48. : m_node(node),
  49. m_map(list)
  50. {
  51. ANKI_ASSERT(list);
  52. }
  53. TValueReference operator*() const
  54. {
  55. ANKI_ASSERT(m_node);
  56. return m_node->m_value;
  57. }
  58. TValuePointer operator->() const
  59. {
  60. ANKI_ASSERT(m_node);
  61. return &m_node->m_value;
  62. }
  63. HashMapIterator& operator++()
  64. {
  65. ANKI_ASSERT(m_node);
  66. m_node = m_node->m_next;
  67. return *this;
  68. }
  69. HashMapIterator operator++(int)
  70. {
  71. ANKI_ASSERT(m_node);
  72. HashMapIterator out = *this;
  73. ++(*this);
  74. return out;
  75. }
  76. HashMapIterator& operator--();
  77. HashMapIterator operator--(int)
  78. {
  79. ANKI_ASSERT(m_node);
  80. HashMapIterator out = *this;
  81. --(*this);
  82. return out;
  83. }
  84. HashMapIterator operator+(U n) const
  85. {
  86. HashMapIterator it = *this;
  87. while(n-- != 0)
  88. {
  89. ++it;
  90. }
  91. return it;
  92. }
  93. HashMapIterator operator-(U n) const
  94. {
  95. HashMapIterator it = *this;
  96. while(n-- != 0)
  97. {
  98. --it;
  99. }
  100. return it;
  101. }
  102. HashMapIterator& operator+=(U n)
  103. {
  104. while(n-- != 0)
  105. {
  106. ++(*this);
  107. }
  108. return *this;
  109. }
  110. HashMapIterator& operator-=(U n)
  111. {
  112. while(n-- != 0)
  113. {
  114. --(*this);
  115. }
  116. return *this;
  117. }
  118. Bool operator==(const HashMapIterator& b) const
  119. {
  120. ANKI_ASSERT(m_list == b.m_list
  121. && "Comparing iterators from different lists");
  122. return m_node == b.m_node;
  123. }
  124. Bool operator!=(const HashMapIterator& b) const
  125. {
  126. return !(*this == b);
  127. }
  128. };
  129. /// @}
  130. /// @addtogroup util_containers
  131. /// @{
  132. /// Hash map template.
  133. template<typename T>
  134. class HashMap
  135. {
  136. public:
  137. using Value = T;
  138. using Node = HashMapNode<Value>;
  139. using Reference = Value&;
  140. using ConstReference = const Value&;
  141. using Pointer = Value*;
  142. using ConstPointer = const Value*;
  143. HashMap() = default;
  144. /// Move.
  145. HashMap(HashMap&& b)
  146. : HashMap()
  147. {
  148. move(b);
  149. }
  150. /// You need to manually destroy the map.
  151. /// @see HashMap::destroy
  152. ~HashMap()
  153. {
  154. ANKI_ASSERT(m_root == nullptr && "Requires manual destruction");
  155. }
  156. /// Move.
  157. HashMap& operator=(HashMap&& b)
  158. {
  159. move(b);
  160. return *this;
  161. }
  162. /// Return true if map is empty.
  163. Bool isEmpty() const
  164. {
  165. return m_root == nullptr;
  166. }
  167. private:
  168. Node* m_root = nullptr;
  169. void move(HashMap& b)
  170. {
  171. ANKI_ASSERT(isEmpty() && "Cannot move before destroying");
  172. m_root = b.m_root;
  173. b.m_root = nullptr;
  174. }
  175. };
  176. /// @}
  177. #endif