1.10
fixedvector.h
1/*
2 * Copyright (C) 2018 Microchip Technology Inc. All rights reserved.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6#ifndef EGT_FIXEDVECTOR_H
7#define EGT_FIXEDVECTOR_H
8
14#include <array>
15#include <cassert>
16#include <cstddef>
17#include <egt/detail/meta.h>
18#include <initializer_list>
19#include <iterator>
20#include <stdexcept>
21#include <utility>
22
23namespace egt
24{
25inline namespace v1
26{
27namespace detail
28{
29
30template <class BinaryPredicate, class InputIterator1, class InputIterator2>
31constexpr bool cmp(InputIterator1 first1, InputIterator1 last1,
32 InputIterator2 first2, InputIterator2 last2,
33 BinaryPredicate pred)
34{
35 for (; first1 != last1 && first2 != last2; ++first1, ++first2)
36 {
37 if (!pred(*first1, *first2))
38 {
39 return false;
40 }
41 }
42 return first1 == last1 && first2 == last2;
43}
44
45template <typename InputIt, typename OutputIt>
46constexpr OutputIt move(InputIt b, InputIt e, OutputIt to)
47{
48 for (; b != e; ++b, (void)++to)
49 {
50 *to = std::move(*b);
51 }
52 return to;
53}
54
55}
56
64template <typename T, std::size_t Capacity = 5>
66{
67public:
68 using value_type = T;
69 using difference_type = std::ptrdiff_t;
72 using pointer = T*;
73 using const_pointer = T const*;
74 using iterator = T*;
75 using const_iterator = T const*;
76 using size_type = size_t;
77 using reverse_iterator = ::std::reverse_iterator<iterator>;
78 using const_reverse_iterator = ::std::reverse_iterator<const_iterator>;
79
80 template<typename I>
81 constexpr FixedVector(I begin, const I& end) noexcept
82 {
83 while (begin != end)
84 {
86 ++begin;
87 }
88 }
89
90 constexpr FixedVector(size_type count, const T& value) noexcept
91 {
92 while (count)
93 {
94 push_back(value);
95 --count;
96 }
97 }
98
99 constexpr FixedVector(std::initializer_list<T> init) noexcept
100 : FixedVector(init.begin(), init.end())
101 {}
102
103 constexpr FixedVector() = default;
104
105 constexpr iterator begin() noexcept
106 {
107 return m_data.begin();
108 }
109
110 constexpr const_iterator begin() const noexcept
111 {
112 return m_data.begin();
113 }
114
115 constexpr iterator end() noexcept
116 {
117 return m_data.begin() + size();
118 }
119
120 constexpr const_iterator end() const noexcept
121 {
122 return m_data.begin() + size();
123 }
124
126 {
127 return reverse_iterator(end());
128 }
129
131 {
132 return const_reverse_iterator(end());
133 }
134
136 {
137 return reverse_iterator(begin());
138 }
139
141 {
143 }
144
145 constexpr const_iterator cbegin() noexcept
146 {
147 return begin();
148 }
149
150 constexpr const_iterator cbegin() const noexcept
151 {
152 return begin();
153 }
154
155 constexpr const_iterator cend() noexcept
156 {
157 return end();
158 }
159
160 constexpr const_iterator cend() const noexcept
161 {
162 return end();
163 }
164
165 constexpr auto capacity() const noexcept { return Capacity; }
166 constexpr auto size() const noexcept { return m_size; }
167 constexpr auto empty() const noexcept { return m_size == 0; }
168 constexpr void clear() noexcept { m_size = 0; }
169
170 constexpr const T* data() const
171 {
172 return m_data.data();
173 }
174
175 constexpr reference operator[](size_type pos) noexcept
176 {
177 return m_data[pos];
178 }
179
180 constexpr const_reference operator[](size_type pos) const noexcept
181 {
182 return m_data[pos];
183 }
184
185 constexpr reference at(size_type pos)
186 {
187 if (pos >= size())
188 throw std::out_of_range("FixedVector::at");
189
190 return m_data[pos];
191 }
192
193 constexpr const_reference at(size_type pos) const
194 {
195 if (pos >= size())
196 throw std::out_of_range("FixedVector::at");
197
198 return m_data[pos];
199 }
200
201 constexpr reference front() noexcept
202 {
203 assert(size() > 0);
204 return m_data[0];
205 }
206 constexpr const_reference front() const noexcept
207 {
208 assert(size() > 0);
209 return m_data[0];
210 }
211
212 constexpr reference back() noexcept
213 {
214 assert(size() > 0);
215 return m_data[size() - 1];
216 }
217 constexpr const_reference back() const noexcept
218 {
219 assert(size() > 0);
220 return m_data[size() - 1];
221 }
222
223 template <typename U>
224 constexpr void push_back(U&& value) noexcept
225 {
226 assert(!full() && "FixedVector is full!");
227 emplace_back(std::forward<U>(value));
228 }
229
231 void push_back() noexcept
232 {
233 assert(!full() && "FixedVector is full!");
234 emplace_back(T{});
235 }
236
237 template <typename... Args>
238 void emplace_back(Args&& ... args) noexcept
239 {
240 assert(!full() && "tried to emplace_back on full storage");
241 new (end()) T(std::forward<Args>(args)...);
242 ++m_size;
243 }
244
245 constexpr void swap(FixedVector& other) noexcept
246 {
247 FixedVector tmp = std::move(other);
248 other = std::move(*this);
249 (*this) = std::move(tmp);
250 }
251
252 constexpr iterator erase(const_iterator position) noexcept
253 {
254 return erase(position, position + 1);
255 }
256
258 const_iterator last) noexcept
259 {
260 iterator p = begin() + (first - begin());
261 if (first != last)
262 {
263 destroy(detail::move(p + (last - first), end(), p), end());
264 m_size = size() - static_cast<size_type>(last - first);
265 }
266
267 return p;
268 }
269
270private:
271
272 constexpr bool full() const
273 {
274 return size() >= capacity();
275 }
276
277 template <typename InputIt>
278 void destroy(InputIt first, InputIt last) noexcept
279 {
280 assert(first >= data() && first <= end()
281 && "first is out-of-bounds");
282 assert(last >= data() && last <= end()
283 && "last is out-of-bounds");
284 for (; first != last; ++first)
285 {
286 first->~T();
287 }
288 }
289
290 using Storage = std::array<T, Capacity>;
291
292 Storage m_data{};
293 std::size_t m_size{0};
294};
295
296template <typename T, size_t Capacity>
297constexpr bool operator==(FixedVector<T, Capacity> const& a,
298 FixedVector<T, Capacity> const& b) noexcept
299{
300 return a.size() == b.size()
301 and detail::cmp(a.begin(), a.end(), b.begin(), b.end(),
302 std::equal_to<> {});
303}
304
305template <typename T, size_t Capacity>
306constexpr bool operator<(FixedVector<T, Capacity> const& a,
307 FixedVector<T, Capacity> const& b) noexcept
308{
309 return detail::cmp(a.begin(), a.end(), b.begin(), b.end(),
310 std::less<> {});
311}
312
313template <typename T, size_t Capacity>
314constexpr bool operator!=(FixedVector<T, Capacity> const& a,
315 FixedVector<T, Capacity> const& b) noexcept
316{
317 return !(a == b);
318}
319
320template <typename T, size_t Capacity>
321constexpr bool operator<=(FixedVector<T, Capacity> const& a,
322 FixedVector<T, Capacity> const& b) noexcept
323{
324 return detail::cmp(a.begin(), a.end(), b.begin(), b.end(),
325 std::less_equal<> {});
326}
327
328template <typename T, size_t Capacity>
329constexpr bool operator>(FixedVector<T, Capacity> const& a,
330 FixedVector<T, Capacity> const& b) noexcept
331{
332 return detail::cmp(a.begin(), a.end(), b.begin(), b.end(),
333 std::greater<> {});
334}
335
336template <typename T, size_t Capacity>
337constexpr bool operator>=(FixedVector<T, Capacity> const& a,
338 FixedVector<T, Capacity> const& b) noexcept
339{
340 return detail::cmp(a.begin(), a.end(), b.begin(), b.end(),
341 std::greater_equal<> {});
342}
343
344}
345}
346
347#endif
constexpr vector that tries to behave like, or have an API like, std::vector.
Definition fixedvector.h:66
constexpr auto capacity() const noexcept
Definition fixedvector.h:165
constexpr const_iterator begin() const noexcept
Definition fixedvector.h:110
constexpr const_reference front() const noexcept
Definition fixedvector.h:206
void emplace_back(Args &&... args) noexcept
Definition fixedvector.h:238
constexpr FixedVector(std::initializer_list< T > init) noexcept
Definition fixedvector.h:99
constexpr reference at(size_type pos)
Definition fixedvector.h:185
constexpr const_iterator end() const noexcept
Definition fixedvector.h:120
constexpr FixedVector(I begin, const I &end) noexcept
Definition fixedvector.h:81
constexpr FixedVector()=default
constexpr void push_back(U &&value) noexcept
Definition fixedvector.h:224
constexpr const T * data() const
Definition fixedvector.h:170
value_type const & const_reference
Definition fixedvector.h:71
T * iterator
Definition fixedvector.h:74
constexpr auto size() const noexcept
Definition fixedvector.h:166
constexpr reference operator[](size_type pos) noexcept
Definition fixedvector.h:175
T const * const_iterator
Definition fixedvector.h:75
::std::reverse_iterator< const_iterator > const_reverse_iterator
Definition fixedvector.h:78
value_type & reference
Definition fixedvector.h:70
size_t size_type
Definition fixedvector.h:76
constexpr const_iterator cbegin() const noexcept
Definition fixedvector.h:150
constexpr FixedVector(size_type count, const T &value) noexcept
Definition fixedvector.h:90
constexpr reference back() noexcept
Definition fixedvector.h:212
constexpr iterator begin() noexcept
Definition fixedvector.h:105
constexpr void clear() noexcept
Definition fixedvector.h:168
constexpr const_iterator cend() const noexcept
Definition fixedvector.h:160
constexpr reference front() noexcept
Definition fixedvector.h:201
constexpr iterator erase(const_iterator first, const_iterator last) noexcept
Definition fixedvector.h:257
constexpr const_reference back() const noexcept
Definition fixedvector.h:217
constexpr const_iterator cend() noexcept
Definition fixedvector.h:155
constexpr iterator end() noexcept
Definition fixedvector.h:115
T * pointer
Definition fixedvector.h:72
constexpr const_reference operator[](size_type pos) const noexcept
Definition fixedvector.h:180
constexpr auto empty() const noexcept
Definition fixedvector.h:167
const_reverse_iterator rend() const noexcept
Definition fixedvector.h:140
reverse_iterator rbegin() noexcept
Definition fixedvector.h:125
std::ptrdiff_t difference_type
Definition fixedvector.h:69
reverse_iterator rend() noexcept
Definition fixedvector.h:135
::std::reverse_iterator< iterator > reverse_iterator
Definition fixedvector.h:77
T const * const_pointer
Definition fixedvector.h:73
constexpr iterator erase(const_iterator position) noexcept
Definition fixedvector.h:252
constexpr void swap(FixedVector &other) noexcept
Definition fixedvector.h:245
constexpr const_iterator cbegin() noexcept
Definition fixedvector.h:145
T value_type
Definition fixedvector.h:68
constexpr const_reference at(size_type pos) const
Definition fixedvector.h:193
void push_back() noexcept
Appends a default constructed T at the end of the FixedVector.
Definition fixedvector.h:231
const_reverse_iterator rbegin() const noexcept
Definition fixedvector.h:130
constexpr bool cmp(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, BinaryPredicate pred)
Definition fixedvector.h:31
constexpr OutputIt move(InputIt b, InputIt e, OutputIt to)
Definition fixedvector.h:46
constexpr bool operator!=(const Color &lhs, const Color &rhs)
Color operator.
Definition color.h:509
constexpr bool operator>(FixedVector< T, Capacity > const &a, FixedVector< T, Capacity > const &b) noexcept
Definition fixedvector.h:329
constexpr bool operator==(const Color &lhs, const Color &rhs)
Color operator.
Definition color.h:500
constexpr bool operator<=(FixedVector< T, Capacity > const &a, FixedVector< T, Capacity > const &b) noexcept
Definition fixedvector.h:321
constexpr bool operator<(FixedVector< T, Capacity > const &a, FixedVector< T, Capacity > const &b) noexcept
Definition fixedvector.h:306
constexpr bool operator>=(FixedVector< T, Capacity > const &a, FixedVector< T, Capacity > const &b) noexcept
Definition fixedvector.h:337
EGT framework namespace.
Definition animation.h:24