59 using size_type = std::size_t;
61 using difference_type = std::ptrdiff_t;
63 using reference = value_type&;
64 using const_reference =
const value_type&;
66 using pointer = value_type*;
67 using const_pointer =
const value_type*;
69 using iterator = pointer;
70 using const_iterator = const_pointer;
72 using reverse_iterator = std::reverse_iterator<iterator>;
73 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
75 static const size_type static_capacity = Capacity;
84 static_vector() noexcept : m_size(0) {}
94 static_vector(size_type count, const_reference value)
95 noexcept(
noexcept(value_type(value)))
97 std::uninitialized_fill(begin(), end(), value);
101 static_vector(size_type count)
noexcept(
noexcept(value_type{})) : m_size(count) {
103 storage_begin(), storage_end(), [](storage_type& store) {
new (
static_cast<void*
>(&store)) value_type; });
107 static_vector(std::initializer_list<value_type> init_list) : m_size(init_list.end() - init_list.begin()) {
108 std::uninitialized_copy(init_list.begin(), init_list.end(), begin());
115 static_vector(
const static_vector& other) : m_size(other.m_size) {
116 std::uninitialized_copy(other.begin(), other.end(), begin());
120 static_vector& operator=(
const static_vector& other) {
121 if (&other ==
this)
return *
this;
123 m_size = other.m_size;
124 std::uninitialized_copy(other.begin(), other.end(), begin());
129 static_vector(static_vector&& other) : m_size(other.m_size) {
130 std::uninitialized_copy(std::make_move_iterator(other.begin()),
131 std::make_move_iterator(other.end()),
136 static_vector& operator=(static_vector&& other) {
137 if (&other ==
this)
return *
this;
139 m_size = other.m_size;
140 std::uninitialized_copy(std::make_move_iterator(other.begin()), std::make_move_iterator(other.end()), begin());
146 template <typename Iter, typename = decltype(*std::declval<Iter&>()),
typename =
decltype(++std::declval<Iter&>())>
147 static_vector(Iter input_begin, Iter input_end) {
148 m_size = std::distance(input_begin, input_end);
149 std::uninitialized_copy(input_begin, input_end, begin());
157 ~static_vector() { clear(); }
171 reference at(size_type index) {
177 const_reference at(size_type index)
const {
189 reference operator[](
size_t index)
noexcept {
return data(index); }
190 const_reference operator[](
size_t index)
const noexcept {
return data(index); }
194 reference front()
noexcept {
return data(0); }
195 const_reference front()
const noexcept {
return data(0); }
199 reference back()
noexcept {
return data(m_size - 1); }
200 const_reference back()
const noexcept {
return data(m_size - 1); }
204 pointer data()
noexcept {
return reinterpret_cast<pointer
>(&m_data[0]); }
205 const_pointer data()
const noexcept {
return reinterpret_cast<const_pointer
>(&m_data[0]); }
213 iterator begin()
noexcept {
return data(); }
214 const_iterator begin()
const noexcept {
return data(); }
215 const_iterator cbegin()
const noexcept {
return data(); }
217 iterator end()
noexcept {
return data() + m_size; }
218 const_iterator end()
const noexcept {
return data() + m_size; }
219 const_iterator cend()
const noexcept {
return data() + m_size; }
225 reverse_iterator rbegin()
noexcept {
return data() + m_size; }
226 const_reverse_iterator rbegin()
const noexcept {
return data() + m_size; }
227 const_reverse_iterator crbegin()
const noexcept {
return data() + m_size; }
229 reverse_iterator rend()
noexcept {
return data(); }
230 const_reverse_iterator rend()
const noexcept {
return data(); }
231 const_reverse_iterator crend()
const noexcept {
return data(); }
239 size_type size()
const noexcept {
return m_size; }
242 bool empty()
const noexcept {
return m_size == 0; }
245 bool full()
const noexcept {
return m_size == static_capacity; }
248 size_type capacity()
const noexcept {
return static_capacity; }
251 size_type max_size()
const noexcept {
return static_capacity; }
263 if (!std::is_trivially_destructible<value_type>::value)
264 std::for_each(begin(), end(), [](reference r) { r.~value_type(); });
272 iterator insert(const_iterator pos,
const value_type& value) {
276 iterator mut_pos =
const_cast<iterator
>(pos);
279 std::move_backward(mut_pos, end(), end() + 1);
281 new (mut_pos) value_type(value);
285 iterator insert(const_iterator pos, value_type&& value) {
289 iterator mut_pos =
const_cast<iterator
>(pos);
292 std::move_backward(mut_pos, end(), end() + 1);
294 new (mut_pos) value_type(std::move(value));
300 iterator insert(const_iterator pos, size_type count,
const value_type& value) {
301 if (m_size + count < m_size || static_capacity < m_size + count)
NNL_THROW(
RangeError(NNL_SRCTAG(
"")));
304 iterator mut_pos =
const_cast<iterator
>(pos);
307 std::move_backward(mut_pos, end(), end() + count);
309 std::for_each(storage_begin() + (mut_pos - begin()), storage_begin() + (mut_pos - begin()) + count,
310 [&](storage_type& store) {
new (&store) value_type(value); });
314 template <
typename InputIter>
315 auto insert(const_iterator pos, InputIter insert_begin, InputIter insert_end)
317 std::is_same<typename std::iterator_traits<InputIter>::reference,
decltype(*insert_begin)>::value, iterator> {
318 auto count = std::distance(insert_begin, insert_end);
319 if (count < 0 || m_size +
static_cast<size_type
>(count) < m_size ||
320 static_capacity < m_size +
static_cast<size_type
>(count)) {
325 iterator mut_pos =
const_cast<iterator
>(pos);
328 std::move_backward(mut_pos, end(), end() + count);
329 std::for_each(storage_begin() + (mut_pos - begin()), storage_begin() + (mut_pos - begin()) + count,
330 [&](storage_type& store) {
new (&store) value_type(*insert_begin++); });
339 template <
typename... CtorArgs>
340 iterator emplace(const_iterator pos, CtorArgs&&... args) {
344 iterator mut_pos =
const_cast<iterator
>(pos);
347 std::move_backward(mut_pos, end(), end() + 1);
349 new (mut_pos) value_type(std::forward<CtorArgs>(args)...);
356 iterator erase(const_iterator pos) {
357 iterator mut_pos =
const_cast<iterator
>(pos);
358 mut_pos->~value_type();
360 std::move(mut_pos + 1, end(), mut_pos);
368 void push_back(
const value_type& value) {
370 new (storage_end()) value_type(value);
373 void push_back(value_type&& value) {
375 new (storage_end()) value_type(std::move(value));
385 void resize(size_type new_size) {
386 if (new_size > static_capacity) {
390 if (new_size < m_size) {
392 if (!std::is_trivially_destructible<value_type>::value) {
393 for (size_type i = new_size; i < m_size; ++i) {
394 data(i).~value_type();
398 }
else if (new_size > m_size) {
400 std::for_each(storage_begin() + m_size, storage_begin() + new_size,
401 [](storage_type& store) {
new (
static_cast<void*
>(&store)) value_type; });
413 void resize(size_type new_size,
const value_type& value) {
414 if (new_size > static_capacity) {
418 if (new_size < m_size) {
420 if (!std::is_trivially_destructible<value_type>::value) {
421 for (size_type i = new_size; i < m_size; ++i) {
422 data(i).~value_type();
426 }
else if (new_size > m_size) {
428 std::for_each(storage_begin() + m_size, storage_begin() + new_size,
429 [&value](storage_type& store) {
new (
static_cast<void*
>(&store)) value_type(value); });
441 template <
typename... Args>
442 reference emplace_back(Args&&... args) {
446 pointer new_element =
reinterpret_cast<pointer
>(&m_data[m_size]);
447 new (new_element) value_type(std::forward<Args>(args)...);
458 using storage_type = std::aligned_storage_t<
sizeof(value_type),
alignof(value_type)>;
460 std::array<storage_type, static_capacity> m_data = {};
463 size_type m_size = 0;
467 reference data(
size_t index)
noexcept {
return *
reinterpret_cast<pointer
>(&m_data[index]); }
468 const_reference data(
size_t index)
const noexcept {
return *
reinterpret_cast<const_pointer
>(&m_data[index]); }
471 storage_type* storage_begin()
noexcept {
return &m_data[0]; }
472 storage_type* storage_end()
noexcept {
return &m_data[m_size]; }