ucommon
|
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