List.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668
  1. // Copyright (C) 2009-present, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #pragma once
  6. #include <AnKi/Util/MemoryPool.h>
  7. #include <AnKi/Util/Forward.h>
  8. #include <functional>
  9. namespace anki {
  10. /// @addtogroup util_containers
  11. /// @{
  12. namespace detail {
  13. /// List node.
  14. /// @internal
  15. template<typename T>
  16. class ListNode
  17. {
  18. public:
  19. T m_value;
  20. ListNode* m_prev = nullptr;
  21. ListNode* m_next = nullptr;
  22. template<typename... TArgs>
  23. ListNode(TArgs&&... args)
  24. : m_value(std::forward<TArgs>(args)...)
  25. {
  26. }
  27. };
  28. /// Gets the value of a list node.
  29. /// @internal
  30. template<typename TNode, typename TValue>
  31. class GetListNodeValueFunc
  32. {
  33. public:
  34. TValue& operator()(TNode& node);
  35. const TValue& operator()(const TNode& node) const;
  36. };
  37. /// Specialization for ListNode
  38. /// @internal
  39. template<typename TValue>
  40. class GetListNodeValueFunc<ListNode<TValue>, TValue>
  41. {
  42. public:
  43. TValue& operator()(ListNode<TValue>& node)
  44. {
  45. return node.m_value;
  46. }
  47. const TValue& operator()(const ListNode<TValue>& node) const
  48. {
  49. return node.m_value;
  50. }
  51. };
  52. /// List bidirectional iterator.
  53. /// @internal
  54. template<typename TNodePointer, typename TValuePointer, typename TValueReference, typename TListPointer>
  55. class ListIterator
  56. {
  57. template<typename, typename>
  58. friend class ListBase;
  59. template<typename, typename>
  60. friend class anki::List;
  61. template<typename, typename, typename, typename>
  62. friend class ListIterator;
  63. public:
  64. ListIterator() = default;
  65. ListIterator(const ListIterator& b)
  66. : m_node(b.m_node)
  67. , m_list(b.m_list)
  68. {
  69. }
  70. /// Allow conversion from iterator to const iterator.
  71. template<typename YNodePointer, typename YValuePointer, typename YValueReference, typename YList>
  72. ListIterator(const ListIterator<YNodePointer, YValuePointer, YValueReference, YList>& b)
  73. : m_node(b.m_node)
  74. , m_list(b.m_list)
  75. {
  76. }
  77. ListIterator(TNodePointer node, TListPointer list)
  78. : m_node(node)
  79. , m_list(list)
  80. {
  81. ANKI_ASSERT(list);
  82. }
  83. ListIterator& operator=(const ListIterator& b)
  84. {
  85. m_node = b.m_node;
  86. m_list = b.m_list;
  87. return *this;
  88. }
  89. TValueReference operator*() const
  90. {
  91. ANKI_ASSERT(m_node);
  92. using NodeType = typename RemovePointer<TNodePointer>::Type;
  93. using ValueType = typename RemovePointer<TValuePointer>::Type;
  94. return detail::GetListNodeValueFunc<NodeType, ValueType>()(*m_node);
  95. }
  96. TValuePointer operator->() const
  97. {
  98. ANKI_ASSERT(m_node);
  99. using NodeType = typename RemovePointer<TNodePointer>::Type;
  100. using ValueType = typename RemovePointer<TValuePointer>::Type;
  101. return &detail::GetListNodeValueFunc<NodeType, ValueType>()(*m_node);
  102. }
  103. ListIterator& operator++()
  104. {
  105. ANKI_ASSERT(m_node);
  106. m_node = m_node->m_next;
  107. return *this;
  108. }
  109. ListIterator operator++(int)
  110. {
  111. ANKI_ASSERT(m_node);
  112. ListIterator out = *this;
  113. ++(*this);
  114. return out;
  115. }
  116. ListIterator& operator--();
  117. ListIterator operator--(int)
  118. {
  119. ANKI_ASSERT(m_node);
  120. ListIterator out = *this;
  121. --(*this);
  122. return out;
  123. }
  124. ListIterator operator+(U n) const
  125. {
  126. ListIterator it = *this;
  127. while(n-- != 0)
  128. {
  129. ++it;
  130. }
  131. return it;
  132. }
  133. ListIterator operator-(U n) const
  134. {
  135. ListIterator it = *this;
  136. while(n-- != 0)
  137. {
  138. --it;
  139. }
  140. return it;
  141. }
  142. ListIterator& operator+=(U n)
  143. {
  144. while(n-- != 0)
  145. {
  146. ++(*this);
  147. }
  148. return *this;
  149. }
  150. ListIterator& operator-=(U n)
  151. {
  152. while(n-- != 0)
  153. {
  154. --(*this);
  155. }
  156. return *this;
  157. }
  158. template<typename YNodePointer, typename YValuePointer, typename YValueReference, typename YList>
  159. Bool operator==(const ListIterator<YNodePointer, YValuePointer, YValueReference, YList>& b) const
  160. {
  161. ANKI_ASSERT(m_list == b.m_list && "Comparing iterators from different lists");
  162. return m_node == b.m_node;
  163. }
  164. template<typename YNodePointer, typename YValuePointer, typename YValueReference, typename YList>
  165. Bool operator!=(const ListIterator<YNodePointer, YValuePointer, YValueReference, YList>& b) const
  166. {
  167. return !(*this == b);
  168. }
  169. private:
  170. TNodePointer m_node = nullptr;
  171. TListPointer m_list = nullptr; ///< Used to go back from the end
  172. };
  173. /// Double linked list base.
  174. /// @internal
  175. template<typename T, typename TNode>
  176. class ListBase
  177. {
  178. template<typename, typename, typename, typename>
  179. friend class ListIterator;
  180. public:
  181. using Value = T;
  182. using Reference = Value&;
  183. using ConstReference = const Value&;
  184. using Pointer = Value*;
  185. using ConstPointer = const Value*;
  186. using Iterator = ListIterator<TNode*, Pointer, Reference, ListBase*>;
  187. using ConstIterator = ListIterator<const TNode*, ConstPointer, ConstReference, const ListBase*>;
  188. ListBase() = default;
  189. ListBase(ListBase&& b)
  190. {
  191. move(b);
  192. }
  193. ListBase(const ListBase&) = delete; // Non-copyable
  194. ListBase& operator=(const ListBase&) = delete; // Non-copyable
  195. ListBase& operator=(ListBase&& b)
  196. {
  197. move(b);
  198. return *this;
  199. }
  200. /// Compare with another list.
  201. Bool operator==(const ListBase& b) const;
  202. /// Get first element.
  203. ConstReference getFront() const
  204. {
  205. ANKI_ASSERT(!isEmpty());
  206. return detail::GetListNodeValueFunc<TNode, T>()(*m_head);
  207. }
  208. /// Get first element.
  209. Reference getFront()
  210. {
  211. ANKI_ASSERT(!isEmpty());
  212. return detail::GetListNodeValueFunc<TNode, T>()(*m_head);
  213. }
  214. /// Get last element.
  215. ConstReference getBack() const
  216. {
  217. ANKI_ASSERT(!isEmpty());
  218. return detail::GetListNodeValueFunc<TNode, T>()(*m_tail);
  219. }
  220. /// Get last element.
  221. Reference getBack()
  222. {
  223. ANKI_ASSERT(!isEmpty());
  224. return detail::GetListNodeValueFunc<TNode, T>()(*m_tail);
  225. }
  226. /// Get begin.
  227. Iterator getBegin()
  228. {
  229. return Iterator(m_head, this);
  230. }
  231. /// Get begin.
  232. ConstIterator getBegin() const
  233. {
  234. return ConstIterator(m_head, this);
  235. }
  236. /// Get end.
  237. Iterator getEnd()
  238. {
  239. return Iterator(nullptr, this);
  240. }
  241. /// Get end.
  242. ConstIterator getEnd() const
  243. {
  244. return ConstIterator(nullptr, this);
  245. }
  246. /// Get begin.
  247. Iterator begin()
  248. {
  249. return getBegin();
  250. }
  251. /// Get begin.
  252. ConstIterator begin() const
  253. {
  254. return getBegin();
  255. }
  256. /// Get end.
  257. Iterator end()
  258. {
  259. return getEnd();
  260. }
  261. /// Get end.
  262. ConstIterator end() const
  263. {
  264. return getEnd();
  265. }
  266. /// Return true if list is empty.
  267. Bool isEmpty() const
  268. {
  269. return m_head == nullptr;
  270. }
  271. /// Iterate the list using lambda.
  272. template<typename TFunc>
  273. Error iterateForward(TFunc func);
  274. /// Iterate the list backwards using lambda.
  275. template<typename TFunc>
  276. Error iterateBackward(TFunc func);
  277. /// Find item.
  278. Iterator find(const Value& a);
  279. /// Sort the list.
  280. /// @note It's almost 300 slower than std::list::sort, at some point replace the algorithm.
  281. template<typename TCompFunc = std::less<Value>>
  282. void sort(TCompFunc compFunc = TCompFunc());
  283. /// Compute the size of elements in the list.
  284. PtrSize getSize() const;
  285. protected:
  286. TNode* m_head = nullptr;
  287. TNode* m_tail = nullptr;
  288. void pushBackNode(TNode* node);
  289. void pushFrontNode(TNode* node);
  290. void insertNode(TNode* pos, TNode* node);
  291. void removeNode(TNode* node);
  292. void popBack();
  293. void popFront();
  294. private:
  295. /// Used in sort.
  296. TNode* swap(TNode* one, TNode* two);
  297. void move(ListBase& b)
  298. {
  299. m_head = b.m_head;
  300. b.m_head = nullptr;
  301. m_tail = b.m_tail;
  302. b.m_tail = nullptr;
  303. }
  304. };
  305. } // end namespace detail
  306. /// Double linked list.
  307. template<typename T, typename TMemoryPool = SingletonMemoryPoolWrapper<DefaultMemoryPool>>
  308. class List : public detail::ListBase<T, detail::ListNode<T>>
  309. {
  310. private:
  311. using Base = detail::ListBase<T, detail::ListNode<T>>;
  312. using Node = detail::ListNode<T>;
  313. public:
  314. using typename Base::Iterator;
  315. using typename Base::ConstIterator;
  316. /// Default constructor.
  317. List(const TMemoryPool& pool = TMemoryPool())
  318. : m_pool(pool)
  319. {
  320. }
  321. /// Move.
  322. List(List&& b)
  323. : Base(std::move(static_cast<Base&>(b)))
  324. , m_pool(std::move(b.m_pool))
  325. {
  326. }
  327. /// Copy.
  328. List(const List& b)
  329. {
  330. *this = b;
  331. }
  332. ~List()
  333. {
  334. destroy();
  335. }
  336. /// Move.
  337. List& operator=(List&& b)
  338. {
  339. destroy();
  340. static_cast<Base&>(*this) = std::move(static_cast<Base&>(b));
  341. m_pool = std::move(b.m_pool);
  342. return *this;
  343. }
  344. /// Copy.
  345. List& operator=(const List& b)
  346. {
  347. destroy();
  348. ConstIterator it = b.getBegin();
  349. while(it != b.getEnd())
  350. {
  351. pushBack(*it);
  352. ++it;
  353. }
  354. return *this;
  355. }
  356. /// Destroy the list.
  357. void destroy();
  358. /// Copy an element at the end of the list.
  359. Iterator pushBack(const T& x)
  360. {
  361. Node* node = newInstance<Node>(m_pool, x);
  362. Base::pushBackNode(node);
  363. return Iterator(node, this);
  364. }
  365. /// Construct an element at the end of the list.
  366. template<typename... TArgs>
  367. Iterator emplaceBack(TArgs&&... args)
  368. {
  369. Node* node = newInstance<Node>(m_pool, std::forward<TArgs>(args)...);
  370. Base::pushBackNode(node);
  371. return Iterator(node, this);
  372. }
  373. /// Copy an element at the beginning of the list.
  374. Iterator pushFront(const T& x)
  375. {
  376. Node* node = newInstance<Node>(m_pool, x);
  377. Base::pushFrontNode(node);
  378. return Iterator(node, this);
  379. }
  380. /// Construct element at the beginning of the list.
  381. template<typename... TArgs>
  382. Iterator emplaceFront(TArgs&&... args)
  383. {
  384. Node* node = newInstance<Node>(m_pool, std::forward<TArgs>(args)...);
  385. Base::pushFrontNode(node);
  386. return Iterator(node, this);
  387. }
  388. /// Copy an element at the given position of the list.
  389. Iterator insert(Iterator pos, const T& x)
  390. {
  391. Node* node = newInstance<Node>(m_pool, x);
  392. Base::insertNode(pos.m_node, node);
  393. return Iterator(node, this);
  394. }
  395. /// Construct element at the the given position.
  396. template<typename... TArgs>
  397. Iterator emplace(Iterator pos, TArgs&&... args)
  398. {
  399. Node* node = newInstance<Node>(m_pool, std::forward<TArgs>(args)...);
  400. Base::insertNode(pos.m_node, node);
  401. return Iterator(node, this);
  402. }
  403. /// Pop a value from the back of the list.
  404. void popBack()
  405. {
  406. ANKI_ASSERT(Base::m_tail);
  407. Node* node = Base::m_tail;
  408. Base::popBack();
  409. deleteInstance(m_pool, node);
  410. }
  411. /// Pop a value from the front of the list.
  412. void popFront()
  413. {
  414. ANKI_ASSERT(Base::m_head);
  415. Node* node = Base::m_head;
  416. Base::popFront();
  417. deleteInstance(m_pool, node);
  418. }
  419. /// Erase an element.
  420. void erase(Iterator pos)
  421. {
  422. ANKI_ASSERT(pos.m_node);
  423. ANKI_ASSERT(pos.m_list == this);
  424. Base::removeNode(pos.m_node);
  425. deleteInstance(m_pool, pos.m_node);
  426. }
  427. TMemoryPool& getMemoryPool()
  428. {
  429. return m_pool;
  430. }
  431. private:
  432. TMemoryPool m_pool;
  433. };
  434. /// The classes that will use the IntrusiveList need to inherit from this one.
  435. template<typename TClass>
  436. class IntrusiveListEnabled
  437. {
  438. template<typename, typename, typename, typename>
  439. friend class detail::ListIterator;
  440. template<typename, typename>
  441. friend class detail::ListBase;
  442. template<typename>
  443. friend class IntrusiveList;
  444. friend TClass;
  445. public:
  446. TClass* getPreviousListNode()
  447. {
  448. return m_prev;
  449. }
  450. const TClass* getPreviousListNode() const
  451. {
  452. return m_prev;
  453. }
  454. TClass* getNextListNode()
  455. {
  456. return m_next;
  457. }
  458. const TClass* getNextListNode() const
  459. {
  460. return m_next;
  461. }
  462. private:
  463. TClass* m_prev = nullptr;
  464. TClass* m_next = nullptr;
  465. };
  466. namespace detail {
  467. /// Specialization for IntrusiveListEnabled
  468. /// @internal
  469. template<typename TValue>
  470. class GetListNodeValueFunc<TValue, TValue>
  471. {
  472. public:
  473. TValue& operator()(TValue& node)
  474. {
  475. return node;
  476. }
  477. const TValue& operator()(const TValue& node) const
  478. {
  479. return node;
  480. }
  481. };
  482. } // end namespace detail
  483. /// List that doesn't perform any allocations. To work the T nodes will have to inherit from IntrusiveListEnabled or
  484. /// have 2 member functions and their const versions. The 2 functions are getPreviousListNode() and getNextListNode().
  485. template<typename T>
  486. class IntrusiveList : public detail::ListBase<T, T>
  487. {
  488. template<typename, typename, typename, typename>
  489. friend class detail::ListIterator;
  490. private:
  491. using Base = detail::ListBase<T, T>;
  492. public:
  493. using typename Base::Iterator;
  494. /// Default constructor.
  495. IntrusiveList()
  496. : Base()
  497. {
  498. }
  499. /// Move.
  500. IntrusiveList(IntrusiveList&& b)
  501. : Base(std::move(static_cast<Base&>(b)))
  502. {
  503. }
  504. ~IntrusiveList() = default;
  505. /// Move.
  506. IntrusiveList& operator=(IntrusiveList&& b)
  507. {
  508. static_cast<Base&>(*this) = std::move(static_cast<Base&>(b));
  509. return *this;
  510. }
  511. /// Copy an element at the end of the list.
  512. Iterator pushBack(T* x)
  513. {
  514. Base::pushBackNode(x);
  515. return Iterator(x, this);
  516. }
  517. /// Copy an element at the beginning of the list.
  518. Iterator pushFront(T* x)
  519. {
  520. Base::pushFrontNode(x);
  521. return Iterator(x, this);
  522. }
  523. /// Copy an element at the given position of the list.
  524. Iterator insert(Iterator pos, T* x)
  525. {
  526. Base::insertNode(pos.m_node, x);
  527. return Iterator(x, this);
  528. }
  529. /// Pop a value from the back of the list.
  530. T* popBack()
  531. {
  532. T* tail = Base::m_tail;
  533. Base::popBack();
  534. return tail;
  535. }
  536. /// Pop a value from the front of the list.
  537. T* popFront()
  538. {
  539. T* head = Base::m_head;
  540. Base::popFront();
  541. return head;
  542. }
  543. /// Erase an element.
  544. void erase(Iterator pos)
  545. {
  546. Base::removeNode(pos.m_node);
  547. }
  548. /// Erase an element.
  549. void erase(T* x)
  550. {
  551. Base::removeNode(x);
  552. }
  553. };
  554. /// @}
  555. } // end namespace anki
  556. #include <AnKi/Util/List.inl.h>