core/vbl/vbl_array_1d.h
Go to the documentation of this file.
00001 // This is core/vbl/vbl_array_1d.h
00002 #ifndef vbl_array_1d_h_
00003 #define vbl_array_1d_h_
00004 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00005 #pragma interface
00006 #endif
00007 //:
00008 // \file
00009 // \brief A simple container.
00010 // \author fsm
00011 //
00012 // \verbatim
00013 // Modifications
00014 //    Peter Vanroose 5apr2001 added operator==
00015 //    Amitha Perera  jan2003  fixed possible alignment issues.
00016 // \endverbatim
00017 
00018 #include <vcl_new.h>
00019 #include <vcl_cassert.h>
00020 #include <vcl_iosfwd.h>
00021 #include <vcl_cstddef.h> // for ptrdiff_t and size_t
00022 
00023 //: A simple container.
00024 // This container stores its elements in contiguous
00025 // storage and whose iterator types are raw pointers. There is
00026 // no requirement that the element type have a default constructor.
00027 template <class T>
00028 struct vbl_array_1d
00029 {
00030   typedef T element_type;
00031 
00032   typedef T       *iterator;
00033   typedef T const *const_iterator;
00034 
00035   typedef T       &reference;
00036   typedef T const &const_reference;
00037 
00038   vbl_array_1d() : begin_(0), end_(0), alloc_(0) { }
00039 
00040   vbl_array_1d(const_iterator b, const_iterator e) {
00041     vcl_ptrdiff_t n = e - b;
00042     assert(n>=0);
00043     // alignment guaranteed by 18.4.1.1
00044     begin_ = (T*) operator new( n * sizeof(T) );
00045     end_   = begin_ + n;
00046     alloc_ = begin_ + n;
00047     for (vcl_ptrdiff_t i=0; i<n; ++i)
00048       new (begin_ + i) T(b[i]);
00049   }
00050 
00051   vbl_array_1d(vbl_array_1d<T> const &that) {
00052     new (this) vbl_array_1d<T>(that.begin_, that.end_);
00053   }
00054 
00055 //: Construct an array with n elements, all equal to v
00056   vbl_array_1d(unsigned long n, const T &v) {
00057     // alignment guaranteed by 18.4.1.1
00058     begin_ = (T*) operator new( n * sizeof(T) );
00059     end_   = begin_ + n;
00060     alloc_ = begin_ + n;
00061     for (unsigned long i=0; i<n; ++i)
00062       new (begin_ + i) T(v);
00063   }
00064 
00065 
00066   vbl_array_1d<T> &operator=(vbl_array_1d<T> const &that) {
00067     this->~vbl_array_1d();
00068     new (this) vbl_array_1d<T>(that.begin_, that.end_);
00069     return *this;
00070   }
00071 
00072   bool operator==(vbl_array_1d<T> const& that) const {
00073     T* i = begin_;
00074     T* j = that.begin_;
00075     for ( ; i!=end_ && j!=that.end_; ++i, ++j)
00076       if (!(*i == *j)) return false;
00077     return i == end_ && j == that.end_;
00078   }
00079 
00080   ~vbl_array_1d() {
00081     if (begin_) {
00082       clear();
00083       operator delete( begin_ );
00084     }
00085   }
00086 
00087   void reserve(vcl_ptrdiff_t new_n) {
00088     vcl_ptrdiff_t n = end_ - begin_;
00089     assert(n>=0);
00090     if (new_n <= n)
00091       return;
00092 
00093     // alignment guaranteed by 18.4.1.1
00094     T *new_begin_ = (T*) operator new( new_n * sizeof(T) );
00095     T *new_end_   = new_begin_ + n;
00096     T *new_alloc_ = new_begin_ + new_n;
00097 
00098     for (vcl_ptrdiff_t i=0; i<n; ++i) {
00099       new (new_begin_ + i) T(begin_[i]);
00100       begin_[i].~T();
00101     }
00102 
00103     operator delete( begin_ );
00104 
00105     begin_ = new_begin_;
00106     end_   = new_end_;
00107     alloc_ = new_alloc_;
00108   }
00109 
00110   void push_back(T const &x) {
00111     if (end_ == alloc_)
00112       reserve(2*size() + 1);
00113     new (end_) T(x);
00114     ++end_;
00115   }
00116 
00117   void pop_back() {
00118     end_->~T();
00119     --end_;
00120   }
00121 
00122   reference back() { return end_[-1]; }
00123   const_reference back() const { return end_[-1]; }
00124 
00125   reference front() { return *begin_; }
00126   const_reference front() const { return *begin_; }
00127 
00128   void clear() {
00129     for (T *p = begin_; p!=end_; ++p)
00130       p->~T();
00131     end_ = begin_;
00132   }
00133 
00134   iterator begin() { return begin_; }
00135   iterator end() { return end_; }
00136 
00137   const_iterator begin() const { return begin_; }
00138   const_iterator end() const { return end_; }
00139 
00140   bool empty() const { return begin_ == end_; }
00141   vcl_size_t size() const { return end_ - begin_; }
00142   vcl_size_t capacity() const { return alloc_ - begin_; }
00143 
00144   //: Get the ith element.
00145   // #define NDEBUG to turn bounds checking off.
00146   reference       operator[](vcl_ptrdiff_t i)
00147   {
00148     assert (i >= 0 && i < end_ - begin_);
00149     return begin_[i];
00150   }
00151 
00152   //: Get the ith element.
00153   // #define NDEBUG to turn bounds checking off.
00154   const_reference operator[](vcl_ptrdiff_t i) const
00155   {
00156     assert (i >= 0 && i < end_ - begin_);
00157     return begin_[i];
00158   }
00159 
00160  private:
00161   // begin_ <= end_ <= alloc_
00162   T *begin_, *end_, *alloc_;
00163 };
00164 
00165 export template <class T>
00166 vcl_ostream& operator<<(vcl_ostream &, vbl_array_1d<T> const &);
00167 
00168 #endif // vbl_array_1d_h_