ScratchVect.h

00001 //===========================================================================
00002 // GoTools - SINTEF Geometry Tools version 1.1
00003 //
00004 // GoTools module: CORE
00005 //
00006 // Copyright (C) 2000-2007 SINTEF ICT, Applied Mathematics, Norway.
00007 //
00008 // This program is free software; you can redistribute it and/or          
00009 // modify it under the terms of the GNU General Public License            
00010 // as published by the Free Software Foundation version 2 of the License. 
00011 //
00012 // This program is distributed in the hope that it will be useful,        
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of         
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          
00015 // GNU General Public License for more details.                           
00016 //
00017 // You should have received a copy of the GNU General Public License      
00018 // along with this program; if not, write to the Free Software            
00019 // Foundation, Inc.,                                                      
00020 // 59 Temple Place - Suite 330,                                           
00021 // Boston, MA  02111-1307, USA.                                           
00022 //
00023 // Contact information: E-mail: tor.dokken@sintef.no                      
00024 // SINTEF ICT, Department of Applied Mathematics,                         
00025 // P.O. Box 124 Blindern,                                                 
00026 // 0314 Oslo, Norway.                                                     
00027 //
00028 // Other licenses are also available for this software, notably licenses
00029 // for:
00030 // - Building commercial software.                                        
00031 // - Building software whose source code you wish to keep private.        
00032 //===========================================================================
00033 #ifndef _GOSCRATCHVECT_H
00034 #define _GOSCRATCHVECT_H
00035 
00036 
00037 #include <vector>
00038 //#include "Utils.h"
00039 
00040 
00041 namespace Go {
00044 
00045 
00051 template <typename T, size_t N>
00052 class ScratchVect {
00053 
00054 private:
00055     T scratch_[N];
00056     std::vector<T> stl_vect_;
00057     T* begin_;
00058     T* end_;
00059 
00060 public:
00061     typedef T* iterator;
00062     typedef const T*  const_iterator;
00063 
00065     ScratchVect() :
00066       stl_vect_(0),
00067       begin_(scratch_),
00068       end_(scratch_) {}
00069 
00071     ScratchVect(size_t size) :
00072       stl_vect_((size>N)?size:0) {
00073       if (size>N) {
00074         begin_ = &stl_vect_[0];
00075         end_ = (&stl_vect_[0])+size; 
00076       } else {
00077         begin_=scratch_;
00078         end_=(&scratch_[size]);
00079       }
00080     }
00081 
00084     ScratchVect(size_t size, T elem) :
00085       stl_vect_((size>N)?size:0) {
00086       if (size>N) {
00087         begin_ = &stl_vect_[0];
00088         end_ = (&stl_vect_[0])+size; 
00089       } else {
00090         begin_=scratch_;
00091         end_=(&scratch_[size]);
00092       }
00093       std::fill(begin_, end_, elem);
00094     }
00095 
00096 
00097 
00100     ScratchVect(const std::vector<T>& vec) {
00101         assign(vec.begin(), vec.end());
00102     }
00103 
00106     template<typename RAIter>
00107     ScratchVect(RAIter beg, RAIter end) {
00108         assign(beg, end);
00109     }
00110 
00114     template <int M>
00115     ScratchVect(const ScratchVect<T,M> &orig) {
00116         assign(orig.begin(), orig.end());
00117     }
00118 
00120     ScratchVect& operator = (const ScratchVect &orig) {
00121         assign(orig.begin(), orig.end());
00122         return *this;
00123     }
00124 
00126     void resize(size_t new_size) {
00127         const int cur_size = size();
00128         if (new_size == cur_size) {
00129             return;
00130         }
00131         if (new_size < cur_size) {
00132             if (cur_size < N) {
00133                 end_ -= (cur_size - new_size);          
00134             } else if (new_size >N) {
00135                 // both cur_size and new_size > N
00136                 end_ -= (cur_size - new_size);          
00137             } else {
00138                 // cur_size > N but new_size < N
00139                 begin_ = scratch_;
00140                 end_ = begin_ + new_size;
00141                 stl_vect_.clear(); // release memory
00142             }
00143         }
00144         // new_size > size
00145         if (new_size < N) {
00146             end_ = begin_ + new_size;
00147         } else {
00148             stl_vect_.resize(new_size);
00149             begin_ = &stl_vect_[0];
00150             end_ = begin_ + new_size;
00151         }
00152     }
00153 
00156     template<typename RAIter>
00157     void assign(RAIter beg, RAIter end) {
00158         size_t sz = end - beg;
00159         stl_vect_.clear();
00160         if (sz>N) {
00161             stl_vect_.insert(stl_vect_.end(), beg, end);
00162             begin_ = &stl_vect_[0];
00163             end_ = (&stl_vect_[0])+sz; 
00164         } else {
00165             begin_=scratch_;
00166             end_=(&scratch_[sz]);
00167             std::copy(beg, end, begin_);
00168         }
00169     }
00170      
00172     inline iterator begin() { return begin_;}
00173 
00175     inline const_iterator begin() const { return begin_;}
00176 
00178     inline iterator end() { return end_;}
00179 
00181     inline const_iterator end() const { return end_;}
00182 
00184     inline size_t size() const {return (end_-begin_);}
00185 
00187     inline const T& operator [] (int i) const { return begin_[i]; }
00188     inline T& operator [] (int i)       { return begin_[i]; }
00189     
00191     void push_back(const T &e)
00192     {
00193       size_t n=size();
00194       if (n<N)
00195         *(end_++)=e;
00196       else if (n>N)
00197       {
00198         stl_vect_.push_back(e);
00199         begin_=&stl_vect_[0];
00200         end_=&stl_vect_[0]+stl_vect_.size();
00201       }
00202       else
00203       {
00204         stl_vect_.reserve(2*n);
00205         stl_vect_.insert(stl_vect_.end(), begin_, end_);
00206         stl_vect_.insert(stl_vect_.end(), e);
00207         begin_=&stl_vect_[0];
00208         end_=&stl_vect_[0]+stl_vect_.size();
00209       }
00210     }
00211     
00213     void clear()
00214     {
00215       if (begin_==scratch_)
00216         end_=scratch_;
00217       else
00218       {
00219         stl_vect_.clear();
00220         begin_=end_=scratch_;
00221       }
00222     }
00223 
00224 };
00226 }
00227 #endif
00228 
00229 

Generated on Mon Jun 11 14:48:18 2007 for GoTools Core Library by  doxygen 1.5.1