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