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.
33 if (size_v == capacity_v) {
34 // double capacity now:
35 if (capacity_v == 0) capacity_v = 1;
36 vec_node * new_array = new vec_node[capacity_v * 2];
37 for (size_t i = 0; i < size_v; i++) {
38 new (&new_array[i].elem) T(std::move(array[i].elem));
39 array[i].elem.T::~T();
48 using size_type = size_t;
50 svector() : array(nullptr), size_v(0), capacity_v(0)
55 svector(const svector<T> &other)
57 capacity_v = other.size_v;
58 size_v = other.size_v;
59 array = new T[capacity_v];
60 for (size_t i = 0; i < size_v; i++) {
61 new (&array[i].elem) T(other[i].elem);
67 for (size_t i = 0; i < size_v; i++) {
68 array[i].elem.T::~T();
73 void push_back(const T &t)
76 new (&array[size_v].elem) T(t);
83 new (&array[size_v].elem) T(t);
87 template <typename ...U>
88 void emplace_back(U... args)
91 new (&array[size_v].elem) T(args...);
100 T &operator[](size_t index)
102 return array[index].elem;
105 const T &operator[](size_t index) const
107 return array[index].elem;
115 size_t capacity() const
125 static size_t max_size() noexcept
127 return std::numeric_limits<size_type>::max() / sizeof(T);
129 // if we were to support allocators:
130 //size_t max = std::allocator_traits<std::allocator<char>>::max_size(std::allocator<T>());
131 //return max / sizeof(T);
132 // (but not / sizeof(T) for C++17 apparently)
135 void reserve(size_t amount)
137 if (capacity_v < amount) {
138 vec_node * new_array = new vec_node[amount];
139 for (size_t i = 0; i < size_v; i++) {
140 new (&new_array[i].elem) T(std::move(array[i].elem));
141 array[i].elem.T::~T();
149 void shrink_to(size_t amount)
151 if (capacity_v > amount) {
152 vec_node * new_array = new(std::nothrow) vec_node[amount];
153 if (new_array == nullptr) {
156 for (size_t i = 0; i < size_v; i++) {
157 new (&new_array[i].elem) T(std::move(array[i].elem));
158 array[i].elem.T::~T();
168 return array[size_v - 1].elem;
173 return reinterpret_cast<T *>(array);
176 const T *begin() const
178 return reinterpret_cast<const T *>(array);
183 return reinterpret_cast<T *>(array + size_v);
188 return reinterpret_cast<const T *>(array + size_v);