Bike-X  0.8
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
OVR_Deque.h
Go to the documentation of this file.
1 /************************************************************************************
2 
3 Filename : OVR_Deque.h
4 Content : Deque container
5 Created : Nov. 15, 2013
6 Authors : Dov Katz
7 
8 Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
9 
10 Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License");
11 you may not use the Oculus VR Rift SDK except in compliance with the License,
12 which is provided at the time of installation or download, or which
13 otherwise accompanies this software in either electronic or hard copy form.
14 
15 You may obtain a copy of the License at
16 
17 http://www.oculusvr.com/licenses/LICENSE-3.1
18 
19 Unless required by applicable law or agreed to in writing, the Oculus VR SDK
20 distributed under the License is distributed on an "AS IS" BASIS,
21 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 See the License for the specific language governing permissions and
23 limitations under the License.
24 
25 *************************************************************************************/
26 
27 #ifndef OVR_Deque_h
28 #define OVR_Deque_h
29 
30 namespace OVR{
31 
32 template <class Elem>
33 class Deque
34 {
35 public:
36  enum
37  {
39  };
40 
41  Deque(int capacity = DefaultCapacity);
42  virtual ~Deque(void);
43 
44  virtual void PushBack (const Elem &Item); // Adds Item to the end
45  virtual void PushFront (const Elem &Item); // Adds Item to the beginning
46  virtual Elem PopBack (void); // Removes Item from the end
47  virtual Elem PopFront (void); // Removes Item from the beginning
48  virtual const Elem& PeekBack (int count = 0) const; // Returns count-th Item from the end
49  virtual const Elem& PeekFront (int count = 0) const; // Returns count-th Item from the beginning
50 
51  virtual inline UPInt GetSize (void) const; // Returns Number of Elements
52  virtual inline UPInt GetCapacity(void) const; // Returns the maximum possible number of elements
53  virtual void Clear (void); // Remove all elements
54  virtual inline bool IsEmpty () const;
55  virtual inline bool IsFull () const;
56 
57 protected:
58  Elem *Data; // The actual Data array
59  const int Capacity; // Deque capacity
60  int Beginning; // Index of the first element
61  int End; // Index of the next after last element
62 
63  // Instead of calculating the number of elements, using this variable
64  // is much more convenient.
65  int ElemCount;
66 
67 private:
68  Deque& operator= (const Deque& q) { }; // forbidden
69  Deque(const Deque<Elem> &OtherDeque) { };
70 };
71 
72 template <class Elem>
73 class InPlaceMutableDeque : public Deque<Elem>
74 {
75 public:
76  InPlaceMutableDeque( int capacity = Deque<Elem>::DefaultCapacity ) : Deque<Elem>( capacity ) {}
77  virtual ~InPlaceMutableDeque() {};
78 
81  virtual Elem& PeekBack (int count = 0); // Returns count-th Item from the end
82  virtual Elem& PeekFront (int count = 0); // Returns count-th Item from the beginning
83 };
84 
85 // Same as Deque, but allows to write more elements than maximum capacity
86 // Old elements are lost as they are overwritten with the new ones
87 template <class Elem>
88 class CircularBuffer : public InPlaceMutableDeque<Elem>
89 {
90 public:
92 
93  // The following methods are inline as a workaround for a VS bug causing erroneous C4505 warnings
94  // See: http://stackoverflow.com/questions/3051992/compiler-warning-at-c-template-base-class
95  inline virtual void PushBack (const Elem &Item); // Adds Item to the end, overwriting the oldest element at the beginning if necessary
96  inline virtual void PushFront (const Elem &Item); // Adds Item to the beginning, overwriting the oldest element at the end if necessary
97 };
98 
99 //----------------------------------------------------------------------------------
100 
101 // Deque Constructor function
102 template <class Elem>
103 Deque<Elem>::Deque(int capacity) :
104 Capacity( capacity ), Beginning(0), End(0), ElemCount(0)
105 {
106  Data = (Elem*) OVR_ALLOC(Capacity * sizeof(Elem));
107  ConstructArray<Elem>(Data, Capacity);
108 }
109 
110 // Deque Destructor function
111 template <class Elem>
113 {
114  DestructArray<Elem>(Data, Capacity);
115  OVR_FREE(Data);
116 }
117 
118 template <class Elem>
120 {
121  Beginning = 0;
122  End = 0;
123  ElemCount = 0;
124 
125  DestructArray<Elem>(Data, Capacity);
126  ConstructArray<Elem>(Data, Capacity);
127 }
128 
129 // Push functions
130 template <class Elem>
131 void Deque<Elem>::PushBack(const Elem &Item)
132 {
133  // Error Check: Make sure we aren't
134  // exceeding our maximum storage space
135  OVR_ASSERT( ElemCount < Capacity );
136 
137  Data[ End++ ] = Item;
138  ++ElemCount;
139 
140  // Check for wrap-around
141  if (End >= Capacity)
142  End -= Capacity;
143 }
144 
145 template <class Elem>
146 void Deque<Elem>::PushFront(const Elem &Item)
147 {
148  // Error Check: Make sure we aren't
149  // exceeding our maximum storage space
150  OVR_ASSERT( ElemCount < Capacity );
151 
152  Beginning--;
153  // Check for wrap-around
154  if (Beginning < 0)
155  Beginning += Capacity;
156 
157  Data[ Beginning ] = Item;
158  ++ElemCount;
159 }
160 
161 // Pop functions
162 template <class Elem>
164 {
165  // Error Check: Make sure we aren't reading from an empty Deque
166  OVR_ASSERT( ElemCount > 0 );
167 
168  Elem ReturnValue = Data[ Beginning ];
169  Destruct<Elem>(&Data[ Beginning ]);
170  Construct<Elem>(&Data[ Beginning ]);
171 
172  ++Beginning;
173  --ElemCount;
174 
175  // Check for wrap-around
176  if (Beginning >= Capacity)
177  Beginning -= Capacity;
178 
179  return ReturnValue;
180 }
181 
182 template <class Elem>
184 {
185  // Error Check: Make sure we aren't reading from an empty Deque
186  OVR_ASSERT( ElemCount > 0 );
187 
188  End--;
189  --ElemCount;
190 
191  // Check for wrap-around
192  if (End < 0)
193  End += Capacity;
194 
195  Elem ReturnValue = Data[ End ];
196  Destruct<Elem>(&Data[ End ]);
197  Construct<Elem>(&Data[ End ]);
198 
199  return ReturnValue;
200 }
201 
202 // Peek functions
203 template <class Elem>
204 const Elem& Deque<Elem>::PeekFront(int count) const
205 {
206  // Error Check: Make sure we aren't reading from an empty Deque
207  OVR_ASSERT( ElemCount > count );
208 
209  int idx = Beginning + count;
210  if (idx >= Capacity)
211  idx -= Capacity;
212  return Data[ idx ];
213 }
214 
215 template <class Elem>
216 const Elem& Deque<Elem>::PeekBack(int count) const
217 {
218  // Error Check: Make sure we aren't reading from an empty Deque
219  OVR_ASSERT( ElemCount > count );
220 
221  int idx = End - count - 1;
222  if (idx < 0)
223  idx += Capacity;
224  return Data[ idx ];
225 }
226 
227 // Mutable Peek functions
228 template <class Elem>
230 {
231  // Error Check: Make sure we aren't reading from an empty Deque
233 
234  int idx = Deque<Elem>::Beginning + count;
235  if (idx >= Deque<Elem>::Capacity)
236  idx -= Deque<Elem>::Capacity;
237  return Deque<Elem>::Data[ idx ];
238 }
239 
240 template <class Elem>
242 {
243  // Error Check: Make sure we aren't reading from an empty Deque
245 
246  int idx = Deque<Elem>::End - count - 1;
247  if (idx < 0)
248  idx += Deque<Elem>::Capacity;
249  return Deque<Elem>::Data[ idx ];
250 }
251 
252 template <class Elem>
253 inline UPInt Deque<Elem>::GetCapacity(void) const
254 {
255  return Deque<Elem>::Capacity;
256 }
257 
258 template <class Elem>
259 inline UPInt Deque<Elem>::GetSize(void) const
260 {
261  return Deque<Elem>::ElemCount;
262 }
263 
264 template <class Elem>
265 inline bool Deque<Elem>::IsEmpty(void) const
266 {
267  return Deque<Elem>::ElemCount==0;
268 }
269 
270 template <class Elem>
271 inline bool Deque<Elem>::IsFull(void) const
272 {
274 }
275 
276 // ******* CircularBuffer<Elem> *******
277 // Push functions
278 template <class Elem>
279 void CircularBuffer<Elem>::PushBack(const Elem &Item)
280 {
281  if (this->IsFull())
282  this->PopFront();
283  Deque<Elem>::PushBack(Item);
284 }
285 
286 template <class Elem>
287 void CircularBuffer<Elem>::PushFront(const Elem &Item)
288 {
289  if (this->IsFull())
290  this->PopBack();
292 }
293 
294 };
295 
296 #endif
const int Capacity
Definition: OVR_Deque.h:59
virtual const Elem & PeekFront(int count=0) const
Definition: OVR_Deque.h:204
virtual ~Deque(void)
Definition: OVR_Deque.h:112
InPlaceMutableDeque(int capacity=Deque< Elem >::DefaultCapacity)
Definition: OVR_Deque.h:76
virtual bool IsFull() const
Definition: OVR_Deque.h:271
int ElemCount
Definition: OVR_Deque.h:65
CircularBuffer(int MaxSize=Deque< Elem >::DefaultCapacity)
Definition: OVR_Deque.h:91
virtual const Elem & PeekBack(int count=0) const
Definition: OVR_Deque.h:216
int Beginning
Definition: OVR_Deque.h:60
virtual Elem PopBack(void)
Definition: OVR_Deque.h:183
Deque & operator=(const Deque &q)
Definition: OVR_Deque.h:68
size_t UPInt
Definition: OVR_Types.h:218
virtual UPInt GetCapacity(void) const
Definition: OVR_Deque.h:253
Deque(const Deque< Elem > &OtherDeque)
Definition: OVR_Deque.h:69
virtual void PushBack(const Elem &Item)
Definition: OVR_Deque.h:279
virtual bool IsEmpty() const
Definition: OVR_Deque.h:265
virtual void PushBack(const Elem &Item)
Definition: OVR_Deque.h:131
#define OVR_ASSERT(p)
virtual void PushFront(const Elem &Item)
Definition: OVR_Deque.h:146
virtual UPInt GetSize(void) const
Definition: OVR_Deque.h:259
Deque(int capacity=DefaultCapacity)
Definition: OVR_Deque.h:103
Elem * Data
Definition: OVR_Deque.h:58
virtual Elem & PeekFront(int count=0)
Definition: OVR_Deque.h:229
virtual Elem PopFront(void)
Definition: OVR_Deque.h:163
virtual void Clear(void)
Definition: OVR_Deque.h:119
virtual Elem & PeekBack(int count=0)
Definition: OVR_Deque.h:241
virtual ~InPlaceMutableDeque()
Definition: OVR_Deque.h:77
#define OVR_ALLOC(s)
#define OVR_FREE(p)
virtual void PushFront(const Elem &Item)
Definition: OVR_Deque.h:287