Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

ixlib_array.hh

Go to the documentation of this file.
00001 // ----------------------------------------------------------------------------
00002 //  Description      : Automatic arrays
00003 // ----------------------------------------------------------------------------
00004 //  (c) Copyright 1999 by iXiONmedia, all rights reserved.
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 // uglier method name, but more STL compliant
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 // this is vital if item is the last remaining item
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

Generated on Wed Oct 31 17:12:23 2001 for ixlib by doxygen1.2.11.1 written by Dimitri van Heesch, © 1997-2001