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 
00184     operator bool();
00185 
00190     bool operator!();
00191 };
00192 
00203 class __EXPORT queue : protected OrderedIndex, protected Conditional
00204 {
00205 private:
00206     mempager *pager;
00207     LinkedObject *freelist;
00208     size_t used;
00209 
00210     class __LOCAL member : public OrderedObject
00211     {
00212     public:
00213         member(queue *q, ObjectProtocol *obj);
00214         ObjectProtocol *object;
00215     };
00216 
00217     friend class member;
00218 
00219 protected:
00220     size_t limit;
00221 
00222 public:
00230     queue(mempager *pager = NULL, size_t number = 0);
00231 
00235     ~queue();
00236 
00244     bool remove(ObjectProtocol *object);
00245 
00254     bool post(ObjectProtocol *object, timeout_t timeout = 0);
00255 
00263     ObjectProtocol *fifo(timeout_t timeout = 0);
00264 
00272     ObjectProtocol *lifo(timeout_t timeout = 0);
00273 
00278     size_t getCount(void);
00279 
00286     static bool remove(queue& queue, ObjectProtocol *object)
00287         {return queue.remove(object);};
00288 
00296     static bool post(queue& queue, ObjectProtocol *object, timeout_t timeout = 0)
00297         {return queue.post(object, timeout);};
00298 
00305     static ObjectProtocol *fifo(queue& queue, timeout_t timeout = 0)
00306         {return queue.fifo(timeout);};
00307 
00314     static ObjectProtocol *lifo(queue& queue, timeout_t timeout = 0)
00315         {return queue.lifo(timeout);};
00316 
00322     static size_t count(queue& queue)
00323         {return queue.getCount();};
00324 };
00325 
00334 class __EXPORT stack : protected Conditional
00335 {
00336 private:
00337     LinkedObject *freelist, *usedlist;
00338     mempager *pager;
00339     size_t used;
00340 
00341     class __LOCAL member : public LinkedObject
00342     {
00343     public:
00344         member(stack *s, ObjectProtocol *obj);
00345         ObjectProtocol *object;
00346     };
00347 
00348     friend class member;
00349 
00350 protected:
00351     size_t limit;
00352 
00353 public:
00360     stack(mempager *pager = NULL, size_t number = 0);
00361 
00365     ~stack();
00366 
00374     bool remove(ObjectProtocol *object);
00375 
00384     bool push(ObjectProtocol *object, timeout_t timeout = 0);
00385 
00393     ObjectProtocol *pull(timeout_t timeout = 0);
00394 
00399     size_t getCount(void);
00400 
00407     static inline bool remove(stack& stack, ObjectProtocol *object)
00408         {return stack.remove(object);};
00409 
00417     static inline bool push(stack& stack, ObjectProtocol *object, timeout_t timeout = 0)
00418         {return stack.push(object, timeout);};
00419 
00426     static inline ObjectProtocol *pull(stack& stack, timeout_t timeout = 0)
00427         {return stack.pull(timeout);};
00428 
00434     static inline size_t count(stack& stack)
00435         {return stack.getCount();};
00436 };
00437 
00445 template <class T>
00446 class linked_allocator : public LinkedAllocator
00447 {
00448 private:
00449     T* array;
00450 
00451 public:
00452     inline linked_allocator(size_t size) : LinkedAllocator() {
00453         array = new T[size];
00454         for(unsigned i = 0; i < size; ++i)
00455             array[i].enlist(&freelist);
00456     }
00457 
00458     ~linked_allocator()
00459         {delete[] array;};
00460 
00461     inline T *get(void)
00462         {return static_cast<T *>(LinkedAllocator::get());};
00463 
00464     inline T *get(timeout_t timeout)
00465         {return static_cast<T *>(LinkedAllocator::get(timeout));};
00466 
00467     inline void release(T *node)
00468         {LinkedAllocator::release(node);};
00469 };
00470 
00482 template<class T>
00483 class bufferof : public Buffer
00484 {
00485 public:
00490     inline bufferof(unsigned count) :
00491         Buffer(sizeof(T), count) {};
00492 
00498     inline T *get(void)
00499         {return static_cast<T*>(get());};
00500 
00506     inline T *get(timeout_t timeout)
00507         {return static_cast<T*>(get(timeout));};
00508 
00514     inline void put(T *object)
00515         {put(object);};
00516 
00523     inline bool put(T *object, timeout_t timeout)
00524         {return put(object, timeout);};
00525 
00531     inline void copy(T *object)
00532         {copy(object);};
00533 
00540     inline bool get(T *object, timeout_t timeout)
00541         {return copy(object, timeout);};
00542 };
00543 
00551 template<class T>
00552 class stackof : public stack
00553 {
00554 public:
00560     inline stackof(mempager *memory, size_t size = 0) : stack(memory, size) {};
00561 
00569     inline bool remove(T *object)
00570         {return stack::remove(object);};
00571 
00580     inline bool push(T *object, timeout_t timeout = 0)
00581         {return stack::push(object);};
00582 
00590     inline T *pull(timeout_t timeout = 0)
00591         {return static_cast<T *>(stack::pull(timeout));};
00592 };
00593 
00601 template<class T>
00602 class queueof : public queue
00603 {
00604 public:
00610     inline queueof(mempager *memory, size_t size = 0) : queue(memory, size) {};
00611 
00619     inline bool remove(T *object)
00620         {return queue::remove(object);};
00621 
00630     inline bool post(T *object, timeout_t timeout = 0)
00631         {return queue::post(object);};
00632 
00640     inline T *fifo(timeout_t timeout = 0)
00641         {return static_cast<T *>(queue::fifo(timeout));};
00642 
00650     inline T *lifo(timeout_t timeout = 0)
00651         {return static_cast<T *>(queue::lifo(timeout));};
00652 };
00653 
00657 typedef stack stack_t;
00658 
00662 typedef queue fifo_t;
00663 
00669 inline void push(stack_t &stack, ObjectProtocol *object)
00670     {stack.push(object);}
00671 
00678 inline ObjectProtocol *pull(stack_t &stack, timeout_t timeout = Timer::inf)
00679     {return stack.pull(timeout);}
00680 
00686 inline void remove(stack_t &stack, ObjectProtocol *object)
00687     {stack.remove(object);}
00688 
00694 inline void push(fifo_t &fifo, ObjectProtocol *object)
00695     {fifo.post(object);}
00696 
00703 inline ObjectProtocol *pull(fifo_t &fifo, timeout_t timeout = Timer::inf)
00704     {return fifo.fifo(timeout);}
00705 
00711 inline void remove(fifo_t &fifo, ObjectProtocol *object)
00712     {fifo.remove(object);}
00713 
00714 END_NAMESPACE
00715 
00716 #endif