UCommon
/usr/src/RPM/BUILD/ucommon-6.3.3/inc/ucommon/vector.h
Go to the documentation of this file.
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