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 00027 #ifndef _UCOMMON_VECTOR_H_ 00028 #define _UCOMMON_VECTOR_H_ 00029 00030 #ifndef _UCOMMON_THREAD_H_ 00031 #include <ucommon/thread.h> 00032 #endif 00033 00034 namespace ucommon { 00035 00036 typedef unsigned short vectorsize_t; 00037 00045 class __EXPORT ArrayReuse : public ReusableAllocator 00046 { 00047 private: 00048 size_t objsize; 00049 unsigned count, limit, used; 00050 caddr_t mem; 00051 00052 protected: 00053 ArrayReuse(size_t objsize, unsigned c); 00054 ArrayReuse(size_t objsize, unsigned c, void *memory); 00055 00056 public: 00060 ~ArrayReuse(); 00061 00062 protected: 00063 bool avail(void); 00064 00065 ReusableObject *get(timeout_t timeout); 00066 ReusableObject *get(void); 00067 ReusableObject *request(void); 00068 }; 00069 00077 class __EXPORT PagerReuse : protected MemoryRedirect, protected ReusableAllocator 00078 { 00079 private: 00080 unsigned limit, count; 00081 size_t osize; 00082 00083 protected: 00084 PagerReuse(mempager *pager, size_t objsize, unsigned count); 00085 ~PagerReuse(); 00086 00087 bool avail(void); 00088 ReusableObject *get(void); 00089 ReusableObject *get(timeout_t timeout); 00090 ReusableObject *request(void); 00091 }; 00092 00108 class __EXPORT Vector 00109 { 00110 public: 00111 class __EXPORT array : public CountedObject 00112 { 00113 public: 00114 #pragma pack(1) 00115 vectorsize_t max, len; 00116 ObjectProtocol *list[1]; 00117 #pragma pack() 00118 00119 array(vectorsize_t size); 00120 void dealloc(void); 00121 void set(ObjectProtocol **items); 00122 void add(ObjectProtocol **list); 00123 void add(ObjectProtocol *obj); 00124 void purge(void); 00125 void inc(vectorsize_t adj); 00126 void dec(vectorsize_t adj); 00127 }; 00128 00129 protected: 00130 array *data; 00131 00132 array *create(vectorsize_t size) const; 00133 00134 virtual void release(void); 00135 virtual void cow(vectorsize_t adj = 0); 00136 ObjectProtocol **list(void) const; 00137 00138 friend class Vector::array; 00139 00140 protected: 00145 virtual ObjectProtocol *invalid(void) const; 00146 00147 public: 00151 static const vectorsize_t npos; 00152 00156 Vector(); 00157 00162 Vector(vectorsize_t size); 00163 00173 Vector(ObjectProtocol **items, vectorsize_t size = 0); 00174 00178 virtual ~Vector(); 00179 00184 vectorsize_t len(void) const; 00185 00191 vectorsize_t size(void) const; 00192 00198 ObjectProtocol *get(int index) const; 00199 00206 vectorsize_t get(void **mem, vectorsize_t max) const; 00207 00213 ObjectProtocol *begin(void) const; 00214 00220 ObjectProtocol *end(void) const; 00221 00228 vectorsize_t find(ObjectProtocol *pointer, vectorsize_t offset = 0) const; 00229 00235 void split(vectorsize_t position); 00236 00243 void rsplit(vectorsize_t position); 00244 00251 void set(vectorsize_t position, ObjectProtocol *pointer); 00252 00257 void set(ObjectProtocol **list); 00258 00263 void add(ObjectProtocol **list); 00264 00269 void add(ObjectProtocol *pointer); 00270 00274 void clear(void); 00275 00280 virtual bool resize(vectorsize_t size); 00281 00286 inline void set(Vector &vector) 00287 {set(vector.list());} 00288 00293 inline void add(Vector &vector) 00294 {add(vector.list());} 00295 00300 inline ObjectProtocol *operator[](int index) 00301 {return get(index);} 00302 00308 inline void operator()(vectorsize_t position, ObjectProtocol *pointer) 00309 {set(position, pointer);} 00310 00316 inline ObjectProtocol *operator()(vectorsize_t position) 00317 {return get(position);} 00318 00323 inline void operator()(ObjectProtocol *pointer) 00324 {add(pointer);} 00325 00330 inline void operator=(Vector &vector) 00331 {set(vector.list());} 00332 00337 inline void operator+=(Vector &vector) 00338 {add(vector.list());} 00339 00344 inline Vector& operator+(Vector &vector) 00345 {add(vector.list()); return *this;} 00346 00351 Vector &operator^(Vector &vector); 00352 00359 void operator^=(Vector &vector); 00360 00364 void operator++(); 00365 00369 void operator--(); 00370 00375 void operator+=(vectorsize_t count); 00376 00381 void operator-=(vectorsize_t count); 00382 00388 static vectorsize_t size(void **list); 00389 }; 00390 00396 class __EXPORT MemVector : public Vector 00397 { 00398 private: 00399 bool resize(vectorsize_t size); 00400 void cow(vectorsize_t adj = 0); 00401 void release(void); 00402 00403 friend class Vector::array; 00404 00405 public: 00411 MemVector(void *pointer, vectorsize_t size); 00412 00416 ~MemVector(); 00417 00422 inline void operator=(Vector &vector) 00423 {set(vector);} 00424 00425 }; 00426 00432 template<class T> 00433 class vectorof : public Vector 00434 { 00435 public: 00439 inline vectorof() : Vector() {} 00440 00445 inline vectorof(vectorsize_t size) : Vector(size) {} 00446 00447 inline T& operator[](int index) 00448 {return static_cast<T&>(Vector::get(index));} 00449 00450 inline const T& at(int index) 00451 {return static_cast<const T&>(Vector::get(index));} 00452 00458 inline T *operator()(vectorsize_t position) 00459 {return static_cast<T *>(Vector::get(position));} 00460 00465 inline T *begin(void) 00466 {return static_cast<T *>(Vector::begin());} 00467 00472 inline T *end(void) 00473 {return static_cast<T *>(Vector::end());} 00474 00480 inline Vector &operator+(Vector &vector) 00481 {Vector::add(vector); return static_cast<Vector &>(*this);} 00482 }; 00483 00490 template<class T> 00491 class array_reuse : protected ArrayReuse 00492 { 00493 public: 00498 inline array_reuse(unsigned count) : 00499 ArrayReuse(sizeof(T), count) {} 00500 00506 inline array_reuse(unsigned count, void *memory) : 00507 ArrayReuse(sizeof(T), count, memory) {} 00508 00513 inline operator bool() const 00514 {return avail();} 00515 00520 inline bool operator!() const 00521 {return !avail();} 00522 00527 inline T* request(void) 00528 {return static_cast<T*>(ArrayReuse::request());} 00529 00535 inline T* get(void) 00536 {return static_cast<T*>(ArrayReuse::get());} 00537 00543 inline T* create(void) 00544 {return init<T>(static_cast<T*>(ArrayReuse::get()));} 00545 00552 inline T* get(timeout_t timeout) 00553 {return static_cast<T*>(ArrayReuse::get(timeout));} 00554 00561 inline T* create(timeout_t timeout) 00562 {return init<T>(static_cast<T*>(ArrayReuse::get(timeout)));} 00563 00568 inline void release(T *object) 00569 {ArrayReuse::release(object);} 00570 00576 inline operator T*() 00577 {return array_reuse::get();} 00578 00584 inline T *operator*() 00585 {return array_reuse::get();} 00586 }; 00587 00594 template <class T> 00595 class paged_reuse : protected PagerReuse 00596 { 00597 public: 00605 inline paged_reuse(mempager *pager, unsigned count) : 00606 PagerReuse(pager, sizeof(T), count) {} 00607 00612 inline operator bool() const 00613 {return PagerReuse::avail();} 00614 00619 inline bool operator!() const 00620 {return !PagerReuse::avail();} 00621 00627 inline T *get(void) 00628 {return static_cast<T*>(PagerReuse::get());} 00629 00636 inline T *create(void) 00637 {return init<T>(static_cast<T*>(PagerReuse::get()));} 00638 00645 inline T *get(timeout_t timeout) 00646 {return static_cast<T*>(PagerReuse::get(timeout));} 00647 00655 inline T *create(timeout_t timeout) 00656 {return init<T>(static_cast<T*>(PagerReuse::get(timeout)));} 00657 00662 inline T *request(void) 00663 {return static_cast<T*>(PagerReuse::request());} 00664 00669 inline void release(T *object) 00670 {PagerReuse::release(object);} 00671 00677 inline T *operator*() 00678 {return paged_reuse::get();} 00679 00685 inline operator T*() 00686 {return paged_reuse::get();} 00687 }; 00688 00696 template<typename T, vectorsize_t S> 00697 class vectorbuf : public MemVector 00698 { 00699 private: 00700 char buffer[sizeof(array) + (S * sizeof(void *))]; 00701 00702 public: 00706 inline vectorbuf() : MemVector(buffer, S) {} 00707 00713 inline const T& at(int index) 00714 {return static_cast<const T&>(Vector::get(index));} 00715 00716 inline T& operator[](int index) 00717 {return static_cast<T&>(Vector::get(index));} 00718 00724 inline T *operator()(vectorsize_t position) 00725 {return static_cast<T *>(Vector::get(position));} 00726 00731 inline T *begin(void) 00732 {return static_cast<T *>(Vector::begin());} 00733 00738 inline T *end(void) 00739 {return static_cast<T *>(Vector::end());} 00740 00746 inline Vector &operator+(Vector &vector) 00747 {Vector::add(vector); return static_cast<Vector &>(*this);} 00748 }; 00749 00750 } // namespace ucommon 00751 00752 #endif