ucommon
ucommon/containers.h
Go to the documentation of this file.
00001 // Copyright (C) 2006-2014 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 bufsize, objsize;
00100     caddr_t buf, head, tail;
00101     unsigned objcount, limit;
00102 
00103 protected:
00109     Buffer(size_t typesize, size_t count);
00110 
00114     virtual ~Buffer();
00115 
00121     void *get(timeout_t timeout);
00122 
00128     void *get(void);
00129 
00135     void put(void *data);
00136 
00143     bool put(void *data, timeout_t timeout);
00144 
00151     void release(void);
00152 
00158     void copy(void *data);
00159 
00166     bool copy(void *data, timeout_t timeout);
00167 
00175     void *peek(unsigned item);
00176 
00177     virtual void *invalid(void) const;
00178 
00179 public:
00184     unsigned size(void);
00185 
00190     unsigned count(void);
00191 
00196     operator bool();
00197 
00202     bool operator!();
00203 };
00204 
00215 class __EXPORT Queue : protected OrderedIndex, protected Conditional
00216 {
00217 private:
00218     mempager *pager;
00219     LinkedObject *freelist;
00220     size_t used;
00221 
00222     class __LOCAL member : public OrderedObject
00223     {
00224     public:
00225         member(Queue *q, ObjectProtocol *obj);
00226         ObjectProtocol *object;
00227     };
00228 
00229     friend class member;
00230 
00231 protected:
00232     size_t limit;
00233 
00234     virtual ObjectProtocol *invalid(void) const;
00235 
00236 public:
00244     Queue(mempager *pager = NULL, size_t number = 0);
00245 
00249     ~Queue();
00250 
00258     bool remove(ObjectProtocol *object);
00259 
00268     bool post(ObjectProtocol *object, timeout_t timeout = 0);
00269 
00275     ObjectProtocol *get(unsigned offset = 0);
00276 
00284     ObjectProtocol *fifo(timeout_t timeout = 0);
00285 
00293     ObjectProtocol *lifo(timeout_t timeout = 0);
00294 
00299     size_t count(void);
00300 };
00301 
00310 class __EXPORT Stack : protected Conditional
00311 {
00312 private:
00313     LinkedObject *freelist, *usedlist;
00314     mempager *pager;
00315     size_t used;
00316 
00317     class __LOCAL member : public LinkedObject
00318     {
00319     public:
00320         member(Stack *s, ObjectProtocol *obj);
00321         ObjectProtocol *object;
00322     };
00323 
00324     friend class member;
00325 
00326 protected:
00327     size_t limit;
00328 
00329     virtual ObjectProtocol *invalid(void) const;
00330 
00331 public:
00338     Stack(mempager *pager = NULL, size_t number = 0);
00339 
00343     virtual ~Stack();
00344 
00352     bool remove(ObjectProtocol *object);
00353 
00362     bool push(ObjectProtocol *object, timeout_t timeout = 0);
00363 
00371     ObjectProtocol *pull(timeout_t timeout = 0);
00372 
00378     ObjectProtocol *get(unsigned offset = 0);
00379 
00384     size_t count(void);
00385 
00386     const ObjectProtocol *peek(timeout_t timeout = 0);
00387 };
00388 
00396 template <class T>
00397 class linked_allocator : public LinkedAllocator
00398 {
00399 private:
00400     T* array;
00401 
00402 public:
00403     inline linked_allocator(size_t size) : LinkedAllocator() {
00404         array = new T[size];
00405         for(unsigned i = 0; i < size; ++i)
00406             array[i].enlist(&freelist);
00407     }
00408 
00409     ~linked_allocator()
00410         {delete[] array;}
00411 
00412     inline T *get(void)
00413         {return static_cast<T *>(LinkedAllocator::get());}
00414 
00415     inline T *get(timeout_t timeout)
00416         {return static_cast<T *>(LinkedAllocator::get(timeout));}
00417 
00418     inline void release(T *node)
00419         {LinkedAllocator::release(node);}
00420 };
00421 
00433 template<class T>
00434 class bufferof : public Buffer
00435 {
00436 public:
00441     inline bufferof(unsigned capacity) :
00442         Buffer(sizeof(T), capacity) {}
00443 
00449     inline T *get(void)
00450         {return static_cast<T*>(get());}
00451 
00457     inline T *get(timeout_t timeout)
00458         {return static_cast<T*>(get(timeout));}
00459 
00465     inline void put(T *object)
00466         {put(object);}
00467 
00474     inline bool put(T *object, timeout_t timeout)
00475         {return put(object, timeout);}
00476 
00482     inline void copy(T *object)
00483         {copy(object);}
00484 
00491     inline bool get(T *object, timeout_t timeout)
00492         {return copy(object, timeout);}
00493 
00500     inline const T& at(unsigned item)
00501         {return static_cast<const T&>(Buffer::peek(item));}
00502 
00509     inline T&operator[](unsigned item)
00510         {return static_cast<T&>(Buffer::peek(item));}
00511 
00512     inline T* operator()(unsigned offset = 0)
00513         {return static_cast<T*>(Buffer::peek(offset));}
00514 };
00515 
00523 template<class T>
00524 class stackof : public Stack
00525 {
00526 public:
00532     inline stackof(mempager *memory, size_t size = 0) : Stack(memory, size) {}
00533 
00541     inline bool remove(T *object)
00542         {return Stack::remove(object);}
00543 
00552     inline bool push(T *object, timeout_t timeout = 0)
00553         {return Stack::push(object);}
00554 
00562     inline T *pull(timeout_t timeout = 0)
00563         {return static_cast<T *>(Stack::pull(timeout));}
00564 
00571     inline const T *peek(timeout_t timeout = 0)
00572         {return static_cast<const T *>(Stack::peek(timeout));}
00573 
00574     inline T* operator()(unsigned offset = 0)
00575         {return static_cast<T*>(Stack::get(offset));}
00576 
00583     inline const T& at(unsigned offset = 0)
00584         {return static_cast<const T&>(Stack::get(offset));}
00585 
00592     inline const T& operator[](unsigned offset)
00593         {return static_cast<T&>(Stack::get(offset));}
00594 
00595 };
00596 
00604 template<class T>
00605 class queueof : public Queue
00606 {
00607 public:
00613     inline queueof(mempager *memory, size_t size = 0) : Queue(memory, size) {}
00614 
00622     inline bool remove(T *object)
00623         {return Queue::remove(object);}
00624 
00633     inline bool post(T *object, timeout_t timeout = 0)
00634         {return Queue::post(object);}
00635 
00643     inline T *fifo(timeout_t timeout = 0)
00644         {return static_cast<T *>(Queue::fifo(timeout));}
00645 
00653     inline T *lifo(timeout_t timeout = 0)
00654         {return static_cast<T *>(Queue::lifo(timeout));}
00655 
00662     inline const T& at(unsigned offset = 0)
00663         {return static_cast<const T&>(Queue::get(offset));}
00664 
00671     inline T& operator[](unsigned offset)
00672         {return static_cast<T&>(Queue::get(offset));}
00673 
00674     inline T* operator()(unsigned offset = 0)
00675         {return static_cast<T*>(Queue::get(offset));}
00676 };
00677 
00681 typedef Stack stack_t;
00682 
00686 typedef Queue fifo_t;
00687 
00688 } // namespace ucommon
00689 
00690 #endif