Embedded Template Library  1.0
array.h
Go to the documentation of this file.
1 
3 /******************************************************************************
4 The MIT License(MIT)
5 
6 Embedded Template Library.
7 https://github.com/ETLCPP/etl
8 https://www.etlcpp.com
9 
10 Copyright(c) 2014 jwellbelove
11 
12 Permission is hereby granted, free of charge, to any person obtaining a copy
13 of this software and associated documentation files(the "Software"), to deal
14 in the Software without restriction, including without limitation the rights
15 to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
16 copies of the Software, and to permit persons to whom the Software is
17 furnished to do so, subject to the following conditions :
18 
19 The above copyright notice and this permission notice shall be included in all
20 copies or substantial portions of the Software.
21 
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
25 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28 SOFTWARE.
29 ******************************************************************************/
30 
31 #ifndef ETL_ARRAY_INCLUDED
32 #define ETL_ARRAY_INCLUDED
33 
34 #include <stddef.h>
35 
36 #include "platform.h"
37 
38 #include "algorithm.h"
39 #include "iterator.h"
40 #include "functional.h"
41 #include "exception.h"
42 #include "type_traits.h"
43 #include "parameter_type.h"
44 #include "static_assert.h"
45 #include "error_handler.h"
46 
50 
51 namespace etl
52 {
53  //***************************************************************************
56  //***************************************************************************
57  class array_exception : public exception
58  {
59  public:
60 
61  array_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
62  : exception(reason_, file_name_, line_number_)
63  {
64  }
65  };
66 
67  //***************************************************************************
70  //***************************************************************************
72  {
73  public:
74 
75  array_out_of_range(string_type file_name_, numeric_type line_number_)
76  : array_exception("array:range", file_name_, line_number_)
77  {
78  }
79  };
80 
81  //***************************************************************************
84  //***************************************************************************
85  template <typename T, const size_t SIZE_>
86  class array
87  {
88  private:
89 
90  typedef typename etl::parameter_type<T>::type parameter_t;
91 
92  public:
93 
94  enum
95  {
96  SIZE = SIZE_
97  };
98 
99  typedef T value_type;
100  typedef size_t size_type;
101  typedef ptrdiff_t difference_type;
102  typedef T& reference;
103  typedef const T& const_reference;
104  typedef T* pointer;
105  typedef const T* const_pointer;
106  typedef T* iterator;
107  typedef const T* const_iterator;
108  typedef ETL_OR_STD::reverse_iterator<iterator> reverse_iterator;
109  typedef ETL_OR_STD::reverse_iterator<const_iterator> const_reverse_iterator;
110 
111  //*************************************************************************
112  // Element access
113  //*************************************************************************
114 
115  //*************************************************************************
118  //*************************************************************************
119  reference at(size_t i)
120  {
121  ETL_ASSERT(i < SIZE, ETL_ERROR(array_out_of_range));
122 
123  return _buffer[i];
124  }
125 
126  //*************************************************************************
129  //*************************************************************************
130  const_reference at(size_t i) const
131  {
132  ETL_ASSERT(i < SIZE, ETL_ERROR(array_out_of_range));
133 
134  return _buffer[i];
135  }
136 
137  //*************************************************************************
141  //*************************************************************************
142  reference operator[](size_t i)
143  {
144  return _buffer[i];
145  }
146 
147  //*************************************************************************
151  //*************************************************************************
152  const_reference operator[](size_t i) const
153  {
154  return _buffer[i];
155  }
156 
157  //*************************************************************************
159  //*************************************************************************
160  reference front()
161  {
162  return _buffer[0];
163  }
164 
165  //*************************************************************************
167  //*************************************************************************
168  const_reference front() const
169  {
170  return _buffer[0];
171  }
172 
173  //*************************************************************************
175  //*************************************************************************
176  reference back()
177  {
178  return _buffer[SIZE - 1];
179  }
180 
181  //*************************************************************************
183  //*************************************************************************
184  const_reference back() const
185  {
186  return _buffer[SIZE - 1];
187  }
188 
189  //*************************************************************************
191  //*************************************************************************
192  pointer data()
193  {
194  return &_buffer[0];
195  }
196 
197  //*************************************************************************
199  //*************************************************************************
200  const_pointer data() const
201  {
202  return &_buffer[0];
203  }
204 
205  //*************************************************************************
206  // Iterators
207  //*************************************************************************
208 
209  //*************************************************************************
211  //*************************************************************************
212  iterator begin()
213  {
214  return &_buffer[0];
215  }
216 
217  //*************************************************************************
219  //*************************************************************************
220  const_iterator begin() const
221  {
222  return &_buffer[0];
223  }
224 
225  //*************************************************************************
227  //*************************************************************************
228  const_iterator cbegin() const
229  {
230  return begin();
231  }
232 
233  //*************************************************************************
235  //*************************************************************************
236  iterator end()
237  {
238  return &_buffer[SIZE];
239  }
240 
241  //*************************************************************************
243  //*************************************************************************
244  const_iterator end() const
245  {
246  return &_buffer[SIZE];
247  }
248 
249  //*************************************************************************
250  // Returns a const iterator to the end of the array.
251  //*************************************************************************
252  const_iterator cend() const
253  {
254  return &_buffer[SIZE];
255  }
256 
257  //*************************************************************************
258  // Returns an reverse iterator to the reverse beginning of the array.
259  //*************************************************************************
260  reverse_iterator rbegin()
261  {
262  return reverse_iterator(end());
263  }
264 
265  //*************************************************************************
267  //*************************************************************************
268  const_reverse_iterator rbegin() const
269  {
270  return const_reverse_iterator(end());
271  }
272 
273  //*************************************************************************
275  //*************************************************************************
276  const_reverse_iterator crbegin() const
277  {
278  return const_reverse_iterator(end());
279  }
280 
281  //*************************************************************************
283  //*************************************************************************
284  reverse_iterator rend()
285  {
286  return reverse_iterator(begin());
287  }
288 
289  //*************************************************************************
291  //*************************************************************************
292  const_reverse_iterator rend() const
293  {
294  return const_reverse_iterator(begin());
295  }
296 
297  //*************************************************************************
299  //*************************************************************************
300  const_reverse_iterator crend() const
301  {
302  return const_reverse_iterator(begin());
303  }
304 
305  //*************************************************************************
306  // Capacity
307  //*************************************************************************
308 
309  //*************************************************************************
311  //*************************************************************************
312  bool empty() const
313  {
314  return (SIZE == 0);
315  }
316 
317  //*************************************************************************
319  //*************************************************************************
320  size_t size() const
321  {
322  return SIZE;
323  }
324 
325  //*************************************************************************
327  //*************************************************************************
328  size_t max_size() const
329  {
330  return SIZE;
331  }
332 
333  //*************************************************************************
334  // Operations
335  //*************************************************************************
336 
337  //*************************************************************************
340  //*************************************************************************
341  void fill(parameter_t value)
342  {
343  etl::fill(begin(), end(), value);
344  }
345 
346  //*************************************************************************
349  //*************************************************************************
350  void swap(array& other)
351  {
352  using ETL_OR_STD::swap; // Allow ADL
353 
354  for (size_t i = 0; i < SIZE; ++i)
355  {
356  swap(_buffer[i], other._buffer[i]);
357  }
358  }
359 
360  //*************************************************************************
365  //*************************************************************************
366  template <typename TIterator>
367  void assign(TIterator first, const TIterator last)
368  {
369  etl::copy_s(first, last, begin(), end());
370  }
371 
372  //*************************************************************************
377  //*************************************************************************
378  template <typename TIterator>
379  void assign(TIterator first, const TIterator last, parameter_t value)
380  {
381  // Copy from the range.
382  iterator p = etl::copy(first, last, begin());
383 
384  // Initialise any that are left.
385  etl::fill(p, end(), value);
386  }
387 
388  //*************************************************************************
392  //*************************************************************************
393  inline iterator insert_at(size_t position, parameter_t value)
394  {
395  return insert(begin() + position, value);
396  }
397 
398  //*************************************************************************
402  //*************************************************************************
403  iterator insert(const_iterator position, parameter_t value)
404  {
405  iterator p = const_cast<iterator>(position);
406 
407  etl::move_backward(p, end() - 1, end());
408  *p = value;
409 
410  return p;
411  }
412 
413  //*************************************************************************
418  //*************************************************************************
419  template <typename TIterator>
420  inline iterator insert_at(size_t position, TIterator first, const TIterator last)
421  {
422  return insert(begin() + position, first, last);
423  }
424 
425  //*************************************************************************
430  //*************************************************************************
431  template <typename TIterator>
432  iterator insert(const_iterator position, TIterator first, const TIterator last)
433  {
434  iterator p = const_cast<iterator>(position);
435  iterator result(p);
436 
437  size_t source_size = etl::distance(first, last);
438  size_t destination_space = etl::distance(position, cend());
439 
440  // Do we need to move anything?
441  if (source_size < destination_space)
442  {
443  size_t length = SIZE - (etl::distance(begin(), p) + source_size);
444  etl::move_backward(p, p + length, end());
445  }
446 
447  // Copy from the range.
448  etl::copy_s(first, last, p, end());
449 
450  return result;
451  }
452 
453  //*************************************************************************
457  //*************************************************************************
458  inline iterator erase_at(size_t position)
459  {
460  return erase(begin() + position);
461  }
462 
463  //*************************************************************************
467  //*************************************************************************
468  iterator erase(const_iterator position)
469  {
470  iterator p = const_cast<iterator>(position);
471  etl::move(p + 1, end(), p);
472 
473  return p;
474  }
475 
476  //*************************************************************************
481  //*************************************************************************
482  iterator erase_range(size_t first, size_t last)
483  {
484  return erase(begin() + first, begin() + last);
485  }
486 
487  //*************************************************************************
492  //*************************************************************************
493  iterator erase(const_iterator first, const_iterator last)
494  {
495  iterator p = const_cast<iterator>(first);
496  etl::move(last, cend(), p);
497  return p;
498  }
499 
500  //*************************************************************************
504  //*************************************************************************
505  inline iterator erase_at(size_t position, parameter_t value)
506  {
507  return erase(begin() + position, value);
508  }
509 
510  //*************************************************************************
514  //*************************************************************************
515  iterator erase(const_iterator position, parameter_t value)
516  {
517  iterator p = const_cast<iterator>(position);
518 
519  etl::move(p + 1, end(), p);
520  back() = value;
521 
522  return p;
523  }
524 
525  //*************************************************************************
530  //*************************************************************************
531  iterator erase_range(size_t first, size_t last, parameter_t value)
532  {
533  return erase(begin() + first, begin() + last, value);
534  }
535 
536  //*************************************************************************
540  //*************************************************************************
541  iterator erase(const_iterator first, const_iterator last, parameter_t value)
542  {
543  iterator p = const_cast<iterator>(first);
544 
545  p = etl::move(last, cend(), p);
546  etl::fill(p, end(), value);
547 
548  return const_cast<iterator>(first);
549  }
550 
552  T _buffer[SIZE];
553  };
554 
555  //*************************************************************************
557  //*************************************************************************
558 #if ETL_CPP17_SUPPORTED
559  template <typename T, typename... Ts>
560  array(T, Ts...)
561  -> array<etl::enable_if_t<(etl::is_same_v<T, Ts> && ...), T>, 1U + sizeof...(Ts)>;
562 #endif
563 
564  //*************************************************************************
568  //*************************************************************************
569  template <typename T, const size_t SIZE>
571  {
572  lhs.swap(rhs);
573  }
574 
575  //*************************************************************************
580  //*************************************************************************
581  template <typename T, size_t SIZE>
583  {
584  return etl::equal(lhs.cbegin(), lhs.cend(), rhs.cbegin());
585  }
586 
587  //*************************************************************************
592  //*************************************************************************
593  template <typename T, size_t SIZE>
595  {
596  return !(lhs == rhs);
597  }
598 
599  //*************************************************************************
604  //*************************************************************************
605  template <typename T, size_t SIZE>
607  {
608  return etl::lexicographical_compare(lhs.cbegin(),
609  lhs.cend(),
610  rhs.cbegin(),
611  rhs.cend());
612  }
613 
614  //*************************************************************************
619  //*************************************************************************
620  template <typename T, size_t SIZE>
622  {
623  return !(lhs > rhs);
624  }
625 
626  //*************************************************************************
631  template <typename T, size_t SIZE>
632  //*************************************************************************
634  {
635  return (rhs < lhs);
636  }
637 
638  //*************************************************************************
643  //*************************************************************************
644  template <typename T, size_t SIZE>
646  {
647  return !(lhs < rhs);
648  }
649 
650  //*************************************************************************
657  //*************************************************************************
658  template <size_t I, typename T, size_t MAXN>
659  inline T& get(array<T, MAXN>& a)
660  {
661  ETL_STATIC_ASSERT(I < MAXN, "Index out of bounds");
662  return a[I];
663  }
664 
665  //*************************************************************************
672  //*************************************************************************
673  template <size_t I, typename T, size_t MAXN>
674  inline const T& get(const array<T, MAXN>& a)
675  {
676  ETL_STATIC_ASSERT(I < MAXN, "Index out of bounds");
677  return a[I];
678  }
679 }
680 
681 #endif
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:2580
const_iterator cbegin() const
Returns a const iterator to the beginning of the array.
Definition: array.h:228
iterator erase(const_iterator first, const_iterator last)
Definition: array.h:493
void assign(TIterator first, const TIterator last)
Definition: array.h:367
const_reference front() const
Returns a const reference to the first element.
Definition: array.h:168
const_reverse_iterator rend() const
Returns a const reverse iterator to the end of the array.
Definition: array.h:292
const_reference operator[](size_t i) const
Definition: array.h:152
pointer data()
Returns a pointer to the first element of the internal buffer.
Definition: array.h:192
iterator begin()
Returns an iterator to the beginning of the array.
Definition: array.h:212
T _buffer[SIZE]
The array data.
Definition: array.h:552
reference at(size_t i)
Definition: array.h:119
void fill(parameter_t value)
Definition: array.h:341
const_reference back() const
Returns a const reference to the last element.
Definition: array.h:184
iterator erase_range(size_t first, size_t last)
Definition: array.h:482
bool empty() const
Returns true if the array size is zero.
Definition: array.h:312
const_pointer data() const
Returns a const pointer to the first element of the internal buffer.
Definition: array.h:200
const_reverse_iterator rbegin() const
Returns a const reverse iterator to the reverse beginning of the array.
Definition: array.h:268
const_iterator end() const
Returns a const iterator to the end of the array.
Definition: array.h:244
iterator insert_at(size_t position, parameter_t value)
Definition: array.h:393
iterator erase_range(size_t first, size_t last, parameter_t value)
Definition: array.h:531
size_t size() const
Returns the size of the array.
Definition: array.h:320
void assign(TIterator first, const TIterator last, parameter_t value)
Definition: array.h:379
const_reference at(size_t i) const
Definition: array.h:130
reference front()
Returns a reference to the first element.
Definition: array.h:160
iterator erase_at(size_t position)
Definition: array.h:458
iterator erase(const_iterator first, const_iterator last, parameter_t value)
Definition: array.h:541
iterator erase(const_iterator position, parameter_t value)
Definition: array.h:515
iterator end()
Returns an iterator to the end of the array.
Definition: array.h:236
const_reverse_iterator crbegin() const
Returns a const reverse iterator to the reverse beginning of the array.
Definition: array.h:276
iterator insert(const_iterator position, parameter_t value)
Definition: array.h:403
size_t max_size() const
Returns the maximum possible size of the array.
Definition: array.h:328
const_reverse_iterator crend() const
Returns a const reverse iterator to the end of the array.
Definition: array.h:300
reverse_iterator rend()
Returns a reverse iterator to the end of the array.
Definition: array.h:284
iterator insert(const_iterator position, TIterator first, const TIterator last)
Definition: array.h:432
iterator erase(const_iterator position)
Definition: array.h:468
const_iterator begin() const
Returns a const iterator to the beginning of the array.
Definition: array.h:220
iterator erase_at(size_t position, parameter_t value)
Definition: array.h:505
iterator insert_at(size_t position, TIterator first, const TIterator last)
Definition: array.h:420
reference operator[](size_t i)
Definition: array.h:142
void swap(array &other)
Definition: array.h:350
reference back()
Returns a reference to the last element.
Definition: array.h:176
Definition: array.h:87
Definition: array.h:58
Definition: array.h:72
#define ETL_ASSERT(b, e)
Definition: error_handler.h:290
exception(string_type reason_, string_type file_, numeric_type line_)
Constructor.
Definition: exception.h:67
Definition: exception.h:47
Definition: absolute.h:37
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:645
bool operator!=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:594
void swap(etl::array< T, SIZE > &lhs, etl::array< T, SIZE > &rhs)
Template deduction guides.
Definition: array.h:570
bool operator==(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:582
T & get(array< T, MAXN > &a)
Definition: array.h:659
bool operator<(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:606
bool operator<=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:621
etl::conditional< etl::is_fundamental< T >::value||etl::is_pointer< T >::value, T, const T & >::type type
By default fundamental and pointer types are passed by value.
Definition: parameter_type.h:48