cisst-saw
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
mtsQueue.h
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* ex: set filetype=cpp softtabstop=4 shiftwidth=4 tabstop=4 cindent expandtab: */
3 
4 /*
5 
6  Author(s): Peter Kazanzides, Anton Deguet
7  Created on: 2007-09-05
8 
9  (C) Copyright 2007-2010 Johns Hopkins University (JHU), All Rights Reserved.
10 
11 --- begin cisst license - do not edit ---
12 
13 This software is provided "as is" under an open source license, with
14 no warranty. The complete license can be found in license.txt and
15 http://www.cisst.org/cisst/license.txt.
16 
17 --- end cisst license ---
18 */
19 
20 
27 #ifndef _mtsQueue_h
28 #define _mtsQueue_h
29 
31 
39 template<class _elementType>
40 class mtsQueue
41 {
42 public:
43  typedef _elementType value_type;
44  typedef value_type * pointer;
45  typedef const value_type * const_pointer;
46  typedef value_type & reference;
47  typedef const value_type & const_reference;
48  typedef size_t size_type;
49  typedef size_t index_type;
50 
51 protected:
55  pointer Sentinel; // end marker
57 
58  // private method, can only be used once by constructor. Doesn't support resize!
59  void Allocate(size_type size, const_reference value) {
60  this->Size = size;
61  if (this->Size > 0) {
62  this->Data = new value_type[this->Size];
63  index_type index;
64  for (index = 0; index < this->Size; index++) {
65  new(&this->Data[index]) value_type(value);
66  }
67  } else {
68  this->Data = 0;
69  }
70  // head == tail implies empty queue
71  this->Head = this->Data;
72  this->Tail = this->Data;
73  this->Sentinel = this->Data + this->Size;
74  }
75 
76 public:
77 
78  inline mtsQueue(void):
79  Data(0),
80  Head(0),
81  Tail(0),
82  Sentinel(0),
83  Size(0)
84  {}
85 
86 
87  inline mtsQueue(size_type size, const_reference value) {
88  Allocate(size, value);
89  }
90 
91 
92  inline ~mtsQueue() {
93  delete [] Data;
94  }
95 
96 
99  inline void SetSize(size_type size, const_reference value) {
100  delete [] Data;
101  this->Allocate(size, value);
102  }
103 
104 
106  inline size_type GetSize(void) const {
107  return Size;
108  }
109 
110 
113  inline size_type GetAvailable(void) const
114  {
115  ptrdiff_t available = Head - Tail;
116  if (available < 0) {
117  available += Size;
118  }
119  return available;
120  }
121 
122 
124  inline bool IsFull(void) const {
125  pointer oneAfterHead = this->Head + 1;
126  if (oneAfterHead >= this->Sentinel) {
127  oneAfterHead = this->Data;
128  }
129  return oneAfterHead == this->Tail;
130  }
131 
132 
134  inline bool IsEmpty(void) const {
135  return Head == Tail;
136  }
137 
138 
143  //inline const_pointer Put(const_reference newObject)
144  //Following signature is equivalent for types that are not Proxy types. If a Proxy type,
145  //then we use the ProxyBase instead, so that we can also accept ProxyRef objects.
147  {
148  pointer newHead = this->Head + 1;
149  // test if end of buffer (same as IsFull method)
150  if (newHead >= this->Sentinel) {
151  newHead = this->Data;
152  }
153  // test if full
154  if (newHead == this->Tail) {
155  return 0; // queue full
156  }
157  // queue new object and move head
158  *(this->Head) = newObject;
159  this->Head = newHead;
160  return this->Head;
161  }
162 
163 
168  inline pointer Peek(void) const {
169  if (this->IsEmpty()) {
170  return 0;
171  }
172  return this->Tail;
173  }
174 
175 
179  inline pointer Get(void) {
180  if (this->IsEmpty()) {
181  return 0;
182  }
183  pointer result = this->Tail;
184  this->Tail++;
185  if (this->Tail >= this->Sentinel) {
186  this->Tail = this->Data;
187  }
188  return result;
189  }
190 
191 };
192 
193 
194 
195 
197 {
198 public:
200  typedef value_type * pointer;
201  typedef const value_type * const_pointer;
203  typedef const value_type & const_reference;
204  typedef size_t size_type;
205  typedef size_t index_type;
206 
207 protected:
212  pointer * Sentinel; // end marker
214 
215  // private method, can only be used once by constructor. Doesn't support resize!
216  void Allocate(size_type size, const_reference value) {
217  CMN_ASSERT(this->ClassServices);
218  this->Size = size;
219  if (this->Size > 0) {
220  this->Data = new pointer[size];
221  size_t index;
222  for (index = 0; index < size; index++) {
223  cmnGenericObject * genericPointer = this->ClassServices->Create(value);
224  if (!genericPointer) {
225  CMN_LOG_RUN_ERROR << "class mtsQueueGeneric: Allocate failed to create generic object for "
226  << this->ClassServices->GetName() << std::endl;
227  }
228  pointer typedPointer = dynamic_cast<pointer>(genericPointer);
229  CMN_ASSERT(typedPointer);
230  this->Data[index] = typedPointer;
231  }
232  } else {
233  this->Data = 0;
234  }
235  // head == tail implies empty queue
236  this->Head = this->Data;
237  this->Tail = this->Data;
238  this->Sentinel = this->Data + this->Size;
239  }
240 
241  void Free(void) {
242  size_t index;
243  for (index = 0; index < this->Size; index++) {
244  delete this->Data[index];
245  }
246  delete [] this->Data;
247  this->Data = 0;
248  }
249 
250 public:
251 
252  inline mtsQueueGeneric(void):
253  ClassServices(0),
254  Data(0),
255  Head(0),
256  Tail(0),
257  Sentinel(0),
258  Size(1)
259  {}
260 
261 
263  this->ClassServices = value.Services();
264  CMN_ASSERT(this->ClassServices);
265  CMN_LOG_INIT_DEBUG << "class mtsQueueGeneric: constructor, created queue of "
266  << this->ClassServices->GetName() << std::endl;
267  Allocate(size + 1, value);
268  }
269 
270 
271  inline ~mtsQueueGeneric() {
272  this->Free();
273  }
274 
275 
278  inline void SetSize(size_type size, const_reference value) {
279  if (this->ClassServices != 0) { // if non zero, it has already been set
280  if (this->ClassServices != value.Services()) {
281  CMN_LOG_INIT_WARNING << "mtsQueueGeneric::SetSize: type of elements expected \""
282  << this->ClassServices->GetName() << "\", now using \""
283  << value.Services()->GetName() << "\"" << std::endl;
284  }
285  this->Free();
286  if (this->Data != 0) {
287  CMN_LOG_INIT_WARNING << "mtsQueueGeneric::SetSize: failed to delete data array for \""
288  << this->ClassServices->GetName() << "\"" << std::endl;
289  }
290  }
291  this->ClassServices = value.Services();
292  this->Allocate(size + 1, value);
293  }
294 
295 
297  inline size_type GetSize(void) const {
298  return (Size - 1);
299  }
300 
301 
304  inline size_type GetAvailable(void) const
305  {
306  ptrdiff_t available = Head - Tail;
307  if (available < 0) {
308  available += Size;
309  }
310  return available;
311  }
312 
313 
315  inline bool IsFull(void) const {
316  pointer * oneAfterHead = this->Head + 1;
317  if (oneAfterHead >= this->Sentinel) {
318  oneAfterHead = this->Data;
319  }
320  return oneAfterHead == this->Tail;
321  }
322 
323 
325  inline bool IsEmpty(void) const {
326  return Head == Tail;
327  }
328 
329 
334  inline const_pointer Put(const_reference newObject) {
335  pointer * newHead = this->Head + 1;
336  // test if end of buffer (same as IsFull method)
337  if (newHead >= this->Sentinel) {
338  newHead = this->Data;
339  }
340  // test if full
341  if (newHead == this->Tail) {
342  return 0; // queue full
343  }
344  // queue new object and move head
345  // using in place new to make sure copy constructor is used
346  if (!this->ClassServices->Create(*(this->Head), newObject)) {
347  // if Create fails, it does not modify the input parameter (this->Head)
348  CMN_LOG_RUN_ERROR << "mtsQueueGeneric::Put failed for " << newObject.Services()->GetName() << std::endl;
349  return 0;
350  }
351  this->Head = newHead;
352  return *(this->Head);
353  }
354 
355 
360  inline pointer Peek(void) const {
361  if (this->IsEmpty()) {
362  return 0;
363  }
364  return *(this->Tail);
365  }
366 
367 
371  inline pointer Get(void) {
372  if (this->IsEmpty()) {
373  return 0;
374  }
375  pointer result = *(this->Tail);
376  this->Tail++;
377  if (this->Tail >= this->Sentinel) {
378  this->Tail = this->Data;
379  }
380  return result;
381  }
382 
383 };
384 
385 
386 #endif // _mtsQueue_h
387 
pointer Get(void)
Definition: mtsQueue.h:371
size_t size_type
Definition: mtsQueue.h:204
pointer Get(void)
Definition: mtsQueue.h:179
#define CMN_ASSERT(expr)
Definition: cmnAssert.h:90
#define CMN_LOG_RUN_ERROR
Definition: cmnLogger.h:166
size_t index_type
Definition: mtsQueue.h:205
~mtsQueue()
Definition: mtsQueue.h:92
pointer * Tail
Definition: mtsQueue.h:211
void SetSize(size_type size, const_reference value)
Definition: mtsQueue.h:99
pointer Tail
Definition: mtsQueue.h:54
mtsQueue(size_type size, const_reference value)
Definition: mtsQueue.h:87
const value_type * const_pointer
Definition: mtsQueue.h:201
size_type Size
Definition: mtsQueue.h:56
const std::string & GetName(void) const
mtsQueueGeneric(size_type size, const_reference value)
Definition: mtsQueue.h:262
void Free(void)
Definition: mtsQueue.h:241
void Allocate(size_type size, const_reference value)
Definition: mtsQueue.h:59
Base class for high level objects.
Definition: cmnGenericObject.h:51
Base class for data object in cisstMultiTask.
Definition: mtsGenericObject.h:56
pointer Head
Definition: mtsQueue.h:53
virtual const cmnClassServicesBase * Services(void) const =0
void SetSize(size_type size, const_reference value)
Definition: mtsQueue.h:278
_elementType value_type
Definition: mtsQueue.h:43
value_type * pointer
Definition: mtsQueue.h:200
const value_type & const_reference
Definition: mtsQueue.h:203
pointer * Sentinel
Definition: mtsQueue.h:212
void Allocate(size_type size, const_reference value)
Definition: mtsQueue.h:216
size_t index_type
Definition: mtsQueue.h:49
mtsGenericTypesUnwrapImpl< T, cmnIsDerivedFromTemplated< T, mtsGenericObjectProxyBase >::IS_DERIVED >::BaseType BaseType
Definition: mtsGenericObjectProxy.h:715
bool IsEmpty(void) const
Definition: mtsQueue.h:325
mtsQueueGeneric(void)
Definition: mtsQueue.h:252
bool IsEmpty(void) const
Definition: mtsQueue.h:134
pointer Data
Definition: mtsQueue.h:52
size_type Size
Definition: mtsQueue.h:213
Definition: mtsQueue.h:196
const_pointer Put(const_reference newObject)
Definition: mtsQueue.h:334
size_type GetSize(void) const
Definition: mtsQueue.h:297
pointer * Data
Definition: mtsQueue.h:209
bool IsFull(void) const
Definition: mtsQueue.h:124
const_pointer Put(const typename mtsGenericTypesUnwrap< value_type >::BaseType &newObject)
Definition: mtsQueue.h:146
size_type GetSize(void) const
Definition: mtsQueue.h:106
pointer * Head
Definition: mtsQueue.h:210
Definition: mtsQueue.h:40
Base class for class services.
Definition: cmnClassServicesBase.h:45
size_type GetAvailable(void) const
Definition: mtsQueue.h:113
bool IsFull(void) const
Definition: mtsQueue.h:315
value_type & reference
Definition: mtsQueue.h:202
const value_type * const_pointer
Definition: mtsQueue.h:45
mtsQueue(void)
Definition: mtsQueue.h:78
value_type & reference
Definition: mtsQueue.h:46
pointer Sentinel
Definition: mtsQueue.h:55
value_type * pointer
Definition: mtsQueue.h:44
#define CMN_LOG_INIT_WARNING
Definition: cmnLogger.h:163
const cmnClassServicesBase * ClassServices
Definition: mtsQueue.h:208
pointer Peek(void) const
Definition: mtsQueue.h:168
mtsGenericObject value_type
Definition: mtsQueue.h:199
const value_type & const_reference
Definition: mtsQueue.h:47
~mtsQueueGeneric()
Definition: mtsQueue.h:271
pointer Peek(void) const
Definition: mtsQueue.h:360
#define CMN_LOG_INIT_DEBUG
Definition: cmnLogger.h:165
virtual cmnGenericObject * Create(void) const =0
size_type GetAvailable(void) const
Definition: mtsQueue.h:304
size_t size_type
Definition: mtsQueue.h:48