fbxsdk/core/base/fbxintrusivelist.h Source File

fbxintrusivelist.h
Go to the documentation of this file.
1 /****************************************************************************************
2 
3  Copyright (C) 2015 Autodesk, Inc.
4  All rights reserved.
5 
6  Use of this software is subject to the terms of the Autodesk license agreement
7  provided at the time of installation or download, or which otherwise accompanies
8  this software in either electronic or hard copy form.
9 
10 ****************************************************************************************/
11 
13 #ifndef _FBXSDK_CORE_BASE_INTRUSIVE_LIST_H_
14 #define _FBXSDK_CORE_BASE_INTRUSIVE_LIST_H_
15 
16 #include <fbxsdk/fbxsdk_def.h>
17 
18 #include <fbxsdk/fbxsdk_nsbegin.h>
19 
20 /*****************************************************************************************************************************
21 ** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! **
22 *****************************************************************************************************************************/
23 #ifndef DOXYGEN_SHOULD_SKIP_THIS
24 
25 #define FBXSDK_INTRUSIVE_LIST_NODE(Class, NodeCount)\
26  public: inline FbxListNode<Class>& GetListNode(int index = 0){ return this->mNode[index]; }\
27  private: FbxListNode<Class> mNode[NodeCount];
28 
29 template <typename T> class FbxListNode
30 {
31  typedef FbxListNode<T> NodeT;
32 
33 public:
34  explicit FbxListNode(T* pData = 0):mNext(0),mPrev(0),mData(pData){}
35  ~FbxListNode(){ Disconnect(); }
36 
37  void Disconnect()
38  {
39  if ( mPrev != 0 )
40  mPrev->mNext = mNext;
41 
42  if ( mNext != 0 )
43  mNext->mPrev = mPrev;
44 
45  mPrev = mNext = 0;
46  }
47 
48  NodeT* mNext;
49  NodeT* mPrev;
50  T* mData;
51 };
52 
53 //-----------------------------------------------------------------
54 // template arg T: Type listed
55 // arg NodeIndex: If an object listed has multiple list node, which
56 // index corresponds to the right node
57 template <typename T, int NodeIndex=0> class FbxIntrusiveList
58 {
59 public:
60  typedef T allocator_type;
61  typedef T value_type;
62  typedef T& reference;
63  typedef const T& const_reference;
64  typedef T* pointer;
65  typedef const T* const_pointer;
66 
67  typedef FbxListNode<T> NodeT;
68 
69  // Construction / Destruction
70  FbxIntrusiveList():mHead(0)
71  {
72  mHead.mNext = mHead.mPrev = &mHead;
73  }
74  ~FbxIntrusiveList()
75  {
76  while(!Empty())
77  Begin().Get()->Disconnect(); // LINUXNote: should be Erase(Begin()); but there's an issue with gcc 4.2
78  };
79 
80  // true if the list's size is 0.
81  bool Empty() const
82  {
83  return ((mHead.mNext==&mHead)&&(mHead.mPrev==&mHead));
84  }
85 
86  // Back Insertion Sequence Inserts a new element at the end.
87  void PushBack(T& pElement)
88  {
89  NodeT* pNode = &pElement.GetListNode(NodeIndex);
90  pNode->mData = &pElement;
91 
92  if (Empty())
93  {
94  pNode->mNext = &mHead;
95  pNode->mPrev = &mHead;
96  mHead.mNext = pNode;
97  mHead.mPrev = pNode;
98  }
99  else
100  {
101  pNode->mNext = &mHead;
102  pNode->mPrev = mHead.mPrev;
103 
104  pNode->mPrev->mNext = pNode;
105  mHead.mPrev = pNode;
106  }
107  }
108 
109  void PushFront(T& pElement)
110  {
111  NodeT* pNode = &pElement.GetListNode(NodeIndex);
112  pNode->mData = &pElement;
113 
114  if (Empty())
115  {
116  pNode->mNext = &mHead;
117  pNode->mPrev = &mHead;
118  mHead.mNext = pNode;
119  mHead.mPrev = pNode;
120  }
121  else
122  {
123  pNode->mNext = mHead.mNext;
124  pNode->mPrev = &mHead;
125 
126  pNode->mNext->mPrev = pNode;
127  mHead.mNext = pNode;
128  }
129  }
130 
131  void PopFront()
132  {
133  iterator begin = Begin();
134  Erase(begin);
135  }
136 
137  void PopBack()
138  {
139  Erase(--(End()));
140  }
141 
142 public:
143  class IntrusiveListIterator
144  {
145  public:
146  explicit IntrusiveListIterator(NodeT* ptr=0):mPtr(ptr){}
147 
148  // pre-increment
149  IntrusiveListIterator& operator++()
150  {
151  mPtr = mPtr->mNext;return (*this);
152  }
153  // post-increment
154  const IntrusiveListIterator operator++(int)
155  {
156  IntrusiveListIterator temp = *this;
157  ++*this;
158  return (temp);
159  }
160  // pre-decrement
161  IntrusiveListIterator& operator--()
162  {
163  mPtr = mPtr->mPrev;return *this;
164  }
165  // post-decrement
166  const IntrusiveListIterator operator--(int)
167  {
168  IntrusiveListIterator temp = *this;
169  --*this;
170  return (temp);
171  }
172  IntrusiveListIterator& operator=(const IntrusiveListIterator &other){mPtr = other.mPtr; return *this;}
173 
174  reference operator*() const { return *(mPtr->mData); }
175  pointer operator->() const { return (&**this); }
176  bool operator==(const IntrusiveListIterator& other)const{ return mPtr==other.mPtr; }
177  bool operator!=(const IntrusiveListIterator& other)const{ return !(*this == other); }
178 
179  inline NodeT* Get()const { return mPtr; }
180 
181  private:
182  NodeT* mPtr;
183  };
184 
185  class IntrusiveListConstIterator
186  {
187  public:
188  explicit IntrusiveListConstIterator(const NodeT* ptr=0):mPtr(ptr){}
189 
190  // pre-increment
191  IntrusiveListConstIterator& operator++()
192  {
193  mPtr = mPtr->mNext;return (*this);
194  }
195  // post-increment
196  const IntrusiveListConstIterator operator++(int)
197  {
198  IntrusiveListConstIterator temp = *this;
199  ++*this;
200  return (temp);
201  }
202  // pre-decrement
203  IntrusiveListConstIterator& operator--()
204  {
205  mPtr = mPtr->mPrev;return *this;
206  }
207  // post-decrement
208  const IntrusiveListConstIterator operator--(int)
209  {
210  IntrusiveListConstIterator temp = *this;
211  --*this;
212  return (temp);
213  }
214  IntrusiveListConstIterator& operator=(const IntrusiveListConstIterator &other){mPtr = other.mPtr; return *this;}
215 
216  const_reference operator*() const { return *(mPtr->mData); }
217  const_pointer operator->() const { return (&**this); }
218  bool operator==(const IntrusiveListConstIterator& other)const{ return mPtr==other.mPtr; }
219  bool operator!=(const IntrusiveListConstIterator& other)const{ return !(*this == other); }
220 
221  inline const NodeT* Get()const { return mPtr; }
222 
223  private:
224  mutable const NodeT* mPtr;
225  };
226 
227  // --- Iterator definitions ---
228  typedef IntrusiveListIterator iterator;
229  typedef IntrusiveListConstIterator const_iterator;
230 
231  // iterator support
232  inline iterator Begin() { return iterator(mHead.mNext); }
233  inline const_iterator Begin() const { return const_iterator(mHead.mNext); }
234  inline iterator End() { return iterator(&mHead); }
235  inline const_iterator End() const { return const_iterator(&mHead); }
236 
237  // Because there is no real use, for the reverse iterators,
238  // they have not been implemented.
239 
240  reference Front(){return (*Begin());}
241  const_reference Front() const { return (*Begin()); }
242  reference Back(){ return (*(--End())); }
243  const_reference Back() const{ return (*(--End())); }
244 
245  iterator& Erase(iterator& it)
246  {
247  it.Get()->Disconnect();
248  return (++it);
249  }
250 private:
251  NodeT mHead;
252 
253  // Not copyable
254  FbxIntrusiveList(const FbxIntrusiveList&);
255  FbxIntrusiveList& operator=(const FbxIntrusiveList& Right){return (*this);}
256 };
257 
258 #endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/
259 
260 #include <fbxsdk/fbxsdk_nsend.h>
261 
262 #endif /* _FBXSDK_CORE_BASE_INTRUSIVE_LIST_H_ */
FBX SDK environment definition.