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