Embedded Template Library 1.0
span.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) 2020 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_SPAN_INCLUDED
32#define ETL_SPAN_INCLUDED
33
34#include "platform.h"
35#include "iterator.h"
36#include "algorithm.h"
37#include "circular_iterator.h"
38#include "nullptr.h"
39#include "hash.h"
40#include "type_traits.h"
41#include "integral_limits.h"
42#include "memory.h"
43#include "array.h"
44#include "byte.h"
45
47
48#if ETL_USING_STL && ETL_USING_CPP11
49 #include <array>
50#endif
51
54
55namespace etl
56{
57 //***************************************************************************
59 //***************************************************************************
60 template <typename T, size_t Extent = etl::dynamic_extent>
61 class span
62 {
63 public:
64
65 typedef T element_type;
66 typedef typename etl::remove_cv<T>::type value_type;
67 typedef size_t size_type;
68 typedef T& reference;
69 typedef const T& const_reference;
70 typedef T* pointer;
71 typedef const T* const_pointer;
72
73 typedef T* iterator;
74 typedef ETL_OR_STD::reverse_iterator<iterator> reverse_iterator;
75
76 typedef etl::circular_iterator<pointer> circular_iterator;
77 typedef etl::circular_iterator<ETL_OR_STD::reverse_iterator<pointer> > reverse_circular_iterator;
78
79 static ETL_CONSTANT size_t extent = Extent;
80
81 //*************************************************************************
83 //*************************************************************************
84 ETL_CONSTEXPR span() ETL_NOEXCEPT
85 : pbegin(ETL_NULLPTR)
86 {
87 }
88
89 //*************************************************************************
91 //*************************************************************************
92 template <typename TIterator, typename TSize>
93 ETL_CONSTEXPR explicit span(const TIterator begin_, const TSize /*size_*/) ETL_NOEXCEPT
94 : pbegin(etl::addressof(*begin_))
95 {
96 }
97
98 //*************************************************************************
100 //*************************************************************************
101 template <typename TIterator>
102 ETL_CONSTEXPR explicit span(const TIterator begin_, const TIterator /*end_*/)
103 : pbegin(etl::addressof(*begin_))
104 {
105 }
106
107 //*************************************************************************
109 //*************************************************************************
110 template<size_t Array_Size>
111 ETL_CONSTEXPR span(element_type(&begin_)[Array_Size]) ETL_NOEXCEPT
112 : pbegin(begin_)
113 {
114 }
115
116#if ETL_USING_CPP11
117 //*************************************************************************
119 //*************************************************************************
120 template <typename U, size_t N, typename = typename etl::enable_if<(N == Extent) && etl::is_same<etl::remove_cv_t<T>, etl::remove_cv_t<U>>::value, void>::type>
121 ETL_CONSTEXPR span(etl::array<U, N>& a) ETL_NOEXCEPT
122 : pbegin(a.data())
123 {
124 }
125
126 //*************************************************************************
128 //*************************************************************************
129 template <typename U, size_t N, typename = typename etl::enable_if<(N == Extent) && etl::is_same<etl::remove_cv_t<T>, etl::remove_cv_t<U>>::value, void>::type>
130 ETL_CONSTEXPR span(const etl::array<U, N>& a) ETL_NOEXCEPT
131 : pbegin(a.data())
132 {
133 }
134#else
135 //*************************************************************************
137 //*************************************************************************
138 template <typename U, size_t N>
139 ETL_CONSTEXPR span(etl::array<U, N>& a, typename etl::enable_if<(N == Extent) && etl::is_same<typename etl::remove_cv<T>::type, typename etl::remove_cv<U>::type>::value, void>::type* = 0) ETL_NOEXCEPT
140 : pbegin(a.data())
141 {
142 }
143
144 //*************************************************************************
146 //*************************************************************************
147 template <typename U, size_t N>
148 ETL_CONSTEXPR span(const etl::array<U, N>& a, typename etl::enable_if<(N == Extent) && etl::is_same<typename etl::remove_cv<T>::type, typename etl::remove_cv<U>::type>::value, void>::type* = 0) ETL_NOEXCEPT
149 : pbegin(a.data())
150 {
151 }
152#endif
153
154#if ETL_USING_STL && ETL_USING_CPP11
155 //*************************************************************************
157 //*************************************************************************
158 template <typename U, size_t N, typename = typename etl::enable_if<(N == Extent) && etl::is_same<etl::remove_cv_t<T>, etl::remove_cv_t<U>>::value, void>::type>
159 ETL_CONSTEXPR span(std::array<U, N>& a) ETL_NOEXCEPT
160 : pbegin(a.data())
161 {
162 }
163
164 //*************************************************************************
166 //*************************************************************************
167 template <typename U, size_t N, typename = typename etl::enable_if<(N == Extent) && etl::is_same<etl::remove_cv_t<T>, etl::remove_cv_t<U>>::value, void>::type>
168 ETL_CONSTEXPR span(const std::array<U, N>& a) ETL_NOEXCEPT
169 : pbegin(a.data())
170 {
171 }
172#endif
173
174#if ETL_USING_CPP11
175 //*************************************************************************
178 //*************************************************************************
179 template <typename TContainer, typename = typename etl::enable_if<!etl::is_pointer<etl::remove_reference_t<TContainer>>::value &&
180 !etl::is_array<etl::remove_reference_t<TContainer>>::value&&
181 etl::is_same<etl::remove_cv_t<T>, etl::remove_cv_t<typename etl::remove_reference_t<TContainer>::value_type>>::value, void>::type>
182 ETL_CONSTEXPR span(TContainer&& a) ETL_NOEXCEPT
183 : pbegin(a.data())
184 {
185 }
186#else
187 //*************************************************************************
190 //*************************************************************************
191 template <typename TContainer>
192 span(TContainer& a, typename etl::enable_if<!etl::is_pointer<typename etl::remove_reference<TContainer>::type>::value &&
194 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
195 : pbegin(a.data())
196 {
197 }
198
199 //*************************************************************************
202 //*************************************************************************
203 template <typename TContainer>
204 ETL_CONSTEXPR span(const TContainer& a, typename etl::enable_if<!etl::is_pointer<typename etl::remove_reference<TContainer>::type>::value &&
206 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
207 : pbegin(a.data())
208 {
209 }
210#endif
211
212 //*************************************************************************
214 //*************************************************************************
215 ETL_CONSTEXPR span(const span& other) ETL_NOEXCEPT
216 : pbegin(other.pbegin)
217 {
218 }
219
220 //*************************************************************************
222 //*************************************************************************
223 template <typename U, size_t N>
224 ETL_CONSTEXPR span(const etl::span<U, N>& other, typename etl::enable_if<(Extent == etl::dynamic_extent) || (N == etl::dynamic_extent) || (N == Extent), void>::type) ETL_NOEXCEPT
225 : pbegin(other.data())
226 {
227 }
228
229 //*************************************************************************
231 //*************************************************************************
232 ETL_NODISCARD ETL_CONSTEXPR reference front() const ETL_NOEXCEPT
233 {
234 return *pbegin;
235 }
236
237 //*************************************************************************
239 //*************************************************************************
240 ETL_NODISCARD ETL_CONSTEXPR reference back() const ETL_NOEXCEPT
241 {
242 return *((pbegin + Extent) - 1);
243 }
244
245 //*************************************************************************
247 //*************************************************************************
248 ETL_NODISCARD ETL_CONSTEXPR pointer data() const ETL_NOEXCEPT
249 {
250 return pbegin;
251 }
252
253 //*************************************************************************
255 //*************************************************************************
256 ETL_NODISCARD ETL_CONSTEXPR iterator begin() const ETL_NOEXCEPT
257 {
258 return pbegin;
259 }
260
261 //*************************************************************************
263 //*************************************************************************
264 ETL_NODISCARD ETL_CONSTEXPR circular_iterator begin_circular() const ETL_NOEXCEPT
265 {
266 return circular_iterator(begin(), end());
267 }
268
269 //*************************************************************************
271 //*************************************************************************
272 ETL_NODISCARD ETL_CONSTEXPR iterator end() const ETL_NOEXCEPT
273 {
274 return (pbegin + Extent);
275 }
276
277 //*************************************************************************
278 // Returns an reverse iterator to the reverse beginning of the span.
279 //*************************************************************************
280 ETL_NODISCARD ETL_CONSTEXPR reverse_iterator rbegin() const ETL_NOEXCEPT
281 {
282 return reverse_iterator((pbegin + Extent));
283 }
284
285 //*************************************************************************
287 //*************************************************************************
288 ETL_NODISCARD ETL_CONSTEXPR reverse_circular_iterator rbegin_circular() const ETL_NOEXCEPT
289 {
290 return reverse_circular_iterator(rbegin(), rend());
291 }
292
293 //*************************************************************************
295 //*************************************************************************
296 ETL_NODISCARD ETL_CONSTEXPR reverse_iterator rend() const ETL_NOEXCEPT
297 {
298 return reverse_iterator(pbegin);
299 }
300
301 //*************************************************************************
303 //*************************************************************************
304 ETL_NODISCARD ETL_CONSTEXPR bool empty() const ETL_NOEXCEPT
305 {
306 return false;
307 }
308
309 //*************************************************************************
311 //*************************************************************************
312 ETL_NODISCARD ETL_CONSTEXPR size_t size() const ETL_NOEXCEPT
313 {
314 return Extent;
315 }
316
317 //*************************************************************************
319 //*************************************************************************
320 ETL_NODISCARD ETL_CONSTEXPR size_t size_bytes() const ETL_NOEXCEPT
321 {
322 return sizeof(element_type) * Extent;
323 }
324
325 //*************************************************************************
327 //*************************************************************************
328 ETL_NODISCARD ETL_CONSTEXPR size_t max_size() const ETL_NOEXCEPT
329 {
330 return size();
331 }
332
333 //*************************************************************************
335 //*************************************************************************
336 ETL_CONSTEXPR14 span& operator =(const span& other) ETL_NOEXCEPT
337 {
338 pbegin = other.pbegin;
339 return *this;
340 }
341
342 //*************************************************************************
344 //*************************************************************************
345 ETL_CONSTEXPR reference operator[](const size_t i) const
346 {
347 return pbegin[i];
348 }
349
353 //template <typename Type2, size_t N2, typename etl::enable_if<etl::is_same<typename etl::remove_cv<Type2>::type, value_type>::value, bool>::type = true>
354 //ETL_NODISCARD ETL_CONSTEXPR bool operator==(const etl::span<Type2, N2>& other) const ETL_NOEXCEPT
355 //{
356 // return ((begin() == other.begin()) && (Extent == other.size())) ||
357 // etl::equal(begin(), end(), other.begin(), other.end());
358 //}
359
363 //template <typename Type2, size_t N2, typename etl::enable_if<etl::is_same<typename etl::remove_cv<Type2>::type, value_type>::value, bool>::type = true>
364 //ETL_NODISCARD ETL_CONSTEXPR bool operator!=(const etl::span<Type2, N2>& other) const ETL_NOEXCEPT
365 //{
366 // return !(*this == other);
367 //}
368
369 //*************************************************************************
371 //*************************************************************************
372 template <size_t COUNT>
373 ETL_NODISCARD ETL_CONSTEXPR etl::span<element_type, COUNT> first() const ETL_NOEXCEPT
374 {
375 return etl::span<element_type, COUNT>(pbegin, pbegin + COUNT);
376 }
377
378 //*************************************************************************
380 //*************************************************************************
381 ETL_NODISCARD ETL_CONSTEXPR etl::span<element_type, etl::dynamic_extent> first(size_t count) const ETL_NOEXCEPT
382 {
383 return etl::span<element_type, etl::dynamic_extent>(pbegin, pbegin + count);
384 }
385
386 //*************************************************************************
388 //*************************************************************************
389 template <size_t COUNT>
390 ETL_NODISCARD ETL_CONSTEXPR etl::span<element_type, COUNT> last() const ETL_NOEXCEPT
391 {
392 return etl::span<element_type, COUNT>(pbegin + Extent - COUNT, (pbegin + Extent));
393 }
394
395 //*************************************************************************
397 //*************************************************************************
398 ETL_NODISCARD ETL_CONSTEXPR etl::span<element_type, etl::dynamic_extent> last(size_t count) const ETL_NOEXCEPT
399 {
400 return etl::span<element_type, etl::dynamic_extent>((pbegin + Extent) - count, (pbegin + Extent));
401 }
402
403#if ETL_USING_CPP11
404 //*************************************************************************
406 //*************************************************************************
407 template <size_t OFFSET, size_t COUNT = etl::dynamic_extent>
408 ETL_NODISCARD ETL_CONSTEXPR
409 etl::span<element_type, COUNT != etl::dynamic_extent ? COUNT : Extent - OFFSET> subspan() const ETL_NOEXCEPT
410 {
411 return (COUNT == etl::dynamic_extent) ? etl::span<element_type, COUNT != etl::dynamic_extent ? COUNT : Extent - OFFSET>(pbegin + OFFSET, (pbegin + Extent))
412 : etl::span<element_type, COUNT != etl::dynamic_extent ? COUNT : Extent - OFFSET>(pbegin + OFFSET, pbegin + OFFSET + COUNT);
413 }
414#else
415 //*************************************************************************
417 //*************************************************************************
418 template <size_t OFFSET, size_t COUNT>
419 etl::span<element_type, COUNT != etl::dynamic_extent ? COUNT : Extent - OFFSET> subspan() const
420 {
421 if (COUNT == etl::dynamic_extent)
422 {
423 return etl::span<element_type, (COUNT != etl::dynamic_extent ? COUNT : Extent - OFFSET)>(pbegin + OFFSET, (pbegin + Extent));
424 }
425 else
426 {
427 return etl::span<element_type, COUNT != etl::dynamic_extent ? COUNT : Extent - OFFSET>(pbegin + OFFSET, pbegin + OFFSET + COUNT);
428 }
429 }
430#endif
431
432 //*************************************************************************
434 //*************************************************************************
435 ETL_NODISCARD ETL_CONSTEXPR etl::span<element_type, etl::dynamic_extent> subspan(size_t offset, size_t count = etl::dynamic_extent) const ETL_NOEXCEPT
436 {
437 return (count == etl::dynamic_extent) ? etl::span<element_type, etl::dynamic_extent>(pbegin + offset, (pbegin + Extent))
438 : etl::span<element_type, etl::dynamic_extent>(pbegin + offset, pbegin + offset + count);
439 }
440
441 private:
442
443 pointer pbegin;
444 };
445
446 //***************************************************************************
448 //***************************************************************************
449 template <typename T>
450 class span<T, etl::dynamic_extent>
451 {
452 public:
453
454 typedef T element_type;
455 typedef typename etl::remove_cv<T>::type value_type;
456 typedef size_t size_type;
457 typedef T& reference;
458 typedef const T& const_reference;
459 typedef T* pointer;
460 typedef const T* const_pointer;
461
462 typedef T* iterator;
463 typedef ETL_OR_STD::reverse_iterator<iterator> reverse_iterator;
464
465 typedef etl::circular_iterator<pointer> circular_iterator;
466 typedef etl::circular_iterator<ETL_OR_STD::reverse_iterator<pointer> > reverse_circular_iterator;
467
468 static ETL_CONSTANT size_t extent = etl::dynamic_extent;
469
470 //*************************************************************************
472 //*************************************************************************
473 ETL_CONSTEXPR span() ETL_NOEXCEPT
474 : pbegin(ETL_NULLPTR)
475 , pend(ETL_NULLPTR)
476 {
477 }
478
479 //*************************************************************************
481 //*************************************************************************
482 template <typename TIterator, typename TSize>
483 ETL_CONSTEXPR span(const TIterator begin_, const TSize size_) ETL_NOEXCEPT
484 : pbegin(etl::addressof(*begin_))
485 , pend(etl::addressof(*begin_) + size_)
486 {
487 }
488
489 //*************************************************************************
491 //*************************************************************************
492 template <typename TIterator>
493 ETL_CONSTEXPR span(const TIterator begin_, const TIterator end_)
494 : pbegin(etl::addressof(*begin_))
495 , pend(etl::addressof(*begin_) + etl::distance(begin_, end_))
496 {
497 }
498
499 //*************************************************************************
501 //*************************************************************************
502 template<size_t Array_Size>
503 ETL_CONSTEXPR span(element_type(&begin_)[Array_Size]) ETL_NOEXCEPT
504 : pbegin(begin_)
505 , pend(begin_ + Array_Size)
506 {
507 }
508
509#if ETL_USING_CPP11
510 //*************************************************************************
512 //*************************************************************************
513 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>
514 ETL_CONSTEXPR span(etl::array<U, N>& a) ETL_NOEXCEPT
515 : pbegin(a.data())
516 , pend(a.data() + a.size())
517 {
518 }
519
520 //*************************************************************************
522 //*************************************************************************
523 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>
524 ETL_CONSTEXPR span(const etl::array<U, N>& a) ETL_NOEXCEPT
525 : pbegin(a.data())
526 , pend(a.data() + a.size())
527 {
528 }
529#else
530 //*************************************************************************
532 //*************************************************************************
533 template <typename U, size_t N>
534 ETL_CONSTEXPR span(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
535 : pbegin(a.data())
536 , pend(a.data() + a.size())
537 {
538 }
539
540 //*************************************************************************
542 //*************************************************************************
543 template <typename U, size_t N>
544 ETL_CONSTEXPR span(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
545 : pbegin(a.data())
546 , pend(a.data() + a.size())
547 {
548 }
549#endif
550
551#if ETL_USING_STL && ETL_USING_CPP11
552 //*************************************************************************
554 //*************************************************************************
555 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>
556 ETL_CONSTEXPR span(std::array<U, N>& a) ETL_NOEXCEPT
557 : pbegin(a.data())
558 , pend(a.data() + a.size())
559 {
560 }
561
562 //*************************************************************************
564 //*************************************************************************
565 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>
566 ETL_CONSTEXPR span(const std::array<U, N>& a) ETL_NOEXCEPT
567 : pbegin(a.data())
568 , pend(a.data() + a.size())
569 {
570 }
571#endif
572
573#if ETL_USING_CPP11
574 //*************************************************************************
577 //*************************************************************************
578 template <typename TContainer, typename = typename etl::enable_if<!etl::is_pointer<etl::remove_reference_t<TContainer>>::value &&
579 !etl::is_array<etl::remove_reference_t<TContainer>>::value &&
580 etl::is_same<etl::remove_cv_t<T>, etl::remove_cv_t<typename etl::remove_reference_t<TContainer>::value_type>>::value, void>::type>
581 ETL_CONSTEXPR span(TContainer&& a) ETL_NOEXCEPT
582 : pbegin(a.data())
583 , pend(a.data() + a.size())
584 {
585 }
586#else
587 //*************************************************************************
590 //*************************************************************************
591 template <typename TContainer>
592 ETL_CONSTEXPR span(TContainer& a, typename etl::enable_if<!etl::is_pointer<typename etl::remove_reference<TContainer>::type>::value &&
594 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
595 : pbegin(a.data())
596 , pend(a.data() + a.size())
597 {
598 }
599
600 //*************************************************************************
603 //*************************************************************************
604 template <typename TContainer>
605 ETL_CONSTEXPR span(const TContainer& a, typename etl::enable_if<!etl::is_pointer<typename etl::remove_reference<TContainer>::type>::value &&
607 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
608 : pbegin(a.data())
609 , pend(a.data() + a.size())
610 {
611 }
612#endif
613
614 //*************************************************************************
616 //*************************************************************************
617 ETL_CONSTEXPR span(const span& other) ETL_NOEXCEPT
618 : pbegin(other.pbegin)
619 , pend(other.pend)
620 {
621 }
622
623 //*************************************************************************
625 //*************************************************************************
626 template <typename U, size_t N>
627 ETL_CONSTEXPR span(const etl::span<U, N>& other) ETL_NOEXCEPT
628 : pbegin(other.data())
629 , pend(other.data() + other.size())
630 {
631 }
632
633 //*************************************************************************
635 //*************************************************************************
636 ETL_NODISCARD ETL_CONSTEXPR reference front() const ETL_NOEXCEPT
637 {
638 return *pbegin;
639 }
640
641 //*************************************************************************
643 //*************************************************************************
644 ETL_NODISCARD ETL_CONSTEXPR reference back() const ETL_NOEXCEPT
645 {
646 return *(pend - 1);
647 }
648
649 //*************************************************************************
651 //*************************************************************************
652 ETL_NODISCARD ETL_CONSTEXPR pointer data() const ETL_NOEXCEPT
653 {
654 return pbegin;
655 }
656
657 //*************************************************************************
659 //*************************************************************************
660 ETL_NODISCARD ETL_CONSTEXPR iterator begin() const ETL_NOEXCEPT
661 {
662 return pbegin;
663 }
664
665 //*************************************************************************
667 //*************************************************************************
668 ETL_NODISCARD ETL_CONSTEXPR circular_iterator begin_circular() const ETL_NOEXCEPT
669 {
670 return circular_iterator(begin(), end());
671 }
672
673 //*************************************************************************
675 //*************************************************************************
676 ETL_NODISCARD ETL_CONSTEXPR iterator end() const ETL_NOEXCEPT
677 {
678 return pend;
679 }
680
681 //*************************************************************************
682 // Returns an reverse iterator to the reverse beginning of the span.
683 //*************************************************************************
684 ETL_NODISCARD ETL_CONSTEXPR reverse_iterator rbegin() const ETL_NOEXCEPT
685 {
686 return reverse_iterator(pend);
687 }
688
689 //*************************************************************************
691 //*************************************************************************
692 ETL_NODISCARD ETL_CONSTEXPR reverse_circular_iterator rbegin_circular() const ETL_NOEXCEPT
693 {
694 return reverse_circular_iterator(rbegin(), rend());
695 }
696
697 //*************************************************************************
699 //*************************************************************************
700 ETL_NODISCARD ETL_CONSTEXPR reverse_iterator rend() const ETL_NOEXCEPT
701 {
702 return reverse_iterator(pbegin);
703 }
704
705 //*************************************************************************
707 //*************************************************************************
708 ETL_NODISCARD ETL_CONSTEXPR bool empty() const ETL_NOEXCEPT
709 {
710 return (pbegin == pend);
711 }
712
713 //*************************************************************************
715 //*************************************************************************
716 ETL_NODISCARD ETL_CONSTEXPR size_t size() const ETL_NOEXCEPT
717 {
718 return (pend - pbegin);
719 }
720
721 //*************************************************************************
723 //*************************************************************************
724 ETL_NODISCARD ETL_CONSTEXPR size_t size_bytes() const ETL_NOEXCEPT
725 {
726 return sizeof(element_type) * (pend - pbegin);
727 }
728
729 //*************************************************************************
731 //*************************************************************************
732 ETL_NODISCARD ETL_CONSTEXPR size_t max_size() const ETL_NOEXCEPT
733 {
734 return size();
735 }
736
737 //*************************************************************************
739 //*************************************************************************
740 ETL_CONSTEXPR14 span& operator =(const span& other) ETL_NOEXCEPT
741 {
742 pbegin = other.pbegin;
743 pend = other.pend;
744 return *this;
745 }
746
747 //*************************************************************************
749 //*************************************************************************
750 ETL_CONSTEXPR reference operator[](const size_t i) const
751 {
752 return pbegin[i];
753 }
754
758 //template <typename Type2, typename etl::enable_if<etl::is_same<typename etl::remove_cv<Type2>::type, value_type>::value, bool>::type = true>
759 //ETL_NODISCARD ETL_CONSTEXPR bool operator==(const etl::span<Type2>& other) const ETL_NOEXCEPT
760 //{
761 // return (empty() && other.empty()) ||
762 // ((begin() == other.begin()) && (end() == other.end())) ||
763 // etl::equal(begin(), end(), other.begin(), other.end());
764 //}
765
769 //template <typename Type2, typename etl::enable_if<etl::is_same<typename etl::remove_cv<Type2>::type, value_type>::value, bool>::type = true>
770 //ETL_NODISCARD ETL_CONSTEXPR bool operator!=(const etl::span<Type2>& other) const ETL_NOEXCEPT
771 //{
772 // return !(*this == other);
773 //}
774
775 //*************************************************************************
777 //*************************************************************************
778 template <size_t COUNT>
779 ETL_NODISCARD ETL_CONSTEXPR etl::span<element_type, COUNT> first() const ETL_NOEXCEPT
780 {
781 return etl::span<element_type, COUNT>(pbegin, pbegin + COUNT);
782 }
783
784 //*************************************************************************
786 //*************************************************************************
787 ETL_NODISCARD ETL_CONSTEXPR etl::span<element_type, etl::dynamic_extent> first(size_t count) const ETL_NOEXCEPT
788 {
789 return etl::span<element_type, etl::dynamic_extent>(pbegin, pbegin + count);
790 }
791
792 //*************************************************************************
794 //*************************************************************************
795 template <size_t COUNT>
796 ETL_NODISCARD ETL_CONSTEXPR etl::span<element_type, COUNT> last() const ETL_NOEXCEPT
797 {
798 return etl::span<element_type, COUNT>(pend - COUNT, pend);
799 }
800
801 //*************************************************************************
803 //*************************************************************************
804 ETL_NODISCARD ETL_CONSTEXPR etl::span<element_type, etl::dynamic_extent> last(size_t count) const ETL_NOEXCEPT
805 {
806 return etl::span<element_type, etl::dynamic_extent>(pend - count, pend);
807 }
808
809#if ETL_USING_CPP11
810 //*************************************************************************
812 //*************************************************************************
813 template <size_t OFFSET, size_t COUNT = etl::dynamic_extent>
814 ETL_NODISCARD ETL_CONSTEXPR
816 {
817 return (COUNT == etl::dynamic_extent) ? etl::span<element_type, COUNT != etl::dynamic_extent ? COUNT : etl::dynamic_extent>(pbegin + OFFSET, pend)
818 : etl::span<element_type, COUNT != etl::dynamic_extent ? COUNT : etl::dynamic_extent>(pbegin + OFFSET, pbegin + OFFSET + COUNT);
819 }
820#else
821 //*************************************************************************
823 //*************************************************************************
824 template <size_t OFFSET, size_t COUNT>
826 {
827 if (COUNT == etl::dynamic_extent)
828 {
830 }
831 else
832 {
834 }
835 }
836#endif
837
838 //*************************************************************************
840 //*************************************************************************
841 ETL_NODISCARD ETL_CONSTEXPR14 etl::span<element_type, etl::dynamic_extent> subspan(size_t offset, size_t count = etl::dynamic_extent) const ETL_NOEXCEPT
842 {
843 return (count == etl::dynamic_extent) ? etl::span<element_type, etl::dynamic_extent>(pbegin + offset, pend)
844 : etl::span<element_type, etl::dynamic_extent>(pbegin + offset, pbegin + offset + count);
845 }
846
847 private:
848
849 pointer pbegin;
850 pointer pend;
851 };
852
853 template <typename T, size_t Extent>
854 ETL_CONSTANT size_t span<T, Extent>::extent;
855
856 template <typename T>
857 ETL_CONSTANT size_t span<T, etl::dynamic_extent>::extent;
858
859 //*************************************************************************
861 //*************************************************************************
862 template <typename T1, size_t N1, typename T2, size_t N2>
863 ETL_NODISCARD
864 ETL_CONSTEXPR
865 typename etl::enable_if<etl::is_same<typename etl::remove_cv<T1>::type, typename etl::remove_cv<T2>::type>::value, bool>::type
866 operator ==(const etl::span<T1, N1>& lhs, const etl::span<T2, N2>& rhs) ETL_NOEXCEPT
867 {
868 return (lhs.begin() == rhs.begin()) && (lhs.size() == rhs.size());
869 }
870
871 //*************************************************************************
873 //*************************************************************************
874 template <typename T1, size_t N1, typename T2, size_t N2>
875 ETL_NODISCARD
876 ETL_CONSTEXPR
877 bool operator !=(const etl::span<T1, N1>& lhs, const etl::span<T2, N2>& rhs) ETL_NOEXCEPT
878 {
879 return !(lhs == rhs);
880 }
881
882 //*************************************************************************
889 //*************************************************************************
890 template <typename T1, size_t N1, typename T2, size_t N2>
891 typename etl::enable_if<etl::is_same<typename etl::remove_cv<T1>::type, typename etl::remove_cv<T2>::type>::value, bool>::type
892 equal(const etl::span<T1, N1>& lhs, const etl::span<T2, N2>& rhs)
893 {
894 return (lhs.empty() && rhs.empty()) ||
895 ((lhs.begin() == rhs.begin()) && (lhs.size() == rhs.size())) ||
896 etl::equal(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
897 }
898
899 //*************************************************************************
901 //*************************************************************************
902#if ETL_USING_CPP17
903 template <typename TIterator>
904 span(const TIterator begin_, const TIterator end_)
905 ->span<etl::remove_pointer_t<TIterator>, etl::dynamic_extent>;
906
907 template <typename TIterator, typename TSize>
908 span(const TIterator begin_, const TSize size_)
909 ->span<etl::remove_pointer_t<TIterator>, etl::dynamic_extent>;
910
911 template <typename T, size_t N>
912 span(T(&)[N])
913 -> span<T, N>;
914
915 template <typename T, size_t N>
916 span(etl::array<T, N>&)
917 -> span<T, N>;
918
919 template <typename T, size_t N>
920 span(const etl::array<T, N>&)
921 -> span<const T, N>;
922
923#if ETL_USING_STL && ETL_USING_CPP11
924 template <typename T, size_t N>
925 span(std::array<T, N>&)
926 ->span<T, N>;
927
928 template <typename T, size_t N>
929 span(const std::array<T, N>&)
930 ->span<const T, N>;
931#endif
932#endif
933
934 //*************************************************************************
936 //*************************************************************************
937#if ETL_USING_8BIT_TYPES
938 template <typename T, size_t Extent>
939 struct hash<etl::span<T, Extent> >
940 {
941 size_t operator()(const etl::span<T>& view) const
942 {
943 return etl::private_hash::generic_hash<size_t>(reinterpret_cast<const uint8_t*>(view.data()),
944 reinterpret_cast<const uint8_t*>(view.data() + view.size()));
945 }
946 };
947#endif
948
949 //*************************************************************************
951 //*************************************************************************
952 template <class T, size_t N>
953 span<const byte, (N == etl::dynamic_extent) ? (etl::dynamic_extent) : (N * sizeof(T))>
954 as_bytes(span<T, N> s) ETL_NOEXCEPT
955 {
956 return span<const byte, (N == etl::dynamic_extent) ? (etl::dynamic_extent) : (N * sizeof(T))>(reinterpret_cast<byte*>(s.data()), s.size_bytes());
957 }
958
959 //*************************************************************************
961 //*************************************************************************
962 template <class T, size_t N>
963 span<byte, (N == etl::dynamic_extent) ? (etl::dynamic_extent) : (N * sizeof(T))>
965 {
966 ETL_STATIC_ASSERT(!etl::is_const<T>::value, "span<T> must be of non-const type");
967 return span<byte, (N == etl::dynamic_extent) ? (etl::dynamic_extent) : (N * sizeof(T))>(reinterpret_cast<byte*>(s.data()), s.size_bytes());
968 }
969}
970
971#endif
Definition: iterator.h:228
etl::span< element_type, COUNT !=etl::dynamic_extent ? COUNT :etl::dynamic_extent > subspan() const
Obtains a span that is a view from OFFSET over the next COUNT elements of this span.
Definition: span.h:825
Span - Fixed Extent.
Definition: span.h:62
ETL_NODISCARD ETL_CONSTEXPR reverse_iterator rend() const ETL_NOEXCEPT
Returns a reverse iterator to the end of the span.
Definition: span.h:296
ETL_NODISCARD ETL_CONSTEXPR circular_iterator begin_circular() const ETL_NOEXCEPT
Returns a circular iterator to the beginning of the span.
Definition: span.h:264
ETL_NODISCARD ETL_CONSTEXPR etl::span< element_type, COUNT > last() const ETL_NOEXCEPT
Obtains a span that is a view over the last COUNT elements of this span.
Definition: span.h:390
etl::span< element_type, COUNT !=etl::dynamic_extent ? COUNT :Extent - OFFSET > subspan() const
Obtains a span that is a view from OFFSET over the next COUNT elements of this span.
Definition: span.h:419
ETL_NODISCARD ETL_CONSTEXPR reverse_circular_iterator rbegin_circular() const ETL_NOEXCEPT
Returns a reverse circular iterator to the end of the span.
Definition: span.h:288
ETL_NODISCARD ETL_CONSTEXPR iterator begin() const ETL_NOEXCEPT
Returns an iterator to the beginning of the span.
Definition: span.h:256
ETL_NODISCARD ETL_CONSTEXPR size_t size_bytes() const ETL_NOEXCEPT
Returns the size of the span in bytes.
Definition: span.h:320
ETL_NODISCARD ETL_CONSTEXPR bool empty() const ETL_NOEXCEPT
Returns true if the span size is zero.
Definition: span.h:304
ETL_NODISCARD ETL_CONSTEXPR etl::span< element_type, COUNT > first() const ETL_NOEXCEPT
Obtains a span that is a view over the first COUNT elements of this span.
Definition: span.h:373
ETL_NODISCARD ETL_CONSTEXPR size_t size() const ETL_NOEXCEPT
Returns the size of the span.
Definition: span.h:312
ETL_NODISCARD ETL_CONSTEXPR reference back() const ETL_NOEXCEPT
Returns a reference to the last element.
Definition: span.h:240
ETL_CONSTEXPR span() ETL_NOEXCEPT
Default constructor.
Definition: span.h:84
ETL_CONSTEXPR14 span & operator=(const span &other) ETL_NOEXCEPT
Assign from a span.
Definition: span.h:336
ETL_NODISCARD ETL_CONSTEXPR pointer data() const ETL_NOEXCEPT
Returns a pointer to the first element of the internal storage.
Definition: span.h:248
ETL_CONSTEXPR reference operator[](const size_t i) const
Returns a reference to the indexed value.
Definition: span.h:345
span(TContainer &a, typename etl::enable_if<!etl::is_pointer< typename etl::remove_reference< TContainer >::type >::value &&!etl::is_array< TContainer >::value &&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
Definition: span.h:192
ETL_NODISCARD ETL_CONSTEXPR size_t max_size() const ETL_NOEXCEPT
Returns the maximum possible size of the span.
Definition: span.h:328
ETL_NODISCARD ETL_CONSTEXPR reference front() const ETL_NOEXCEPT
Returns a reference to the first element.
Definition: span.h:232
ETL_NODISCARD ETL_CONSTEXPR iterator end() const ETL_NOEXCEPT
Returns an iterator to the end of the span.
Definition: span.h:272
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
Definition: array.h:88
ETL_CONSTEXPR17 T * addressof(T &t)
Definition: addressof.h:51
enable_if
Definition: type_traits_generator.h:1191
extent
Definition: type_traits_generator.h:1202
is_array
Definition: type_traits_generator.h:1091
is_const
Definition: type_traits_generator.h:908
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
span< byte,(N==etl::dynamic_extent) ?(etl::dynamic_extent) :(N *sizeof(T))> as_writable_bytes(span< T, N > s) ETL_NOEXCEPT
Obtains a view to the byte representation of the elements of the span s.
Definition: span.h:964
span< const byte,(N==etl::dynamic_extent) ?(etl::dynamic_extent) :(N *sizeof(T))> as_bytes(span< T, N > s) ETL_NOEXCEPT
Template deduction guides.
Definition: span.h:954
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:633