00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #ifndef IXLIB_ARRAY
00011 #define IXLIB_ARRAY
00012
00013
00014
00015
00016 #include <memory>
00017
00018
00019
00020
00021 namespace ixion {
00027 template<class T,class Allocator = std::allocator<T> >
00028 struct array {
00029 typedef T value_type;
00030 typedef Allocator allocator_type;
00031 typedef typename Allocator::reference reference;
00032 typedef typename Allocator::const_reference const_reference;
00033 typedef typename Allocator::size_type size_type;
00034 typedef typename Allocator::difference_type difference_type;
00035 typedef typename Allocator::pointer pointer;
00036 typedef typename Allocator::const_pointer const_pointer;
00037
00038 protected:
00039 pointer Data;
00040 size_type Capacity;
00041 Allocator Alloc;
00042
00043 public:
00044 array(Allocator const &alloc = Allocator())
00045 : Data(NULL),Capacity(0),Alloc(alloc)
00046 { }
00047 array(size_type cap,Allocator const &alloc = Allocator())
00048 : Data(NULL),Capacity(0),Alloc(alloc)
00049 { allocate(cap); }
00050 array(array const &source)
00051 : Data(source.Data),Capacity(source.Capacity),Alloc(source.Alloc)
00052 { }
00053 virtual ~array()
00054 { }
00055
00056 array &operator=(array const &source) {
00057 Data = source.Data;
00058 Capacity = source.Capacity;
00059 Alloc = source.Alloc;
00060 return *this;
00061 }
00062
00063 reference operator[](size_type pos) const
00064 { return Data[pos]; }
00065 reference operator*() const
00066 { return *Data; }
00067 pointer operator+(size_type pos) const
00068 { return Data+pos; }
00069
00070 pointer get() const
00071 { return Data; }
00072 size_type capacity() const
00073 { return Capacity; }
00074 allocator_type get_allocator() const
00075 { return Alloc; }
00076
00077 virtual void allocate(size_type cap) {
00078 pointer tmp = Alloc.allocate(cap);
00079 if (!tmp && cap) throw std::bad_alloc();
00080 Data = tmp;
00081 Capacity = cap;
00082 }
00083 virtual void deallocate() {
00084 internal_deallocate();
00085 invalidate();
00086 }
00087 virtual void construct(pointer first,pointer last,
00088 const_reference value = T())
00089 { for (;first!=last;first++) Alloc.construct(first,value); }
00090 virtual void construct(pointer first,pointer last,const_pointer source)
00091 { for (;first!=last;first++) Alloc.construct(first,*(source++)); }
00092 virtual void construct(pointer item,const_reference source = T())
00093 { Alloc.construct(item,source); }
00094 virtual void destroy(pointer first,pointer last)
00095 { for (;first!=last;first++) Alloc.destroy(first); }
00096 virtual void destroy(pointer item)
00097 { Alloc.destroy(item); }
00098 virtual void invalidate() {
00099 Data = NULL;
00100 Capacity = 0;
00101 }
00102 protected:
00103 void internal_deallocate()
00104 { if (Data) Alloc.deallocate(Data,Capacity); }
00105 };
00106
00107
00108
00109
00117 template<class T,class Allocator = std::allocator<T> >
00118 class tracking_array: public array<T,Allocator> {
00119 pointer FirstValid,LastValid;
00120
00121 typedef array<T,Allocator> super;
00122
00123 public:
00124 tracking_array(Allocator const &alloc = Allocator())
00125 : super(alloc),FirstValid(NULL),LastValid(NULL)
00126 { }
00127 tracking_array(size_type cap,Allocator const &alloc = Allocator())
00128 : super(cap,alloc),FirstValid(NULL),LastValid(NULL)
00129 { }
00130 tracking_array(tracking_array const &source)
00131 : super(source),FirstValid(source.FirstValid),LastValid(source.LastValid)
00132 { }
00133 virtual ~tracking_array()
00134 { }
00135
00136 pointer begin() const
00137 { return FirstValid; }
00138 pointer end() const
00139 { return LastValid; }
00140 size_type size() const {
00141 if (!FirstValid)
00142 return 0;
00143 else
00144 return LastValid-FirstValid;
00145 }
00146
00147 tracking_array &operator=(tracking_array const &source) {
00148 FirstValid = source.FirstValid;
00149 LastValid = source.LastValid;
00150 super::operator=(source);
00151 return *this;
00152 }
00153
00154 virtual void allocate(size_type cap) {
00155 FirstValid = NULL;
00156 LastValid = NULL;
00157 super::allocate(cap);
00158 }
00159 virtual void deallocate() {
00160 FirstValid = NULL;
00161 LastValid = NULL;
00162 super::deallocate();
00163 }
00164
00165 virtual void construct(pointer first,pointer last,
00166 const_reference value = typename tracking_array::value_type()) {
00167 if (!FirstValid || first<FirstValid) FirstValid = first;
00168 if (!LastValid || last>LastValid) LastValid = last;
00169 super::construct(first,last,value);
00170 }
00171 virtual void construct(pointer first,pointer last,const_pointer source) {
00172 if (!FirstValid || first<FirstValid) FirstValid = first;
00173 if (!LastValid || last>LastValid) LastValid = last;
00174 super::construct(first,last,source);
00175 }
00176 virtual void construct(pointer item,const_reference source = T()) {
00177 if (!FirstValid || item<FirstValid) FirstValid = item;
00178 if (!LastValid || item+1>LastValid) LastValid = item+1;
00179 super::construct(item,source);
00180 }
00181 virtual void destroy(pointer first,pointer last) {
00182 if (first == FirstValid) FirstValid = last;
00183 else if (last == LastValid) LastValid = first;
00184 super::destroy(first,last);
00185 }
00186 virtual void destroy(pointer item) {
00187 if (item+1 == LastValid) LastValid = item;
00188 else
00189 if (item == FirstValid) FirstValid = item+1;
00190 super::destroy(item);
00191 }
00192 virtual void destroy() {
00193 internal_destroy();
00194 FirstValid = NULL;
00195 LastValid = NULL;
00196 }
00197 virtual void invalidate() {
00198 super::invalidate();
00199 FirstValid = NULL;
00200 LastValid = NULL;
00201 }
00202 protected:
00203 void internal_destroy()
00204 { if (FirstValid) super::destroy(FirstValid,LastValid); }
00205 };
00206
00207
00208
00209
00214 template<class T,class Allocator = std::allocator<T> >
00215 class auto_array : public array<T,Allocator> {
00216 typedef array<T,Allocator> super;
00217
00218 public:
00219 auto_array(Allocator const &alloc = Allocator())
00220 : super(alloc)
00221 { }
00222 auto_array(size_type cap,Allocator const &alloc = Allocator())
00223 : super(cap,alloc)
00224 { }
00225 auto_array(auto_array &source)
00226 : super(source)
00227 { source.invalidate(); }
00228 virtual ~auto_array()
00229 { internal_deallocate(); }
00230
00231 auto_array &operator=(auto_array &source) {
00232 internal_deallocate();
00233 super::operator=(source);
00234 source.invalidate();
00235 return *this;
00236 }
00237
00238 virtual void allocate(size_type cap) {
00239 internal_deallocate();
00240 super::allocate(cap);
00241 }
00242 };
00243
00244
00245
00246
00251 template<class T,class Allocator = std::allocator<T> >
00252 class auto_destroy_array: public tracking_array<T,Allocator> {
00253 typedef tracking_array<T,Allocator> super;
00254
00255 public:
00256 auto_destroy_array(Allocator const &alloc = Allocator())
00257 : super(alloc)
00258 { }
00259 auto_destroy_array(size_type cap,Allocator const &alloc = Allocator())
00260 : super(cap,alloc)
00261 { }
00262 auto_destroy_array(auto_destroy_array &source)
00263 : super(source)
00264 { source.invalidate(); }
00265 virtual ~auto_destroy_array() {
00266 internal_destroy();
00267 internal_deallocate();
00268 }
00269
00270 auto_destroy_array &operator=(auto_destroy_array &source) {
00271 internal_destroy();
00272 internal_deallocate();
00273 super::operator=(source);
00274 source.invalidate();
00275 return *this;
00276 }
00277
00278 virtual void allocate(size_type cap) {
00279 internal_destroy();
00280 internal_deallocate();
00281 super::allocate(cap);
00282 }
00283 virtual void deallocate() {
00284 internal_destroy();
00285 super::deallocate();
00286 }
00287 };
00288 }
00289
00290
00291
00292
00293 #endif