Embedded Template Library 1.0
array_view.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) 2017 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_VIEW_INCLUDED
32#define ETL_ARRAY_VIEW_INCLUDED
33
34#include "platform.h"
35#include "memory.h"
36#include "array.h"
37#include "iterator.h"
38#include "error_handler.h"
39#include "exception.h"
40#include "nullptr.h"
41#include "hash.h"
42#include "algorithm.h"
43#include "type_traits.h"
44
45#if ETL_USING_STL && ETL_USING_CPP11
46#include <array>
47#endif
48
52
53namespace etl
54{
55 //***************************************************************************
57 //***************************************************************************
59 {
60 public:
61
62 array_view_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_view_bounds(string_type file_name_, numeric_type line_number_)
77 : array_view_exception(ETL_ERROR_TEXT("array_view:bounds", ETL_ARRAY_VIEW_FILE_ID"A"), file_name_, line_number_)
78 {
79 }
80 };
81
82 //***************************************************************************
85 //***************************************************************************
87 {
88 public:
89
90 array_view_uninitialised(string_type file_name_, numeric_type line_number_)
91 : array_view_exception(ETL_ERROR_TEXT("array_view:uninitialised", ETL_ARRAY_VIEW_FILE_ID"B"), file_name_, line_number_)
92 {
93 }
94 };
95
96 //***************************************************************************
98 //***************************************************************************
99 template <typename T>
101 {
102 public:
103
104 typedef T value_type;
105 typedef size_t size_type;
106 typedef const T& const_reference;
107 typedef const T* const_pointer;
108 typedef const T* const_iterator;
109 typedef ETL_OR_STD::reverse_iterator<const_iterator> const_reverse_iterator;
110
111#if defined(ETL_ARRAY_VIEW_IS_MUTABLE)
112 typedef T* pointer;
113 typedef T& reference;
114 typedef T* iterator;
115 typedef ETL_OR_STD::reverse_iterator<iterator> reverse_iterator;
116#else
117 typedef const_pointer pointer;
118 typedef const_reference reference;
119 typedef const_pointer iterator;
120 typedef const_reverse_iterator reverse_iterator;
121#endif
122
123 //*************************************************************************
125 //*************************************************************************
126 ETL_CONSTEXPR array_view()
127 : mbegin(ETL_NULLPTR),
128 mend(ETL_NULLPTR)
129 {
130 }
131
132#if ETL_USING_CPP11
133 //*************************************************************************
135 //*************************************************************************
136 template <typename U, size_t N, typename = typename etl::enable_if<etl::is_same<etl::remove_cv_t<T>, etl::remove_cv_t<U>>::value, void>::type>
137 ETL_CONSTEXPR array_view(etl::array<U, N>& a) ETL_NOEXCEPT
138 : mbegin(a.data())
139 , mend(a.data() + a.size())
140 {
141 }
142
143 //*************************************************************************
145 //*************************************************************************
146 template <typename U, size_t N, typename = typename etl::enable_if<etl::is_same<etl::remove_cv_t<T>, etl::remove_cv_t<U>>::value, void>::type>
147 ETL_CONSTEXPR array_view(const etl::array<U, N>& a) ETL_NOEXCEPT
148 : mbegin(a.data())
149 , mend(a.data() + a.size())
150 {
151 }
152#else
153 //*************************************************************************
155 //*************************************************************************
156 template <typename U, size_t N>
157 ETL_CONSTEXPR array_view(etl::array<U, N>& a, typename etl::enable_if<etl::is_same<typename etl::remove_cv<T>::type, typename etl::remove_cv<U>::type>::value, void>::type* = 0) ETL_NOEXCEPT
158 : mbegin(a.data())
159 , mend(a.data() + a.size())
160 {
161 }
162
163 //*************************************************************************
165 //*************************************************************************
166 template <typename U, size_t N>
167 ETL_CONSTEXPR array_view(const etl::array<U, N>& a, typename etl::enable_if<etl::is_same<typename etl::remove_cv<T>::type, typename etl::remove_cv<U>::type>::value, void>::type* = 0) ETL_NOEXCEPT
168 : mbegin(a.data())
169 , mend(a.data() + a.size())
170 {
171 }
172#endif
173
174#if ETL_USING_STL && ETL_USING_CPP11
175 //*************************************************************************
177 //*************************************************************************
178 template <typename U, size_t N, typename = typename etl::enable_if<etl::is_same<etl::remove_cv_t<T>, etl::remove_cv_t<U>>::value, void>::type>
179 ETL_CONSTEXPR array_view(std::array<U, N>& a) ETL_NOEXCEPT
180 : mbegin(a.data())
181 , mend(a.data() + a.size())
182 {
183 }
184
185 //*************************************************************************
187 //*************************************************************************
188 template <typename U, size_t N, typename = typename etl::enable_if<etl::is_same<etl::remove_cv_t<T>, etl::remove_cv_t<U>>::value, void>::type>
189 ETL_CONSTEXPR array_view(const std::array<U, N>& a) ETL_NOEXCEPT
190 : mbegin(a.data())
191 , mend(a.data() + a.size())
192 {
193 }
194#endif
195
196#if ETL_USING_CPP11
197 //*************************************************************************
200 //*************************************************************************
201 template <typename TContainer, typename = typename etl::enable_if<!etl::is_pointer<etl::remove_reference_t<TContainer>>::value &&
202 !etl::is_array<etl::remove_reference_t<TContainer>>::value &&
203 etl::is_same<etl::remove_cv_t<T>, etl::remove_cv_t<typename etl::remove_reference_t<TContainer>::value_type>>::value, void>::type>
204 ETL_CONSTEXPR array_view(TContainer&& a) ETL_NOEXCEPT
205 : mbegin(a.data())
206 , mend(a.data() + a.size())
207 {
208 }
209#else
210 //*************************************************************************
213 //*************************************************************************
214 template <typename TContainer>
215 ETL_CONSTEXPR array_view(TContainer& a, typename etl::enable_if<!etl::is_pointer<typename etl::remove_reference<TContainer>::type>::value &&
217 etl::is_same<typename etl::remove_cv<T>::type, typename etl::remove_cv<typename etl::remove_reference<TContainer>::type::value_type>::type>::value, void>::type* = 0) ETL_NOEXCEPT
218 : mbegin(a.data())
219 , mend(a.data() + a.size())
220 {
221 }
222
223 //*************************************************************************
226 //*************************************************************************
227 template <typename TContainer>
228 ETL_CONSTEXPR array_view(const TContainer& a, typename etl::enable_if<!etl::is_pointer<typename etl::remove_reference<TContainer>::type>::value &&
230 etl::is_same<typename etl::remove_cv<T>::type, typename etl::remove_cv<typename etl::remove_reference<TContainer>::type::value_type>::type>::value, void>::type* = 0) ETL_NOEXCEPT
231 : mbegin(a.data())
232 , mend(a.data() + a.size())
233 {
234 }
235#endif
236
237 //*************************************************************************
239 //*************************************************************************
240 template <typename TIterator>
241 ETL_CONSTEXPR array_view(const TIterator begin_, const TIterator end_)
242 : mbegin(etl::addressof(*begin_)),
243 mend(etl::addressof(*begin_) + etl::distance(begin_, end_))
244 {
245 }
246
247 //*************************************************************************
249 //*************************************************************************
250 template <typename TIterator,
251 typename TSize>
252 ETL_CONSTEXPR array_view(const TIterator begin_, const TSize size_)
253 : mbegin(etl::addressof(*begin_)),
254 mend(etl::addressof(*begin_) + size_)
255 {
256 }
257
258 //*************************************************************************
260 //*************************************************************************
261 template<size_t Array_Size>
262 ETL_CONSTEXPR array_view(T(&begin_)[Array_Size])
263 : mbegin(begin_),
264 mend(begin_ + Array_Size)
265 {
266 }
267
268 //*************************************************************************
270 //*************************************************************************
271 ETL_CONSTEXPR array_view(const array_view& other)
272 : mbegin(other.mbegin),
273 mend(other.mend)
274 {
275 }
276
277 //*************************************************************************
279 //*************************************************************************
280 reference front()
281 {
282 return *mbegin;
283 }
284
285 //*************************************************************************
287 //*************************************************************************
288 const_reference front() const
289 {
290 return *mbegin;
291 }
292
293 //*************************************************************************
295 //*************************************************************************
296 reference back()
297 {
298 return *(mend - 1);
299 }
300
301 //*************************************************************************
303 //*************************************************************************
304 const_reference back() const
305 {
306 return *(mend - 1);
307 }
308
309 //*************************************************************************
311 //*************************************************************************
312 pointer data()
313 {
314 return mbegin;
315 }
316
317 //*************************************************************************
319 //*************************************************************************
320 const_pointer data() const
321 {
322 return mbegin;
323 }
324
325 //*************************************************************************
327 //*************************************************************************
328 iterator begin()
329 {
330 return mbegin;
331 }
332
333 //*************************************************************************
335 //*************************************************************************
336 const_iterator begin() const
337 {
338 return mbegin;
339 }
340
341 //*************************************************************************
343 //*************************************************************************
344 const_iterator cbegin() const
345 {
346 return mbegin;
347 }
348
349 //*************************************************************************
351 //*************************************************************************
352 iterator end()
353 {
354 return mend;
355 }
356
357 //*************************************************************************
359 //*************************************************************************
360 const_iterator end() const
361 {
362 return mend;
363 }
364
365 //*************************************************************************
366 // Returns a const iterator to the end of the array.
367 //*************************************************************************
368 const_iterator cend() const
369 {
370 return mend;
371 }
372
373 //*************************************************************************
374 // Returns an reverse iterator to the reverse beginning of the array.
375 //*************************************************************************
376 reverse_iterator rbegin()
377 {
378 return reverse_iterator(mend);
379 }
380
381 //*************************************************************************
383 //*************************************************************************
384 const_reverse_iterator rbegin() const
385 {
386 return const_reverse_iterator(mend);
387 }
388
389 //*************************************************************************
391 //*************************************************************************
392 const_reverse_iterator crbegin() const
393 {
394 return const_reverse_iterator(mend);
395 }
396
397 //*************************************************************************
399 //*************************************************************************
400 reverse_iterator rend()
401 {
402 return reverse_iterator(mbegin);
403 }
404
405 //*************************************************************************
407 //*************************************************************************
408 const_reverse_iterator rend() const
409 {
410 return const_reverse_iterator(mbegin);
411 }
412
413 //*************************************************************************
415 //*************************************************************************
416 const_reverse_iterator crend() const
417 {
418 return const_reverse_iterator(mbegin);
419 }
420
421 //*************************************************************************
423 //*************************************************************************
424 bool empty() const
425 {
426 return (mbegin == mend);
427 }
428
429 //*************************************************************************
431 //*************************************************************************
432 size_t size() const
433 {
434 return (mend - mbegin);
435 }
436
437 //*************************************************************************
439 //*************************************************************************
440 size_t max_size() const
441 {
442 return size();
443 }
444
445 //*************************************************************************
447 //*************************************************************************
449 {
450 mbegin = other.mbegin;
451 mend = other.mend;
452 return *this;
453 }
454
455 //*************************************************************************
457 //*************************************************************************
458 template <typename TIterator>
459 void assign(const TIterator begin_, const TIterator end_)
460 {
461 mbegin = etl::addressof(*begin_);
462 mend = etl::addressof(*begin_) + etl::distance(begin_, end_);
463 }
464
465 //*************************************************************************
467 //*************************************************************************
468 template <typename TIterator,
469 typename TSize>
470 void assign(const TIterator begin_, const TSize size_)
471 {
472 mbegin = etl::addressof(*begin_);
473 mend = etl::addressof(*begin_) + size_;
474 }
475
476#if defined(ETL_ARRAY_VIEW_IS_MUTABLE)
477 //*************************************************************************
479 //*************************************************************************
480 reference operator[](const size_t i)
481 {
482 return mbegin[i];
483 }
484#endif
485
486 //*************************************************************************
488 //*************************************************************************
489 const_reference operator[](const size_t i) const
490 {
491 return mbegin[i];
492 }
493
494#if defined(ETL_ARRAY_VIEW_IS_MUTABLE)
495 //*************************************************************************
497 //*************************************************************************
498 reference at(const size_t i)
499 {
500 ETL_ASSERT((mbegin != ETL_NULLPTR && mend != ETL_NULLPTR), ETL_ERROR(array_view_uninitialised));
501 ETL_ASSERT(i < size(), ETL_ERROR(array_view_bounds));
502 return mbegin[i];
503 }
504#endif
505
506 //*************************************************************************
508 //*************************************************************************
509 const_reference at(const size_t i) const
510 {
511 ETL_ASSERT((mbegin != ETL_NULLPTR && mend != ETL_NULLPTR), ETL_ERROR(array_view_uninitialised));
512 ETL_ASSERT(i < size(), ETL_ERROR(array_view_bounds));
513 return mbegin[i];
514 }
515
516 //*************************************************************************
518 //*************************************************************************
519 void swap(array_view& other)
520 {
521 using ETL_OR_STD::swap; // Allow ADL
522
523 swap(mbegin, other.mbegin);
524 swap(mend, other.mend);
525 }
526
527 //*************************************************************************
529 //*************************************************************************
530 void remove_prefix(const size_type n)
531 {
532 if (n < size())
533 mbegin += n;
534 else
535 mbegin = mend;
536 }
537
538 //*************************************************************************
540 //*************************************************************************
541 void remove_suffix(const size_type n)
542 {
543 if (n < size())
544 mend -= n;
545 else
546 mend = mbegin;
547 }
548
549 //*************************************************************************
551 //*************************************************************************
552 void fill(const T& value)
553 {
554 etl::fill(begin(), end(), value);
555 }
556
557 //*************************************************************************
559 //*************************************************************************
560 friend bool operator == (const array_view<T>& lhs, const array_view<T>& rhs)
561 {
562 return (lhs.size() == rhs.size()) &&
563 etl::equal(lhs.begin(), lhs.end(), rhs.begin());
564 }
565
566 //*************************************************************************
568 //*************************************************************************
569 friend bool operator != (const array_view<T>& lhs, const array_view<T>& rhs)
570 {
571 return !(lhs == rhs);
572 }
573
574 //*************************************************************************
576 //*************************************************************************
577 friend bool operator < (const array_view<T>& lhs, const array_view<T>& rhs)
578 {
579 return etl::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
580 }
581
582 //*************************************************************************
584 //*************************************************************************
585 friend bool operator > (const array_view<T>& lhs, const array_view<T>& rhs)
586 {
587 return rhs < lhs;
588 }
589
590 //*************************************************************************
592 //*************************************************************************
593 friend bool operator <= (const array_view<T>& lhs, const array_view<T>& rhs)
594 {
595 return !(lhs > rhs);
596 }
597
598 //*************************************************************************
600 //*************************************************************************
601 friend bool operator >= (const array_view<T>& lhs, const array_view<T>& rhs)
602 {
603 return !(lhs < rhs);
604 }
605
606 private:
607
608 pointer mbegin;
609 pointer mend;
610 };
611
612 //*************************************************************************
614 //*************************************************************************
615#if ETL_USING_CPP17
616 template <typename TArray>
617 array_view(TArray& a)
618 -> array_view<typename TArray::value_type>;
619
620 template <typename TIterator>
621 array_view(const TIterator begin_, const TIterator end_)
622 -> array_view<etl::remove_pointer_t<TIterator>>;
623
624 template <typename TIterator,
625 typename TSize>
626 array_view(const TIterator begin_, const TSize size_)
627 -> array_view<etl::remove_pointer_t<TIterator>>;
628#endif
629
630 //*************************************************************************
632 //*************************************************************************
633#if ETL_USING_8BIT_TYPES
634 template <typename T>
635 struct hash<etl::array_view<T> >
636 {
637 size_t operator()(const etl::array_view<T>& view) const
638 {
639 return etl::private_hash::generic_hash<size_t>(reinterpret_cast<const uint8_t*>(view.data()),
640 reinterpret_cast<const uint8_t*>(view.data() + view.size()));
641 }
642 };
643#endif
644}
645
646//*************************************************************************
648//*************************************************************************
649template <typename T>
651{
652 lhs.swap(rhs);
653}
654
655#endif
void swap(etl::array_view< T > &lhs, etl::array_view< T > &rhs)
Swaps the values.
Definition: array_view.h:650
The base class for array_view exceptions.
Definition: array_view.h:59
Array view.
Definition: array_view.h:101
iterator begin()
Returns an iterator to the beginning of the array.
Definition: array_view.h:328
const_reverse_iterator crbegin() const
Returns a const reverse iterator to the reverse beginning of the array.
Definition: array_view.h:392
friend bool operator!=(const array_view< T > &lhs, const array_view< T > &rhs)
Inequality for array views.
Definition: array_view.h:569
array_view & operator=(const array_view &other)
Assign from a view.
Definition: array_view.h:448
reference front()
Returns a reference to the first element.
Definition: array_view.h:280
const_reference back() const
Returns a const reference to the last element.
Definition: array_view.h:304
friend bool operator<=(const array_view< T > &lhs, const array_view< T > &rhs)
Less-than-equal for array views.
Definition: array_view.h:593
pointer data()
Returns a pointer to the first element of the internal storage.
Definition: array_view.h:312
iterator end()
Returns an iterator to the end of the array.
Definition: array_view.h:352
const_reverse_iterator rbegin() const
Returns a const reverse iterator to the reverse beginning of the array.
Definition: array_view.h:384
void remove_prefix(const size_type n)
Shrinks the view by moving its start forward.
Definition: array_view.h:530
void swap(array_view &other)
Swaps with another array_view.
Definition: array_view.h:519
const_reference front() const
Returns a const reference to the first element.
Definition: array_view.h:288
const_reverse_iterator rend() const
Returns a const reverse iterator to the end of the array.
Definition: array_view.h:408
const_reference at(const size_t i) const
Returns a const reference to the indexed value.
Definition: array_view.h:509
const_iterator cbegin() const
Returns a const iterator to the beginning of the array.
Definition: array_view.h:344
ETL_CONSTEXPR array_view()
Default constructor.
Definition: array_view.h:126
void fill(const T &value)
Fills the array.
Definition: array_view.h:552
const_pointer data() const
Returns a const pointer to the first element of the internal storage.
Definition: array_view.h:320
size_t size() const
Returns the size of the array.
Definition: array_view.h:432
void remove_suffix(const size_type n)
Shrinks the view by moving its end backward.
Definition: array_view.h:541
friend bool operator>(const array_view< T > &lhs, const array_view< T > &rhs)
Greater-than for array views.
Definition: array_view.h:585
friend bool operator==(const array_view< T > &lhs, const array_view< T > &rhs)
Equality for array views.
Definition: array_view.h:560
bool empty() const
Returns true if the array size is zero.
Definition: array_view.h:424
const_reverse_iterator crend() const
Returns a const reverse iterator to the end of the array.
Definition: array_view.h:416
const_reference operator[](const size_t i) const
Returns a const reference to the indexed value.
Definition: array_view.h:489
friend bool operator>=(const array_view< T > &lhs, const array_view< T > &rhs)
Greater-than-equal for array views.
Definition: array_view.h:601
reverse_iterator rend()
Returns a reverse iterator to the end of the array.
Definition: array_view.h:400
const_iterator end() const
Returns a const iterator to the end of the array.
Definition: array_view.h:360
size_t max_size() const
Returns the maximum possible size of the array.
Definition: array_view.h:440
void assign(const TIterator begin_, const TIterator end_)
Assign from iterators.
Definition: array_view.h:459
void assign(const TIterator begin_, const TSize size_)
Assign from iterator and size.
Definition: array_view.h:470
const_iterator begin() const
Returns a const iterator to the beginning of the array.
Definition: array_view.h:336
friend bool operator<(const array_view< T > &lhs, const array_view< T > &rhs)
Less-than for array views.
Definition: array_view.h:577
reference back()
Returns a reference to the last element.
Definition: array_view.h:296
Definition: array.h:88
#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
ETL_CONSTEXPR17 T * addressof(T &t)
Definition: addressof.h:51
Definition: array_view.h:73
Definition: array_view.h:87
enable_if
Definition: type_traits_generator.h:1191
is_array
Definition: type_traits_generator.h:1091
is_pointer
Definition: type_traits_generator.h:1101
is_same
Definition: type_traits_generator.h:1041
remove_cv
Definition: type_traits_generator.h:968
remove_reference
Definition: type_traits_generator.h:878
bitset_ext
Definition: absolute.h:38