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 00028 #ifndef _UCOMMON_VECTOR_H_ 00029 #define _UCOMMON_VECTOR_H_ 00030 00031 #ifndef _UCOMMON_THREAD_H_ 00032 #include <ucommon/thread.h> 00033 #endif 00034 00035 namespace ucommon { 00036 00037 typedef unsigned short vectorsize_t; 00038 00046 class __EXPORT ArrayReuse : public ReusableAllocator 00047 { 00048 private: 00049 size_t objsize; 00050 unsigned count, limit, used; 00051 caddr_t mem; 00052 00053 protected: 00054 ArrayReuse(size_t objsize, unsigned c); 00055 ArrayReuse(size_t objsize, unsigned c, void *memory); 00056 00057 public: 00061 ~ArrayReuse(); 00062 00063 protected: 00064 bool avail(void) const; 00065 00066 ReusableObject *get(timeout_t timeout); 00067 ReusableObject *get(void); 00068 ReusableObject *request(void); 00069 }; 00070 00078 class __EXPORT PagerReuse : protected MemoryRedirect, protected ReusableAllocator 00079 { 00080 private: 00081 unsigned limit, count; 00082 size_t osize; 00083 00084 protected: 00085 PagerReuse(mempager *pager, size_t objsize, unsigned count); 00086 ~PagerReuse(); 00087 00088 bool avail(void) const; 00089 ReusableObject *get(void); 00090 ReusableObject *get(timeout_t timeout); 00091 ReusableObject *request(void); 00092 }; 00093 00109 class __EXPORT Vector 00110 { 00111 public: 00112 class __EXPORT array : public CountedObject 00113 { 00114 public: 00115 #pragma pack(1) 00116 vectorsize_t max, len; 00117 ObjectProtocol *list[1]; 00118 #pragma pack() 00119 00120 array(vectorsize_t size); 00121 void dealloc(void); 00122 void set(ObjectProtocol **items); 00123 void add(ObjectProtocol **list); 00124 void add(ObjectProtocol *obj); 00125 void purge(void); 00126 void inc(vectorsize_t adj); 00127 void dec(vectorsize_t adj); 00128 }; 00129 00130 protected: 00131 array *data; 00132 00133 array *create(vectorsize_t size) const; 00134 00135 virtual void release(void); 00136 virtual void cow(vectorsize_t adj = 0); 00137 ObjectProtocol **list(void) const; 00138 00139 friend class Vector::array; 00140 00141 protected: 00146 virtual ObjectProtocol *invalid(void) const; 00147 00148 public: 00152 static const vectorsize_t npos; 00153 00157 Vector(); 00158 00163 Vector(vectorsize_t size); 00164 00174 Vector(ObjectProtocol **items, vectorsize_t size = 0); 00175 00179 virtual ~Vector(); 00180 00185 vectorsize_t len(void) const; 00186 00192 vectorsize_t size(void) const; 00193 00199 ObjectProtocol *get(int index) const; 00200 00207 vectorsize_t get(void **mem, vectorsize_t max) const; 00208 00214 ObjectProtocol *begin(void) const; 00215 00221 ObjectProtocol *end(void) const; 00222 00229 vectorsize_t find(ObjectProtocol *pointer, vectorsize_t offset = 0) const; 00230 00236 void split(vectorsize_t position); 00237 00244 void rsplit(vectorsize_t position); 00245 00252 void set(vectorsize_t position, ObjectProtocol *pointer); 00253 00258 void set(ObjectProtocol **list); 00259 00264 void add(ObjectProtocol **list); 00265 00270 void add(ObjectProtocol *pointer); 00271 00275 void clear(void); 00276 00281 virtual bool resize(vectorsize_t size); 00282 00287 inline void set(Vector &vector) { 00288 set(vector.list()); 00289 } 00290 00295 inline void add(Vector &vector) { 00296 add(vector.list()); 00297 } 00298 00303 inline ObjectProtocol *operator[](int index) { 00304 return get(index); 00305 } 00306 00312 inline void operator()(vectorsize_t position, ObjectProtocol *pointer) { 00313 set(position, pointer); 00314 } 00315 00321 inline ObjectProtocol *operator()(vectorsize_t position) { 00322 return get(position); 00323 } 00324 00329 inline void operator()(ObjectProtocol *pointer) { 00330 add(pointer); 00331 } 00332 00337 inline void operator=(Vector &vector) { 00338 set(vector.list()); 00339 } 00340 00345 inline void operator+=(Vector &vector) { 00346 add(vector.list()); 00347 } 00348 00353 inline Vector& operator+(Vector &vector) { 00354 add(vector.list()); 00355 return *this; 00356 } 00357 00362 Vector &operator^(Vector &vector); 00363 00370 void operator^=(Vector &vector); 00371 00375 void operator++(); 00376 00380 void operator--(); 00381 00386 void operator+=(vectorsize_t count); 00387 00392 void operator-=(vectorsize_t count); 00393 00399 static vectorsize_t size(void **list); 00400 }; 00401 00407 class __EXPORT MemVector : public Vector 00408 { 00409 private: 00410 bool resize(vectorsize_t size); 00411 void cow(vectorsize_t adj = 0); 00412 void release(void); 00413 00414 friend class Vector::array; 00415 00416 public: 00422 MemVector(void *pointer, vectorsize_t size); 00423 00427 ~MemVector(); 00428 00433 inline void operator=(Vector &vector) { 00434 set(vector); 00435 } 00436 00437 }; 00438 00444 template<class T> 00445 class vectorof : public Vector 00446 { 00447 public: 00451 inline vectorof() : Vector() {} 00452 00457 inline vectorof(vectorsize_t size) : Vector(size) {} 00458 00459 inline T& operator[](int index) { 00460 return static_cast<T&>(Vector::get(index)); 00461 } 00462 00463 inline const T& at(int index) { 00464 return static_cast<const T&>(Vector::get(index)); 00465 } 00466 00472 inline T *operator()(vectorsize_t position) { 00473 return static_cast<T *>(Vector::get(position)); 00474 } 00475 00480 inline T *begin(void) { 00481 return static_cast<T *>(Vector::begin()); 00482 } 00483 00488 inline T *end(void) { 00489 return static_cast<T *>(Vector::end()); 00490 } 00491 00497 inline Vector &operator+(Vector &vector) { 00498 Vector::add(vector); 00499 return static_cast<Vector &>(*this); 00500 } 00501 }; 00502 00509 template<class T> 00510 class array_reuse : protected ArrayReuse 00511 { 00512 public: 00517 inline array_reuse(unsigned count) : 00518 ArrayReuse(sizeof(T), count) {} 00519 00525 inline array_reuse(unsigned count, void *memory) : 00526 ArrayReuse(sizeof(T), count, memory) {} 00527 00532 inline operator bool() const { 00533 return avail(); 00534 } 00535 00540 inline bool operator!() const { 00541 return !avail(); 00542 } 00543 00548 inline T* request(void) { 00549 return static_cast<T*>(ArrayReuse::request()); 00550 } 00551 00557 inline T* get(void) { 00558 return static_cast<T*>(ArrayReuse::get()); 00559 } 00560 00566 inline T* create(void) { 00567 return init<T>(static_cast<T*>(ArrayReuse::get())); 00568 } 00569 00576 inline T* get(timeout_t timeout) { 00577 return static_cast<T*>(ArrayReuse::get(timeout)); 00578 } 00579 00586 inline T* create(timeout_t timeout) { 00587 return init<T>(static_cast<T*>(ArrayReuse::get(timeout))); 00588 } 00589 00594 inline void release(T *object) { 00595 ArrayReuse::release(object); 00596 } 00597 00603 inline operator T*() { 00604 return array_reuse::get(); 00605 } 00606 00612 inline T *operator*() { 00613 return array_reuse::get(); 00614 } 00615 }; 00616 00623 template <class T> 00624 class paged_reuse : protected PagerReuse 00625 { 00626 public: 00634 inline paged_reuse(mempager *pager, unsigned count) : 00635 PagerReuse(pager, sizeof(T), count) {} 00636 00641 inline operator bool() const { 00642 return PagerReuse::avail(); 00643 } 00644 00649 inline bool operator!() const { 00650 return !PagerReuse::avail(); 00651 } 00652 00658 inline T *get(void) { 00659 return static_cast<T*>(PagerReuse::get()); 00660 } 00661 00668 inline T *create(void) { 00669 return init<T>(static_cast<T*>(PagerReuse::get())); 00670 } 00671 00678 inline T *get(timeout_t timeout) { 00679 return static_cast<T*>(PagerReuse::get(timeout)); 00680 } 00681 00689 inline T *create(timeout_t timeout) { 00690 return init<T>(static_cast<T*>(PagerReuse::get(timeout))); 00691 } 00692 00697 inline T *request(void) { 00698 return static_cast<T*>(PagerReuse::request()); 00699 } 00700 00705 inline void release(T *object) { 00706 PagerReuse::release(object); 00707 } 00708 00714 inline T *operator*() { 00715 return paged_reuse::get(); 00716 } 00717 00723 inline operator T*() { 00724 return paged_reuse::get(); 00725 } 00726 }; 00727 00735 template<typename T, vectorsize_t S> 00736 class vectorbuf : public MemVector 00737 { 00738 private: 00739 char buffer[sizeof(array) + (S * sizeof(void *))]; 00740 00741 public: 00745 inline vectorbuf() : MemVector(buffer, S) {} 00746 00752 inline const T& at(int index) { 00753 return static_cast<const T&>(Vector::get(index)); 00754 } 00755 00756 inline T& operator[](int index) { 00757 return static_cast<T&>(Vector::get(index)); 00758 } 00759 00765 inline T *operator()(vectorsize_t position) { 00766 return static_cast<T *>(Vector::get(position)); 00767 } 00768 00773 inline T *begin(void) { 00774 return static_cast<T *>(Vector::begin()); 00775 } 00776 00781 inline T *end(void) { 00782 return static_cast<T *>(Vector::end()); 00783 } 00784 00790 inline Vector &operator+(Vector &vector) { 00791 Vector::add(vector); return static_cast<Vector &>(*this); 00792 } 00793 }; 00794 00795 } // namespace ucommon 00796 00797 #endif