25 # define TRACE( lvl, ... )
26 # define UNDEF_TRACE_AT_END
29 #define USE_UNIQUE_PTR 0
31 static inline void *QV_MEMALIGN(
size_t boundary,
size_t size) {
void *retadr; posix_memalign(&retadr, boundary, size);
return retadr; }
33 #ifndef QUICKVEC_DO_TEMPLATE
34 # define QUICKVEC_DO_TEMPLATE 1
38 #if !defined(__GCCXML__) && defined(__GXX_EXPERIMENTAL_CXX0X__)
39 # define NOT_OLD_CXXSTD 1
42 #if QUICKVEC_DO_TEMPLATE == 0
44 # define QUICKVEC_TT unsigned long long
46 # define TT_ QUICKVEC_TT
47 # define QUICKVEC_TEMPLATE
48 # define QUICKVEC QuickVec
49 # define QUICKVEC_TN QuickVec
50 # define QUICKVEC_VERSION
52 # define QUICKVEC_TEMPLATE template <typename TT_>
53 # define QUICKVEC QuickVec<TT_>
54 # define QUICKVEC_TN typename QuickVec<TT_>
56 # define QUICKVEC_VERSION static short Class_Version() { return 5; } // proper version for templates
62 typedef TT_* iterator;
63 typedef const TT_* const_iterator;
64 typedef TT_& reference;
65 typedef const TT_& const_reference;
66 typedef TT_ value_type;
67 typedef ptrdiff_t difference_type;
68 typedef size_t size_type;
72 # if USE_UNIQUE_PTR == 0
76 # define PTR_(xx) xx.get()
80 : size_(other.size()), data_((TT_*)QV_MEMALIGN(QV_ALIGN, other.capacity() *
sizeof(TT_))), capacity_(other.capacity())
82 memcpy(PTR_(data_), (
void*)&other[0], size_ *
sizeof(TT_));
84 void clear() { size_ = 0; }
88 : size_(other.size_), data_((TT_*)QV_MEMALIGN(QV_ALIGN, other.capacity() *
sizeof(TT_))), capacity_(other.capacity_)
90 TRACE(10,
"QuickVec copy ctor this=%p data_=%p other.data_=%p size_=%d other.size_=%d"
91 , (
void*)
this, (
void*)PTR_(data_), (
void*)PTR_(other.data_), size_, other.size_);
92 memcpy(PTR_(data_), PTR_(other.data_), size_ *
sizeof(TT_));
94 QUICKVEC & operator=(
const QuickVec & other)
96 TRACE(10,
"QuickVec copy assign this=%p data_=%p other.data_=%p size_=%d other.size_=%d"
97 , (
void*)
this, (
void*)PTR_(data_), (
void*)PTR_(other.data_), size_, other.size_);
99 memcpy(PTR_(data_), PTR_(other.data_), size_ *
sizeof(TT_));
104 : size_(other.size_), data_(std::move(other.data_)), capacity_(other.capacity_)
106 TRACE(10,
"QuickVec move ctor this=%p data_=%p other.data_=%p"
107 , (
void*)
this, (
void*)PTR_(data_), (
void*)PTR_(other.data_));
108 # if USE_UNIQUE_PTR == 0
109 other.data_ =
nullptr;
112 QUICKVEC & operator=(
QuickVec && other) noexcept
114 TRACE(10,
"QuickVec move assign this=%p data_=%p other.data_=%p"
115 , (
void*)
this, (
void*)PTR_(data_), (
void*)PTR_(other.data_));
119 data_ = std::move(other.data_);
120 capacity_ = other.capacity_;
121 # if USE_UNIQUE_PTR == 0
122 other.data_ =
nullptr;
128 TT_& operator[](
int idx);
129 const TT_& operator[](
int idx)
const;
131 size_t capacity()
const;
133 const_iterator begin()
const;
135 const_iterator end()
const;
136 void reserve(
size_t size);
137 void resize(
size_t size);
138 void resize(
size_t size, TT_ val);
139 iterator insert(const_iterator position,
size_t nn,
const TT_& val);
140 iterator insert(const_iterator position, const_iterator first
141 , const_iterator last);
142 iterator erase(const_iterator first, const_iterator last);
144 void push_back(
const value_type& val);
153 # if USE_UNIQUE_PTR == 0
156 std::unique_ptr<TT_[]> data_;
162 inline QUICKVEC::QuickVec(
size_t sz)
164 : size_(sz), data_((TT_*)QV_MEMALIGN(QV_ALIGN, sz * sizeof(TT_))), capacity_(sz)
166 TRACE(15,
"QuickVec %p ctor sz=%d data_=%p", (
void*)
this, size_, (
void*)PTR_(data_));
169 inline QUICKVEC::QuickVec(
size_t sz, TT_ val)
171 : size_(sz), data_((TT_*)QV_MEMALIGN(QV_ALIGN, sz * sizeof(TT_))), capacity_(sz)
173 TRACE(15,
"QuickVec %p ctor sz=%d/v data_=%p", (
void*)
this, size_, (
void*)PTR_(data_));
174 for (iterator ii = begin(); ii != end(); ++ii) *ii = val;
178 #if USE_UNIQUE_PTR == 0
180 inline QUICKVEC::~QuickVec() noexcept
182 TRACE(15,
"QuickVec %p dtor start data_=%p size_=%d"
183 , (
void*)
this, (
void*)PTR_(data_), size_);
186 TRACE(15,
"QuickVec %p dtor return", (
void*)
this);
191 inline TT_& QUICKVEC::operator[](
int idx)
193 assert(idx < (
int)size_);
return data_[idx];
197 inline const TT_& QUICKVEC::operator[](
int idx)
const
199 assert(idx < (
int)size_);
204 inline size_t QUICKVEC::size()
const {
return size_; }
206 inline size_t QUICKVEC::capacity()
const {
return capacity_; }
209 inline QUICKVEC_TN::iterator QUICKVEC::begin() {
return iterator(PTR_(data_)); }
211 inline QUICKVEC_TN::const_iterator QUICKVEC::begin()
const {
return iterator(PTR_(data_)); }
213 inline QUICKVEC_TN::iterator QUICKVEC::end() {
return iterator(PTR_(data_) + size_); }
215 inline QUICKVEC_TN::const_iterator QUICKVEC::end()
const {
return const_iterator(PTR_(data_) + size_); }
218 inline void QUICKVEC::reserve(
size_t size)
220 if (size > capacity_)
222 # if USE_UNIQUE_PTR == 0
225 data_ = (TT_*)QV_MEMALIGN(QV_ALIGN, size *
sizeof(TT_));
226 memcpy(data_, old, size_ *
sizeof(TT_));
227 TRACE(13,
"QUICKVEC::reserve this=%p old=%p data_=%p"
228 , (
void*)
this, (
void*)old, (
void*)data_);
232 std::unique_ptr<TT_[]> old = std::move(data_);
234 data_ = std::unique_ptr<TT_[]>((TT_*)QV_MEMALIGN(QV_ALIGN, size *
sizeof(TT_)));
235 memcpy(data_.get(), old.get(), size_ *
sizeof(TT_));
243 inline void QUICKVEC::resize(
size_t size)
245 if (size < size_) size_ = size;
246 else if (size <= capacity_) size_ = size;
249 # if USE_UNIQUE_PTR == 0
252 data_ = (TT_*)QV_MEMALIGN(QV_ALIGN, size *
sizeof(TT_));
253 memcpy(data_, old, size_ *
sizeof(TT_));
254 TRACE(13,
"QUICKVEC::resize this=%p old=%p data_=%p"
255 , (
void*)
this, (
void*)old, (
void*)data_);
259 std::unique_ptr<TT_[]> old = std::move(data_);
261 data_ = std::unique_ptr<TT_[]>((TT_*)QV_MEMALIGN(QV_ALIGN, size *
sizeof(TT_)));
262 memcpy(data_.get(), old.get(), size_ *
sizeof(TT_));
264 size_ = capacity_ = size;
269 inline void QUICKVEC::resize(size_type size, TT_ val)
271 size_type old_size = size;
274 for (iterator ii = begin() + old_size; ii != end(); ++ii) *ii = val;
278 inline QUICKVEC_TN::iterator QUICKVEC::insert(const_iterator position
282 assert(position <= end());
283 size_t offset = position - begin();
286 iterator dst = end() + nn;
287 iterator src = end();
288 size_t cnt = end() - (begin() + offset);
289 while (cnt--) *--dst = *--src;
291 dst = begin() + offset;
293 while (nn--) *dst++ = val;
294 return begin() + offset;
297 inline QUICKVEC_TN::iterator QUICKVEC::insert(const_iterator position
298 , const_iterator first
299 , const_iterator last)
301 assert(position <= end());
302 size_t nn = (last - first);
303 size_t offset = position - begin();
306 iterator dst = end() + nn;
307 iterator src = end();
308 size_t cnt = end() - (begin() + offset);
309 while (cnt--) *--dst = *--src;
311 dst = begin() + offset;
313 while (nn--) *dst++ = *first++;
314 return begin() + offset;
318 inline QUICKVEC_TN::iterator QUICKVEC::erase(const_iterator first
319 , const_iterator last)
321 assert(last <= end());
322 size_t nn = (last - first);
323 size_t offset = first - begin();
325 iterator dst = begin() + offset;
326 iterator src = dst + nn;
327 size_t cnt = end() - src;
328 while (cnt--) *dst++ = *src++;
331 return begin() + offset;
335 inline void QUICKVEC::swap(
QuickVec& x) noexcept
337 TRACE(12,
"QUICKVEC::swap this=%p enter data_=%p x.data_=%p"
338 , (
void*)
this, (
void*)PTR_(data_), (
void*)PTR_(x.data_));
339 std::swap(data_, x.data_);
340 std::swap(size_, x.size_);
341 std::swap(capacity_, x.capacity_);
342 TRACE(12,
"QUICKVEC::swap return data_=%p x.data_=%p"
343 , (
void*)PTR_(data_), (
void*)PTR_(x.data_));
347 inline void QUICKVEC::push_back(
const value_type& val)
349 if (size_ == capacity_)
351 reserve(size_ + size_ / 10 + 1);
357 #ifdef UNDEF_TRACE_AT_END