Embedded Template Library 1.0
array.h
Go to the documentation of this file.
1
2
3/******************************************************************************
4The MIT License(MIT)
5
6Embedded Template Library.
7https://github.com/ETLCPP/etl
8https://www.etlcpp.com
9
10Copyright(c) 2014 John Wellbelove
11
12Permission is hereby granted, free of charge, to any person obtaining a copy
13of this software and associated documentation files(the "Software"), to deal
14in the Software without restriction, including without limitation the rights
15to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
16copies of the Software, and to permit persons to whom the Software is
17furnished to do so, subject to the following conditions :
18
19The above copyright notice and this permission notice shall be included in all
20copies or substantial portions of the Software.
21
22THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
25AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28SOFTWARE.
29******************************************************************************/
30
31#ifndef ETL_ARRAY_INCLUDED
32#define ETL_ARRAY_INCLUDED
33
34#include "platform.h"
35#include "algorithm.h"
36#include "iterator.h"
37#include "functional.h"
38#include "exception.h"
39#include "type_traits.h"
40#include "parameter_type.h"
41#include "static_assert.h"
42#include "error_handler.h"
43#include "nth_type.h"
44#include "initializer_list.h"
45
46#include <stddef.h>
47
51
52namespace etl
53{
54 //***************************************************************************
57 //***************************************************************************
59 {
60 public:
61
62 array_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
63 : exception(reason_, file_name_, line_number_)
64 {
65 }
66 };
67
68 //***************************************************************************
71 //***************************************************************************
73 {
74 public:
75
76 array_out_of_range(string_type file_name_, numeric_type line_number_)
77 : array_exception("array:range", file_name_, line_number_)
78 {
79 }
80 };
81
82 //***************************************************************************
85 //***************************************************************************
86 template <typename T, size_t SIZE_>
87 class array
88 {
89 private:
90
91 typedef typename etl::parameter_type<T>::type parameter_t;
92
93 public:
94
95 static ETL_CONSTANT size_t SIZE = SIZE_;
96
97 typedef T value_type;
98 typedef size_t size_type;
99 typedef ptrdiff_t difference_type;
100 typedef T& reference;
101 typedef const T& const_reference;
102 typedef T* pointer;
103 typedef const T* const_pointer;
104 typedef T* iterator;
105 typedef const T* const_iterator;
106 typedef ETL_OR_STD::reverse_iterator<iterator> reverse_iterator;
107 typedef ETL_OR_STD::reverse_iterator<const_iterator> const_reverse_iterator;
108
109 //*************************************************************************
110 // Element access
111 //*************************************************************************
112
113 //*************************************************************************
116 //*************************************************************************
117 ETL_NODISCARD
118 reference at(size_t i)
119 {
120 ETL_ASSERT(i < SIZE, ETL_ERROR(array_out_of_range));
121
122 return _buffer[i];
123 }
124
125 //*************************************************************************
128 //*************************************************************************
129 ETL_NODISCARD
130#if defined(ETL_THROW_EXCEPTIONS)
131 ETL_CONSTEXPR14
132#else
133 ETL_CONSTEXPR
134#endif
135 const_reference at(size_t i) const
136 {
137 ETL_ASSERT(i < SIZE, ETL_ERROR(array_out_of_range));
138
139 return _buffer[i];
140 }
141
142 //*************************************************************************
146 //*************************************************************************
147 ETL_NODISCARD
148 reference operator[](size_t i)
149 {
150 return _buffer[i];
151 }
152
153 //*************************************************************************
157 //*************************************************************************
158 ETL_NODISCARD
159 ETL_CONSTEXPR const_reference operator[](size_t i) const
160 {
161 return _buffer[i];
162 }
163
164 //*************************************************************************
166 //*************************************************************************
167 ETL_NODISCARD
168 reference front()
169 {
170 return _buffer[0];
171 }
172
173 //*************************************************************************
175 //*************************************************************************
176 ETL_NODISCARD
177 ETL_CONSTEXPR const_reference front() const
178 {
179 return _buffer[0];
180 }
181
182 //*************************************************************************
184 //*************************************************************************
185 ETL_NODISCARD
186 reference back()
187 {
188 return _buffer[SIZE - 1];
189 }
190
191 //*************************************************************************
193 //*************************************************************************
194 ETL_NODISCARD
195 ETL_CONSTEXPR const_reference back() const
196 {
197 return _buffer[SIZE - 1];
198 }
199
200 //*************************************************************************
202 //*************************************************************************
203 ETL_NODISCARD
204 pointer data() ETL_NOEXCEPT
205 {
206 return &_buffer[0];
207 }
208
209 //*************************************************************************
211 //*************************************************************************
212 ETL_NODISCARD
213 ETL_CONSTEXPR const_pointer data() const ETL_NOEXCEPT
214 {
215 return &_buffer[0];
216 }
217
218 //*************************************************************************
219 // Iterators
220 //*************************************************************************
221
222 //*************************************************************************
224 //*************************************************************************
225 ETL_NODISCARD
226 iterator begin() ETL_NOEXCEPT
227 {
228 return &_buffer[0];
229 }
230
231 //*************************************************************************
233 //*************************************************************************
234 ETL_NODISCARD
235 ETL_CONSTEXPR const_iterator begin() const ETL_NOEXCEPT
236 {
237 return &_buffer[0];
238 }
239
240 //*************************************************************************
242 //*************************************************************************
243 ETL_NODISCARD
244 ETL_CONSTEXPR const_iterator cbegin() const ETL_NOEXCEPT
245 {
246 return begin();
247 }
248
249 //*************************************************************************
251 //*************************************************************************
252 ETL_NODISCARD
253 iterator end() ETL_NOEXCEPT
254 {
255 return _buffer + SIZE;
256 }
257
258 //*************************************************************************
260 //*************************************************************************
261 ETL_NODISCARD
262 ETL_CONSTEXPR const_iterator end() const ETL_NOEXCEPT
263 {
264 return _buffer + SIZE;
265 }
266
267 //*************************************************************************
268 // Returns a const iterator to the end of the array.
269 //*************************************************************************
270 ETL_NODISCARD
271 ETL_CONSTEXPR const_iterator cend() const ETL_NOEXCEPT
272 {
273 return _buffer + SIZE;
274 }
275
276 //*************************************************************************
277 // Returns an reverse iterator to the reverse beginning of the array.
278 //*************************************************************************
279 ETL_NODISCARD
280 reverse_iterator rbegin() ETL_NOEXCEPT
281 {
282 return reverse_iterator(end());
283 }
284
285 //*************************************************************************
287 //*************************************************************************
288 ETL_NODISCARD
289 ETL_CONSTEXPR const_reverse_iterator rbegin() const ETL_NOEXCEPT
290 {
291 return const_reverse_iterator(end());
292 }
293
294 //*************************************************************************
296 //*************************************************************************
297 ETL_NODISCARD
298 ETL_CONSTEXPR const_reverse_iterator crbegin() const ETL_NOEXCEPT
299 {
300 return const_reverse_iterator(end());
301 }
302
303 //*************************************************************************
305 //*************************************************************************
306 ETL_NODISCARD
307 reverse_iterator rend() ETL_NOEXCEPT
308 {
309 return reverse_iterator(begin());
310 }
311
312 //*************************************************************************
314 //*************************************************************************
315 ETL_NODISCARD
316 ETL_CONSTEXPR const_reverse_iterator rend() const ETL_NOEXCEPT
317 {
318 return const_reverse_iterator(begin());
319 }
320
321 //*************************************************************************
323 //*************************************************************************
324 ETL_NODISCARD
325 ETL_CONSTEXPR const_reverse_iterator crend() const ETL_NOEXCEPT
326 {
327 return const_reverse_iterator(begin());
328 }
329
330 //*************************************************************************
331 // Capacity
332 //*************************************************************************
333
334 //*************************************************************************
336 //*************************************************************************
337 ETL_NODISCARD
338 ETL_CONSTEXPR bool empty() const ETL_NOEXCEPT
339 {
340 return (SIZE == 0);
341 }
342
343 //*************************************************************************
345 //*************************************************************************
346 ETL_NODISCARD
347 ETL_CONSTEXPR size_t size() const ETL_NOEXCEPT
348 {
349 return SIZE;
350 }
351
352 //*************************************************************************
354 //*************************************************************************
355 ETL_NODISCARD
356 ETL_CONSTEXPR size_t max_size() const ETL_NOEXCEPT
357 {
358 return SIZE;
359 }
360
361 //*************************************************************************
362 // Operations
363 //*************************************************************************
364
365 //*************************************************************************
368 //*************************************************************************
369 ETL_CONSTEXPR14 void fill(parameter_t value)
370 {
371 etl::fill(_buffer, _buffer + SIZE, value);
372 }
373
374 //*************************************************************************
377 //*************************************************************************
378 ETL_CONSTEXPR14 void swap(array& other) ETL_NOEXCEPT
379 {
380 using ETL_OR_STD::swap; // Allow ADL
381
382 for (size_t i = 0UL; i < SIZE; ++i)
383 {
384 swap(_buffer[i], other._buffer[i]);
385 }
386 }
387
388 //*************************************************************************
393 //*************************************************************************
394 template <typename TIterator>
395 void assign(TIterator first, const TIterator last)
396 {
397 etl::copy_s(first, last, begin(), end());
398 }
399
400 //*************************************************************************
405 //*************************************************************************
406 template <typename TIterator>
407 void assign(TIterator first, const TIterator last, parameter_t value)
408 {
409 // Copy from the range.
410 iterator p = etl::copy(first, last, begin());
411
412 // Initialise any that are left.
413 etl::fill(p, end(), value);
414 }
415
416 //*************************************************************************
420 //*************************************************************************
421 inline iterator insert_at(size_t position, parameter_t value)
422 {
423 return insert(begin() + position, value);
424 }
425
426 //*************************************************************************
430 //*************************************************************************
431 iterator insert(const_iterator position, parameter_t value)
432 {
433 iterator p = to_iterator(position);
434
435 etl::move_backward(p, end() - 1, end());
436 *p = value;
437
438 return p;
439 }
440
441 //*************************************************************************
446 //*************************************************************************
447 template <typename TIterator>
448 inline iterator insert_at(size_t position, TIterator first, const TIterator last)
449 {
450 return insert(begin() + position, first, last);
451 }
452
453 //*************************************************************************
458 //*************************************************************************
459 template <typename TIterator>
460 iterator insert(const_iterator position, TIterator first, const TIterator last)
461 {
462 iterator p = to_iterator(position);
463 iterator result(p);
464
465 size_t source_size = etl::distance(first, last);
466 size_t destination_space = etl::distance(position, cend());
467
468 // Do we need to move anything?
469 if (source_size < destination_space)
470 {
471 size_t length = SIZE - (etl::distance(begin(), p) + source_size);
472 etl::move_backward(p, p + length, end());
473 }
474
475 // Copy from the range.
476 etl::copy_s(first, last, p, end());
477
478 return result;
479 }
480
481 //*************************************************************************
485 //*************************************************************************
486 inline iterator erase_at(size_t position)
487 {
488 return erase(begin() + position);
489 }
490
491 //*************************************************************************
495 //*************************************************************************
496 iterator erase(const_iterator position)
497 {
498 iterator p = to_iterator(position);
499 etl::move(p + 1, end(), p);
500
501 return p;
502 }
503
504 //*************************************************************************
509 //*************************************************************************
510 iterator erase_range(size_t first, size_t last)
511 {
512 return erase(begin() + first, begin() + last);
513 }
514
515 //*************************************************************************
520 //*************************************************************************
521 iterator erase(const_iterator first, const_iterator last)
522 {
523 iterator p = to_iterator(first);
524 etl::move(last, cend(), p);
525 return p;
526 }
527
528 //*************************************************************************
532 //*************************************************************************
533 inline iterator erase_at(size_t position, parameter_t value)
534 {
535 return erase(begin() + position, value);
536 }
537
538 //*************************************************************************
542 //*************************************************************************
543 iterator erase(const_iterator position, parameter_t value)
544 {
545 iterator p = to_iterator(position);
546
547 etl::move(p + 1, end(), p);
548 back() = value;
549
550 return p;
551 }
552
553 //*************************************************************************
558 //*************************************************************************
559 iterator erase_range(size_t first, size_t last, parameter_t value)
560 {
561 return erase(begin() + first, begin() + last, value);
562 }
563
564 //*************************************************************************
568 //*************************************************************************
569 iterator erase(const_iterator first, const_iterator last, parameter_t value)
570 {
571 iterator p = to_iterator(first);
572
573 p = etl::move(last, cend(), p);
574 etl::fill(p, end(), value);
575
576 return to_iterator(first);
577 }
578
580 T _buffer[SIZE];
581
582 private:
583
584 //*************************************************************************
586 //*************************************************************************
587 iterator to_iterator(const_iterator itr) const
588 {
589 return const_cast<iterator>(itr);
590 }
591 };
592
593 template <typename T, size_t SIZE_>
594 ETL_CONSTANT size_t array<T, SIZE_>::SIZE;
595
596 //*************************************************************************
598 //*************************************************************************
599#if ETL_USING_CPP17
600 template <typename... T>
601 array(T...) -> array<typename etl::common_type<T...>::type, sizeof...(T)>;
602#endif
603
604 //*************************************************************************
606 //*************************************************************************
607#if ETL_HAS_INITIALIZER_LIST
608 template <typename T, typename... TValues>
609 constexpr auto make_array(TValues&&... values) -> etl::array<T, sizeof...(TValues)>
610 {
611 return { { etl::forward<T>(values)... } };
612 }
613#endif
614
615 //*************************************************************************
619 //*************************************************************************
620 template <typename T, const size_t SIZE>
622 {
623 lhs.swap(rhs);
624 }
625
626 //*************************************************************************
631 //*************************************************************************
632 template <typename T, size_t SIZE>
634 {
635 return etl::equal(lhs.cbegin(), lhs.cend(), rhs.cbegin());
636 }
637
638 //*************************************************************************
643 //*************************************************************************
644 template <typename T, size_t SIZE>
646 {
647 return !(lhs == rhs);
648 }
649
650 //*************************************************************************
655 //*************************************************************************
656 template <typename T, size_t SIZE>
658 {
659 return etl::lexicographical_compare(lhs.cbegin(),
660 lhs.cend(),
661 rhs.cbegin(),
662 rhs.cend());
663 }
664
665 //*************************************************************************
670 //*************************************************************************
671 template <typename T, size_t SIZE>
673 {
674 return !(lhs > rhs);
675 }
676
677 //*************************************************************************
682 template <typename T, size_t SIZE>
683 //*************************************************************************
685 {
686 return (rhs < lhs);
687 }
688
689 //*************************************************************************
694 //*************************************************************************
695 template <typename T, size_t SIZE>
697 {
698 return !(lhs < rhs);
699 }
700
701 //*************************************************************************
708 //*************************************************************************
709 template <size_t I, typename T, size_t MAXN>
710 inline T& get(array<T, MAXN>& a)
711 {
712 ETL_STATIC_ASSERT(I < MAXN, "Index out of bounds");
713 return a[I];
714 }
715
716 //*************************************************************************
723 //*************************************************************************
724 template <size_t I, typename T, size_t MAXN>
725 inline const T& get(const array<T, MAXN>& a)
726 {
727 ETL_STATIC_ASSERT(I < MAXN, "Index out of bounds");
728 return a[I];
729 }
730}
731
732#endif
ETL_CONSTEXPR14 etl::enable_if< etl::is_random_iterator< TInputIterator >::value &&etl::is_random_iterator< TOutputIterator >::value, TOutputIterator >::type copy_s(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin, TOutputIterator o_end)
Definition: algorithm.h:2008
ETL_NODISCARD reverse_iterator rend() ETL_NOEXCEPT
Returns a reverse iterator to the end of the array.
Definition: array.h:307
ETL_NODISCARD reference front()
Returns a reference to the first element.
Definition: array.h:168
iterator erase(const_iterator first, const_iterator last)
Definition: array.h:521
ETL_CONSTEXPR14 void swap(array &other) ETL_NOEXCEPT
Definition: array.h:378
void assign(TIterator first, const TIterator last)
Definition: array.h:395
ETL_NODISCARD ETL_CONSTEXPR const_reverse_iterator crbegin() const ETL_NOEXCEPT
Returns a const reverse iterator to the reverse beginning of the array.
Definition: array.h:298
T _buffer[SIZE]
The array data.
Definition: array.h:580
iterator erase_range(size_t first, size_t last)
Definition: array.h:510
ETL_NODISCARD reference at(size_t i)
Definition: array.h:118
ETL_CONSTEXPR14 void fill(parameter_t value)
Definition: array.h:369
ETL_NODISCARD ETL_CONSTEXPR const_reference at(size_t i) const
Definition: array.h:135
iterator insert_at(size_t position, parameter_t value)
Definition: array.h:421
iterator erase_range(size_t first, size_t last, parameter_t value)
Definition: array.h:559
void assign(TIterator first, const TIterator last, parameter_t value)
Definition: array.h:407
iterator erase_at(size_t position)
Definition: array.h:486
iterator erase(const_iterator first, const_iterator last, parameter_t value)
Definition: array.h:569
iterator erase(const_iterator position, parameter_t value)
Definition: array.h:543
ETL_NODISCARD iterator begin() ETL_NOEXCEPT
Returns an iterator to the beginning of the array.
Definition: array.h:226
iterator insert(const_iterator position, parameter_t value)
Definition: array.h:431
ETL_NODISCARD iterator end() ETL_NOEXCEPT
Returns an iterator to the end of the array.
Definition: array.h:253
ETL_NODISCARD ETL_CONSTEXPR const_reverse_iterator crend() const ETL_NOEXCEPT
Returns a const reverse iterator to the end of the array.
Definition: array.h:325
ETL_NODISCARD ETL_CONSTEXPR bool empty() const ETL_NOEXCEPT
Returns true if the array size is zero.
Definition: array.h:338
ETL_NODISCARD reference operator[](size_t i)
Definition: array.h:148
ETL_NODISCARD ETL_CONSTEXPR size_t size() const ETL_NOEXCEPT
Returns the size of the array.
Definition: array.h:347
ETL_NODISCARD pointer data() ETL_NOEXCEPT
Returns a pointer to the first element of the internal buffer.
Definition: array.h:204
iterator insert(const_iterator position, TIterator first, const TIterator last)
Definition: array.h:460
ETL_NODISCARD ETL_CONSTEXPR const_iterator cbegin() const ETL_NOEXCEPT
Returns a const iterator to the beginning of the array.
Definition: array.h:244
iterator erase(const_iterator position)
Definition: array.h:496
iterator erase_at(size_t position, parameter_t value)
Definition: array.h:533
iterator insert_at(size_t position, TIterator first, const TIterator last)
Definition: array.h:448
ETL_NODISCARD reference back()
Returns a reference to the last element.
Definition: array.h:186
ETL_NODISCARD ETL_CONSTEXPR size_t max_size() const ETL_NOEXCEPT
Returns the maximum possible size of the array.
Definition: array.h:356
Definition: array.h:88
Definition: array.h:59
Definition: array.h:73
#define ETL_ASSERT(b, e)
Definition: error_handler.h:316
ETL_CONSTEXPR exception(string_type reason_, string_type, numeric_type line_)
Constructor.
Definition: exception.h:69
Definition: exception.h:47
bitset_ext
Definition: absolute.h:38
bool operator>(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:684
T & get(array< T, MAXN > &a)
Definition: array.h:710
bool operator>=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:696
bool operator!=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:645
void swap(etl::array< T, SIZE > &lhs, etl::array< T, SIZE > &rhs)
Template deduction guides.
Definition: array.h:621
bool operator==(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:633
bool operator<(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:657
bool operator<=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:672
etl::conditional< etl::is_fundamental< T >::value||etl::is_pointer< T >::value, T, constT & >::type type
By default fundamental and pointer types are passed by value.
Definition: parameter_type.h:48