00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #ifndef _GOSCRATCHVECT_H
00034 #define _GOSCRATCHVECT_H
00035
00036
00037 #include <vector>
00038
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
00136 end_ -= (cur_size - new_size);
00137 } else {
00138
00139 begin_ = scratch_;
00140 end_ = begin_ + new_size;
00141 stl_vect_.clear();
00142 }
00143 }
00144
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