OpenNI 1.3.2
XnList.h
Go to the documentation of this file.
1 /****************************************************************************
2 * *
3 * OpenNI 1.1 Alpha *
4 * Copyright (C) 2011 PrimeSense Ltd. *
5 * *
6 * This file is part of OpenNI. *
7 * *
8 * OpenNI is free software: you can redistribute it and/or modify *
9 * it under the terms of the GNU Lesser General Public License as published *
10 * by the Free Software Foundation, either version 3 of the License, or *
11 * (at your option) any later version. *
12 * *
13 * OpenNI is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU Lesser General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU Lesser General Public License *
19 * along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
20 * *
21 ****************************************************************************/
22 #ifndef _XN_LIST_H
23 #define _XN_LIST_H
24 
25 //---------------------------------------------------------------------------
26 // Includes
27 //---------------------------------------------------------------------------
28 #include <XnDataTypes.h>
29 #include <IXnNodeAllocator.h>
30 #include <XnNodeAllocator.h>
31 #include <XnNode.h>
32 #include <XnStatusCodes.h>
33 
34 //---------------------------------------------------------------------------
35 // Types
36 //---------------------------------------------------------------------------
37 
41 class XnList
42 {
43 public:
45  {
46  public:
47  friend class XnList;
48 
55 
60  {
62  return *this;
63  }
64 
69  {
72  return other;
73  }
74 
79  {
81  return *this;
82  }
83 
88  {
89  ConstIterator other = *this;
90  --*this;
91  return other;
92  }
93 
99  XnBool operator==(const ConstIterator& other) const
100  {
101  return m_pCurrent == other.m_pCurrent;
102  }
108  XnBool operator!=(const ConstIterator& other) const
109  {
110  return m_pCurrent != other.m_pCurrent;
111  }
112 
116  const XnValue& operator*() const
117  {
118  return m_pCurrent->Data();
119  }
120 
121 
125  const XnNode* GetNode() const
126  {
127  return m_pCurrent;
128  }
129 
134  {
135  return m_pCurrent;
136  }
137 
138  protected:
144  ConstIterator(XnNode* pNode) : m_pCurrent(pNode) {}
145 
148  };
149 
153  class Iterator : public ConstIterator
154  {
155  public:
156  friend class XnList;
157 
163  inline Iterator(const Iterator& other) : ConstIterator(other) {}
164 
168  inline Iterator& operator++()
169  {
170  ++(*(ConstIterator*)this);
171  return (*this);
172  }
176  inline Iterator operator++(int)
177  {
178  Iterator result = *this;
179  ++*this;
180  return (result);
181  }
182 
186  inline Iterator& operator--()
187  {
188  --(*(ConstIterator*)this);
189  return (*this);
190  }
194  inline Iterator operator--(int)
195  {
196  Iterator result = *this;
197  --*this;
198  return (result);
199  }
200 
204  inline XnValue& operator*() const { return ((XnValue&)**(ConstIterator*)this); }
205 
206  protected:
212  inline Iterator(XnNode* pNode) : ConstIterator(pNode) {}
213  };
214 
215 public:
220  {
221  //Default node allocator is XnNodeAllocator
224  }
225 
229  virtual ~XnList()
230  {
231  Clear();
232 
233  // Return base node to the pool
235 
236  if (m_bOwnsAllocator)
237  {
238  //We created the allocator in this object, so we must release it
240  }
241  }
242 
250  XnStatus AddFirst(const XnValue& value)
251  {
252  return Add(m_pBase, value);
253  }
254 
262  XnStatus AddLast(const XnValue& value)
263  {
264  return Add(rbegin().m_pCurrent, value);
265  }
266 
277  {
278  if (where == end())
279  {
280  return XN_STATUS_ILLEGAL_POSITION;
281  }
282 
283  return Add(where.m_pCurrent, val);
284  }
285 
295  {
296  if (where == end())
297  {
298  return XN_STATUS_ILLEGAL_POSITION;
299  }
300 
301  return Add(where.m_pCurrent->Previous(), val);
302  }
303 
304 
312  Iterator Find(const XnValue& value)
313  {
314  if (IsEmpty())
315  {
316  return end();
317  }
318 
319  Iterator iter = begin();
320  for (; iter != end(); ++iter)
321  {
322  if (*iter == value)
323  break;
324  }
325  return iter;
326  }
327 
328 
336  ConstIterator Find(const XnValue& value) const
337  {
338  if (IsEmpty())
339  {
340  return end();
341  }
342 
343  ConstIterator iter = begin();
344  for (; iter != end(); ++iter)
345  {
346  if (*iter == value)
347  break;
348  }
349  return iter;
350  }
351 
352 
362  {
363  value = *where;
364  return Remove(where);
365  }
366 
375  {
376  // Verify iterator is valid
377  if (where == end())
378  {
379  return XN_STATUS_ILLEGAL_POSITION;
380  }
381  if (IsEmpty())
382  {
383  return XN_STATUS_IS_EMPTY;
384  }
385 
386  XnNode* pToRemove = where.m_pCurrent;
387 
388  // Connect other nodes to bypass the one removed
389  pToRemove->Previous()->Next() = pToRemove->Next();
390  pToRemove->Next()->Previous() = pToRemove->Previous();
391 
392  // Return removed node to the pool
393  m_pNodeAllocator->Deallocate(pToRemove);
394 
395  return XN_STATUS_OK;
396  }
397 
398 
403  {
404  while (!IsEmpty())
405  Remove(begin());
406 
407  return XN_STATUS_OK;
408  }
409 
413  XnBool IsEmpty() const
414  {
415  return (begin() == end());
416  }
417 
421  XnUInt32 Size() const
422  {
423  XnUInt32 nSize = 0;
424  for (ConstIterator iter = begin(); iter != end(); ++iter, ++nSize)
425  ;
426 
427  return nSize;
428  }
429 
434  {
435  return Iterator(m_pBase->Next());
436  }
437 
442  {
443  return ConstIterator(m_pBase->Next());
444  }
445 
450  {
451  return Iterator(m_pBase);
452  }
453 
458  {
459  return ConstIterator(m_pBase);
460  }
461 
466  {
467  return Iterator(m_pBase->Previous());
468  }
469 
474  {
475  return ConstIterator(m_pBase->Previous());
476  }
477 
482  {
483  return Iterator(m_pBase);
484  }
485 
490  {
491  return ConstIterator(m_pBase);
492  }
493 
494 protected:
495  friend class XnNodeManager;
496 
500  XnList(INiNodeAllocator* pNodeAllocator)
501  {
502  Init(pNodeAllocator);
504  }
505 
506  void Init(INiNodeAllocator* pNodeAllocator)
507  {
508  m_pNodeAllocator = pNodeAllocator;
509  // Allocate a node to act as base node.
511  if (m_pBase == NULL)
512  {
513  // OZOZ: Allocation failed in ctor...
514  }
515 
516  m_pBase->Next() = m_pBase->Previous() = m_pBase;
517  }
518 
527  XnStatus Add(XnNode* pWhere, const XnValue& val)
528  {
529  // Get a node from the pool for the entry
530  XnNode* pNewNode = m_pNodeAllocator->Allocate();
531  if (pNewNode == NULL)
532  {
533  return XN_STATUS_ALLOC_FAILED;
534  }
535  // push new node to position
536  pNewNode->Data() = val;
537  pNewNode->Next() = pWhere->Next();
538  pNewNode->Previous() = pWhere;
539  pWhere->Next()->Previous() = pNewNode;
540  pWhere->Next() = pNewNode;
541 
542  return XN_STATUS_OK;
543  }
544 
545 
548 
551 };
552 
557 #define XN_DECLARE_LIST_WITH_TRANSLATOR_DECL(decl, Type, ClassName, Translator) \
558  class decl ClassName : public XnList \
559  { \
560  public: \
561  class decl ConstIterator : public XnList::ConstIterator \
562  { \
563  public: \
564  friend class ClassName; \
565  inline ConstIterator(const ConstIterator& other) : XnList::ConstIterator(other) {} \
566  inline ConstIterator& operator++() \
567  { \
568  ++(*(XnList::ConstIterator*)this); \
569  return (*this); \
570  } \
571  inline ConstIterator operator++(int) \
572  { \
573  ConstIterator result = *this; \
574  ++*this; \
575  return result; \
576  } \
577  inline ConstIterator& operator--() \
578  { \
579  --(*(XnList::ConstIterator*)this); \
580  return (*this); \
581  } \
582  inline ConstIterator operator--(int) \
583  { \
584  ConstIterator result = *this; \
585  --*this; \
586  return result; \
587  } \
588  inline Type const& operator*() const \
589  { \
590  return Translator::GetFromValue(**((XnList::ConstIterator*)this)); \
591  } \
592  inline Type const* operator->() const { return (&**this); } \
593  protected: \
594  inline ConstIterator(XnNode* pNode) : XnList::ConstIterator(pNode) {} \
595  inline ConstIterator(const XnList::ConstIterator& other) : \
596  XnList::ConstIterator(other) \
597  {} \
598  }; \
599  class decl Iterator : public ConstIterator \
600  { \
601  public: \
602  friend class ClassName; \
603  Iterator(const Iterator& other) : ConstIterator(other) {} \
604  inline Iterator& operator++() \
605  { \
606  ++(*(ConstIterator*)this); \
607  return (*this); \
608  } \
609  inline Iterator operator++(int) \
610  { \
611  Iterator result = *this; \
612  ++*this; \
613  return result; \
614  } \
615  inline Iterator& operator--() \
616  { \
617  --(*(ConstIterator*)this); \
618  return (*this); \
619  } \
620  inline Iterator operator--(int) \
621  { \
622  Iterator result = *this; \
623  --*this; \
624  return result; \
625  } \
626  inline Type& operator*() const { return ((Type&)**(ConstIterator*)this); } \
627  inline Type* operator->() const { return (&**this); } \
628  protected: \
629  inline Iterator(XnNode* pNode) : ConstIterator(pNode) {} \
630  inline Iterator(const XnList::Iterator& other) : ConstIterator(other) {} \
631  }; \
632  public: \
633  ClassName() \
634  { \
635  } \
636  ClassName(const ClassName& other) \
637  { \
638  *this = other; \
639  } \
640  ~ClassName() \
641  { \
642  while (!IsEmpty()) \
643  Remove(begin()); \
644  } \
645  ClassName& operator=(const ClassName& other) \
646  { \
647  Clear(); \
648  for (ConstIterator it = other.begin(); it != other.end(); ++it) \
649  { \
650  AddLast(*it); \
651  } \
652  return *this; \
653  } \
654  inline XnStatus AddFirst(Type const& value) \
655  { \
656  XnValue val = Translator::CreateValueCopy(value); \
657  XnStatus nRetVal = XnList::AddFirst(val); \
658  if (nRetVal != XN_STATUS_OK) \
659  { \
660  Translator::FreeValue(val); \
661  return (nRetVal); \
662  } \
663  return XN_STATUS_OK; \
664  } \
665  inline XnStatus AddLast(Type const& value) \
666  { \
667  XnValue val = Translator::CreateValueCopy(value); \
668  XnStatus nRetVal = XnList::AddLast(val); \
669  if (nRetVal != XN_STATUS_OK) \
670  { \
671  Translator::FreeValue(val); \
672  return (nRetVal); \
673  } \
674  return XN_STATUS_OK; \
675  } \
676  inline XnStatus AddAfter(ConstIterator where, Type const& value) \
677  { \
678  XnValue val = Translator::CreateValueCopy(value); \
679  XnStatus nRetVal = XnList::AddAfter(where, val); \
680  if (nRetVal != XN_STATUS_OK) \
681  { \
682  Translator::FreeValue(val); \
683  return (nRetVal); \
684  } \
685  return XN_STATUS_OK; \
686  } \
687  inline XnStatus AddBefore(ConstIterator where, Type const& value) \
688  { \
689  XnValue val = Translator::CreateValueCopy(value); \
690  XnStatus nRetVal = XnList::AddBefore(where, val); \
691  if (nRetVal != XN_STATUS_OK) \
692  { \
693  Translator::FreeValue(val); \
694  return (nRetVal); \
695  } \
696  return XN_STATUS_OK; \
697  } \
698  inline ConstIterator Find(Type const& value) const \
699  { \
700  XnValue _value = Translator::GetAsValue(value); \
701  return XnList::Find(_value); \
702  } \
703  inline Iterator Find(Type const& value) \
704  { \
705  XnValue _value = Translator::GetAsValue(value); \
706  return XnList::Find(_value); \
707  } \
708  inline XnStatus Remove(ConstIterator where) \
709  { \
710  XnValue val = Translator::GetAsValue(*where); \
711  XnStatus nRetVal = XnList::Remove(where); \
712  if (nRetVal != XN_STATUS_OK) return (nRetVal); \
713  Translator::FreeValue(val); \
714  return XN_STATUS_OK; \
715  } \
716  inline XnStatus Remove(Type const& value) \
717  { \
718  Iterator it = Find(value); \
719  return Remove(it); \
720  } \
721  inline Iterator begin() { return XnList::begin(); } \
722  inline ConstIterator begin() const { return XnList::begin(); } \
723  inline Iterator end() { return XnList::end(); } \
724  inline ConstIterator end() const { return XnList::end(); } \
725  inline Iterator rbegin() { return XnList::rbegin(); } \
726  inline ConstIterator rbegin() const { return XnList::rbegin(); } \
727  inline Iterator rend() { return XnList::rend(); } \
728  inline ConstIterator rend() const { return XnList::rend(); } \
729  protected: \
730  virtual XnStatus Remove(XnList::ConstIterator where) \
731  { \
732  return Remove(ConstIterator(where)); \
733  } \
734  };
735 
739 #define XN_DECLARE_LIST_WITH_TRANSLATOR(Type, ClassName, Translator) \
740  XN_DECLARE_LIST_WITH_TRANSLATOR_DECL(, Type, ClassName, Translator)
741 
746 #define XN_DECLARE_LIST_DECL(decl, Type, ClassName) \
747  XN_DECLARE_DEFAULT_VALUE_TRANSLATOR_DECL(decl, Type, XN_DEFAULT_TRANSLATOR_NAME(ClassName)) \
748  XN_DECLARE_LIST_WITH_TRANSLATOR_DECL(decl, Type, ClassName, XN_DEFAULT_TRANSLATOR_NAME(ClassName))
749 
753 #define XN_DECLARE_LIST(Type, ClassName) \
754  XN_DECLARE_LIST_DECL(, Type, ClassName)
755 
756 #endif // _XN_LIST_H
757