ucommon
ucommon/vector.h
Go to the documentation of this file.
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