1 #ifndef DASYNQ_SVEC_H_INCLUDED
2 #define DASYNQ_SVEC_H_INCLUDED
8 // Vector with possibility to shrink capacity arbitrarily.
10 // The standard vector (std::vector) only allows shrinking a vector's capacity to its current size. In cases
11 // where we need to keep some reserved capacity beyond the current size, we need an alternative solution: hence,
12 // this class, svector.
32 if (size_v == capacity_v) {
33 // double capacity now:
34 if (capacity_v == 0) capacity_v = 1;
35 vec_node * new_array = new vec_node[capacity_v * 2];
36 for (size_t i = 0; i < size_v; i++) {
37 new (&new_array[i].elem) T(std::move(array[i].elem));
38 array[i].elem.T::~T();
47 using size_type = size_t;
49 svector() : array(nullptr), size_v(0), capacity_v(0)
54 svector(const svector<T> &other)
56 capacity_v = other.size_v;
57 size_v = other.size_v;
58 array = new T[capacity_v];
59 for (size_t i = 0; i < size_v; i++) {
60 new (&array[i].elem) T(other[i].elem);
66 for (size_t i = 0; i < size_v; i++) {
67 array[i].elem.T::~T();
72 void push_back(const T &t)
75 new (&array[size_v].elem) T(t);
82 new (&array[size_v].elem) T(t);
86 template <typename ...U>
87 void emplace_back(U... args)
90 new (&array[size_v].elem) T(args...);
99 T &operator[](size_t index)
101 return array[index].elem;
104 const T &operator[](size_t index) const
106 return array[index].elem;
114 size_t capacity() const
124 static size_t max_size() noexcept
126 return std::numeric_limits<size_type>::max() / sizeof(T);
128 // if we were to support allocators:
129 //size_t max = std::allocator_traits<std::allocator<char>>::max_size(std::allocator<T>());
130 //return max / sizeof(T);
131 // (but not / sizeof(T) for C++17 apparently)
134 void reserve(size_t amount)
136 if (capacity_v < amount) {
137 vec_node * new_array = new vec_node[amount];
138 for (size_t i = 0; i < size_v; i++) {
139 new (&new_array[i].elem) T(std::move(array[i].elem));
140 array[i].elem.T::~T();
148 void shrink_to(size_t amount)
150 if (capacity_v > amount) {
151 vec_node * new_array = new(std::nothrow) vec_node[amount];
152 if (new_array == nullptr) {
155 for (size_t i = 0; i < size_v; i++) {
156 new (&new_array[i].elem) T(std::move(array[i].elem));
157 array[i].elem.T::~T();
167 return array[size_v - 1].elem;
172 return reinterpret_cast<T *>(array);
175 const T *begin() const
177 return reinterpret_cast<const T *>(array);
182 return reinterpret_cast<T *>(array + size_v);
187 return reinterpret_cast<const T *>(array + size_v);