ucommon
containers.h
Go to the documentation of this file.
1 // Copyright (C) 2006-2010 David Sugar, Tycho Softworks.
2 //
3 // This file is part of GNU uCommon C++.
4 //
5 // GNU uCommon C++ is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU Lesser General Public License as published
7 // by the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // GNU uCommon C++ is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public License
16 // along with GNU uCommon C++. If not, see <http://www.gnu.org/licenses/>.
17 
29 #ifndef _UCOMMON_CONTAINERS_H_
30 #define _UCOMMON_CONTAINERS_H_
31 
32 #ifndef _UCOMMON_CONFIG_H_
33 #include <ucommon/platform.h>
34 #endif
35 
36 #ifndef _UCOMMON_PROTOCOLS_H_
37 #include <ucommon/protocols.h>
38 #endif
39 
40 #ifndef _UCOMMON_LINKED_H_
41 #include <ucommon/linked.h>
42 #endif
43 
44 #ifndef _UCOMMON_MEMORY_H_
45 #include <ucommon/memory.h>
46 #endif
47 
48 #ifndef _UCOMMON_THREAD_H_
49 #include <ucommon/thread.h>
50 #endif
51 
52 NAMESPACE_UCOMMON
53 
60 class __EXPORT LinkedAllocator : private Conditional
61 {
62 protected:
63  LinkedObject *freelist;
64 
66 
67  LinkedObject *get(void);
68 
69  LinkedObject *get(timeout_t timeout);
70 
71  void release(LinkedObject *node);
72 
73 public:
78  operator bool();
79 
84  bool operator!();
85 };
86 
96 class __EXPORT Buffer : protected Conditional
97 {
98 private:
99  size_t size, objsize;
100  caddr_t buf, head, tail;
101  unsigned count, limit;
102 
103 public:
109  Buffer(size_t size, size_t count);
110 
114  virtual ~Buffer();
115 
120  unsigned getSize(void);
121 
126  unsigned getCount(void);
127 
133  void *get(timeout_t timeout);
134 
140  void *get(void);
141 
147  void put(void *data);
148 
155  bool put(void *data, timeout_t timeout);
156 
163  void release(void);
164 
170  void copy(void *data);
171 
178  bool copy(void *data, timeout_t timeout);
179 
187  void *peek(unsigned item);
188 
193  operator bool();
194 
199  bool operator!();
200 };
201 
212 class __EXPORT queue : protected OrderedIndex, protected Conditional
213 {
214 private:
215  mempager *pager;
216  LinkedObject *freelist;
217  size_t used;
218 
219  class __LOCAL member : public OrderedObject
220  {
221  public:
222  member(queue *q, ObjectProtocol *obj);
223  ObjectProtocol *object;
224  };
225 
226  friend class member;
227 
228 protected:
229  size_t limit;
230 
231 public:
239  queue(mempager *pager = NULL, size_t number = 0);
240 
244  ~queue();
245 
253  bool remove(ObjectProtocol *object);
254 
263  bool post(ObjectProtocol *object, timeout_t timeout = 0);
264 
270  ObjectProtocol *peek(unsigned offset = 0);
271 
279  ObjectProtocol *fifo(timeout_t timeout = 0);
280 
288  ObjectProtocol *lifo(timeout_t timeout = 0);
289 
294  size_t getCount(void);
295 
302  static bool remove(queue& queue, ObjectProtocol *object)
303  {return queue.remove(object);};
304 
312  static bool post(queue& queue, ObjectProtocol *object, timeout_t timeout = 0)
313  {return queue.post(object, timeout);};
314 
321  static ObjectProtocol *fifo(queue& queue, timeout_t timeout = 0)
322  {return queue.fifo(timeout);};
323 
330  static ObjectProtocol *lifo(queue& queue, timeout_t timeout = 0)
331  {return queue.lifo(timeout);};
332 
338  static size_t count(queue& queue)
339  {return queue.getCount();};
340 
341  inline ObjectProtocol *operator[](unsigned pos)
342  {return peek(pos);};
343 };
344 
353 class __EXPORT stack : protected Conditional
354 {
355 private:
356  LinkedObject *freelist, *usedlist;
357  mempager *pager;
358  size_t used;
359 
360  class __LOCAL member : public LinkedObject
361  {
362  public:
363  member(stack *s, ObjectProtocol *obj);
364  ObjectProtocol *object;
365  };
366 
367  friend class member;
368 
369 protected:
370  size_t limit;
371 
372 public:
379  stack(mempager *pager = NULL, size_t number = 0);
380 
384  ~stack();
385 
393  bool remove(ObjectProtocol *object);
394 
403  bool push(ObjectProtocol *object, timeout_t timeout = 0);
404 
412  ObjectProtocol *pull(timeout_t timeout = 0);
413 
419  ObjectProtocol *peek(unsigned offset = 0);
420 
425  size_t getCount(void);
426 
433  static inline bool remove(stack& stack, ObjectProtocol *object)
434  {return stack.remove(object);};
435 
443  static inline bool push(stack& stack, ObjectProtocol *object, timeout_t timeout = 0)
444  {return stack.push(object, timeout);};
445 
452  static inline ObjectProtocol *pull(stack& stack, timeout_t timeout = 0)
453  {return stack.pull(timeout);};
454 
460  static inline size_t count(stack& stack)
461  {return stack.getCount();};
462 
463  inline ObjectProtocol *operator[](unsigned pos)
464  {return peek(pos);};
465 };
466 
474 template <class T>
476 {
477 private:
478  T* array;
479 
480 public:
481  inline linked_allocator(size_t size) : LinkedAllocator() {
482  array = new T[size];
483  for(unsigned i = 0; i < size; ++i)
484  array[i].enlist(&freelist);
485  }
486 
488  {delete[] array;};
489 
490  inline T *get(void)
491  {return static_cast<T *>(LinkedAllocator::get());};
492 
493  inline T *get(timeout_t timeout)
494  {return static_cast<T *>(LinkedAllocator::get(timeout));};
495 
496  inline void release(T *node)
497  {LinkedAllocator::release(node);};
498 };
499 
511 template<class T>
512 class bufferof : public Buffer
513 {
514 public:
519  inline bufferof(unsigned count) :
520  Buffer(sizeof(T), count) {};
521 
527  inline T *get(void)
528  {return static_cast<T*>(get());};
529 
535  inline T *get(timeout_t timeout)
536  {return static_cast<T*>(get(timeout));};
537 
543  inline void put(T *object)
544  {put(object);};
545 
552  inline bool put(T *object, timeout_t timeout)
553  {return put(object, timeout);};
554 
560  inline void copy(T *object)
561  {copy(object);};
562 
569  inline bool get(T *object, timeout_t timeout)
570  {return copy(object, timeout);};
571 
578  inline T *peek(unsigned item)
579  {return static_cast<T *>(Buffer::peek(item));};
580 
587  inline T *operator[](unsigned item)
588  {return static_cast<T *>(queue::peek(item));};
589 
590 };
591 
599 template<class T>
600 class stackof : public stack
601 {
602 public:
608  inline stackof(mempager *memory, size_t size = 0) : stack(memory, size) {};
609 
617  inline bool remove(T *object)
618  {return stack::remove(object);};
619 
628  inline bool push(T *object, timeout_t timeout = 0)
629  {return stack::push(object);};
630 
638  inline T *pull(timeout_t timeout = 0)
639  {return static_cast<T *>(stack::pull(timeout));};
640 
647  inline T *peek(unsigned offset = 0)
648  {return static_cast<T *>(stack::peek(offset));};
649 
656  inline T *operator[](unsigned offset)
657  {return static_cast<T *>(stack::peek(offset));};
658 
659 };
660 
668 template<class T>
669 class queueof : public queue
670 {
671 public:
677  inline queueof(mempager *memory, size_t size = 0) : queue(memory, size) {};
678 
686  inline bool remove(T *object)
687  {return queue::remove(object);};
688 
697  inline bool post(T *object, timeout_t timeout = 0)
698  {return queue::post(object);};
699 
707  inline T *fifo(timeout_t timeout = 0)
708  {return static_cast<T *>(queue::fifo(timeout));};
709 
717  inline T *lifo(timeout_t timeout = 0)
718  {return static_cast<T *>(queue::lifo(timeout));};
719 
726  inline T *peek(unsigned offset = 0)
727  {return static_cast<T *>(queue::peek(offset));};
728 
735  inline T *operator[](unsigned offset)
736  {return static_cast<T *>(queue::peek(offset));};
737 
738 };
739 
743 typedef stack stack_t;
744 
748 typedef queue fifo_t;
749 
755 inline void push(stack_t &stack, ObjectProtocol *object)
756  {stack.push(object);}
757 
764 inline ObjectProtocol *pull(stack_t &stack, timeout_t timeout = Timer::inf)
765  {return stack.pull(timeout);}
766 
772 inline void remove(stack_t &stack, ObjectProtocol *object)
773  {stack.remove(object);}
774 
780 inline void push(fifo_t &fifo, ObjectProtocol *object)
781  {fifo.post(object);}
782 
789 inline ObjectProtocol *pull(fifo_t &fifo, timeout_t timeout = Timer::inf)
790  {return fifo.fifo(timeout);}
791 
797 inline void remove(fifo_t &fifo, ObjectProtocol *object)
798  {fifo.remove(object);}
799 
800 END_NAMESPACE
801 
802 #endif