gwnavruntime/containers/sharedpoollist.h Source File

sharedpoollist.h
Go to the documentation of this file.
1 /*
2 * Copyright 2015 Autodesk, Inc. All rights reserved.
3 * Use of this software is subject to the terms of the Autodesk license agreement and any attachments or Appendices thereto provided at the time of installation or download,
4 * or which otherwise accompanies this software in either electronic or hard copy form, or which is signed by you and accepted by Autodesk.
5 */
6 
7 
8 #ifndef Navigation_SharedPoolList_H
9 #define Navigation_SharedPoolList_H
10 
14 
15 namespace Kaim
16 {
17 
19 template <typename T>
21 {
22  KY_DEFINE_NEW_DELETE_OPERATORS(Stat_Default_Mem)
24 
25 private:
26  typedef Pool<SPListNode<T> > NodePool;
27  typedef typename NodePool::Key NodeKey;
28 
29 public:
30  SPListNode() : m_prev(KY_NULL), m_next(KY_NULL) {}
31  explicit SPListNode(const T& data) : m_prev(KY_NULL), m_next(KY_NULL), m_data(data) {}
32 
33 public: // internal
34  SPListNode* m_prev;
35  SPListNode* m_next;
36  NodeKey m_nodeKey;
37  T m_data;
38 };
39 
40 
42 template <typename T>
43 class SPL_Iterator
44 {
45  KY_DEFINE_NEW_DELETE_OPERATORS(Stat_Default_Mem)
46 
47 public:
48  // ---------------------------------- Public typedef ----------------------------------
49 
50  typedef SPListNode<T> Node;
51 
52 
53  // ---------------------------------- Public Member Functions ----------------------------------
54 
55  SPL_Iterator() : m_node(KY_NULL) {}
56  explicit SPL_Iterator(Node* listNode) : m_node(listNode) {}
57  SPL_Iterator(const SPL_Iterator& rhs) : m_node(rhs.m_node) {}
58 
59  KY_INLINE const SPL_Iterator& operator=(const SPL_Iterator& rhs) { m_node = rhs.m_node; return *this; }
60 
61  KY_INLINE bool operator==(const SPL_Iterator& rhs) const { return m_node == rhs.m_node; }
62  KY_INLINE bool operator!=(const SPL_Iterator& rhs) const { return m_node != rhs.m_node; }
63 
64  KY_INLINE SPL_Iterator& operator++() { m_node = m_node->m_next; return *this; }
65  KY_INLINE SPL_Iterator& operator--() { m_node = m_node->m_prev; return *this; }
66 
67  KY_INLINE SPL_Iterator operator++(int) { SPL_Iterator old = *this; m_node = m_node->m_next; return old; }
68  KY_INLINE SPL_Iterator operator--(int) { SPL_Iterator old = *this; m_node = m_node->m_prev; return old; }
69 
70  KY_INLINE T& operator*() const { return m_node->m_data; }
71  KY_INLINE T* operator->() const { return &m_node->m_data; }
72 
73  KY_INLINE SPL_Iterator GetNext() const { return SPL_Iterator(m_node->m_next); }
74  KY_INLINE SPL_Iterator GetPrev() const { return SPL_Iterator(m_node->m_prev); }
75 
76  KY_INLINE bool IsNull() const { return m_node == KY_NULL; }
77  KY_INLINE bool IsNotNull() const { return m_node != KY_NULL; }
78 
79 public: // internal
80  Node* m_node;
81 };
82 
83 
85 template <typename T>
86 class SPL_ConstIterator
87 {
88  KY_DEFINE_NEW_DELETE_OPERATORS(Stat_Default_Mem)
89 
90 public:
91  // ---------------------------------- Public typedef ----------------------------------
92 
93  typedef SPListNode<T> Node;
94 
95 
96  // ---------------------------------- Public Member Functions ----------------------------------
97 
98  SPL_ConstIterator() : m_node(KY_NULL) {}
99  SPL_ConstIterator(const SPL_Iterator<T>& it) : m_node(it.m_node) {}
100  SPL_ConstIterator(const SPL_ConstIterator& it) : m_node(it.m_node) {}
101  explicit SPL_ConstIterator(const Node* listNode) : m_node(listNode) {}
102 
103  KY_INLINE const SPL_ConstIterator& operator=(const SPL_ConstIterator& rhs) { m_node = rhs.m_node; return *this; }
104 
105  KY_INLINE bool operator==(const SPL_ConstIterator& rhs) const { return m_node == rhs.m_node; }
106  KY_INLINE bool operator!=(const SPL_ConstIterator& rhs) const { return m_node != rhs.m_node; }
107 
108  KY_INLINE SPL_ConstIterator& operator++() { m_node = m_node->m_next; return *this; }
109  KY_INLINE SPL_ConstIterator& operator--() { m_node = m_node->m_prev; return *this; }
110 
111  KY_INLINE SPL_ConstIterator operator++(int) { SPL_ConstIterator old = *this; m_node = m_node->m_next; return old; }
112  KY_INLINE SPL_ConstIterator operator--(int) { SPL_ConstIterator old = *this; m_node = m_node->m_prev; return old; }
113 
114  KY_INLINE const T& operator*() const { return m_node->m_data; }
115  KY_INLINE const T* operator->() const { return &m_node->m_data; }
116 
117  KY_INLINE SPL_ConstIterator GetNext() const { return SPL_ConstIterator(m_node->m_next); }
118  KY_INLINE SPL_ConstIterator GetPrev() const { return SPL_ConstIterator(m_node->m_prev); }
119 
120  KY_INLINE bool IsNull() const { return m_node == KY_NULL; }
121  KY_INLINE bool IsNotNull() const { return m_node != KY_NULL; }
122 
123 public: // internal
124  const Node* m_node;
125 };
126 
127 
149 
152 template <typename T>
153 class SharedPoolList
154 {
155  KY_DEFINE_NEW_DELETE_OPERATORS(Stat_Default_Mem)
156  KY_CLASS_WITHOUT_COPY(SharedPoolList)
157 
158 public:
159  // ---------------------------------- Public typedefs ----------------------------------
160 
161  typedef SPListNode<T> Node;
162  typedef SPL_Iterator<T> Iterator;
163  typedef SPL_ConstIterator<T> ConstIterator;
164  typedef Pool<SPListNode<T> > NodePool;
165  typedef typename NodePool::Key NodeKey;
166 
167 public:
168  // ---------------------------------- Main API Functions ----------------------------------
169 
170  explicit SharedPoolList(NodePool* nodePool = KY_NULL) : m_nodePool(nodePool), m_count(0)
171  { m_root.m_next = m_root.m_prev = RootAsNode(); }
172 
173  void SetNodePool(NodePool* nodePool) { m_nodePool = nodePool; }
174 
175  ~SharedPoolList() { Clear(); }
176 
177  void Clear();
178 
179  KyUInt32 GetCount() const { return m_count; }
180 
181 
182  // ---------------------------------- Bounds ----------------------------------
183 
184  ConstIterator GetFirst() const { return ConstIterator(m_root.m_next); }
185  ConstIterator GetLast() const { return ConstIterator(m_root.m_prev); }
186  Iterator GetFirst() { return Iterator(m_root.m_next); }
187  Iterator GetLast () { return Iterator(m_root.m_prev); }
188 
189  ConstIterator Begin() const { return ConstIterator(m_root.m_next); }
190  ConstIterator End() const { return ConstIterator(RootAsNode()); }
191  Iterator Begin() { return Iterator(m_root.m_next); }
192  Iterator End() { return Iterator(RootAsNode()); }
193 
194 
195 
196  // ---------------------------------- Utility Functions ----------------------------------
197 
198  // Determine if list is empty (i.e.) points to itself.
199  // Go through void* access to avoid issues with strict-aliasing optimizing out the
200  // access after RemoveNode(), etc.
201  bool IsEmpty() const { return m_root.m_next == RootAsNode(); }
202 
203  bool IsFirst(ConstIterator it) const { return it.m_node == m_root.m_next; }
204  bool IsFirst(Iterator it) const { return it.m_node == m_root.m_next; }
205 
206  bool IsLast (ConstIterator it) const { return it.m_node == m_root.m_prev; }
207  bool IsLast (Iterator it) const { return it.m_node == m_root.m_prev; }
208 
209  bool IsNull (ConstIterator it) const { return it.m_node == RootAsNode(); }
210  bool IsNull (Iterator it) const { return it.m_node == RootAsNode(); }
211 
212  bool IsValid(ConstIterator it) const { return it.m_node != RootAsNode(); }
213  bool IsValid(Iterator it) const { return it.m_node != RootAsNode(); }
214 
215  ConstIterator Find(const T& data) const;
216  Iterator Find(const T& data);
217 
218 
219  // ---------------------------------- Node Insertion ----------------------------------
220 
221  Iterator InsertBefore(const T& data, Iterator nextNodeIt) { Node* newNode = NewNode(data); InsertNodeBefore(newNode, nextNodeIt.m_node); return Iterator(newNode); }
222  Iterator InsertAfter(Iterator prevNodeIt, const T& data) { Node* newNode = NewNode(data); InsertNodeAfter(prevNodeIt.m_node, newNode); return Iterator(newNode); }
223 
224  Iterator InsertBefore(Iterator nextNodeIt) { Node* newNode = NewNode(); InsertNodeBefore(newNode, nextNodeIt.m_node); return Iterator(newNode); }
225  Iterator InsertAfter(Iterator prevNodeIt) { Node* newNode = NewNode(); InsertNodeAfter(prevNodeIt.m_node, newNode); return Iterator(newNode); }
226 
227  Iterator PushFront(const T& data) { Node* newNode = NewNode(data); InsertNodeBefore(newNode, m_root.m_next); return Iterator(newNode); }
228  Iterator PushBack(const T& data) { Node* newNode = NewNode(data); InsertNodeAfter(m_root.m_prev, newNode); return Iterator(newNode); }
229 
230  Iterator PushFront() { Node* newNode = NewNode(); InsertNodeBefore(newNode, m_root.m_next); return Iterator(newNode); }
231  Iterator PushBack() { Node* newNode = NewNode(); InsertNodeAfter(m_root.m_prev, newNode); return Iterator(newNode); }
232 
233 
234  // ---------------------------------- Node Removal ----------------------------------
235 
236  Iterator Erase(Iterator it);
237 
238  Iterator RemoveFirstOccurrence(Iterator begin, const T& data);
239 
240  KyUInt32 RemoveAllOccurrences(const T& data);
241 
242  template<class Predicate>
243  KyUInt32 Remove_If(Predicate predicate)
244  {
245  KyUInt32 count = 0;
246  for (Iterator it = Begin(); it != End(); )
247  {
248  if (!predicate(*it))
249  ++it;
250  else
251  {
252  it = Erase(it);
253  ++count;
254  }
255  }
256  return count;
257  }
258 
259 private:
260  void InsertNodeBefore(Node* newNode, Node* nextNode) { InsertNodeBetween(nextNode->m_prev, newNode, nextNode); }
261  void InsertNodeAfter(Node* prevNode, Node* newNode) { InsertNodeBetween(prevNode, newNode, prevNode->m_next); }
262  void InsertNodeBetween(Node* prevNode, Node* newNode, Node* nextNode);
263  Node* NewNode(const T& data); // return NewNode with m_data=data, m_nodeKey=newone, m_prev=m_next=0
264  Node* NewNode(); // return NewNode with m_data=T() , m_nodeKey=newone, m_prev=m_next=0
265  void RemoveNode(Node* node) { node->m_prev->m_next = node->m_next; node->m_next->m_prev = node->m_prev; }
266  Node* RootAsNode() { return &m_root; }
267  const Node* RootAsNode() const { return &m_root; }
268 
269 private:
270  NodePool* m_nodePool;
271  Node m_root;
272  KyUInt32 m_count;
273 };
274 
275 
276 template <typename T>
277 typename SharedPoolList<T>::Node* SharedPoolList<T>::NewNode(const T& data)
278 {
279  NodeKey key;
280  Node* node = KY_NULL;
281  m_nodePool->New_CompactKeyAndPtr(key, node);
282 
283  node->m_data = data;
284  node->m_nodeKey = key;
285 
286  ++m_count;
287  return node;
288 }
289 
290 
291 template <typename T>
292 typename SharedPoolList<T>::Node* SharedPoolList<T>::NewNode()
293 {
294  NodeKey nodeKey = m_nodePool->New_CompactKey();
295  Node* node = &m_nodePool->Get(nodeKey);
296  // TODO one call to m_nodePool that returns {nodeKey, node}
297  node->m_nodeKey = nodeKey;
298  ++m_count;
299  return node;
300 }
301 
302 template <typename T>
303 void SharedPoolList<T>::InsertNodeBetween(Node* prevNode, Node* newNode, Node* nextNode)
304 {
305  prevNode->m_next = newNode;
306  newNode->m_prev = prevNode;
307 
308  newNode->m_next = nextNode;
309  nextNode->m_prev = newNode;
310 }
311 
312 
313 template <typename T>
314 typename SharedPoolList<T>::Iterator SharedPoolList<T>::Erase(Iterator it)
315 {
316  Node* node = it.m_node;
317  Node* nextNode = node->m_next;
318  RemoveNode(node);
319  m_nodePool->Delete(node->m_nodeKey);
320  --m_count;
321  return Iterator(nextNode);
322 }
323 
324 
325 template <typename T>
326 void SharedPoolList<T>::Clear()
327 {
328  for (Iterator it = Begin(); it != End(); ++it)
329  m_nodePool->Delete(it.m_node->m_nodeKey);
330 
331  m_count = 0;
332  m_root.m_next = m_root.m_prev = RootAsNode();
333 }
334 
335 
336 template <typename T>
337 typename SharedPoolList<T>::ConstIterator SharedPoolList<T>::Find(const T& data) const
338 {
339  for (ConstIterator it = Begin(); it != End(); ++it)
340  {
341  if (*it == data)
342  return it;
343  }
344  return End();
345 }
346 
347 template <typename T>
348 typename SharedPoolList<T>::Iterator SharedPoolList<T>::Find(const T& data)
349 {
350  for (Iterator it = Begin(); it != End(); ++it)
351  {
352  if (*it == data)
353  return it;
354  }
355  return End();
356 }
357 
358 
359 template <typename T>
360 typename SharedPoolList<T>::Iterator SharedPoolList<T>::RemoveFirstOccurrence(Iterator begin, const T& data)
361 {
362  Iterator it = begin;
363  for (; it != End(); ++it)
364  {
365  if (*it == data)
366  return Erase(it);
367  }
368  return it;
369 }
370 
371 
372 template <typename T>
373 KyUInt32 SharedPoolList<T>::RemoveAllOccurrences(const T& data)
374 {
375  KyUInt32 count = 0;
376  for (Iterator it = Begin(); it != End(); )
377  {
378  if (*it != data)
379  ++it;
380  else
381  {
382  it = Erase(it);
383  ++count;
384  }
385  }
386  return count;
387 }
388 
389 } // namespace Kaim
390 
391 
392 #endif // Navigation_SharedPoolList_H
Const iterator on SharedPoolList nodes (SPL stands for SharedPoolList).
Definition: sharedpoollist.h:103
#define KY_NULL
Null value.
Definition: types.h:247
#define KY_CLASS_WITHOUT_COPY(ClassName)
Define to forbid copy constructor and copy assignment.
Definition: types.h:387
This is the list node used in SharedPoolList implementation (SP stands for SharedPool).
Definition: sharedpoollist.h:20
Definition: gamekitcrowddispersion.h:20
Iterator on SharedPoolList nodes (SPL stands for SharedPoolList).
Definition: sharedpoollist.h:48
#define KY_DEFINE_NEW_DELETE_OPERATORS(MemStat)
This macro defines new and delete operators.
Definition: memory.h:137
unsigned int KyUInt32
Type used internally to represent an unsigned 32-bit integer.
Definition: types.h:36