Embedded Template Library  1.0
array_view.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) 2017 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_VIEW_INCLUDED
32 #define ETL_ARRAY_VIEW_INCLUDED
33 
34 #include "platform.h"
35 #include "memory.h"
36 #include "iterator.h"
37 #include "error_handler.h"
38 #include "exception.h"
39 #include "nullptr.h"
40 #include "hash.h"
41 #include "algorithm.h"
42 #include "memory.h"
43 #include "type_traits.h"
44 
48 
49 #undef ETL_FILE
50 #define ETL_FILE "41"
51 
52 namespace etl
53 {
54  //***************************************************************************
56  //***************************************************************************
58  {
59  public:
60 
61  array_view_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_view_bounds(string_type file_name_, numeric_type line_number_)
76  : array_view_exception(ETL_ERROR_TEXT("array_view:bounds", ETL_FILE"A"), file_name_, line_number_)
77  {
78  }
79  };
80 
81  //***************************************************************************
84  //***************************************************************************
86  {
87  public:
88 
89  array_view_uninitialised(string_type file_name_, numeric_type line_number_)
90  : array_view_exception(ETL_ERROR_TEXT("array_view:uninitialised", ETL_FILE"B"), file_name_, line_number_)
91  {
92  }
93  };
94 
95  //***************************************************************************
97  //***************************************************************************
98  template <typename T>
99  class array_view
100  {
101  public:
102 
103  typedef T value_type;
104  typedef size_t size_type;
105  typedef const T& const_reference;
106  typedef const T* const_pointer;
107  typedef const T* const_iterator;
108  typedef ETL_OR_STD::reverse_iterator<const_iterator> const_reverse_iterator;
109 
110 #if defined(ETL_ARRAY_VIEW_IS_MUTABLE)
111  typedef T* pointer;
112  typedef T& reference;
113  typedef T* iterator;
114  typedef ETL_OR_STD::reverse_iterator<iterator> reverse_iterator;
115 #else
116  typedef const_pointer pointer;
117  typedef const_reference reference;
118  typedef const_pointer iterator;
119  typedef const_reverse_iterator reverse_iterator;
120 #endif
121 
122  //*************************************************************************
124  //*************************************************************************
125  ETL_CONSTEXPR array_view()
126  : mbegin(ETL_NULLPTR),
127  mend(ETL_NULLPTR)
128  {
129  }
130 
131  //*************************************************************************
134  //*************************************************************************
135  template <typename TArray>
136  ETL_CONSTEXPR array_view(TArray& a)
137  : mbegin(a.data()),
138  mend(a.data() + a.size())
139  {
140  }
141 
142  //*************************************************************************
144  //*************************************************************************
145  template <typename TIterator>
146  ETL_CONSTEXPR array_view(const TIterator begin_, const TIterator end_)
147  : mbegin(etl::addressof(*begin_)),
148  mend(etl::addressof(*begin_) + etl::distance(begin_, end_))
149  {
150  }
151 
152  //*************************************************************************
154  //*************************************************************************
155  template <typename TIterator,
156  typename TSize>
157  ETL_CONSTEXPR array_view(const TIterator begin_, const TSize size_)
158  : mbegin(etl::addressof(*begin_)),
159  mend(etl::addressof(*begin_) + size_)
160  {
161  }
162 
163  //*************************************************************************
165  //*************************************************************************
166  template<size_t ARRAY_SIZE>
167  ETL_CONSTEXPR array_view(T(&begin_)[ARRAY_SIZE])
168  : mbegin(begin_),
169  mend(begin_ + ARRAY_SIZE)
170  {
171  }
172 
173  //*************************************************************************
175  //*************************************************************************
176  ETL_CONSTEXPR array_view(const array_view& other)
177  : mbegin(other.mbegin),
178  mend(other.mend)
179  {
180  }
181 
182  //*************************************************************************
184  //*************************************************************************
185  reference front()
186  {
187  return *mbegin;
188  }
189 
190  //*************************************************************************
192  //*************************************************************************
193  const_reference front() const
194  {
195  return *mbegin;
196  }
197 
198  //*************************************************************************
200  //*************************************************************************
201  reference back()
202  {
203  return *(mend - 1);
204  }
205 
206  //*************************************************************************
208  //*************************************************************************
209  const_reference back() const
210  {
211  return *(mend - 1);
212  }
213 
214  //*************************************************************************
216  //*************************************************************************
217  pointer data()
218  {
219  return mbegin;
220  }
221 
222  //*************************************************************************
224  //*************************************************************************
225  const_pointer data() const
226  {
227  return mbegin;
228  }
229 
230  //*************************************************************************
232  //*************************************************************************
233  iterator begin()
234  {
235  return mbegin;
236  }
237 
238  //*************************************************************************
240  //*************************************************************************
241  const_iterator begin() const
242  {
243  return mbegin;
244  }
245 
246  //*************************************************************************
248  //*************************************************************************
249  const_iterator cbegin() const
250  {
251  return mbegin;
252  }
253 
254  //*************************************************************************
256  //*************************************************************************
257  iterator end()
258  {
259  return mend;
260  }
261 
262  //*************************************************************************
264  //*************************************************************************
265  const_iterator end() const
266  {
267  return mend;
268  }
269 
270  //*************************************************************************
271  // Returns a const iterator to the end of the array.
272  //*************************************************************************
273  const_iterator cend() const
274  {
275  return mend;
276  }
277 
278  //*************************************************************************
279  // Returns an reverse iterator to the reverse beginning of the array.
280  //*************************************************************************
281  reverse_iterator rbegin()
282  {
283  return reverse_iterator(mend);
284  }
285 
286  //*************************************************************************
288  //*************************************************************************
289  const_reverse_iterator rbegin() const
290  {
291  return const_reverse_iterator(mend);
292  }
293 
294  //*************************************************************************
296  //*************************************************************************
297  const_reverse_iterator crbegin() const
298  {
299  return const_reverse_iterator(mend);
300  }
301 
302  //*************************************************************************
304  //*************************************************************************
305  reverse_iterator rend()
306  {
307  return reverse_iterator(mbegin);
308  }
309 
310  //*************************************************************************
312  //*************************************************************************
313  const_reverse_iterator rend() const
314  {
315  return const_reverse_iterator(mbegin);
316  }
317 
318  //*************************************************************************
320  //*************************************************************************
321  const_reverse_iterator crend() const
322  {
323  return const_reverse_iterator(mbegin);
324  }
325 
326  //*************************************************************************
328  //*************************************************************************
329  bool empty() const
330  {
331  return (mbegin == mend);
332  }
333 
334  //*************************************************************************
336  //*************************************************************************
337  size_t size() const
338  {
339  return (mend - mbegin);
340  }
341 
342  //*************************************************************************
344  //*************************************************************************
345  size_t max_size() const
346  {
347  return size();
348  }
349 
350  //*************************************************************************
352  //*************************************************************************
354  {
355  mbegin = other.mbegin;
356  mend = other.mend;
357  return *this;
358  }
359 
360  //*************************************************************************
362  //*************************************************************************
363  template <typename TIterator>
364  void assign(const TIterator begin_, const TIterator end_)
365  {
366  mbegin = etl::addressof(*begin_);
367  mend = etl::addressof(*begin_) + etl::distance(begin_, end_);
368  }
369 
370  //*************************************************************************
372  //*************************************************************************
373  template <typename TIterator,
374  typename TSize>
375  void assign(const TIterator begin_, const TSize size_)
376  {
377  mbegin = etl::addressof(*begin_);
378  mend = etl::addressof(*begin_) + size_;
379  }
380 
381 #if defined(ETL_ARRAY_VIEW_IS_MUTABLE)
382  //*************************************************************************
384  //*************************************************************************
385  reference operator[](const size_t i)
386  {
387  return mbegin[i];
388  }
389 #endif
390 
391  //*************************************************************************
393  //*************************************************************************
394  const_reference operator[](const size_t i) const
395  {
396  return mbegin[i];
397  }
398 
399 #if defined(ETL_ARRAY_VIEW_IS_MUTABLE)
400  //*************************************************************************
402  //*************************************************************************
403  reference at(const size_t i)
404  {
405  ETL_ASSERT((mbegin != ETL_NULLPTR && mend != ETL_NULLPTR), ETL_ERROR(array_view_uninitialised));
406  ETL_ASSERT(i < size(), ETL_ERROR(array_view_bounds));
407  return mbegin[i];
408  }
409 #endif
410 
411  //*************************************************************************
413  //*************************************************************************
414  const_reference at(const size_t i) const
415  {
416  ETL_ASSERT((mbegin != ETL_NULLPTR && mend != ETL_NULLPTR), ETL_ERROR(array_view_uninitialised));
417  ETL_ASSERT(i < size(), ETL_ERROR(array_view_bounds));
418  return mbegin[i];
419  }
420 
421  //*************************************************************************
423  //*************************************************************************
424  void swap(array_view& other)
425  {
426  using ETL_OR_STD::swap; // Allow ADL
427 
428  swap(mbegin, other.mbegin);
429  swap(mend, other.mend);
430  }
431 
432  //*************************************************************************
434  //*************************************************************************
435  void remove_prefix(const size_type n)
436  {
437  if (n < size())
438  mbegin += n;
439  else
440  mbegin = mend;
441  }
442 
443  //*************************************************************************
445  //*************************************************************************
446  void remove_suffix(const size_type n)
447  {
448  if (n < size())
449  mend -= n;
450  else
451  mend = mbegin;
452  }
453 
454  //*************************************************************************
456  //*************************************************************************
457  friend bool operator == (const array_view<T>& lhs, const array_view<T>& rhs)
458  {
459  return (lhs.size() == rhs.size()) &&
460  etl::equal(lhs.begin(), lhs.end(), rhs.begin());
461  }
462 
463  //*************************************************************************
465  //*************************************************************************
466  friend bool operator != (const array_view<T>& lhs, const array_view<T>& rhs)
467  {
468  return !(lhs == rhs);
469  }
470 
471  //*************************************************************************
473  //*************************************************************************
474  friend bool operator < (const array_view<T>& lhs, const array_view<T>& rhs)
475  {
476  return etl::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
477  }
478 
479  //*************************************************************************
481  //*************************************************************************
482  friend bool operator > (const array_view<T>& lhs, const array_view<T>& rhs)
483  {
484  return rhs < lhs;
485  }
486 
487  //*************************************************************************
489  //*************************************************************************
490  friend bool operator <= (const array_view<T>& lhs, const array_view<T>& rhs)
491  {
492  return !(lhs > rhs);
493  }
494 
495  //*************************************************************************
497  //*************************************************************************
498  friend bool operator >= (const array_view<T>& lhs, const array_view<T>& rhs)
499  {
500  return !(lhs < rhs);
501  }
502 
503  private:
504 
505  pointer mbegin;
506  pointer mend;
507  };
508 
509  //*************************************************************************
511  //*************************************************************************
512 #if ETL_CPP17_SUPPORTED
513  template <typename TArray>
514  array_view(TArray& a)
515  -> array_view<typename TArray::value_type>;
516 
517  template <typename TIterator>
518  array_view(const TIterator begin_, const TIterator end_)
519  -> array_view<etl::remove_pointer_t<TIterator>>;
520 
521  template <typename TIterator,
522  typename TSize>
523  array_view(const TIterator begin_, const TSize size_)
524  -> array_view<etl::remove_pointer_t<TIterator>>;
525 #endif
526 
527  //*************************************************************************
529  //*************************************************************************
530 #if ETL_8BIT_SUPPORT
531  template <typename T>
532  struct hash<etl::array_view<T> >
533  {
534  size_t operator()(const etl::array_view<T>& view) const
535  {
536  return etl::private_hash::generic_hash<size_t>(reinterpret_cast<const uint8_t*>(&view[0]),
537  reinterpret_cast<const uint8_t*>(&view[view.size()]));
538  }
539  };
540 #endif
541 }
542 
543 //*************************************************************************
545 //*************************************************************************
546 template <typename T>
548 {
549  lhs.swap(rhs);
550 }
551 
552 #undef ETL_FILE
553 
554 #endif
void swap(etl::array_view< T > &lhs, etl::array_view< T > &rhs)
Swaps the values.
Definition: array_view.h:547
The base class for array_view exceptions.
Definition: array_view.h:58
Array view.
Definition: array_view.h:100
iterator begin()
Returns an iterator to the beginning of the array.
Definition: array_view.h:233
const_reverse_iterator crbegin() const
Returns a const reverse iterator to the reverse beginning of the array.
Definition: array_view.h:297
friend bool operator!=(const array_view< T > &lhs, const array_view< T > &rhs)
Inequality for array views.
Definition: array_view.h:466
array_view & operator=(const array_view &other)
Assign from a view.
Definition: array_view.h:353
reference front()
Returns a reference to the first element.
Definition: array_view.h:185
const_reference back() const
Returns a const reference to the last element.
Definition: array_view.h:209
friend bool operator<=(const array_view< T > &lhs, const array_view< T > &rhs)
Less-than-equal for array views.
Definition: array_view.h:490
pointer data()
Returns a pointer to the first element of the internal storage.
Definition: array_view.h:217
iterator end()
Returns an iterator to the end of the array.
Definition: array_view.h:257
const_reverse_iterator rbegin() const
Returns a const reverse iterator to the reverse beginning of the array.
Definition: array_view.h:289
void remove_prefix(const size_type n)
Shrinks the view by moving its start forward.
Definition: array_view.h:435
void swap(array_view &other)
Swaps with another array_view.
Definition: array_view.h:424
const_reference front() const
Returns a const reference to the first element.
Definition: array_view.h:193
const_reverse_iterator rend() const
Returns a const reverse iterator to the end of the array.
Definition: array_view.h:313
const_reference at(const size_t i) const
Returns a const reference to the indexed value.
Definition: array_view.h:414
const_iterator cbegin() const
Returns a const iterator to the beginning of the array.
Definition: array_view.h:249
ETL_CONSTEXPR array_view()
Default constructor.
Definition: array_view.h:125
const_pointer data() const
Returns a const pointer to the first element of the internal storage.
Definition: array_view.h:225
size_t size() const
Returns the size of the array.
Definition: array_view.h:337
void remove_suffix(const size_type n)
Shrinks the view by moving its end backward.
Definition: array_view.h:446
friend bool operator>(const array_view< T > &lhs, const array_view< T > &rhs)
Greater-than for array views.
Definition: array_view.h:482
friend bool operator==(const array_view< T > &lhs, const array_view< T > &rhs)
Equality for array views.
Definition: array_view.h:457
bool empty() const
Returns true if the array size is zero.
Definition: array_view.h:329
const_reverse_iterator crend() const
Returns a const reverse iterator to the end of the array.
Definition: array_view.h:321
const_reference operator[](const size_t i) const
Returns a const reference to the indexed value.
Definition: array_view.h:394
friend bool operator>=(const array_view< T > &lhs, const array_view< T > &rhs)
Greater-than-equal for array views.
Definition: array_view.h:498
reverse_iterator rend()
Returns a reverse iterator to the end of the array.
Definition: array_view.h:305
const_iterator end() const
Returns a const iterator to the end of the array.
Definition: array_view.h:265
size_t max_size() const
Returns the maximum possible size of the array.
Definition: array_view.h:345
void assign(const TIterator begin_, const TIterator end_)
Assign from iterators.
Definition: array_view.h:364
void assign(const TIterator begin_, const TSize size_)
Assign from iterator and size.
Definition: array_view.h:375
const_iterator begin() const
Returns a const iterator to the beginning of the array.
Definition: array_view.h:241
friend bool operator<(const array_view< T > &lhs, const array_view< T > &rhs)
Less-than for array views.
Definition: array_view.h:474
reference back()
Returns a reference to the last element.
Definition: array_view.h:201
#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
T * addressof(T &t)
Definition: memory.h:61
Definition: array_view.h:72
Definition: array_view.h:86
Definition: absolute.h:37