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 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, Object *obj); 00214 Object *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(Object *object); 00245 00254 bool post(Object *object, timeout_t timeout = 0); 00255 00263 Object *fifo(timeout_t timeout = 0); 00264 00272 Object *lifo(timeout_t timeout = 0); 00273 00278 size_t getCount(void); 00279 00286 static bool remove(queue& queue, Object *object) 00287 {return queue.remove(object);}; 00288 00296 static bool post(queue& queue, Object *object, timeout_t timeout = 0) 00297 {return queue.post(object, timeout);}; 00298 00305 static Object *fifo(queue& queue, timeout_t timeout = 0) 00306 {return queue.fifo(timeout);}; 00307 00314 static Object *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, Object *obj); 00345 Object *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(Object *object); 00375 00384 bool push(Object *object, timeout_t timeout = 0); 00385 00393 Object *pull(timeout_t timeout = 0); 00394 00399 size_t getCount(void); 00400 00407 static inline bool remove(stack& stack, Object *object) 00408 {return stack.remove(object);}; 00409 00417 static inline bool push(stack& stack, Object *object, timeout_t timeout = 0) 00418 {return stack.push(object, timeout);}; 00419 00426 static inline Object *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, Object *object) 00670 {stack.push(object);} 00671 00678 inline Object *pull(stack_t &stack, timeout_t timeout = Timer::inf) 00679 {return stack.pull(timeout);} 00680 00686 inline void remove(stack_t &stack, Object *object) 00687 {stack.remove(object);} 00688 00694 inline void push(fifo_t &fifo, Object *object) 00695 {fifo.post(object);} 00696 00703 inline Object *pull(fifo_t &fifo, timeout_t timeout = Timer::inf) 00704 {return fifo.fifo(timeout);} 00705 00711 inline void remove(fifo_t &fifo, Object *object) 00712 {fifo.remove(object);} 00713 00714 END_NAMESPACE 00715 00716 #endif