28 #define TRACEN(nam, lvl, ...)
29 #define UNDEF_TRACE_AT_END
32 #define QV_ALIGN 512 // 512 byte align to support _possible_ direct I/O - see artdaq/artdaq/ArtModules/BinaryFileOutput_module.cc and artdaq issue #24437
40 static inline void* QV_MEMALIGN(
size_t boundary,
size_t size)
42 void* retadr =
nullptr;
43 posix_memalign(&retadr, boundary, size);
47 #ifndef QUICKVEC_DO_TEMPLATE
48 #define QUICKVEC_DO_TEMPLATE 1
52 #if !defined(__GCCXML__) && defined(__GXX_EXPERIMENTAL_CXX0X__)
53 #define NOT_OLD_CXXSTD 1
56 #if QUICKVEC_DO_TEMPLATE == 0
58 #define QUICKVEC_TT unsigned long long
60 #define TT_ QUICKVEC_TT
61 #define QUICKVEC_TEMPLATE
62 #define QUICKVEC QuickVec
63 #define QUICKVEC_TN QuickVec
64 #define QUICKVEC_VERSION
66 #define QUICKVEC_TEMPLATE template<typename TT_>
67 #define QUICKVEC QuickVec<TT_>
68 #define QUICKVEC_TN typename QuickVec<TT_>
69 #define QUICKVEC_VERSION \
76 static short Class_Version() { return 5; } // proper version for templates
120 : size_(other.
size())
121 , data_(reinterpret_cast<TT_*>(QV_MEMALIGN(QV_ALIGN, other.
capacity() * sizeof(TT_))))
124 TRACEN(
"QuickVec", 10,
"QuickVec std::vector ctor b4 memcpy this=%p data_=%p &other[0]=%p size_=%d other.size()=%d", (
void*)
this, (
void*)data_, (
void*)&other[0], size_, other.size());
125 memcpy(data_, (
void*)&other[0], size_ *
sizeof(TT_));
140 , data_(reinterpret_cast<TT_*>(QV_MEMALIGN(QV_ALIGN, other.
capacity() * sizeof(TT_))))
141 , capacity_(other.capacity_)
143 TRACEN(
"QuickVec", 10,
"QuickVec copy ctor b4 memcpy this=%p data_=%p other.data_=%p size_=%d other.size_=%d", (
void*)
this, (
void*)data_, (
void*)other.data_, size_, other.size_);
144 memcpy(data_, other.data_, size_ *
sizeof(TT_));
154 TRACEN(
"QuickVec", 10,
"QuickVec copy assign b4 resize/memcpy this=%p data_=%p other.data_=%p size_=%d other.size_=%d", (
void*)
this, (
void*)data_, (
void*)other.data_, size_, other.size_);
156 memcpy(data_, other.data_, size_ *
sizeof(TT_));
166 , data_(std::move(other.data_))
167 , capacity_(other.capacity_)
169 TRACEN(
"QuickVec", 10,
"QuickVec move ctor this=%p data_=%p other.data_=%p", (
void*)
this, (
void*)data_, (
void*)other.data_);
170 other.data_ =
nullptr;
180 TRACEN(
"QuickVec", 10,
"QuickVec move assign this=%p data_=%p other.data_=%p", (
void*)
this, (
void*)data_, (
void*)other.data_);
184 data_ = std::move(other.data_);
185 capacity_ = other.capacity_;
186 other.data_ =
nullptr;
345 inline QUICKVEC::QuickVec(
size_t sz)
347 , data_(reinterpret_cast<TT_*>(QV_MEMALIGN(QV_ALIGN, sz * sizeof(TT_))))
350 TRACEN(
"QuickVec", 15,
"QuickVec %p ctor sz=%d data_=%p", (
void*)
this, size_, (
void*)data_);
354 inline QUICKVEC::QuickVec(
size_t sz, TT_ val)
356 , data_(reinterpret_cast<TT_*>(QV_MEMALIGN(QV_ALIGN, sz * sizeof(TT_))))
359 TRACEN(
"QuickVec", 15,
"QuickVec %p ctor sz=%d/v data_=%p", (
void*)
this, size_, (
void*)data_);
365 inline QUICKVEC::~QuickVec() noexcept
367 TRACEN(
"QuickVec", 15,
"QuickVec %p dtor start data_=%p size_=%d", (
void*)
this, (
void*)data_, size_);
371 TRACEN(
"QuickVec", 15,
"QuickVec %p dtor return", (
void*)
this);
375 inline TT_& QUICKVEC::operator[](
int idx)
377 assert(idx < (
int)size_);
382 inline const TT_& QUICKVEC::operator[](
int idx)
const
384 assert(idx < (
int)size_);
389 inline size_t QUICKVEC::size()
const {
return size_; }
392 inline size_t QUICKVEC::capacity()
const {
return capacity_; }
395 inline QUICKVEC_TN::iterator QUICKVEC::begin() {
return iterator(data_); }
398 inline QUICKVEC_TN::const_iterator QUICKVEC::begin()
const {
return iterator(data_); }
401 inline QUICKVEC_TN::iterator QUICKVEC::end()
407 inline QUICKVEC_TN::const_iterator QUICKVEC::end()
const
413 inline void QUICKVEC::reserve(
size_t size)
415 if (size > capacity_)
419 data_ =
reinterpret_cast<TT_*
>(QV_MEMALIGN(QV_ALIGN, size *
sizeof(TT_)));
420 memcpy(data_, old, size_ *
sizeof(TT_));
421 TRACEN(
"QuickVec", 13,
"QUICKVEC::reserve after memcpy this=%p old=%p data_=%p capacity=%d", (
void*)
this, (
void*)old, (
void*)data_, (
int)size);
429 inline void QUICKVEC::resize(
size_t size)
433 else if (size <= capacity_)
438 data_ =
reinterpret_cast<TT_*
>(QV_MEMALIGN(QV_ALIGN, size *
sizeof(TT_)));
439 memcpy(data_, old, size_ *
sizeof(TT_));
440 TRACEN(
"QuickVec", 13,
"QUICKVEC::resize after memcpy this=%p old=%p data_=%p size=%d", (
void*)
this, (
void*)old, (
void*)data_, (
int)size);
443 size_ = capacity_ = size;
448 inline void QUICKVEC::resizeWithCushion(
size_t size,
double growthFactor)
450 if (size > capacity_)
452 size_t new_size = std::round(capacity_ * growthFactor);
453 if (new_size < size) { new_size = size; }
454 if (new_size < 512) { new_size = 512; }
455 else if (new_size < 2048)
459 else if (new_size < 4096)
463 else if (new_size < 8192)
479 TRACEN(
"QuickVec", 13,
"QUICKVEC::resize initializing %zu elements", size - old_size);
480 for (
iterator ii = begin() + old_size; ii != end(); ++ii) *ii = val;
485 inline QUICKVEC_TN::iterator QUICKVEC::insert(
const_iterator position,
size_t nn,
const TT_& val)
487 assert(position <= end());
488 size_t offset = position - begin();
493 size_t cnt = end() - (begin() + offset);
494 while (cnt--) *--dst = *--src;
496 dst = begin() + offset;
498 while (nn--) *dst++ = val;
499 return begin() + offset;
505 assert(position <= end());
506 size_t nn = (last - first);
507 size_t offset = position - begin();
512 size_t cnt = end() - (begin() + offset);
513 while (cnt--) *--dst = *--src;
515 dst = begin() + offset;
517 while (nn--) *dst++ = *first++;
518 return begin() + offset;
524 assert(last <= end());
525 size_t nn = (last - first);
526 size_t offset = first - begin();
530 size_t cnt = end() - src;
531 while (cnt--) *dst++ = *src++;
534 return begin() + offset;
538 inline void QUICKVEC::swap(
QuickVec& other) noexcept
540 TRACEN(
"QuickVec", 12,
"QUICKVEC::swap this=%p enter data_=%p other.data_=%p", (
void*)
this, (
void*)data_, (
void*)other.data_);
541 std::swap(data_, other.data_);
542 std::swap(size_, other.size_);
543 std::swap(capacity_, other.capacity_);
544 TRACEN(
"QuickVec", 12,
"QUICKVEC::swap return data_=%p other.data_=%p", (
void*)data_, (
void*)other.data_);
550 if (size_ == capacity_)
552 reserve(size_ + size_ / 10 + 1);
560 #ifdef UNDEF_TRACE_AT_END
562 #undef UNDEF_TRACE_AT_END
iterator erase(const_iterator first, const_iterator last)
Erases elements in given range from the QuickVec.
iterator end()
Gets an iterator to the end of the QuickVec.
void clear()
Sets the size to 0. QuickVec does not reinitialize memory, so no further action will be taken...
void reserve(size_t size)
Allocates memory for the QuickVec so that its capacity is at least size.
void resize(size_t size)
Resizes the QuickVec.
TT_ & operator[](int idx)
Returns a reference to a given element.
size_t size_type
size_type is size_t
TT_ value_type
value_type is member type
size_t size() const
Accesses the current size of the QuickVec.
TT_ * iterator
Iterator is pointer-to-member type.
ptrdiff_t difference_type
difference_type is ptrdiff_t
size_t capacity() const
Accesses the current capacity of the QuickVec.
void swap(QuickVec &other) noexcept
Exchanges references to two QuickVec objects.
void resizeWithCushion(size_t size, double growthFactor=1.3)
Resizes the QuickVec and requests additional capacity.
iterator insert(const_iterator position, size_t nn, const TT_ &val)
Inserts an element into the QuickVec.
void push_back(const value_type &val)
Adds a value to the QuickVec, resizing if necessary (adds 10% capacity)
A QuickVec behaves like a std::vector, but does no initialization of its data, making it faster at th...
QuickVec(size_t sz)
Allocates a QuickVec object, doing no initialization of allocated memory.
const TT_ * const_iterator
const_iterator is const-pointer-to-member type
const TT_ & const_reference
const_reference is const-reference-to-member type
iterator begin()
Gets an iterator to the beginning of the QuickVec.
QuickVec< TT_ > & operator=(const QuickVec &other)
Copy assignment operator.
virtual ~QuickVec() noexcept
Destructor calls free on data.
TT_ & reference
reference is reference-to-member tpye
QuickVec(const QuickVec &other)
Copy Constructor.