7 #include <initializer_list>
10 #include <type_traits>
14 template <
typename T, std::
size_t N>
20 template <
typename Container>
23 template <
typename T, std::
size_t N>
29 template <typename Container1, typename Container2>
30 friend auto operator+(static_vector_iterator<Container1> const&, static_vector_iterator<Container2> const&);
32 template <typename Container1>
33 friend
static_vector_iterator<Container1> operator+(static_vector_iterator<Container1> const&, std::size_t n);
35 template <typename Container1>
36 friend
static_vector_iterator<Container1> operator+(std::size_t n, static_vector_iterator<Container1> const&);
38 template <typename Container1, typename Container2>
39 friend auto operator-(static_vector_iterator<Container1> const&, static_vector_iterator<Container2> const&);
41 template <typename Container1>
42 friend
static_vector_iterator<Container1> operator-(static_vector_iterator<Container1> const&, std::size_t n);
44 template <typename Container1, typename Container2>
45 friend bool operator==(static_vector_iterator<Container1> const&, static_vector_iterator<Container2> const&);
47 template <typename Container1, typename Container2>
48 friend bool operator!=(static_vector_iterator<Container1> const&, static_vector_iterator<Container2> const&);
50 template <typename Container1, typename Container2>
51 friend bool operator>(static_vector_iterator<Container1> const&, static_vector_iterator<Container2> const&);
53 template <typename Container1, typename Container2>
54 friend bool operator<(static_vector_iterator<Container1> const&, static_vector_iterator<Container2> const&);
56 template <typename Container1, typename Container2>
57 friend bool operator>=(static_vector_iterator<Container1> const&, static_vector_iterator<Container2> const&);
59 template <typename Container1, typename Container2>
60 friend bool operator<=(static_vector_iterator<Container1> const&, static_vector_iterator<Container2> const&);
63 using container = Container;
65 using value_type = typename container::value_type;
66 using size_type = typename container::size_type;
67 using difference_type = typename container::difference_type;
68 using reference = std::conditional_t<std::is_const_v<container>, value_type const&, value_type&>;
69 using const_reference = typename container::const_reference;
70 using pointer = std::conditional_t<std::is_const_v<container>, value_type const*, value_type*>;
71 using const_pointer = typename container::const_pointer;
73 using iterator_category = std::random_access_iterator_tag;
76 static_vector_iterator()
77 : m_container(nullptr)
82 static_vector_iterator(container& c, difference_type pos)
83 : m_container(std::addressof(c))
88 template <typename Container1>
89 static_vector_iterator(static_vector_iterator<Container1> const& rhs)
90 : m_container(rhs.m_container)
91 , m_position(rhs.m_position)
95 static_vector_iterator(static_vector_iterator const&) = default;
97 static_vector_iterator(static_vector_iterator&&) = default;
99 ~static_vector_iterator() noexcept = default;
101 template <typename Container1>
102 static_vector_iterator& operator=(static_vector_iterator<Container1> const& rhs)
104 static_assert(std::is_const_v<container>);
106 m_container = rhs.m_container;
107 m_position = rhs.m_position;
111 static_vector_iterator& operator=(static_vector_iterator const&) = default;
113 static_vector_iterator& operator=(static_vector_iterator&&) = default;
115 reference operator*()
117 return *(m_container->data() + m_position);
120 const_reference operator*() const {
return *(m_container->data() + m_position); }
122 pointer operator->() {
return m_container->data() + m_position; }
124 const_pointer operator->()
const {
return m_container->data() + m_position; }
126 reference operator[](
int n) {
return *(m_container->data() + m_position + n); }
128 const_reference operator[](
int n)
const {
return *(m_container->data() + m_position + n); }
132 assert(
static_cast<std::make_unsigned_t<decltype(m_position)
>>(m_position) < m_container->size());
146 assert(
static_cast<std::make_unsigned_t<difference_type>
>(m_position) <= m_container->size());
161 assert(
static_cast<std::make_unsigned_t<difference_type>
>(m_position) < m_container->size());
168 assert(0 <= m_position);
173 container* m_container;
174 difference_type m_position;
177 template <
typename Container1,
typename Container2>
180 return lhs.m_position + rhs.m_position;
183 template <
typename Container1>
184 inline static_vector_iterator<Container1> operator+(static_vector_iterator<Container1>
const& it, std::size_t n)
186 return static_vector_iterator<Container1>(*it.m_container, it.m_position + n);
189 template <
typename Container1>
190 inline static_vector_iterator<Container1> operator+(std::size_t n, static_vector_iterator<Container1>
const& it)
192 return static_vector_iterator<Container1>(*it.m_container, n + it.m_position);
195 template <
typename Container1,
typename Container2>
196 inline auto operator-(static_vector_iterator<Container1>
const& lhs, static_vector_iterator<Container2>
const& rhs)
198 return lhs.m_position - rhs.m_position;
201 template <
typename Container1>
202 inline static_vector_iterator<Container1> operator-(static_vector_iterator<Container1>
const& it, std::size_t n)
204 return static_vector_iterator<Container1>(*it.m_container, it.m_position - n);
207 template <
typename Container1,
typename Container2>
208 inline bool operator==(static_vector_iterator<Container1>
const& lhs, static_vector_iterator<Container2>
const& rhs)
210 return lhs.m_position == rhs.m_position;
213 template <
typename Container1,
typename Container2>
214 inline bool operator!=(static_vector_iterator<Container1>
const& lhs, static_vector_iterator<Container2>
const& rhs)
216 return !(lhs == rhs);
219 template <
typename Container1,
typename Container2>
220 inline bool operator>(static_vector_iterator<Container1>
const& lhs, static_vector_iterator<Container2>
const& rhs)
225 template <
typename Container1,
typename Container2>
226 inline bool operator<(static_vector_iterator<Container1>
const& lhs, static_vector_iterator<Container2>
const& rhs)
228 return rhs.m_position - lhs.m_position > 0;
231 template <
typename Container1,
typename Container2>
232 inline bool operator>=(static_vector_iterator<Container1>
const& lhs, static_vector_iterator<Container2>
const& rhs)
237 template <
typename Container1,
typename Container2>
238 inline bool operator<=(static_vector_iterator<Container1>
const& lhs, static_vector_iterator<Container2>
const& rhs)
256 template <
typename T, std::
size_t N>
259 template <
typename T1, std::
size_t N1>
260 friend bool operator==(static_vector<T1, N1>
const& lhs, static_vector<T1, N1>
const& rhs);
262 template <
typename T1, std::
size_t N1>
263 friend bool operator!=(static_vector<T1, N1>
const& lhs, static_vector<T1, N1>
const& rhs);
265 template <
typename T1, std::
size_t N1>
266 friend bool operator<(static_vector<T1, N1>
const& lhs, static_vector<T1, N1>
const& rhs);
268 template <
typename T1, std::
size_t N1>
269 friend bool operator<=(static_vector<T1, N1>
const& lhs, static_vector<T1, N1>
const& rhs);
271 template <
typename T1, std::
size_t N1>
272 friend bool operator>(static_vector<T1, N1>
const& lhs, static_vector<T1, N1>
const& rhs);
274 template <
typename T1, std::
size_t N1>
275 friend bool operator>=(static_vector<T1, N1>
const& lhs, static_vector<T1, N1>
const& rhs);
278 using container = std::array<T, N>;
283 using value_type =
typename container::value_type;
284 using size_type =
typename container::size_type;
285 using difference_type =
typename container::difference_type;
286 using reference =
typename container::reference;
287 using const_reference =
typename container::const_reference;
288 using pointer =
typename container::pointer;
289 using const_pointer =
typename container::const_pointer;
290 using iterator = detail::static_vector_iterator<container>;
291 using const_iterator = detail::static_vector_iterator<container const>;
292 using reverse_iterator = std::reverse_iterator<iterator>;
293 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
296 static_vector() noexcept
302 static_vector(size_type count, value_type
const& value)
307 for (size_type i = 0; i < count; ++i) *(m_container.data() + i) = value;
310 explicit static_vector(size_type count)
315 for (size_type i = 0; i < count; ++i) *(m_container.data() + i) = value_type();
318 template <
typename InputIterator>
319 static_vector(InputIterator first, InputIterator last)
323 assert(std::distance(first, last) <= N);
324 for (; first != last; ++m_size) *(m_container.data() + m_size) = *first++;
327 static_vector(static_vector
const&) =
default;
329 static_vector(static_vector&&) =
default;
331 static_vector(std::initializer_list<value_type> ilist)
335 assert(ilist.size() <= N);
336 for (
auto it = ilist.begin(); it != ilist.end(); ++m_size) *(m_container.data() + m_size) = *it++;
339 ~static_vector() =
default;
341 static_vector& operator=(static_vector
const&) =
default;
343 static_vector& operator=(static_vector&&) =
default;
345 static_vector& operator=(std::initializer_list<value_type> ilist)
347 assert(ilist.size() <= N);
349 for (
auto it = ilist.begin(); it != ilist.end(); ++m_size) *(m_container.data() + m_size) = *it++;
354 void assign(size_type count, value_type
const& value)
357 for (m_size = 0; m_size < count; ++m_size) *(m_container.data() + m_size) = value;
360 template <
typename InputIterator>
361 void assign(InputIterator first, InputIterator last)
363 assert(std::distance(first, last) <= N);
364 for (m_size = 0; first != last; ++m_size) *(m_container.data() + m_size) = *first++;
367 void assign(std::initializer_list<value_type> ilist)
369 assert(ilist.size() <= N);
371 for (
auto it = ilist.begin(); it != ilist.end(); ++m_size) *(m_container.data() + m_size) = *it++;
376 reference at(size_type pos) {
return m_container.at(pos); }
378 const_reference at(size_type pos)
const {
return m_container.at(pos); }
380 reference operator[](size_type pos) {
return m_container.operator[](pos); }
382 const_reference operator[](size_type pos)
const {
return m_container.operator[](pos); }
384 reference front() {
return m_container.front(); }
386 const_reference front()
const {
return m_container.front(); }
388 reference back() {
return *(m_container.data() + m_size - 1); }
390 const_reference back()
const {
return *(m_container.data() + m_size - 1); }
392 pointer data() noexcept {
return m_container.data(); }
394 const_pointer data() const noexcept {
return m_container.data(); }
398 iterator begin() {
return iterator(m_container, 0); }
400 const_iterator begin()
const {
return const_iterator(m_container, 0); }
402 const_iterator cbegin()
const {
return const_iterator(m_container, 0); }
404 iterator end() {
return iterator(m_container, m_size); }
406 const_iterator end()
const {
return const_iterator(m_container, m_size); }
408 const_iterator cend()
const {
return const_iterator(m_container, m_size); }
410 reverse_iterator rbegin() {
return std::make_reverse_iterator(end()); }
412 const_reverse_iterator rbegin()
const {
return std::make_reverse_iterator(end()); }
414 const_reverse_iterator crbegin()
const {
return std::make_reverse_iterator(cend()); }
416 reverse_iterator rend() {
return std::make_reverse_iterator(begin()); }
418 const_reverse_iterator rend()
const {
return std::make_reverse_iterator(begin()); }
420 const_reverse_iterator crend()
const {
return std::make_reverse_iterator(cbegin()); }
424 bool empty() const noexcept {
return m_size == 0; }
426 size_type size() const noexcept {
return m_size; }
428 size_type max_size() const noexcept {
return N; }
430 size_type capacity() const noexcept {
return N; }
434 void clear() noexcept { m_size = 0; }
436 iterator insert(const_iterator pos, value_type
const& value)
440 std::copy_backward(pos, cend(), end() + 1);
441 *(m_container.data() + pos.m_position) = value;
444 return iterator(m_container, pos.m_position);
447 iterator insert(const_iterator pos, value_type&& value)
451 std::copy_backward(pos, cend(), end() + 1);
452 *(m_container.data() + pos.m_position) = std::move(value);
455 return iterator(m_container, pos.m_position);
458 iterator insert(const_iterator pos, size_type count, value_type
const& value)
460 assert(size() + count <= N);
462 std::copy_backward(pos, cend(), end() + count);
464 iterator p(m_container, pos.m_position);
465 for (const_iterator last = pos + count; p != last; ++p) *p = value;
469 return iterator(m_container, pos.m_position);
472 template <
typename InputIterator>
473 iterator insert(const_iterator pos, InputIterator first, InputIterator last)
475 size_type count = std::distance(first, last);
477 assert(size() + count <= N);
479 std::copy_backward(pos, cend(), end() + count);
481 iterator p(m_container, pos.m_position);
482 for (const_iterator last = pos + count; p != last; ++p) *p = *first++;
486 return iterator(m_container, pos.m_position);;
489 iterator insert(const_iterator pos, std::initializer_list<value_type> ilist)
491 assert(size() + ilist.size() <= N);
493 std::copy_backward(pos, cend(), end() + ilist.size());
495 iterator p(m_container, pos.m_position);
496 auto it = ilist.begin();
497 while (it != ilist.end()) *p++ = *it++;
499 m_size += ilist.size();
501 return iterator(m_container, pos.m_position);
504 iterator erase(const_iterator pos)
506 assert(pos != cend());
508 iterator p(m_container, pos.m_position);
509 std::copy(pos + 1, cend(), p);
513 return iterator(m_container, pos.m_position);
516 iterator erase(const_iterator first, const_iterator last)
518 assert(first != cend());
519 assert(first <= last);
521 std::copy(last, cend(), iterator(m_container, first.m_position));
522 m_size -= std::distance(first, last);
524 return iterator(m_container, first.m_position);
527 void push_back(value_type
const& value)
529 assert(m_size < m_container.size());
531 *(m_container.data() + m_size) = value;
535 void push_back(value_type&& value)
537 assert(m_size < m_container.size());
539 *(m_container.data() + m_size) = std::move(value);
550 void resize(size_type count)
552 resize(count, value_type());
555 void resize(size_type count, value_type
const& value)
557 assert(count <= m_container.max_size());
559 if (count < m_size) erase(const_iterator(m_container, count), cend());
560 else if(m_size < count) insert(cend(), count - m_size, value);
563 void swap(static_vector& other)
565 m_container.swap(other.m_container);
566 std::swap(m_size, other.m_size);
570 container m_container;
574 template <
typename T1, std::
size_t N1>
575 inline bool operator==(static_vector<T1, N1>
const& lhs, static_vector<T1, N1>
const& rhs)
577 return std::equal(lhs.cbegin(), lhs.cend(), rhs.cbegin(), rhs.cend());
580 template <
typename T1, std::
size_t N1>
581 inline bool operator!=(static_vector<T1, N1>
const& lhs, static_vector<T1, N1>
const& rhs)
583 return !(lhs == rhs);
586 template <
typename T1, std::
size_t N1>
587 inline bool operator<(static_vector<T1, N1>
const& lhs, static_vector<T1, N1>
const& rhs)
589 return std::lexicographical_compare(lhs.cbegin(), lhs.cend(), rhs.cbegin(), rhs.cend());
592 template <
typename T1, std::
size_t N1>
593 inline bool operator<=(static_vector<T1, N1>
const& lhs, static_vector<T1, N1>
const& rhs)
595 return lhs < rhs || lhs == rhs;
598 template <
typename T1, std::
size_t N1>
599 inline bool operator>(static_vector<T1, N1>
const& lhs, static_vector<T1, N1>
const& rhs)
601 return std::lexicographical_compare(rhs.cbegin(), rhs.cend(), lhs.cbegin(), lhs.cend());
604 template <
typename T1, std::
size_t N1>
605 inline bool operator>=(static_vector<T1, N1>
const& lhs, static_vector<T1, N1>
const& rhs)
607 return lhs > rhs || lhs == rhs;