UCommon
ucommon/containers.h
Go to the documentation of this file.
00001 // Copyright (C) 2006-2010 David Sugar, Tycho Softworks.
00002 //
00003 // This file is part of GNU uCommon C++.
00004 //
00005 // GNU uCommon C++ is free software: you can redistribute it and/or modify
00006 // it under the terms of the GNU Lesser General Public License as published
00007 // by the Free Software Foundation, either version 3 of the License, or
00008 // (at your option) any later version.
00009 //
00010 // GNU uCommon C++ is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 // GNU Lesser General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU Lesser General Public License
00016 // along with GNU uCommon C++.  If not, see <http://www.gnu.org/licenses/>.
00017 
00029 #ifndef _UCOMMON_CONTAINERS_H_
00030 #define _UCOMMON_CONTAINERS_H_
00031 
00032 #ifndef _UCOMMON_CONFIG_H_
00033 #include <ucommon/platform.h>
00034 #endif
00035 
00036 #ifndef _UCOMMON_PROTOCOLS_H_
00037 #include <ucommon/protocols.h>
00038 #endif
00039 
00040 #ifndef  _UCOMMON_LINKED_H_
00041 #include <ucommon/linked.h>
00042 #endif
00043 
00044 #ifndef  _UCOMMON_MEMORY_H_
00045 #include <ucommon/memory.h>
00046 #endif
00047 
00048 #ifndef  _UCOMMON_THREAD_H_
00049 #include <ucommon/thread.h>
00050 #endif
00051 
00052 NAMESPACE_UCOMMON
00053 
00060 class __EXPORT LinkedAllocator : private Conditional
00061 {
00062 protected:
00063     LinkedObject *freelist;
00064 
00065     LinkedAllocator();
00066 
00067     LinkedObject *get(void);
00068 
00069     LinkedObject *get(timeout_t timeout);
00070 
00071     void release(LinkedObject *node);
00072 
00073 public:
00078     operator bool();
00079 
00084     bool operator!();
00085 };
00086 
00096 class __EXPORT Buffer : protected Conditional
00097 {
00098 private:
00099     size_t size, objsize;
00100     caddr_t buf, head, tail;
00101     unsigned count, limit;
00102 
00103 public:
00109     Buffer(size_t size, size_t count);
00110 
00114     virtual ~Buffer();
00115 
00120     unsigned getSize(void);
00121 
00126     unsigned getCount(void);
00127 
00133     void *get(timeout_t timeout);
00134 
00140     void *get(void);
00141 
00147     void put(void *data);
00148 
00155     bool put(void *data, timeout_t timeout);
00156 
00163     void release(void);
00164 
00170     void copy(void *data);
00171 
00178     bool copy(void *data, timeout_t timeout);
00179 
00187     void *peek(unsigned item);
00188 
00193     operator bool();
00194 
00199     bool operator!();
00200 };
00201 
00212 class __EXPORT queue : protected OrderedIndex, protected Conditional
00213 {
00214 private:
00215     mempager *pager;
00216     LinkedObject *freelist;
00217     size_t used;
00218 
00219     class __LOCAL member : public OrderedObject
00220     {
00221     public:
00222         member(queue *q, ObjectProtocol *obj);
00223         ObjectProtocol *object;
00224     };
00225 
00226     friend class member;
00227 
00228 protected:
00229     size_t limit;
00230 
00231 public:
00239     queue(mempager *pager = NULL, size_t number = 0);
00240 
00244     ~queue();
00245 
00253     bool remove(ObjectProtocol *object);
00254 
00263     bool post(ObjectProtocol *object, timeout_t timeout = 0);
00264 
00270     ObjectProtocol *peek(unsigned offset = 0);
00271 
00279     ObjectProtocol *fifo(timeout_t timeout = 0);
00280 
00288     ObjectProtocol *lifo(timeout_t timeout = 0);
00289 
00294     size_t getCount(void);
00295 
00302     static bool remove(queue& queue, ObjectProtocol *object)
00303         {return queue.remove(object);};
00304 
00312     static bool post(queue& queue, ObjectProtocol *object, timeout_t timeout = 0)
00313         {return queue.post(object, timeout);};
00314 
00321     static ObjectProtocol *fifo(queue& queue, timeout_t timeout = 0)
00322         {return queue.fifo(timeout);};
00323 
00330     static ObjectProtocol *lifo(queue& queue, timeout_t timeout = 0)
00331         {return queue.lifo(timeout);};
00332 
00338     static size_t count(queue& queue)
00339         {return queue.getCount();};
00340 
00341     inline ObjectProtocol *operator[](unsigned pos)
00342         {return peek(pos);};
00343 };
00344 
00353 class __EXPORT stack : protected Conditional
00354 {
00355 private:
00356     LinkedObject *freelist, *usedlist;
00357     mempager *pager;
00358     size_t used;
00359 
00360     class __LOCAL member : public LinkedObject
00361     {
00362     public:
00363         member(stack *s, ObjectProtocol *obj);
00364         ObjectProtocol *object;
00365     };
00366 
00367     friend class member;
00368 
00369 protected:
00370     size_t limit;
00371 
00372 public:
00379     stack(mempager *pager = NULL, size_t number = 0);
00380 
00384     ~stack();
00385 
00393     bool remove(ObjectProtocol *object);
00394 
00403     bool push(ObjectProtocol *object, timeout_t timeout = 0);
00404 
00412     ObjectProtocol *pull(timeout_t timeout = 0);
00413 
00419     ObjectProtocol *peek(unsigned offset = 0);
00420 
00425     size_t getCount(void);
00426 
00433     static inline bool remove(stack& stack, ObjectProtocol *object)
00434         {return stack.remove(object);};
00435 
00443     static inline bool push(stack& stack, ObjectProtocol *object, timeout_t timeout = 0)
00444         {return stack.push(object, timeout);};
00445 
00452     static inline ObjectProtocol *pull(stack& stack, timeout_t timeout = 0)
00453         {return stack.pull(timeout);};
00454 
00460     static inline size_t count(stack& stack)
00461         {return stack.getCount();};
00462 
00463     inline ObjectProtocol *operator[](unsigned pos)
00464         {return peek(pos);};
00465 };
00466 
00474 template <class T>
00475 class linked_allocator : public LinkedAllocator
00476 {
00477 private:
00478     T* array;
00479 
00480 public:
00481     inline linked_allocator(size_t size) : LinkedAllocator() {
00482         array = new T[size];
00483         for(unsigned i = 0; i < size; ++i)
00484             array[i].enlist(&freelist);
00485     }
00486 
00487     ~linked_allocator()
00488         {delete[] array;};
00489 
00490     inline T *get(void)
00491         {return static_cast<T *>(LinkedAllocator::get());};
00492 
00493     inline T *get(timeout_t timeout)
00494         {return static_cast<T *>(LinkedAllocator::get(timeout));};
00495 
00496     inline void release(T *node)
00497         {LinkedAllocator::release(node);};
00498 };
00499 
00511 template<class T>
00512 class bufferof : public Buffer
00513 {
00514 public:
00519     inline bufferof(unsigned count) :
00520         Buffer(sizeof(T), count) {};
00521 
00527     inline T *get(void)
00528         {return static_cast<T*>(get());};
00529 
00535     inline T *get(timeout_t timeout)
00536         {return static_cast<T*>(get(timeout));};
00537 
00543     inline void put(T *object)
00544         {put(object);};
00545 
00552     inline bool put(T *object, timeout_t timeout)
00553         {return put(object, timeout);};
00554 
00560     inline void copy(T *object)
00561         {copy(object);};
00562 
00569     inline bool get(T *object, timeout_t timeout)
00570         {return copy(object, timeout);};
00571 
00578     inline T *peek(unsigned item)
00579         {return static_cast<T *>(Buffer::peek(item));};
00580 
00587     inline T *operator[](unsigned item)
00588         {return static_cast<T *>(queue::peek(item));};
00589 
00590 };
00591 
00599 template<class T>
00600 class stackof : public stack
00601 {
00602 public:
00608     inline stackof(mempager *memory, size_t size = 0) : stack(memory, size) {};
00609 
00617     inline bool remove(T *object)
00618         {return stack::remove(object);};
00619 
00628     inline bool push(T *object, timeout_t timeout = 0)
00629         {return stack::push(object);};
00630 
00638     inline T *pull(timeout_t timeout = 0)
00639         {return static_cast<T *>(stack::pull(timeout));};
00640 
00647     inline T *peek(unsigned offset = 0)
00648         {return static_cast<T *>(stack::peek(offset));};
00649 
00656     inline T *operator[](unsigned offset)
00657         {return static_cast<T *>(stack::peek(offset));};
00658 
00659 };
00660 
00668 template<class T>
00669 class queueof : public queue
00670 {
00671 public:
00677     inline queueof(mempager *memory, size_t size = 0) : queue(memory, size) {};
00678 
00686     inline bool remove(T *object)
00687         {return queue::remove(object);};
00688 
00697     inline bool post(T *object, timeout_t timeout = 0)
00698         {return queue::post(object);};
00699 
00707     inline T *fifo(timeout_t timeout = 0)
00708         {return static_cast<T *>(queue::fifo(timeout));};
00709 
00717     inline T *lifo(timeout_t timeout = 0)
00718         {return static_cast<T *>(queue::lifo(timeout));};
00719 
00726     inline T *peek(unsigned offset = 0)
00727         {return static_cast<T *>(queue::peek(offset));};
00728 
00735     inline T *operator[](unsigned offset)
00736         {return static_cast<T *>(queue::peek(offset));};
00737 
00738 };
00739 
00743 typedef stack stack_t;
00744 
00748 typedef queue fifo_t;
00749 
00755 inline void push(stack_t &stack, ObjectProtocol *object)
00756     {stack.push(object);}
00757 
00764 inline ObjectProtocol *pull(stack_t &stack, timeout_t timeout = Timer::inf)
00765     {return stack.pull(timeout);}
00766 
00772 inline void remove(stack_t &stack, ObjectProtocol *object)
00773     {stack.remove(object);}
00774 
00780 inline void push(fifo_t &fifo, ObjectProtocol *object)
00781     {fifo.post(object);}
00782 
00789 inline ObjectProtocol *pull(fifo_t &fifo, timeout_t timeout = Timer::inf)
00790     {return fifo.fifo(timeout);}
00791 
00797 inline void remove(fifo_t &fifo, ObjectProtocol *object)
00798     {fifo.remove(object);}
00799 
00800 END_NAMESPACE
00801 
00802 #endif