3 #include "../utility/assert.h"
4 #include "../utility/empty_base.h"
19 template<
typename T,
typename Alloc>
23 static_assert(std::is_default_constructible<T>::value,
"Template class needs to be default constructible");
24 static_assert(std::is_trivially_copyable<T>::value,
"Template class needs to be trivially copyable");
26 typedef std::allocator_traits<Alloc> Traits;
62 m_Begin(Traits::allocate(m_Alloc, n)),
72 explicit trivial_vector(
size_t n,
const T& value,
const Alloc& allocator = Alloc()) :
74 m_Begin(Traits::allocate(m_Alloc, n)),
78 std::uninitialized_fill_n<T*, size_t>(m_Begin, n, value);
86 trivial_vector(std::initializer_list<T> initializer,
const Alloc& allocator = Alloc()) :
88 m_Begin(Traits::allocate(m_Alloc, initializer.
size())),
89 m_End(m_Begin + initializer.
size()),
93 for (
auto value : initializer)
106 explicit trivial_vector(
const T* first,
const T* last,
const Alloc& allocator = Alloc()) :
108 m_Begin(Traits::allocate(m_Alloc, size_t(last - first))),
109 m_End(m_Begin + size_t(last - first)),
112 size_t n = last - first;
113 std::memcpy(m_Begin, first, n *
sizeof(T));
117 m_Alloc(Traits::select_on_container_copy_construction(
static_cast<Alloc
>(other.m_Alloc))),
118 m_Begin(Traits::allocate(m_Alloc, other.size())),
119 m_End(m_Begin + other.size()),
122 if (other.m_Begin !=
nullptr)
123 std::memcpy(m_Begin, other.m_Begin, other.size() *
sizeof(T));
127 m_Alloc(std::move(other.m_Alloc)),
128 m_Begin(other.m_Begin),
130 m_EndMax(other.m_EndMax)
132 other.m_Begin =
nullptr;
133 other.m_End =
nullptr;
134 other.m_EndMax =
nullptr;
139 m_Begin(Traits::allocate(m_Alloc, other.size())),
140 m_End(m_Begin + other.size()),
143 if (other.m_Begin !=
nullptr)
144 std::memcpy(m_Begin, other.m_Begin, other.size() *
sizeof(T));
149 m_Begin(Traits::allocate(m_Alloc, other.size())),
150 m_End(m_Begin + other.size()),
154 if (other.m_Begin !=
nullptr)
156 std::memcpy(m_Begin, other.m_Begin, other.size() *
sizeof(T));
158 Traits::deallocate(other.m_Alloc, other.m_Begin, other.capacity() *
sizeof(T));
161 other.m_Begin =
nullptr;
162 other.m_End =
nullptr;
163 other.m_EndMax =
nullptr;
168 if (m_Begin !=
nullptr)
169 Traits::deallocate(m_Alloc, m_Begin,
capacity());
174 if (m_Begin !=
nullptr)
175 Traits::deallocate(m_Alloc, m_Begin,
capacity());
177 m_Alloc = other.m_Alloc;
179 size_t n = other.size();
181 T* alBlock = Traits::allocate(m_Alloc, n);
185 m_EndMax = m_Begin + n;
187 std::memcpy(m_Begin, other.m_Begin, n *
sizeof(T));
193 if (m_Begin !=
nullptr)
194 Traits::deallocate(m_Alloc, m_Begin,
capacity());
196 m_Alloc = std::move(other.m_Alloc);
197 m_Begin = other.m_Begin;
199 m_EndMax = other.m_EndMax;
201 other.m_Begin =
nullptr;
202 other.m_End =
nullptr;
203 other.m_EndMax =
nullptr;
245 size_t size() const noexcept {
return m_End - m_Begin; }
251 size_t capacity() const noexcept {
return m_EndMax - m_Begin; }
257 bool empty() const noexcept {
return m_Begin == m_End; }
310 if (m_End == m_EndMax)
324 if (m_End == m_EndMax)
326 *m_End = std::move(element);
339 const size_t n = (last - first);
341 if (
size_t(m_EndMax - m_End) < n)
344 T* lastElement = m_End;
347 std::memcpy(lastElement, first, n *
sizeof(T));
358 template<
typename... Args>
361 if (m_End == m_EndMax)
363 *m_End = T(std::forward<Args>(args)...);
375 template<
typename... Args>
380 if (m_End == m_EndMax)
383 std::memmove(
const_cast<iterator>(iter + 1), iter, (m_End - iter) *
sizeof(T));
385 *iter = T(std::forward<Args>(args)...);
398 std::memmove(
const_cast<iterator>(iter), iter + 1, ((m_End - iter) - 1) *
sizeof(T));
414 KTL_ASSERT(first >= m_Begin && last <= m_End);
416 std::memmove(
const_cast<iterator>(first), last, (m_End - last) *
sizeof(T));
418 m_End -= (last - first);
432 void clear() noexcept { m_End = m_Begin; }
435 void expand(
size_t n) noexcept
438 size_t alSize = curCap + (std::max)(curCap / 2, n);
443 void set_size(
size_t n) noexcept
445 size_t curSize = (std::min)(
size(), n);
447 T* alBlock = Traits::allocate(m_Alloc, n);
449 if (m_Begin !=
nullptr)
451 std::memcpy(alBlock, m_Begin, curSize *
sizeof(T));
453 Traits::deallocate(m_Alloc, m_Begin,
capacity());
457 m_End = m_Begin + curSize;
458 m_EndMax = m_Begin + n;
#define KTL_ASSERT(x)
Definition: assert.h:17
A dynamically allocated vector or trivial types.
Definition: trivial_vector.h:21
T * iterator
Definition: trivial_vector.h:29
iterator begin() noexcept
Definition: trivial_vector.h:224
iterator data() noexcept
Returns an iterator to the start of the vector.
Definition: trivial_vector.h:264
trivial_vector(const T *first, const T *last, const Alloc &allocator=Alloc())
Construct the vector with the allocator and range of values.
Definition: trivial_vector.h:106
const T * const_iterator
Definition: trivial_vector.h:30
const_reverse_iterator rbegin() const noexcept
Definition: trivial_vector.h:234
iterator end() noexcept
Definition: trivial_vector.h:228
T & at(size_t index) const noexcept
Returns a reference to the element at index.
Definition: trivial_vector.h:278
const_reverse_iterator rend() const noexcept
Definition: trivial_vector.h:238
trivial_vector(size_t n, const T &value, const Alloc &allocator=Alloc())
Construct the vector with the given allocator, initial size and default value.
Definition: trivial_vector.h:72
trivial_vector(std::initializer_list< T > initializer, const Alloc &allocator=Alloc())
Construct the vector with the allocator and range of values.
Definition: trivial_vector.h:86
T & operator[](size_t index) noexcept
Returns a reference to the element at index.
Definition: trivial_vector.h:213
const T & operator[](size_t index) const noexcept
Returns a reference to the element at index.
Definition: trivial_vector.h:221
trivial_vector(const Alloc &allocator) noexcept
Construct the vector with the given allocator.
Definition: trivial_vector.h:49
trivial_vector(trivial_vector &&other) noexcept
Definition: trivial_vector.h:126
size_t capacity() const noexcept
Returns the current capacity of the vector.
Definition: trivial_vector.h:251
T pop_back() noexcept
Removes the last element from the vector and returns it.
Definition: trivial_vector.h:427
const_iterator begin() const noexcept
Definition: trivial_vector.h:226
trivial_vector(trivial_vector &&other, const Alloc &allocator) noexcept
Definition: trivial_vector.h:147
iterator push_back(const T *first, const T *last) noexcept
Pushes a range of values into the vector.
Definition: trivial_vector.h:337
const_iterator end() const noexcept
Definition: trivial_vector.h:230
bool empty() const noexcept
Returns true if the vector has no elements.
Definition: trivial_vector.h:257
trivial_vector & operator=(const trivial_vector &other) noexcept
Definition: trivial_vector.h:172
trivial_vector(size_t n, const Alloc &allocator=Alloc())
Construct the vector with the given allocator and initial size.
Definition: trivial_vector.h:60
trivial_vector(const trivial_vector &other, const Alloc &allocator) noexcept
Definition: trivial_vector.h:137
const_iterator data() const noexcept
Returns a const iterator to the start of the vector.
Definition: trivial_vector.h:270
iterator push_back(const T &element) noexcept
Pushes a new element into the vector by copying it.
Definition: trivial_vector.h:308
iterator emplace_back(Args &&... args) noexcept
Pushes a new element into the vector by constructing it.
Definition: trivial_vector.h:359
iterator push_back(T &&element) noexcept
Pushes a new element into the vector by moving it.
Definition: trivial_vector.h:322
size_t size() const noexcept
Returns the current size of the vector.
Definition: trivial_vector.h:245
void reserve(size_t n) noexcept
Reserves the capacity of the vector to n, without initializing any elements.
Definition: trivial_vector.h:297
std::reverse_iterator< const T * > const_reverse_iterator
Definition: trivial_vector.h:33
~trivial_vector() noexcept
Definition: trivial_vector.h:166
std::reverse_iterator< T * > reverse_iterator
Definition: trivial_vector.h:32
void clear() noexcept
Clears all elements in the vector.
Definition: trivial_vector.h:432
trivial_vector() noexcept
Construct the vector with a default constructed allocator.
Definition: trivial_vector.h:39
void resize(size_t n) noexcept
Resizes the vector to the given size.
Definition: trivial_vector.h:285
trivial_vector & operator=(trivial_vector &&other) noexcept
Definition: trivial_vector.h:191
reverse_iterator rend() noexcept
Definition: trivial_vector.h:236
iterator erase(const_iterator first, const_iterator last) noexcept
Erases all elements in a range.
Definition: trivial_vector.h:411
reverse_iterator rbegin() noexcept
Definition: trivial_vector.h:232
void emplace(const_iterator iter, Args &&... args) noexcept
Inserts a new element into the vector by constructing it.
Definition: trivial_vector.h:376
trivial_vector(const trivial_vector &other) noexcept
Definition: trivial_vector.h:116
iterator erase(const_iterator iter) noexcept
Erases the element pointed to by the iterator.
Definition: trivial_vector.h:394
#define KTL_EMPTY_BASE
Definition: empty_base.h:6
Definition: cascading.h:15