00001 #ifndef ARRAYPOOL_HPP_INCLUDED
00002 #define ARRAYPOOL_HPP_INCLUDED
00003
00004 #include <iostream>
00005
00006
00013 #include "../Common.h"
00014
00015
00016 template< class BaseT>
00017 class ArrayPool
00018 {
00019 public:
00020
00021
00022
00023
00024
00025 ArrayPool(): pool_(NULL), size_(0), uniqueID_(0), sizeChange_(0), capacity_(0), nDeleted_(0)
00026 {
00027 clear();
00028 }
00029
00030
00031 ~ArrayPool()
00032 {
00033 safeDeleteArray(pool_);
00034 }
00035
00036 BaseT & first(){ return *reinterpret_cast<BaseT*>(pool_); }
00037 const BaseT & first() const { return *reinterpret_cast<BaseT*>(pool_); }
00038 const BaseT* end() const { return reinterpret_cast<const BaseT*>(pool_+size_+1); }
00039 uTind last() const { return static_cast<uTind>(size_); }
00040 size_t size() const { return size_-nDeleted_; }
00041 size_t capacity() const { return capacity_; }
00042 bool empty() const { return size_==0; }
00043 void clear()
00044 {
00045 safeDeleteArray(pool_);
00046 size_=0;
00047 size_=0;
00048 capacity_=0;
00049 nDeleted_=0;
00050 }
00051 BaseT & operator[](const uTind pos) { return reinterpret_cast<BaseT*>(pool_)[pos-FIRST]; }
00052 const BaseT & operator[](const uTind pos) const { return reinterpret_cast<const BaseT*>(pool_)[pos-FIRST]; }
00053
00054 BaseT & at(const uTind pos) { assert(pos > 0 && pos <= size_); return reinterpret_cast<BaseT*>(pool_)[pos-FIRST];}
00055 const BaseT & at(const uTind pos) const { assert(pos > 0 && pos <= size_); return reinterpret_cast<const BaseT*>(pool_)[pos-FIRST];}
00056
00057 BaseT& getById(const ID id)
00058 {
00059 assert( at(BaseT::posFromId(id)).type_== BaseT::typeFromId(id));
00060 assert( at(BaseT::posFromId(id)).id_== id);
00061 return at(BaseT::posFromId(id));
00062 }
00063
00064 const BaseT & getById(const ID id) const
00065 {
00066 assert( at(BaseT::posFromId(id)).type_== BaseT::typeFromId(id));
00067 assert( at(BaseT::posFromId(id)).id_== id);
00068 return at(BaseT::posFromId(id));
00069 }
00070
00071 BaseT* newObj(const uTind verts[])
00072 {
00073 assert( size_+1 <= capacity_);
00074 assert(usedMemory() < totalMemory());
00075 assert(uniqueID_ == size_);
00076
00077 BaseT & obj(* new (pool_+(sizeof(BaseT)*size_++)) BaseT(verts, uniqueID() ) );
00078
00079
00080
00081
00082
00083 return &obj;
00084 }
00085
00086 size_t totalMemory() const { return sizeof(BaseT)*capacity_; }
00087 size_t usedMemory() const {return sizeof(BaseT)*size_;}
00088
00089 void reserve(const size_t newcapacity, bool force=false)
00090 {
00091 if(force || newcapacity > capacity_)
00092 {
00093 BYTE * newPool=new BYTE[newcapacity*sizeof(BaseT)];
00094 memset(newPool,0,newcapacity*sizeof(BaseT));
00095 if(size_ > 0)
00096 {
00097 memcpy(newPool,pool_,std::min(size_,newcapacity)*sizeof(BaseT));
00098 safeDeleteArray(pool_);
00099 }
00100 pool_ = newPool;
00101 capacity_ = newcapacity;
00102 }
00103 }
00104
00105 void requestChange(const Tind sizeChange)
00106 {
00107 sizeChange_+=sizeChange;
00108 }
00109
00110 uTind memoryNeeded() const
00111 {
00112 return static_cast<uTind>(usedMemory() + sizeChange_*sizeof(BaseT));
00113 }
00114
00115 void adjust()
00116 {
00119
00120 {
00121 reserve(size_+sizeChange_,true);
00122
00123 for(BaseT *ptr(&first()); ptr != end(); ++ptr) {
00124 if(ptr->nMyClassSons_ == BaseT::delMark) {
00125 memset(ptr,0,sizeof(BaseT));
00126 ++nDeleted_;
00127
00128 }
00129 }
00130 sizeChange_=0;
00131 }
00132 }
00133
00134 typedef BaseT* Iterator;
00135 typedef const Iterator const_Iterator;
00136
00137
00138
00139
00140 std::ostream& write(std::ostream& stream) const
00141 {
00142 if(stream.good())
00143 {
00144 stream << capacity_ << " ";
00145 stream << size_ << " ";
00146 stream << uniqueID_ << " ";
00147 stream << sizeChange_ << " " ;
00148 const std::streamsize size(size_*sizeof(BaseT));
00149 stream.write(reinterpret_cast<const char*>(pool_),size);
00150 }
00151 assert(stream.good());
00152 return stream;
00153 }
00154
00155 std::istream& read(std::istream& stream)
00156 {
00157 if(stream.good())
00158 {
00159 stream >> capacity_;
00160 assert(stream.good());
00161
00162 reserve(capacity_,true);
00163 stream >> size_;
00164 assert(stream.good());
00165
00166 stream >> uniqueID_;
00167 assert(stream.good());
00168
00169 stream >> sizeChange_;
00170 assert(stream.good());
00171
00172 char tmp('E');
00173 stream.get(tmp);
00174 assert(tmp == ' ');
00175 const std::streamsize size(size_*sizeof(BaseT));
00176 stream.read(reinterpret_cast<char*>(pool_),size);
00177 assert(stream.gcount() == static_cast<std::streamsize>(size_*sizeof(BaseT)));
00178 }
00179 assert(stream.good());
00180 return stream;
00181 }
00182
00183
00184 private:
00185 uTind uniqueID()
00186 {
00187 return static_cast<uTind>(++uniqueID_);
00188 }
00189
00190 BYTE * pool_;
00191 size_t size_,uniqueID_,sizeChange_,capacity_,nDeleted_;
00192
00193 };
00194
00197 #endif // ARRAYPOOL_HPP_INCLUDED