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 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 typedef unsigned short vectorsize_t; 00035 00036 NAMESPACE_UCOMMON 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 00055 public: 00059 ~ArrayReuse(); 00060 00061 protected: 00062 bool avail(void); 00063 00064 ReusableObject *get(timeout_t timeout); 00065 ReusableObject *get(void); 00066 ReusableObject *request(void); 00067 }; 00068 00076 class __EXPORT PagerReuse : protected MemoryRedirect, protected ReusableAllocator 00077 { 00078 private: 00079 unsigned limit, count; 00080 size_t osize; 00081 00082 protected: 00083 PagerReuse(mempager *pager, size_t objsize, unsigned count); 00084 ~PagerReuse(); 00085 00086 bool avail(void); 00087 ReusableObject *get(void); 00088 ReusableObject *get(timeout_t timeout); 00089 ReusableObject *request(void); 00090 }; 00091 00107 class __EXPORT Vector 00108 { 00109 public: 00110 class __EXPORT array : public CountedObject 00111 { 00112 public: 00113 #pragma pack(1) 00114 vectorsize_t max, len; 00115 ObjectProtocol *list[1]; 00116 #pragma pack() 00117 00118 array(vectorsize_t size); 00119 void dealloc(void); 00120 void set(ObjectProtocol **items); 00121 void add(ObjectProtocol **list); 00122 void add(ObjectProtocol *obj); 00123 void purge(void); 00124 void inc(vectorsize_t adj); 00125 void dec(vectorsize_t adj); 00126 }; 00127 00128 protected: 00129 array *data; 00130 00131 array *create(vectorsize_t size) const; 00132 00133 virtual void release(void); 00134 virtual void cow(vectorsize_t adj = 0); 00135 ObjectProtocol **list(void) const; 00136 00137 friend class Vector::array; 00138 00139 public: 00143 static const vectorsize_t npos; 00144 00148 Vector(); 00149 00154 Vector(vectorsize_t size); 00155 00165 Vector(ObjectProtocol **items, vectorsize_t size = 0); 00166 00170 virtual ~Vector(); 00171 00176 vectorsize_t len(void) const; 00177 00183 vectorsize_t size(void) const; 00184 00190 ObjectProtocol *get(int index) const; 00191 00198 vectorsize_t get(void **mem, vectorsize_t max) const; 00199 00205 ObjectProtocol *begin(void) const; 00206 00212 ObjectProtocol *end(void) const; 00213 00220 vectorsize_t find(ObjectProtocol *pointer, vectorsize_t offset = 0) const; 00221 00227 void split(vectorsize_t position); 00228 00235 void rsplit(vectorsize_t position); 00236 00243 void set(vectorsize_t position, ObjectProtocol *pointer); 00244 00249 void set(ObjectProtocol **list); 00250 00255 void add(ObjectProtocol **list); 00256 00261 void add(ObjectProtocol *pointer); 00262 00266 void clear(void); 00267 00272 virtual bool resize(vectorsize_t size); 00273 00278 inline void set(Vector &vector) 00279 {set(vector.list());}; 00280 00285 inline void add(Vector &vector) 00286 {add(vector.list());}; 00287 00292 inline ObjectProtocol *operator[](int index) 00293 {return get(index);}; 00294 00300 inline void operator()(vectorsize_t position, ObjectProtocol *pointer) 00301 {set(position, pointer);}; 00302 00308 inline ObjectProtocol *operator()(vectorsize_t position) 00309 {return get(position);}; 00310 00315 inline void operator()(ObjectProtocol *pointer) 00316 {add(pointer);}; 00317 00322 inline void operator=(Vector &vector) 00323 {set(vector.list());}; 00324 00329 inline void operator+=(Vector &vector) 00330 {add(vector.list());}; 00331 00336 inline Vector& operator+(Vector &vector) 00337 {add(vector.list()); return *this;}; 00338 00343 Vector &operator^(Vector &vector); 00344 00351 void operator^=(Vector &vector); 00352 00356 void operator++(); 00357 00361 void operator--(); 00362 00367 void operator+=(vectorsize_t count); 00368 00373 void operator-=(vectorsize_t count); 00374 00380 static vectorsize_t size(void **list); 00381 }; 00382 00388 class __EXPORT MemVector : public Vector 00389 { 00390 private: 00391 bool resize(vectorsize_t size); 00392 void cow(vectorsize_t adj = 0); 00393 void release(void); 00394 00395 friend class Vector::array; 00396 00397 public: 00403 MemVector(void *pointer, vectorsize_t size); 00404 00408 ~MemVector(); 00409 00414 inline void operator=(Vector &vector) 00415 {set(vector);}; 00416 00417 }; 00418 00424 template<class T> 00425 class vectorof : public Vector 00426 { 00427 public: 00431 inline vectorof() : Vector() {}; 00432 00437 inline vectorof(vectorsize_t size) : Vector(size) {}; 00438 00444 inline T *get(int index) 00445 {return static_cast<T *>(Vector::get(index));}; 00446 00447 inline T& operator[](int index) 00448 {return static_cast<T *>(Vector::get(index));}; 00449 00455 inline T *operator()(vectorsize_t position) 00456 {return static_cast<T *>(Vector::get(position));}; 00457 00462 inline T *begin(void) 00463 {return static_cast<T *>(Vector::begin());}; 00464 00469 inline T *end(void) 00470 {return static_cast<T *>(Vector::end());}; 00471 00477 inline Vector &operator+(Vector &vector) 00478 {Vector::add(vector); return static_cast<Vector &>(*this);}; 00479 }; 00480 00487 template<class T> 00488 class array_reuse : protected ArrayReuse 00489 { 00490 public: 00495 inline array_reuse(unsigned count) : 00496 ArrayReuse(sizeof(T), count) {}; 00497 00502 inline operator bool() const 00503 {return avail();}; 00504 00509 inline bool operator!() const 00510 {return !avail();}; 00511 00516 inline T* request(void) 00517 {return static_cast<T*>(ArrayReuse::request());}; 00518 00524 inline T* get(void) 00525 {return static_cast<T*>(ArrayReuse::get());}; 00526 00532 inline T* create(void) 00533 {return init<T>(static_cast<T*>(ArrayReuse::get()));}; 00534 00541 inline T* get(timeout_t timeout) 00542 {return static_cast<T*>(ArrayReuse::get(timeout));}; 00543 00550 inline T* create(timeout_t timeout) 00551 {return init<T>(static_cast<T*>(ArrayReuse::get(timeout)));}; 00552 00557 inline void release(T *object) 00558 {ArrayReuse::release(object);}; 00559 00565 inline operator T*() 00566 {return array_reuse::get();}; 00567 00573 inline T *operator*() 00574 {return array_reuse::get();}; 00575 }; 00576 00583 template <class T> 00584 class paged_reuse : protected PagerReuse 00585 { 00586 public: 00594 inline paged_reuse(mempager *pager, unsigned count) : 00595 PagerReuse(pager, sizeof(T), count) {}; 00596 00601 inline operator bool() const 00602 {return PagerReuse::avail();}; 00603 00608 inline bool operator!() const 00609 {return !PagerReuse::avail();}; 00610 00616 inline T *get(void) 00617 {return static_cast<T*>(PagerReuse::get());}; 00618 00625 inline T *create(void) 00626 {return init<T>(static_cast<T*>(PagerReuse::get()));}; 00627 00634 inline T *get(timeout_t timeout) 00635 {return static_cast<T*>(PagerReuse::get(timeout));}; 00636 00644 inline T *create(timeout_t timeout) 00645 {return init<T>(static_cast<T*>(PagerReuse::get(timeout)));}; 00646 00651 inline T *request(void) 00652 {return static_cast<T*>(PagerReuse::request());}; 00653 00658 inline void release(T *object) 00659 {PagerReuse::release(object);}; 00660 00666 inline T *operator*() 00667 {return paged_reuse::get();}; 00668 00674 inline operator T*() 00675 {return paged_reuse::get();}; 00676 }; 00677 00685 template<typename T, vectorsize_t S> 00686 class vectorbuf : public MemVector 00687 { 00688 private: 00689 char buffer[sizeof(array) + (S * sizeof(void *))]; 00690 00691 public: 00695 inline vectorbuf() : MemVector(buffer, S) {}; 00696 00702 inline T *get(int index) 00703 {return static_cast<T *>(Vector::get(index));}; 00704 00705 inline T& operator[](int index) 00706 {return static_cast<T*>(Vector::get(index));}; 00707 00713 inline T *operator()(vectorsize_t position) 00714 {return static_cast<T *>(Vector::get(position));}; 00715 00720 inline T *begin(void) 00721 {return static_cast<T *>(Vector::begin());}; 00722 00727 inline T *end(void) 00728 {return static_cast<T *>(Vector::end());}; 00729 00735 inline Vector &operator+(Vector &vector) 00736 {Vector::add(vector); return static_cast<Vector &>(*this);}; 00737 }; 00738 00739 END_NAMESPACE 00740 00741 #endif