Embedded Template Library 1.0
Loading...
Searching...
No Matches
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#include "static_assert.h"
46
48
49#if ETL_USING_CPP20 && ETL_USING_STL
50 #include <span>
51#endif
52
55
56namespace etl
57{
58 //***************************************************************************
60 //***************************************************************************
61 template <typename T, size_t Extent = etl::dynamic_extent>
62 class span
63 {
64 public:
65
66 typedef T element_type;
67 typedef typename etl::remove_cv<T>::type value_type;
68 typedef size_t size_type;
69 typedef T& reference;
70 typedef const T& const_reference;
71 typedef T* pointer;
72 typedef const T* const_pointer;
73
74 typedef T* iterator;
75 typedef const T* const_iterator;
76 typedef ETL_OR_STD::reverse_iterator<iterator> reverse_iterator;
77 typedef ETL_OR_STD::reverse_iterator<const_iterator> const_reverse_iterator;
78
81
82 static ETL_CONSTANT size_t extent = Extent;
83
84 //*************************************************************************
86 //*************************************************************************
87 template <typename TIterator, typename TSize>
88 ETL_CONSTEXPR explicit span(const TIterator begin_, const TSize /*size_*/) ETL_NOEXCEPT
89 : pbegin(etl::to_address(begin_))
90 {
91 }
92
93 //*************************************************************************
95 //*************************************************************************
96 template <typename TIterator>
97 ETL_CONSTEXPR explicit span(const TIterator begin_, const TIterator /*end_*/)
98 : pbegin(etl::to_address(begin_))
99 {
100 }
101
102 //*************************************************************************
104 //*************************************************************************
105 template<size_t Array_Size>
106 ETL_CONSTEXPR span(element_type(&begin_)[Array_Size]) ETL_NOEXCEPT
107 : pbegin(begin_)
108 {
109 }
110
111#if ETL_USING_CPP11
112 //*************************************************************************
115 //*************************************************************************
116 template <typename TContainer, typename = typename etl::enable_if<!etl::is_pointer<etl::remove_reference_t<TContainer>>::value &&
117 !etl::is_array<etl::remove_reference_t<TContainer>>::value&&
118 etl::is_same<etl::remove_cv_t<T>, etl::remove_cv_t<typename etl::remove_reference_t<TContainer>::value_type>>::value, void>::type>
119 ETL_CONSTEXPR span(TContainer&& a) ETL_NOEXCEPT
120 : pbegin(a.data())
121 {
122 }
123#else
124 //*************************************************************************
127 //*************************************************************************
128 template <typename TContainer>
131 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
132 : pbegin(a.data())
133 {
134 }
135
136 //*************************************************************************
139 //*************************************************************************
140 template <typename TContainer>
141 ETL_CONSTEXPR span(const TContainer& a, typename etl::enable_if<!etl::is_pointer<typename etl::remove_reference<TContainer>::type>::value &&
143 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
144 : pbegin(a.data())
145 {
146 }
147#endif
148
149 //*************************************************************************
151 //*************************************************************************
152 ETL_CONSTEXPR span(const span& other) ETL_NOEXCEPT
153 : pbegin(other.pbegin)
154 {
155 }
156
157 //*************************************************************************
159 //*************************************************************************
160 template <typename U, size_t N>
161 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
162 : pbegin(other.data())
163 {
164 }
165
166 //*************************************************************************
168 //*************************************************************************
169 ETL_NODISCARD ETL_CONSTEXPR reference front() const ETL_NOEXCEPT
170 {
171 return *pbegin;
172 }
173
174 //*************************************************************************
176 //*************************************************************************
177 ETL_NODISCARD ETL_CONSTEXPR reference back() const ETL_NOEXCEPT
178 {
179 return *((pbegin + Extent) - 1);
180 }
181
182 //*************************************************************************
184 //*************************************************************************
185 ETL_NODISCARD ETL_CONSTEXPR pointer data() const ETL_NOEXCEPT
186 {
187 return pbegin;
188 }
189
190 //*************************************************************************
192 //*************************************************************************
193 ETL_NODISCARD ETL_CONSTEXPR const_iterator cbegin() const ETL_NOEXCEPT
194 {
195 return pbegin;
196 }
197
198 //*************************************************************************
200 //*************************************************************************
201 ETL_NODISCARD ETL_CONSTEXPR iterator begin() const ETL_NOEXCEPT
202 {
203 return pbegin;
204 }
205
206 //*************************************************************************
208 //*************************************************************************
209 ETL_NODISCARD ETL_CONSTEXPR circular_iterator begin_circular() const ETL_NOEXCEPT
210 {
211 return circular_iterator(begin(), end());
212 }
213
214 //*************************************************************************
216 //*************************************************************************
217 ETL_NODISCARD ETL_CONSTEXPR const_iterator cend() const ETL_NOEXCEPT
218 {
219 return (pbegin + Extent);
220 }
221
222 //*************************************************************************
224 //*************************************************************************
225 ETL_NODISCARD ETL_CONSTEXPR iterator end() const ETL_NOEXCEPT
226 {
227 return (pbegin + Extent);
228 }
229
230 //*************************************************************************
231 // Returns a const reverse iterator to the reverse beginning of the span.
232 //*************************************************************************
233 ETL_NODISCARD ETL_CONSTEXPR const_reverse_iterator crbegin() const ETL_NOEXCEPT
234 {
235 return const_reverse_iterator((pbegin + Extent));
236 }
237
238 //*************************************************************************
239 // Returns an reverse iterator to the reverse beginning of the span.
240 //*************************************************************************
241 ETL_NODISCARD ETL_CONSTEXPR reverse_iterator rbegin() const ETL_NOEXCEPT
242 {
243 return reverse_iterator((pbegin + Extent));
244 }
245
246 //*************************************************************************
248 //*************************************************************************
249 ETL_NODISCARD ETL_CONSTEXPR reverse_circular_iterator rbegin_circular() const ETL_NOEXCEPT
250 {
251 return reverse_circular_iterator(rbegin(), rend());
252 }
253
254 //*************************************************************************
256 //*************************************************************************
257 ETL_NODISCARD ETL_CONSTEXPR const_reverse_iterator crend() const ETL_NOEXCEPT
258 {
259 return const_reverse_iterator(pbegin);
260 }
261
262 //*************************************************************************
264 //*************************************************************************
265 ETL_NODISCARD ETL_CONSTEXPR reverse_iterator rend() const ETL_NOEXCEPT
266 {
267 return reverse_iterator(pbegin);
268 }
269
270 //*************************************************************************
272 //*************************************************************************
273 ETL_NODISCARD ETL_CONSTEXPR bool empty() const ETL_NOEXCEPT
274 {
275 return Extent == 0;
276 }
277
278 //*************************************************************************
280 //*************************************************************************
281 ETL_NODISCARD ETL_CONSTEXPR size_t size() const ETL_NOEXCEPT
282 {
283 return Extent;
284 }
285
286 //*************************************************************************
288 //*************************************************************************
289 ETL_NODISCARD ETL_CONSTEXPR size_t size_bytes() const ETL_NOEXCEPT
290 {
291 return sizeof(element_type) * Extent;
292 }
293
294 //*************************************************************************
296 //*************************************************************************
297 ETL_NODISCARD ETL_CONSTEXPR size_t max_size() const ETL_NOEXCEPT
298 {
299 return size();
300 }
301
302 //*************************************************************************
304 //*************************************************************************
305 ETL_CONSTEXPR14 span& operator =(const span& other) ETL_NOEXCEPT
306 {
307 pbegin = other.pbegin;
308 return *this;
309 }
310
311 //*************************************************************************
313 //*************************************************************************
314 ETL_NODISCARD ETL_CONSTEXPR14 reference at(size_t i)
315 {
316 ETL_ASSERT(i < size(), ETL_ERROR(array_out_of_range));
317
318 return pbegin[i];
319 }
320
321 //*************************************************************************
323 //*************************************************************************
324 ETL_NODISCARD ETL_CONSTEXPR14 const_reference at(size_t i) const
325 {
326 ETL_ASSERT(i < size(), ETL_ERROR(array_out_of_range));
327
328 return pbegin[i];
329 }
330
331 //*************************************************************************
333 //*************************************************************************
334 ETL_CONSTEXPR reference operator[](const size_t i) const
335 {
336 return pbegin[i];
337 }
338
339 //*************************************************************************
341 //*************************************************************************
342 template <size_t COUNT>
343 ETL_NODISCARD ETL_CONSTEXPR etl::span<element_type, COUNT> first() const ETL_NOEXCEPT
344 {
345 // If Extent is static, check that original span contains at least COUNT elements
346 ETL_STATIC_ASSERT((Extent != etl::dynamic_extent) ? COUNT <= Extent : true, "Original span does not contain COUNT elements");
347
348 return etl::span<element_type, COUNT>(pbegin, pbegin + COUNT);
349 }
350
351 //*************************************************************************
353 //*************************************************************************
354 ETL_NODISCARD ETL_CONSTEXPR etl::span<element_type, etl::dynamic_extent> first(size_t count) const ETL_NOEXCEPT
355 {
356 return etl::span<element_type, etl::dynamic_extent>(pbegin, pbegin + count);
357 }
358
359 //*************************************************************************
361 //*************************************************************************
362 template <size_t COUNT>
363 ETL_NODISCARD ETL_CONSTEXPR etl::span<element_type, COUNT> last() const ETL_NOEXCEPT
364 {
365 // If Extent is static, check that original span contains at least COUNT elements
366 ETL_STATIC_ASSERT((Extent != etl::dynamic_extent) ? COUNT <= Extent : true, "Original span does not contain COUNT elements");
367
368 return etl::span<element_type, COUNT>(pbegin + Extent - COUNT, (pbegin + Extent));
369 }
370
371 //*************************************************************************
373 //*************************************************************************
374 ETL_NODISCARD ETL_CONSTEXPR etl::span<element_type, etl::dynamic_extent> last(size_t count) const ETL_NOEXCEPT
375 {
376 return etl::span<element_type, etl::dynamic_extent>((pbegin + Extent) - count, (pbegin + Extent));
377 }
378
379#if ETL_USING_CPP11
380 //*************************************************************************
382 //*************************************************************************
383 template <size_t OFFSET, size_t COUNT = etl::dynamic_extent>
384 ETL_NODISCARD ETL_CONSTEXPR
385 etl::span<element_type, COUNT != etl::dynamic_extent ? COUNT : Extent - OFFSET> subspan() const ETL_NOEXCEPT
386 {
387 // If Extent is static, check that OFFSET is within the original span
388 ETL_STATIC_ASSERT((Extent != etl::dynamic_extent) ? OFFSET <= Extent : true, "OFFSET is not within the original span");
389
390 // If count is also static, check that OFFSET + COUNT is within the original span
391 ETL_STATIC_ASSERT((Extent != etl::dynamic_extent) && (COUNT != etl::dynamic_extent) ? COUNT <= (Extent - OFFSET) : true, "OFFSET + COUNT is not within the original span");
392
393 return (COUNT == etl::dynamic_extent) ? etl::span<element_type, COUNT != etl::dynamic_extent ? COUNT : Extent - OFFSET>(pbegin + OFFSET, (pbegin + Extent))
394 : etl::span<element_type, COUNT != etl::dynamic_extent ? COUNT : Extent - OFFSET>(pbegin + OFFSET, pbegin + OFFSET + COUNT);
395 }
396#else
397 //*************************************************************************
399 //*************************************************************************
400 template <size_t OFFSET, size_t COUNT>
401 etl::span<element_type, COUNT != etl::dynamic_extent ? COUNT : Extent - OFFSET> subspan() const
402 {
403 // If Extent is static, check that OFFSET is within the original span
404 ETL_STATIC_ASSERT((Extent != etl::dynamic_extent) ? OFFSET <= Extent : true, "OFFSET is not within the original span");
405
406 // If count is also static, check that OFFSET + COUNT is within the original span
407 ETL_STATIC_ASSERT((Extent != etl::dynamic_extent) && (COUNT != etl::dynamic_extent) ? COUNT <= (Extent - OFFSET) : true, "OFFSET + COUNT is not within the original span");
408
409 if (COUNT == etl::dynamic_extent)
410 {
411 return etl::span<element_type, (COUNT != etl::dynamic_extent ? COUNT : Extent - OFFSET)>(pbegin + OFFSET, (pbegin + Extent));
412 }
413 else
414 {
415 return etl::span<element_type, COUNT != etl::dynamic_extent ? COUNT : Extent - OFFSET>(pbegin + OFFSET, pbegin + OFFSET + COUNT);
416 }
417 }
418#endif
419
420 //*************************************************************************
422 //*************************************************************************
423 ETL_NODISCARD ETL_CONSTEXPR etl::span<element_type, etl::dynamic_extent> subspan(size_t offset, size_t count = etl::dynamic_extent) const ETL_NOEXCEPT
424 {
425 return (count == etl::dynamic_extent) ? etl::span<element_type, etl::dynamic_extent>(pbegin + offset, (pbegin + Extent))
426 : etl::span<element_type, etl::dynamic_extent>(pbegin + offset, pbegin + offset + count);
427 }
428
429 private:
430
431 pointer pbegin;
432 };
433
434 //*************************************************************************
437 //*************************************************************************
438 template <typename T, size_t Extent>
439 ETL_CONSTEXPR span<T, Extent> make_span(T (&data)[Extent])
440 {
441 return span<T, Extent>(data);
442 }
443
444 //***************************************************************************
446 //***************************************************************************
447 template <typename T>
448 class span<T, etl::dynamic_extent>
449 {
450 public:
451
452 typedef T element_type;
453 typedef typename etl::remove_cv<T>::type value_type;
454 typedef size_t size_type;
455 typedef T& reference;
456 typedef const T& const_reference;
457 typedef T* pointer;
458 typedef const T* const_pointer;
459
460 typedef T* iterator;
461 typedef const T* const_iterator;
462 typedef ETL_OR_STD::reverse_iterator<iterator> reverse_iterator;
463 typedef ETL_OR_STD::reverse_iterator<const_iterator> const_reverse_iterator;
464
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::to_address(begin_))
485 , pend(etl::to_address(begin_) + size_)
486 {
487 }
488
489 //*************************************************************************
491 //*************************************************************************
492 template <typename TIterator>
493 ETL_CONSTEXPR span(const TIterator begin_, const TIterator end_)
494 : pbegin(etl::to_address(begin_))
495 , pend(etl::to_address(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 //*************************************************************************
513 //*************************************************************************
514 template <typename TContainer, typename = typename etl::enable_if<!etl::is_pointer<etl::remove_reference_t<TContainer>>::value &&
515 !etl::is_array<etl::remove_reference_t<TContainer>>::value &&
516 etl::is_same<etl::remove_cv_t<T>, etl::remove_cv_t<typename etl::remove_reference_t<TContainer>::value_type>>::value, void>::type>
517 ETL_CONSTEXPR span(TContainer&& a) ETL_NOEXCEPT
518 : pbegin(a.data())
519 , pend(a.data() + a.size())
520 {
521 }
522#else
523 //*************************************************************************
526 //*************************************************************************
527 template <typename TContainer>
530 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
531 : pbegin(a.data())
532 , pend(a.data() + a.size())
533 {
534 }
535
536 //*************************************************************************
539 //*************************************************************************
540 template <typename TContainer>
541 ETL_CONSTEXPR span(const TContainer& a, typename etl::enable_if<!etl::is_pointer<typename etl::remove_reference<TContainer>::type>::value &&
543 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
544 : pbegin(a.data())
545 , pend(a.data() + a.size())
546 {
547 }
548#endif
549
550 //*************************************************************************
552 //*************************************************************************
553 ETL_CONSTEXPR span(const span& other) ETL_NOEXCEPT
554 : pbegin(other.pbegin)
555 , pend(other.pend)
556 {
557 }
558
559 //*************************************************************************
561 //*************************************************************************
562 template <typename U, size_t N>
563 ETL_CONSTEXPR span(const etl::span<U, N>& other) ETL_NOEXCEPT
564 : pbegin(other.data())
565 , pend(other.data() + other.size())
566 {
567 }
568
569 //*************************************************************************
571 //*************************************************************************
572 ETL_NODISCARD ETL_CONSTEXPR reference front() const ETL_NOEXCEPT
573 {
574 return *pbegin;
575 }
576
577 //*************************************************************************
579 //*************************************************************************
580 ETL_NODISCARD ETL_CONSTEXPR reference back() const ETL_NOEXCEPT
581 {
582 return *(pend - 1);
583 }
584
585 //*************************************************************************
587 //*************************************************************************
588 ETL_NODISCARD ETL_CONSTEXPR pointer data() const ETL_NOEXCEPT
589 {
590 return pbegin;
591 }
592
593 //*************************************************************************
595 //*************************************************************************
596 ETL_NODISCARD ETL_CONSTEXPR const_iterator cbegin() const ETL_NOEXCEPT
597 {
598 return pbegin;
599 }
600
601 //*************************************************************************
603 //*************************************************************************
604 ETL_NODISCARD ETL_CONSTEXPR iterator begin() const ETL_NOEXCEPT
605 {
606 return pbegin;
607 }
608
609 //*************************************************************************
611 //*************************************************************************
612 ETL_NODISCARD ETL_CONSTEXPR circular_iterator begin_circular() const ETL_NOEXCEPT
613 {
614 return circular_iterator(begin(), end());
615 }
616
617 //*************************************************************************
619 //*************************************************************************
620 ETL_NODISCARD ETL_CONSTEXPR const_iterator cend() const ETL_NOEXCEPT
621 {
622 return pend;
623 }
624
625 //*************************************************************************
627 //*************************************************************************
628 ETL_NODISCARD ETL_CONSTEXPR iterator end() const ETL_NOEXCEPT
629 {
630 return pend;
631 }
632
633 //*************************************************************************
634 // Returns an reverse iterator to the reverse beginning of the span.
635 //*************************************************************************
636 ETL_NODISCARD ETL_CONSTEXPR reverse_iterator rbegin() const ETL_NOEXCEPT
637 {
638 return reverse_iterator(pend);
639 }
640
641 //*************************************************************************
642 // Returns a const reverse iterator to the reverse beginning of the span.
643 //*************************************************************************
644 ETL_NODISCARD ETL_CONSTEXPR const_reverse_iterator crbegin() const ETL_NOEXCEPT
645 {
646 return const_reverse_iterator(pend);
647 }
648
649 //*************************************************************************
651 //*************************************************************************
652 ETL_NODISCARD ETL_CONSTEXPR reverse_circular_iterator rbegin_circular() const ETL_NOEXCEPT
653 {
654 return reverse_circular_iterator(rbegin(), rend());
655 }
656
657 //*************************************************************************
659 //*************************************************************************
660 ETL_NODISCARD ETL_CONSTEXPR const_reverse_iterator crend() const ETL_NOEXCEPT
661 {
662 return const_reverse_iterator(pbegin);
663 }
664
665 //*************************************************************************
667 //*************************************************************************
668 ETL_NODISCARD ETL_CONSTEXPR reverse_iterator rend() const ETL_NOEXCEPT
669 {
670 return reverse_iterator(pbegin);
671 }
672
673 //*************************************************************************
675 //*************************************************************************
676 ETL_NODISCARD ETL_CONSTEXPR bool empty() const ETL_NOEXCEPT
677 {
678 return (pbegin == pend);
679 }
680
681 //*************************************************************************
683 //*************************************************************************
684 ETL_NODISCARD ETL_CONSTEXPR size_t size() const ETL_NOEXCEPT
685 {
686 return (pend - pbegin);
687 }
688
689 //*************************************************************************
691 //*************************************************************************
692 ETL_NODISCARD ETL_CONSTEXPR size_t size_bytes() const ETL_NOEXCEPT
693 {
694 return sizeof(element_type) * (pend - pbegin);
695 }
696
697 //*************************************************************************
699 //*************************************************************************
700 ETL_NODISCARD ETL_CONSTEXPR size_t max_size() const ETL_NOEXCEPT
701 {
702 return size();
703 }
704
705 //*************************************************************************
707 //*************************************************************************
708 ETL_CONSTEXPR14 span& operator =(const span& other) ETL_NOEXCEPT
709 {
710 pbegin = other.pbegin;
711 pend = other.pend;
712 return *this;
713 }
714
715 //*************************************************************************
717 //*************************************************************************
718 ETL_NODISCARD ETL_CONSTEXPR14 reference at(size_t i)
719 {
720 ETL_ASSERT(i < size(), ETL_ERROR(array_out_of_range));
721
722 return pbegin[i];
723 }
724
725 //*************************************************************************
727 //*************************************************************************
728 ETL_NODISCARD ETL_CONSTEXPR14 const_reference at(size_t i) const
729 {
730 ETL_ASSERT(i < size(), ETL_ERROR(array_out_of_range));
731
732 return pbegin[i];
733 }
734
735 //*************************************************************************
737 //*************************************************************************
738 ETL_CONSTEXPR reference operator[](const size_t i) const
739 {
740 return pbegin[i];
741 }
742
743 //*************************************************************************
745 //*************************************************************************
746 template <size_t COUNT>
747 ETL_NODISCARD ETL_CONSTEXPR etl::span<element_type, COUNT> first() const ETL_NOEXCEPT
748 {
749 return etl::span<element_type, COUNT>(pbegin, pbegin + COUNT);
750 }
751
752 //*************************************************************************
754 //*************************************************************************
755 ETL_NODISCARD ETL_CONSTEXPR etl::span<element_type, etl::dynamic_extent> first(size_t count) const ETL_NOEXCEPT
756 {
757 return etl::span<element_type, etl::dynamic_extent>(pbegin, pbegin + count);
758 }
759
760 //*************************************************************************
762 //*************************************************************************
763 template <size_t COUNT>
764 ETL_NODISCARD ETL_CONSTEXPR etl::span<element_type, COUNT> last() const ETL_NOEXCEPT
765 {
766 return etl::span<element_type, COUNT>(pend - COUNT, pend);
767 }
768
769 //*************************************************************************
771 //*************************************************************************
772 ETL_NODISCARD ETL_CONSTEXPR etl::span<element_type, etl::dynamic_extent> last(size_t count) const ETL_NOEXCEPT
773 {
774 return etl::span<element_type, etl::dynamic_extent>(pend - count, pend);
775 }
776
777#if ETL_USING_CPP11
778 //*************************************************************************
780 //*************************************************************************
781 template <size_t OFFSET, size_t COUNT = etl::dynamic_extent>
782 ETL_NODISCARD ETL_CONSTEXPR
784 {
786 : etl::span<element_type, COUNT != etl::dynamic_extent ? COUNT : etl::dynamic_extent>(pbegin + OFFSET, pbegin + OFFSET + COUNT);
787 }
788#else
789 //*************************************************************************
791 //*************************************************************************
792 template <size_t OFFSET, size_t COUNT>
804#endif
805
806 //*************************************************************************
808 //*************************************************************************
809 ETL_NODISCARD ETL_CONSTEXPR14 etl::span<element_type, etl::dynamic_extent> subspan(size_t offset, size_t count = etl::dynamic_extent) const ETL_NOEXCEPT
810 {
811 return (count == etl::dynamic_extent) ? etl::span<element_type, etl::dynamic_extent>(pbegin + offset, pend)
812 : etl::span<element_type, etl::dynamic_extent>(pbegin + offset, pbegin + offset + count);
813 }
814
815 private:
816
817 pointer pbegin;
818 pointer pend;
819 };
820
821 //*************************************************************************
824 //*************************************************************************
825 template <typename T>
830
831 //*************************************************************************
834 //*************************************************************************
835 template <typename T>
840
841 template <typename T, size_t Extent>
842 ETL_CONSTANT size_t span<T, Extent>::extent;
843
844 template <typename T>
845 ETL_CONSTANT size_t span<T, etl::dynamic_extent>::extent;
846
847 //*************************************************************************
849 //*************************************************************************
850 template <typename T1, size_t N1, typename T2, size_t N2>
851 ETL_NODISCARD
852 ETL_CONSTEXPR
855 {
856 return (lhs.begin() == rhs.begin()) && (lhs.size() == rhs.size());
857 }
858
859 //*************************************************************************
861 //*************************************************************************
862 template <typename T1, size_t N1, typename T2, size_t N2>
863 ETL_NODISCARD
864 ETL_CONSTEXPR
865 bool operator !=(const etl::span<T1, N1>& lhs, const etl::span<T2, N2>& rhs) ETL_NOEXCEPT
866 {
867 return !(lhs == rhs);
868 }
869
870 //*************************************************************************
877 //*************************************************************************
878 template <typename T1, size_t N1, typename T2, size_t N2>
881 {
882 return (lhs.empty() && rhs.empty()) ||
883 ((lhs.begin() == rhs.begin()) && (lhs.size() == rhs.size())) ||
884 etl::equal(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
885 }
886
887 //*************************************************************************
889 //*************************************************************************
890#if ETL_USING_CPP17
891 template <typename TIterator>
892 span(const TIterator begin_, const TIterator end_)
893 ->span<etl::remove_pointer_t<TIterator>, etl::dynamic_extent>;
894
895 template <typename TIterator, typename TSize>
896 span(const TIterator begin_, const TSize size_)
897 ->span<etl::remove_pointer_t<TIterator>, etl::dynamic_extent>;
898
899 template <typename T, size_t N>
900 span(T(&)[N])
901 -> span<T, N>;
902
903 template <typename T, size_t N>
904 span(etl::array<T, N>&)
905 -> span<T, N>;
906
907 template <typename T, size_t N>
908 span(const etl::array<T, N>&)
909 -> span<const T, N>;
910
911#if ETL_USING_STL && ETL_USING_CPP11
912 template <typename T, size_t N>
913 span(std::array<T, N>&)
914 ->span<T, N>;
915
916 template <typename T, size_t N>
917 span(const std::array<T, N>&)
918 ->span<const T, N>;
919#endif
920#endif
921
922 //*************************************************************************
924 //*************************************************************************
925#if ETL_USING_8BIT_TYPES
926 template <typename T, size_t Extent>
927 struct hash<etl::span<T, Extent> >
928 {
929 size_t operator()(const etl::span<T>& view) const
930 {
931 return etl::private_hash::generic_hash<size_t>(reinterpret_cast<const uint8_t*>(view.data()),
932 reinterpret_cast<const uint8_t*>(view.data() + view.size()));
933 }
934 };
935#endif
936
937 //*************************************************************************
939 //*************************************************************************
940 template <class T, size_t N>
941 span<const byte, (N == etl::dynamic_extent) ? (etl::dynamic_extent) : (N * sizeof(T))>
942 as_bytes(span<T, N> s) ETL_NOEXCEPT
943 {
944 return span<const byte, (N == etl::dynamic_extent) ? (etl::dynamic_extent) : (N * sizeof(T))>(reinterpret_cast<byte*>(s.data()), s.size_bytes());
945 }
946
947 //*************************************************************************
949 //*************************************************************************
950 template <class T, size_t N>
951 span<byte, (N == etl::dynamic_extent) ? (etl::dynamic_extent) : (N * sizeof(T))>
953 {
954 ETL_STATIC_ASSERT(!etl::is_const<T>::value, "span<T> must be of non-const type");
955 return span<byte, (N == etl::dynamic_extent) ? (etl::dynamic_extent) : (N * sizeof(T))>(reinterpret_cast<byte*>(s.data()), s.size_bytes());
956 }
957}
958
959#endif
Definition iterator.h:228
ETL_NODISCARD ETL_CONSTEXPR circular_iterator begin_circular() const ETL_NOEXCEPT
Returns a circular iterator to the beginning of the span.
Definition span.h:612
ETL_CONSTEXPR span(const span &other) ETL_NOEXCEPT
Copy constructor.
Definition span.h:553
ETL_CONSTEXPR span() ETL_NOEXCEPT
Default constructor.
Definition span.h:473
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:793
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:652
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:747
ETL_CONSTEXPR 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:528
ETL_NODISCARD ETL_CONSTEXPR size_t size() const ETL_NOEXCEPT
Returns the size of the span.
Definition span.h:684
ETL_CONSTEXPR span(const etl::span< U, N > &other) ETL_NOEXCEPT
Copy constructor.
Definition span.h:563
ETL_NODISCARD ETL_CONSTEXPR14 etl::span< element_type, etl::dynamic_extent > subspan(size_t offset, size_t count=etl::dynamic_extent) const ETL_NOEXCEPT
Obtains a span that is a view from 'offset' over the next 'count' elements of this span.
Definition span.h:809
ETL_NODISCARD ETL_CONSTEXPR bool empty() const ETL_NOEXCEPT
Returns true if the span size is zero.
Definition span.h:676
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:764
ETL_NODISCARD ETL_CONSTEXPR etl::span< element_type, etl::dynamic_extent > first(size_t count) const ETL_NOEXCEPT
Obtains a span that is a view over the first count elements of this span.
Definition span.h:755
ETL_NODISCARD ETL_CONSTEXPR reference back() const ETL_NOEXCEPT
Returns a reference to the last element.
Definition span.h:580
ETL_NODISCARD ETL_CONSTEXPR etl::span< element_type, etl::dynamic_extent > last(size_t count) const ETL_NOEXCEPT
Obtains a span that is a view over the last count elements of this span.
Definition span.h:772
ETL_NODISCARD ETL_CONSTEXPR const_reverse_iterator crend() const ETL_NOEXCEPT
Returns a const reverse iterator to the end of the span.
Definition span.h:660
ETL_CONSTEXPR reference operator[](const size_t i) const
Returns a reference to the indexed value.
Definition span.h:738
ETL_NODISCARD ETL_CONSTEXPR const_iterator cend() const ETL_NOEXCEPT
Returns a const iterator to the end of the span.
Definition span.h:620
ETL_NODISCARD ETL_CONSTEXPR iterator begin() const ETL_NOEXCEPT
Returns an iterator to the beginning of the span.
Definition span.h:604
ETL_NODISCARD ETL_CONSTEXPR14 const_reference at(size_t i) const
Returns a const reference to the value at index 'i'.
Definition span.h:728
ETL_CONSTEXPR span(const 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:541
ETL_NODISCARD ETL_CONSTEXPR reference front() const ETL_NOEXCEPT
Returns a reference to the first element.
Definition span.h:572
ETL_CONSTEXPR span(element_type(&begin_)[Array_Size]) ETL_NOEXCEPT
Construct from C array.
Definition span.h:503
ETL_NODISCARD ETL_CONSTEXPR iterator end() const ETL_NOEXCEPT
Returns an iterator to the end of the span.
Definition span.h:628
ETL_CONSTEXPR span(const TIterator begin_, const TIterator end_)
Construct from iterators.
Definition span.h:493
ETL_NODISCARD ETL_CONSTEXPR const_iterator cbegin() const ETL_NOEXCEPT
Returns a const iterator to the beginning of the span.
Definition span.h:596
ETL_NODISCARD ETL_CONSTEXPR pointer data() const ETL_NOEXCEPT
Returns a pointer to the first element of the internal storage.
Definition span.h:588
ETL_CONSTEXPR span(const TIterator begin_, const TSize size_) ETL_NOEXCEPT
Construct from pointer + size.
Definition span.h:483
ETL_NODISCARD ETL_CONSTEXPR reverse_iterator rend() const ETL_NOEXCEPT
Returns a reverse iterator to the end of the span.
Definition span.h:668
ETL_NODISCARD ETL_CONSTEXPR size_t max_size() const ETL_NOEXCEPT
Returns the maximum possible size of the span.
Definition span.h:700
ETL_NODISCARD ETL_CONSTEXPR size_t size_bytes() const ETL_NOEXCEPT
Returns the size of the span in bytes.
Definition span.h:692
ETL_NODISCARD ETL_CONSTEXPR14 reference at(size_t i)
Returns a reference to the value at index 'i'.
Definition span.h:718
Span - Fixed Extent.
Definition span.h:63
ETL_NODISCARD ETL_CONSTEXPR reverse_iterator rend() const ETL_NOEXCEPT
Returns a reverse iterator to the end of the span.
Definition span.h:265
ETL_NODISCARD ETL_CONSTEXPR circular_iterator begin_circular() const ETL_NOEXCEPT
Returns a circular iterator to the beginning of the span.
Definition span.h:209
ETL_NODISCARD ETL_CONSTEXPR const_iterator cbegin() const ETL_NOEXCEPT
Returns a const iterator to the beginning of the span.
Definition span.h:193
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:363
ETL_CONSTEXPR span(const span &other) ETL_NOEXCEPT
Copy constructor.
Definition span.h:152
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:401
ETL_NODISCARD ETL_CONSTEXPR etl::span< element_type, etl::dynamic_extent > first(size_t count) const ETL_NOEXCEPT
Obtains a span that is a view over the first count elements of this span.
Definition span.h:354
ETL_NODISCARD ETL_CONSTEXPR etl::span< element_type, etl::dynamic_extent > subspan(size_t offset, size_t count=etl::dynamic_extent) const ETL_NOEXCEPT
Obtains a span that is a view from 'offset' over the next 'count' elements of this span.
Definition span.h:423
ETL_NODISCARD ETL_CONSTEXPR etl::span< element_type, etl::dynamic_extent > last(size_t count) const ETL_NOEXCEPT
Obtains a span that is a view over the last count elements of this span.
Definition span.h:374
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:249
ETL_NODISCARD ETL_CONSTEXPR iterator begin() const ETL_NOEXCEPT
Returns an iterator to the beginning of the span.
Definition span.h:201
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
Copy constructor.
Definition span.h:161
ETL_NODISCARD ETL_CONSTEXPR size_t size_bytes() const ETL_NOEXCEPT
Returns the size of the span in bytes.
Definition span.h:289
ETL_NODISCARD ETL_CONSTEXPR bool empty() const ETL_NOEXCEPT
Returns true if the span size is zero.
Definition span.h:273
ETL_NODISCARD ETL_CONSTEXPR const_iterator cend() const ETL_NOEXCEPT
Returns a const iterator to the end of the span.
Definition span.h:217
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:343
ETL_NODISCARD ETL_CONSTEXPR size_t size() const ETL_NOEXCEPT
Returns the size of the span.
Definition span.h:281
ETL_NODISCARD ETL_CONSTEXPR reference back() const ETL_NOEXCEPT
Returns a reference to the last element.
Definition span.h:177
ETL_CONSTEXPR14 span & operator=(const span &other) ETL_NOEXCEPT
Assign from a span.
Definition span.h:305
ETL_CONSTEXPR span(const TIterator begin_, const TIterator)
Construct from iterators.
Definition span.h:97
ETL_CONSTEXPR span(element_type(&begin_)[Array_Size]) ETL_NOEXCEPT
Construct from C array.
Definition span.h:106
ETL_NODISCARD ETL_CONSTEXPR pointer data() const ETL_NOEXCEPT
Returns a pointer to the first element of the internal storage.
Definition span.h:185
ETL_CONSTEXPR span(const 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:141
ETL_CONSTEXPR span(const TIterator begin_, const TSize) ETL_NOEXCEPT
Construct from iterators + size.
Definition span.h:88
ETL_NODISCARD ETL_CONSTEXPR14 reference at(size_t i)
Returns a reference to the value at index 'i'.
Definition span.h:314
ETL_CONSTEXPR reference operator[](const size_t i) const
Returns a reference to the indexed value.
Definition span.h:334
ETL_NODISCARD ETL_CONSTEXPR14 const_reference at(size_t i) const
Returns a const reference to the value at index 'i'.
Definition span.h:324
ETL_NODISCARD ETL_CONSTEXPR const_reverse_iterator crend() const ETL_NOEXCEPT
Returns a const reverse iterator to the end of the span.
Definition span.h:257
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:129
ETL_NODISCARD ETL_CONSTEXPR size_t max_size() const ETL_NOEXCEPT
Returns the maximum possible size of the span.
Definition span.h:297
ETL_NODISCARD ETL_CONSTEXPR reference front() const ETL_NOEXCEPT
Returns a reference to the first element.
Definition span.h:169
ETL_NODISCARD ETL_CONSTEXPR iterator end() const ETL_NOEXCEPT
Returns an iterator to the end of the span.
Definition span.h:225
Definition array.h:73
#define ETL_ASSERT(b, e)
Definition error_handler.h:356
enable_if
Definition type_traits_generator.h:1186
extent
Definition type_traits_generator.h:1197
is_array
Definition type_traits_generator.h:1086
is_const
Definition type_traits_generator.h:903
is_pointer
Definition type_traits_generator.h:1096
is_same
Definition type_traits_generator.h:1036
remove_cv
Definition type_traits_generator.h:963
remove_reference
Definition type_traits_generator.h:873
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:952
ETL_CONSTEXPR T * to_address(T *p)
Definition memory.h:62
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:942
bool operator!=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:654
bool operator==(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:642
ETL_CONSTEXPR span< T, Extent > make_span(T(&data)[Extent])
Definition span.h:439
pair holds two objects of arbitrary type
Definition utility.h:164