00001
00002
00003
00004
00005
00006
00007 #ifndef QuickVec_hh
00008 #define QuickVec_hh
00009
00010 extern "C" {
00011 #include <stdint.h>
00012 }
00013
00014 #include <cassert>
00015 #include <cstddef>
00016 #include <string.h>
00017 #include <strings.h>
00018 #include <utility>
00019 #include <memory>
00020 #include <vector>
00021
00022
00023 #ifndef TRACE
00024 # define TRACE( lvl, ... )
00025 # define UNDEF_TRACE_AT_END
00026 #endif
00027
00028 #define USE_UNIQUE_PTR 0
00029
00030 #ifndef QUICKVEC_DO_TEMPLATE
00031 # define QUICKVEC_DO_TEMPLATE 1
00032 #endif
00033
00034 #undef NOT_OLD_CXXSTD
00035 #if !defined(__GCCXML__) && defined(__GXX_EXPERIMENTAL_CXX0X__)
00036 # define NOT_OLD_CXXSTD 1
00037 #endif
00038
00039 #if QUICKVEC_DO_TEMPLATE == 0
00040 # ifndef QUICKVEC_TT
00041 # define QUICKVEC_TT unsigned long long
00042 # endif
00043 # define TT_ QUICKVEC_TT
00044 # define QUICKVEC_TEMPLATE
00045 # define QUICKVEC QuickVec
00046 # define QUICKVEC_TN QuickVec
00047 # define QUICKVEC_VERSION
00048 #else
00049 # define QUICKVEC_TEMPLATE template <typename TT_>
00050 # define QUICKVEC QuickVec<TT_>
00051 # define QUICKVEC_TN typename QuickVec<TT_>
00052
00053 # define QUICKVEC_VERSION static short Class_Version() { return 5; } // proper version for templates
00054 #endif
00055
00056 QUICKVEC_TEMPLATE
00057 struct QuickVec
00058 {
00059 typedef TT_* iterator;
00060 typedef const TT_* const_iterator;
00061 typedef TT_& reference;
00062 typedef const TT_& const_reference;
00063 typedef TT_ value_type;
00064 typedef ptrdiff_t difference_type;
00065 typedef size_t size_type;
00066
00067 QuickVec( size_t sz );
00068 QuickVec( size_t sz, TT_ val );
00069 # if USE_UNIQUE_PTR == 0
00070 ~QuickVec();
00071 # define PTR_(xx) xx
00072 # else
00073 # define PTR_(xx) xx.get()
00074 # endif
00075 QuickVec( std::vector<TT_> & other )
00076 : size_(other.size()), data_(new TT_[other.capacity()]), capacity_(other.capacity())
00077 { memcpy( PTR_(data_), (void*)&other[0], size_*sizeof(TT_) );
00078 }
00079 void clear() { size_=0; }
00080
00081 QuickVec( const QuickVec & other )
00082 : size_(other.size_), data_(new TT_[other.capacity_]), capacity_(other.capacity_)
00083 { TRACE( 10, "QuickVec copy ctor this=%p data_=%p other.data_=%p size_=%d other.size_=%d"
00084 , (void*)this, (void*)PTR_(data_), (void*)PTR_(other.data_), size_, other.size_ );
00085 memcpy( PTR_(data_), PTR_(other.data_), size_*sizeof(TT_) );
00086 }
00087 QUICKVEC & operator=( const QuickVec & other )
00088 { TRACE( 10, "QuickVec copy assign this=%p data_=%p other.data_=%p size_=%d other.size_=%d"
00089 , (void*)this, (void*)PTR_(data_), (void*)PTR_(other.data_), size_, other.size_ );
00090 resize( other.size_ );
00091 memcpy( PTR_(data_), PTR_(other.data_), size_*sizeof(TT_) );
00092 return *this;
00093 }
00094 # if NOT_OLD_CXXSTD
00095 QuickVec( QuickVec && other )
00096 : size_(other.size_), data_(std::move(other.data_)), capacity_(other.capacity_)
00097 { TRACE( 10, "QuickVec move ctor this=%p data_=%p other.data_=%p"
00098 , (void*)this, (void*)PTR_(data_), (void*)PTR_(other.data_) );
00099 # if USE_UNIQUE_PTR == 0
00100 other.data_ = nullptr;
00101 # endif
00102 }
00103 QUICKVEC & operator=( QuickVec && other )
00104 { TRACE( 10, "QuickVec move assign this=%p data_=%p other.data_=%p"
00105 , (void*)this, (void*)PTR_(data_), (void*)PTR_(other.data_) );
00106 size_ = other.size_;
00107 delete [] data_;
00108 data_ = std::move(other.data_);
00109 capacity_ = other.capacity_;
00110 # if USE_UNIQUE_PTR == 0
00111 other.data_ = nullptr;
00112 # endif
00113 return *this;
00114 }
00115 # endif
00116
00117 TT_& operator[](int idx);
00118 const TT_& operator[](int idx) const;
00119 size_t size() const;
00120 size_t capacity() const;
00121 iterator begin();
00122 const_iterator begin() const;
00123 iterator end();
00124 const_iterator end() const;
00125 void reserve( size_t size );
00126 void resize( size_t size );
00127 void resize( size_t size, TT_ val );
00128 iterator insert( const_iterator position, size_t nn, const TT_& val );
00129 iterator insert( const_iterator position, const_iterator first
00130 , const_iterator last);
00131 iterator erase( const_iterator first, const_iterator last );
00132 void swap( QuickVec& x );
00133 void push_back( const value_type& val );
00134
00135 QUICKVEC_VERSION
00136
00137 private:
00138
00139
00140
00141 unsigned size_;
00142 # if USE_UNIQUE_PTR == 0
00143 TT_ * data_;
00144 # else
00145 std::unique_ptr<TT_[]> data_;
00146 # endif
00147 unsigned capacity_;
00148 };
00149
00150 QUICKVEC_TEMPLATE
00151 inline QUICKVEC::QuickVec( size_t sz )
00152 : size_(sz), data_(new TT_[sz]), capacity_(sz)
00153 { TRACE( 15, "QuickVec %p ctor sz=%d data_=%p", (void*)this, size_, (void*)PTR_(data_) );
00154 }
00155 QUICKVEC_TEMPLATE
00156 inline QUICKVEC::QuickVec( size_t sz, TT_ val )
00157 : size_(sz), data_(new TT_[sz]), capacity_(sz)
00158 { TRACE( 15, "QuickVec %p ctor sz=%d/v data_=%p", (void*)this, size_, (void*)PTR_(data_) );
00159 for (iterator ii=begin(); ii!=end(); ++ii) *ii=val;
00160
00161 }
00162
00163 #if USE_UNIQUE_PTR == 0
00164 QUICKVEC_TEMPLATE
00165 inline QUICKVEC::~QuickVec()
00166 { TRACE( 15, "QuickVec %p dtor start data_=%p size_=%d"
00167 , (void*)this, (void*)PTR_(data_), size_ );
00168 delete [] data_;
00169 TRACE( 15, "QuickVec %p dtor return", (void*)this );
00170 }
00171 #endif
00172
00173 QUICKVEC_TEMPLATE
00174 inline TT_& QUICKVEC::operator[](int idx)
00175 { assert(idx<(int)size_); return data_[idx];
00176 }
00177
00178 QUICKVEC_TEMPLATE
00179 inline const TT_& QUICKVEC::operator[](int idx) const
00180 { assert(idx < (int)size_);
00181 return data_[idx];
00182 }
00183
00184 QUICKVEC_TEMPLATE
00185 inline size_t QUICKVEC::size() const { return size_; }
00186 QUICKVEC_TEMPLATE
00187 inline size_t QUICKVEC::capacity() const { return capacity_; }
00188
00189 QUICKVEC_TEMPLATE
00190 inline QUICKVEC_TN::iterator QUICKVEC::begin() { return iterator(PTR_(data_)); }
00191 QUICKVEC_TEMPLATE
00192 inline QUICKVEC_TN::const_iterator QUICKVEC::begin() const { return iterator(PTR_(data_)); }
00193 QUICKVEC_TEMPLATE
00194 inline QUICKVEC_TN::iterator QUICKVEC::end() { return iterator(PTR_(data_)+size_); }
00195 QUICKVEC_TEMPLATE
00196 inline QUICKVEC_TN::const_iterator QUICKVEC::end() const { return const_iterator(PTR_(data_)+size_); }
00197
00198 QUICKVEC_TEMPLATE
00199 inline void QUICKVEC::reserve( size_t size )
00200 { if (size > capacity_)
00201 {
00202 # if USE_UNIQUE_PTR == 0
00203 TT_ * old=data_;
00204 data_ = new TT_[size];
00205 memcpy( data_, old, size_*sizeof(TT_) );
00206 TRACE( 13, "QUICKVEC::reserve this=%p old=%p data_=%p"
00207 , (void*)this, (void*)old, (void*)data_ );
00208 delete [] old;
00209 # else
00210 std::unique_ptr<TT_[]> old=std::move(data_);
00211 data_ = std::unique_ptr<TT_[]>(new TT_[size]);
00212 memcpy( data_.get(), old.get(), size_*sizeof(TT_) );
00213 # endif
00214 capacity_ = size;
00215
00216 }
00217 }
00218
00219 QUICKVEC_TEMPLATE
00220 inline void QUICKVEC::resize( size_t size )
00221 { if (size < size_) size_ = size;
00222 else if (size <= capacity_) size_ = size;
00223 else
00224 {
00225 # if USE_UNIQUE_PTR == 0
00226 TT_ * old=data_;
00227 data_ = new TT_[size];
00228 memcpy( data_, old, size_*sizeof(TT_) );
00229 TRACE( 13, "QUICKVEC::resize this=%p old=%p data_=%p"
00230 , (void*)this, (void*)old, (void*)data_ );
00231 delete [] old;
00232 # else
00233 std::unique_ptr<TT_[]> old=std::move(data_);
00234 data_ = std::unique_ptr<TT_[]>(new TT_[size]);
00235 memcpy( data_.get(), old.get(), size_*sizeof(TT_) );
00236 # endif
00237 size_ = capacity_ = size;
00238
00239 }
00240 }
00241 QUICKVEC_TEMPLATE
00242 inline void QUICKVEC::resize( size_type size, TT_ val )
00243 { size_type old_size=size;
00244 resize( size );
00245 if (size > old_size)
00246 for (iterator ii=begin()+old_size; ii!=end(); ++ii) *ii=val;
00247 }
00248
00249 QUICKVEC_TEMPLATE
00250 inline QUICKVEC_TN::iterator QUICKVEC::insert( const_iterator position
00251 , size_t nn
00252 , const TT_& val)
00253 { assert(position<=end());
00254 size_t offset=position-begin();
00255 reserve( size_+nn );
00256
00257 iterator dst=end()+nn;
00258 iterator src=end();
00259 size_t cnt=end()-(begin()+offset);
00260 while (cnt--) *--dst = *--src;
00261
00262 dst=begin()+offset;
00263 size_+=nn;
00264 while (nn--) *dst++ = val;
00265 return begin()+offset;
00266 }
00267 QUICKVEC_TEMPLATE
00268 inline QUICKVEC_TN::iterator QUICKVEC::insert( const_iterator position
00269 , const_iterator first
00270 , const_iterator last)
00271 { assert(position<=end());
00272 size_t nn=(last-first);
00273 size_t offset=position-begin();
00274 reserve( size_+nn );
00275
00276 iterator dst=end()+nn;
00277 iterator src=end();
00278 size_t cnt=end()-(begin()+offset);
00279 while (cnt--) *--dst = *--src;
00280
00281 dst=begin()+offset;
00282 size_+=nn;
00283 while (nn--) *dst++ = *first++;
00284 return begin()+offset;
00285 }
00286
00287 QUICKVEC_TEMPLATE
00288 inline QUICKVEC_TN::iterator QUICKVEC::erase( const_iterator first
00289 ,const_iterator last )
00290 { assert(last<=end());
00291 size_t nn=(last-first);
00292 size_t offset=first-begin();
00293
00294 iterator dst=begin()+offset;
00295 iterator src=dst+nn;
00296 size_t cnt=end()-src;
00297 while (cnt--) *dst++ = *src++;
00298
00299 size_-=nn;
00300 return begin()+offset;
00301 }
00302
00303 QUICKVEC_TEMPLATE
00304 inline void QUICKVEC::swap( QuickVec& x )
00305 { TRACE( 12, "QUICKVEC::swap this=%p enter data_=%p x.data_=%p"
00306 , (void*)this, (void*)PTR_(data_), (void*)PTR_(x.data_) );
00307 std::swap( data_, x.data_ );
00308 std::swap( size_, x.size_ );
00309 std::swap( capacity_, x.capacity_ );
00310 TRACE( 12, "QUICKVEC::swap return data_=%p x.data_=%p"
00311 , (void*)PTR_(data_), (void*)PTR_(x.data_) );
00312 }
00313
00314 QUICKVEC_TEMPLATE
00315 inline void QUICKVEC::push_back( const value_type& val )
00316 { if (size_ == capacity_)
00317 { reserve( size_ + size_/10 + 1 );
00318 }
00319 *end() = val;
00320 ++size_;
00321 }
00322
00323 #ifdef UNDEF_TRACE_AT_END
00324 # undef TRACE
00325 #endif
00326 #endif