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