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 class vbl_array_1d
00029 {
00030  public:
00031   typedef vcl_size_t size_type;
00032   typedef T element_type;
00033 
00034  private:
00035   element_type *begin_, *end_, *alloc_; // begin_ <= end_ <= alloc_
00036 
00037  public:
00038   typedef T       *iterator;
00039   typedef T const *const_iterator;
00040 
00041   typedef T       &reference;
00042   typedef T const &const_reference;
00043  public:
00044 
00045   vbl_array_1d() : begin_(0), end_(0), alloc_(0) { }
00046 
00047   vbl_array_1d(const_iterator b, const_iterator e) {
00048     vcl_ptrdiff_t n = e - b;
00049     assert(n>=0);
00050     // alignment guaranteed by 18.4.1.1
00051     begin_ = (T*) operator new( n * sizeof(T) );
00052     end_   = begin_ + n;
00053     alloc_ = begin_ + n;
00054     for (vcl_ptrdiff_t i=0; i<n; ++i)
00055       new (begin_ + i) T(b[i]);
00056   }
00057 
00058   vbl_array_1d(vbl_array_1d<T> const &that) {
00059     new (this) vbl_array_1d<T>(that.begin_, that.end_);
00060   }
00061 
00062 //: Construct an array with n elements, all equal to v
00063   vbl_array_1d(size_type n, const T &v) {
00064     // alignment guaranteed by 18.4.1.1
00065     begin_ = (T*) operator new( n * sizeof(T) );
00066     end_   = begin_ + n;
00067     alloc_ = begin_ + n;
00068     for (size_type i=0; i<n; ++i)
00069       new (begin_ + i) T(v);
00070   }
00071 
00072 
00073   vbl_array_1d<T> &operator=(vbl_array_1d<T> const &that) {
00074     this->~vbl_array_1d();
00075     new (this) vbl_array_1d<T>(that.begin_, that.end_);
00076     return *this;
00077   }
00078 
00079   bool operator==(vbl_array_1d<T> const& that) const {
00080     T* i = begin_;
00081     T* j = that.begin_;
00082     for ( ; i!=end_ && j!=that.end_; ++i, ++j)
00083       if (!(*i == *j)) return false;
00084     return i == end_ && j == that.end_;
00085   }
00086 
00087   ~vbl_array_1d() {
00088     if (begin_) {
00089       clear();
00090       operator delete( begin_ );
00091     }
00092   }
00093 
00094   void reserve(vcl_ptrdiff_t new_n) {
00095     vcl_ptrdiff_t n = end_ - begin_;
00096     assert(n>=0);
00097     if (new_n <= n)
00098       return;
00099 
00100     // alignment guaranteed by 18.4.1.1
00101     T *new_begin_ = (T*) operator new( new_n * sizeof(T) );
00102     T *new_end_   = new_begin_ + n;
00103     T *new_alloc_ = new_begin_ + new_n;
00104 
00105     for (vcl_ptrdiff_t i=0; i<n; ++i) {
00106       new (new_begin_ + i) T(begin_[i]);
00107       begin_[i].~T();
00108     }
00109 
00110     operator delete( begin_ );
00111 
00112     begin_ = new_begin_;
00113     end_   = new_end_;
00114     alloc_ = new_alloc_;
00115   }
00116 
00117   void push_back(T const &x) {
00118     if (end_ == alloc_)
00119       reserve(2*size() + 1);
00120     new (end_) T(x);
00121     ++end_;
00122   }
00123 
00124   void pop_back() {
00125     end_->~T();
00126     --end_;
00127   }
00128 
00129   reference back() { return end_[-1]; }
00130   const_reference back() const { return end_[-1]; }
00131 
00132   reference front() { return *begin_; }
00133   const_reference front() const { return *begin_; }
00134 
00135   void clear() {
00136     for (T *p = begin_; p!=end_; ++p)
00137       p->~T();
00138     end_ = begin_;
00139   }
00140 
00141   iterator begin() { return begin_; }
00142   iterator end() { return end_; }
00143 
00144   const_iterator begin() const { return begin_; }
00145   const_iterator end() const { return end_; }
00146 
00147   bool empty() const { return begin_ == end_; }
00148   size_type size() const { return end_ - begin_; }
00149   size_type capacity() const { return alloc_ - begin_; }
00150 
00151   //: Get the ith element.
00152   // #define NDEBUG to turn bounds checking off.
00153   reference       operator[](vcl_ptrdiff_t i)
00154   {
00155     assert (i >= 0 && i < end_ - begin_);
00156     return begin_[i];
00157   }
00158 
00159   //: Get the ith element.
00160   // #define NDEBUG to turn bounds checking off.
00161   const_reference operator[](vcl_ptrdiff_t i) const
00162   {
00163     assert (i >= 0 && i < end_ - begin_);
00164     return begin_[i];
00165   }
00166 };
00167 
00168 export template <class T>
00169 vcl_ostream& operator<<(vcl_ostream &, vbl_array_1d<T> const &);
00170 
00171 #endif // vbl_array_1d_h_