UCommon
|
00001 // Copyright (C) 2006-2014 David Sugar, Tycho Softworks. 00002 // Copyright (C) 2015 Cherokees of Idaho. 00003 // 00004 // This file is part of GNU uCommon C++. 00005 // 00006 // GNU uCommon C++ is free software: you can redistribute it and/or modify 00007 // it under the terms of the GNU Lesser General Public License as published 00008 // by the Free Software Foundation, either version 3 of the License, or 00009 // (at your option) any later version. 00010 // 00011 // GNU uCommon C++ is distributed in the hope that it will be useful, 00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 // GNU Lesser General Public License for more details. 00015 // 00016 // You should have received a copy of the GNU Lesser General Public License 00017 // along with GNU uCommon C++. If not, see <http://www.gnu.org/licenses/>. 00018 00030 #ifndef _UCOMMON_CONTAINERS_H_ 00031 #define _UCOMMON_CONTAINERS_H_ 00032 00033 #ifndef _UCOMMON_CONFIG_H_ 00034 #include <ucommon/platform.h> 00035 #endif 00036 00037 #ifndef _UCOMMON_PROTOCOLS_H_ 00038 #include <ucommon/protocols.h> 00039 #endif 00040 00041 #ifndef _UCOMMON_LINKED_H_ 00042 #include <ucommon/linked.h> 00043 #endif 00044 00045 #ifndef _UCOMMON_MEMORY_H_ 00046 #include <ucommon/memory.h> 00047 #endif 00048 00049 #ifndef _UCOMMON_THREAD_H_ 00050 #include <ucommon/thread.h> 00051 #endif 00052 00053 namespace ucommon { 00054 00061 class __EXPORT LinkedAllocator : private Conditional 00062 { 00063 protected: 00064 LinkedObject *freelist; 00065 00066 LinkedAllocator(); 00067 00068 LinkedObject *get(void); 00069 00070 LinkedObject *get(timeout_t timeout); 00071 00072 void release(LinkedObject *node); 00073 00074 public: 00079 operator bool() const; 00080 00085 bool operator!() const; 00086 }; 00087 00097 class __EXPORT Buffer : protected Conditional 00098 { 00099 private: 00100 size_t bufsize, objsize; 00101 caddr_t buf, head, tail; 00102 unsigned objcount, limit; 00103 00104 protected: 00110 Buffer(size_t typesize, size_t count); 00111 00115 virtual ~Buffer(); 00116 00122 void *get(timeout_t timeout); 00123 00129 void *get(void); 00130 00136 void put(void *data); 00137 00144 bool put(void *data, timeout_t timeout); 00145 00152 void release(void); 00153 00159 void copy(void *data); 00160 00167 bool copy(void *data, timeout_t timeout); 00168 00176 void *peek(unsigned item); 00177 00178 virtual void *invalid(void) const; 00179 00180 public: 00185 unsigned size(void) const; 00186 00191 unsigned count(void) const; 00192 00197 operator bool() const; 00198 00203 bool operator!() const; 00204 }; 00205 00216 class __EXPORT Queue : protected OrderedIndex, protected Conditional 00217 { 00218 private: 00219 mempager *pager; 00220 LinkedObject *freelist; 00221 size_t used; 00222 00223 class __LOCAL member : public OrderedObject 00224 { 00225 public: 00226 member(Queue *q, ObjectProtocol *obj); 00227 ObjectProtocol *object; 00228 }; 00229 00230 friend class member; 00231 00232 protected: 00233 size_t limit; 00234 00235 virtual ObjectProtocol *invalid(void) const; 00236 00237 public: 00245 Queue(mempager *pager = NULL, size_t number = 0); 00246 00250 ~Queue(); 00251 00259 bool remove(ObjectProtocol *object); 00260 00269 bool post(ObjectProtocol *object, timeout_t timeout = 0); 00270 00276 ObjectProtocol *get(unsigned offset = 0); 00277 00285 ObjectProtocol *fifo(timeout_t timeout = 0); 00286 00294 ObjectProtocol *lifo(timeout_t timeout = 0); 00295 00300 size_t count(void) const; 00301 }; 00302 00311 class __EXPORT Stack : protected Conditional 00312 { 00313 private: 00314 LinkedObject *freelist, *usedlist; 00315 mempager *pager; 00316 size_t used; 00317 00318 class __LOCAL member : public LinkedObject 00319 { 00320 public: 00321 member(Stack *s, ObjectProtocol *obj); 00322 ObjectProtocol *object; 00323 }; 00324 00325 friend class member; 00326 00327 protected: 00328 size_t limit; 00329 00330 virtual ObjectProtocol *invalid(void) const; 00331 00332 public: 00339 Stack(mempager *pager = NULL, size_t number = 0); 00340 00344 virtual ~Stack(); 00345 00353 bool remove(ObjectProtocol *object); 00354 00363 bool push(ObjectProtocol *object, timeout_t timeout = 0); 00364 00372 ObjectProtocol *pull(timeout_t timeout = 0); 00373 00379 ObjectProtocol *get(unsigned offset = 0); 00380 00385 size_t count(void) const; 00386 00387 const ObjectProtocol *peek(timeout_t timeout = 0); 00388 }; 00389 00397 template <class T> 00398 class linked_allocator : public LinkedAllocator 00399 { 00400 private: 00401 T* array; 00402 00403 public: 00404 inline linked_allocator(size_t size) : LinkedAllocator() { 00405 array = new T[size]; 00406 for(unsigned i = 0; i < size; ++i) 00407 array[i].enlist(&freelist); 00408 } 00409 00410 ~linked_allocator() 00411 {delete[] array;} 00412 00413 inline T *get(void) 00414 {return static_cast<T *>(LinkedAllocator::get());} 00415 00416 inline T *get(timeout_t timeout) 00417 {return static_cast<T *>(LinkedAllocator::get(timeout));} 00418 00419 inline void release(T *node) 00420 {LinkedAllocator::release(node);} 00421 }; 00422 00434 template<class T> 00435 class bufferof : public Buffer 00436 { 00437 public: 00442 inline bufferof(unsigned capacity) : 00443 Buffer(sizeof(T), capacity) {} 00444 00450 inline T *get(void) 00451 {return static_cast<T*>(get());} 00452 00458 inline T *get(timeout_t timeout) 00459 {return static_cast<T*>(get(timeout));} 00460 00466 inline void put(T *object) 00467 {put(object);} 00468 00475 inline bool put(T *object, timeout_t timeout) 00476 {return put(object, timeout);} 00477 00483 inline void copy(T *object) 00484 {copy(object);} 00485 00492 inline bool get(T *object, timeout_t timeout) 00493 {return copy(object, timeout);} 00494 00501 inline const T& at(unsigned item) 00502 {return static_cast<const T&>(Buffer::peek(item));} 00503 00510 inline T&operator[](unsigned item) 00511 {return static_cast<T&>(Buffer::peek(item));} 00512 00513 inline T* operator()(unsigned offset = 0) 00514 {return static_cast<T*>(Buffer::peek(offset));} 00515 }; 00516 00524 template<class T> 00525 class stackof : public Stack 00526 { 00527 public: 00533 inline stackof(mempager *memory, size_t size = 0) : Stack(memory, size) {} 00534 00542 inline bool remove(T *object) 00543 {return Stack::remove(object);} 00544 00553 inline bool push(T *object, timeout_t timeout = 0) 00554 {return Stack::push(object);} 00555 00563 inline T *pull(timeout_t timeout = 0) 00564 {return static_cast<T *>(Stack::pull(timeout));} 00565 00572 inline const T *peek(timeout_t timeout = 0) 00573 {return static_cast<const T *>(Stack::peek(timeout));} 00574 00575 inline T* operator()(unsigned offset = 0) 00576 {return static_cast<T*>(Stack::get(offset));} 00577 00584 inline const T& at(unsigned offset = 0) 00585 {return static_cast<const T&>(Stack::get(offset));} 00586 00593 inline const T& operator[](unsigned offset) 00594 {return static_cast<T&>(Stack::get(offset));} 00595 00596 }; 00597 00605 template<class T> 00606 class queueof : public Queue 00607 { 00608 public: 00614 inline queueof(mempager *memory, size_t size = 0) : Queue(memory, size) {} 00615 00623 inline bool remove(T *object) 00624 {return Queue::remove(object);} 00625 00634 inline bool post(T *object, timeout_t timeout = 0) 00635 {return Queue::post(object);} 00636 00644 inline T *fifo(timeout_t timeout = 0) 00645 {return static_cast<T *>(Queue::fifo(timeout));} 00646 00654 inline T *lifo(timeout_t timeout = 0) 00655 {return static_cast<T *>(Queue::lifo(timeout));} 00656 00663 inline const T& at(unsigned offset = 0) 00664 {return static_cast<const T&>(Queue::get(offset));} 00665 00672 inline T& operator[](unsigned offset) 00673 {return static_cast<T&>(Queue::get(offset));} 00674 00675 inline T* operator()(unsigned offset = 0) 00676 {return static_cast<T*>(Queue::get(offset));} 00677 }; 00678 00682 typedef Stack stack_t; 00683 00687 typedef Queue fifo_t; 00688 00689 } // namespace ucommon 00690 00691 #endif