Embedded Template Library 1.0
Loading...
Searching...
No Matches
poly_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) 2022 John Wellbelove
11
12Inspired by the techniques used in https://github.com/mrshurik/poly_span
13Copyright(c) 2020 Dr. Alexander Bulovyatov
14
15Permission is hereby granted, free of charge, to any person obtaining a copy
16of this software and associated documentation files(the "Software"), to deal
17in the Software without restriction, including without limitation the rights
18to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
19copies of the Software, and to permit persons to whom the Software is
20furnished to do so, subject to the following conditions :
21
22The above copyright notice and this permission notice shall be included in all
23copies or substantial portions of the Software.
24
25THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
28AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
29LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
30OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31SOFTWARE.
32******************************************************************************/
33
34#ifndef ETL_POLY_SPAN_INCLUDED
35#define ETL_POLY_SPAN_INCLUDED
36
37#include "platform.h"
38#include "iterator.h"
39#include "nullptr.h"
40#include "hash.h"
41#include "type_traits.h"
42#include "integral_limits.h"
43#include "memory.h"
44#include "array.h"
45
47
48#if ETL_USING_STL && ETL_USING_CPP11
49 #include <array>
50#endif
51
54
55namespace etl
56{
57 template <typename U, size_t Extent>
58 class poly_span;
59
60 namespace private_poly_span
61 {
62 //*************************************************************************
63 // Iterator
64 //*************************************************************************
65 template <typename TBase>
67 {
68 public:
69
70 template <typename U, size_t Extent>
71 friend class etl::poly_span;
72
73 template <typename UBase>
74 friend class const_iterator;
75
76 typedef TBase value_type;
77 typedef ptrdiff_t difference_type;
78 typedef TBase* pointer;
79 typedef TBase& reference;
80 typedef ETL_OR_STD::random_access_iterator_tag iterator_category;
81
82 //*****************************************
83 iterator()
84 : ptr(ETL_NULLPTR)
85 , element_size(0U)
86 {
87 }
88
89 //*****************************************
90 iterator(const iterator& other)
91 : ptr(other.ptr)
92 , element_size(other.element_size)
93 {
94 }
95
96 //*****************************************
98 {
99 ptr = rhs.ptr;
100 element_size = rhs.element_size;
101
102 return *this;
103 }
104
105 //*****************************************
106 TBase& operator *() const
107 {
108 return *ptr;
109 }
110
111 //*****************************************
112 TBase* operator ->() const
113 {
114 return ptr;
115 }
116
117 //*****************************************
119 {
120 ptr = reinterpret_cast<pointer>(reinterpret_cast<char*>(ptr) + element_size);
121 return *this;
122 }
123
124 //*****************************************
126 {
127 iterator temp(*this);
128 ptr = reinterpret_cast<pointer>(reinterpret_cast<char*>(ptr) + element_size);
129 return temp;
130 }
131
132 //*****************************************
134 {
135 ptr = reinterpret_cast<pointer>(reinterpret_cast<char*>(ptr) - element_size);
136 return *this;
137 }
138
139 //*****************************************
141 {
142 iterator temp(*this);
143 ptr = reinterpret_cast<pointer>(reinterpret_cast<char*>(ptr) - element_size);
144 return temp;
145 }
146
147 //***************************************************
148 iterator& operator +=(difference_type offset)
149 {
150 ptr = reinterpret_cast<pointer>(reinterpret_cast<char*>(ptr) + (offset * difference_type(element_size)));
151 return *this;
152 }
153
154 //***************************************************
155 iterator& operator -=(difference_type offset)
156 {
157 ptr = reinterpret_cast<pointer>(reinterpret_cast<char*>(ptr) - (offset * difference_type(element_size)));
158 return *this;
159 }
160
161 //***************************************************
162 friend bool operator == (const iterator& lhs, const iterator& rhs)
163 {
164 return (lhs.ptr == rhs.ptr) && (lhs.element_size == rhs.element_size);
165 }
166
167 //***************************************************
168 friend bool operator != (const iterator& lhs, const iterator& rhs)
169 {
170 return !(lhs == rhs);
171 }
172
173 //***************************************************
174 friend bool operator < (const iterator& lhs, const iterator& rhs)
175 {
176 return lhs.ptr < rhs.ptr;
177 }
178
179 //***************************************************
180 friend bool operator <= (const iterator& lhs, const iterator& rhs)
181 {
182 return !(lhs > rhs);
183 }
184
185 //***************************************************
186 friend bool operator > (const iterator& lhs, const iterator& rhs)
187 {
188 return (rhs < lhs);
189 }
190
191 //***************************************************
192 friend bool operator >= (const iterator& lhs, const iterator& rhs)
193 {
194 return !(lhs < rhs);
195 }
196
197 //***************************************************
198 friend iterator operator + (const iterator& lhs, difference_type offset)
199 {
201 temp += offset;
202 return temp;
203 }
204
205 //***************************************************
206 friend iterator operator + (difference_type offset, const iterator& rhs)
207 {
209 temp += offset;
210 return temp;
211 }
212
213 //***************************************************
214 friend iterator operator - (const iterator& lhs, difference_type offset)
215 {
217 temp -= offset;
218 return temp;
219 }
220
221 //***************************************************
222 friend iterator operator - (difference_type offset, const iterator& rhs)
223 {
225 temp -= offset;
226 return temp;
227 }
228
229 //***************************************************
230 friend difference_type operator - (const iterator& lhs, const iterator& rhs)
231 {
232 return lhs.ptr - rhs.ptr;
233 }
234
235 private:
236
237 //***************************************************
238 iterator(TBase* pbegin_, size_t index_, size_t element_size_)
239 : element_size(element_size_)
240 {
241 ptr = reinterpret_cast<pointer>(reinterpret_cast<char*>(pbegin_) + (index_ * element_size));
242 }
243
244 TBase* ptr;
245 size_t element_size;
246 };
247 }
248
249 //***************************************************************************
251 //***************************************************************************
252 template <typename TBase, size_t Extent = etl::dynamic_extent>
254 {
255 public:
256
257 typedef TBase element_type;
259 typedef size_t size_type;
260 typedef TBase& reference;
261 typedef const TBase& const_reference;
262 typedef TBase* pointer;
263 typedef const TBase* const_pointer;
265
266 typedef ETL_OR_STD::reverse_iterator<iterator> reverse_iterator;
267
268 static ETL_CONSTANT size_t extent = Extent;
269
270 template <typename UBase, size_t UExtent>
271 friend class poly_span;
272
273 //*************************************************************************
275 //*************************************************************************
276 ETL_CONSTEXPR poly_span() ETL_NOEXCEPT
277 : pbegin(ETL_NULLPTR)
278 , element_size(0U)
279 {
280 }
281
282 //*************************************************************************
284 //*************************************************************************
285 template <typename TIterator, typename TSize>
286 ETL_CONSTEXPR poly_span(const TIterator begin_, const TSize /*size_*/) ETL_NOEXCEPT
287 : pbegin(etl::addressof(*begin_))
288 , element_size(sizeof(typename etl::iterator_traits<TIterator>::value_type))
289 {
290 typedef typename etl::iterator_traits<TIterator>::value_type data_type;
291
292 ETL_STATIC_ASSERT((etl::is_same<ETL_OR_STD::random_access_iterator_tag, typename etl::iterator_traits<TIterator>::iterator_category>::value), "Not a random access iterator");
293 ETL_STATIC_ASSERT((etl::is_base_of<TBase, data_type>::value || etl::is_same<TBase, data_type>::value), "TBase not a base of the data type");
294 }
295
296 //*************************************************************************
298 //*************************************************************************
299 template <typename TIterator>
300 ETL_CONSTEXPR poly_span(const TIterator begin_, const TIterator /*end_*/)
301 : pbegin(etl::addressof(*begin_))
303 {
304 typedef typename etl::iterator_traits<TIterator>::value_type data_type;
305 typedef typename etl::iterator_traits<TIterator>::iterator_category iterator_category;
306
307 ETL_STATIC_ASSERT((etl::is_same<ETL_OR_STD::random_access_iterator_tag, iterator_category>::value), "Not a random access iterator");
308 ETL_STATIC_ASSERT((etl::is_base_of<TBase, data_type>::value || etl::is_same<TBase, data_type>::value), "TBase not a base of the data type");
309 }
310
311 //*************************************************************************
313 //*************************************************************************
314 template<typename U, size_t N>
315 ETL_CONSTEXPR poly_span(U(&begin_)[N]) ETL_NOEXCEPT
316 : pbegin(begin_)
317 , element_size(sizeof(U))
318 {
319 ETL_STATIC_ASSERT(N <= Extent, "Array data overflow");
320 ETL_STATIC_ASSERT((etl::is_base_of<TBase, U>::value || etl::is_same<TBase, U>::value), "TBase not a base of the data type");
321 }
322
323 //*************************************************************************
325 //*************************************************************************
326 template <typename U, size_t N>
327 ETL_CONSTEXPR poly_span(etl::array<U, N>& a) ETL_NOEXCEPT
328 : pbegin(a.data())
329 , element_size(sizeof(U))
330 {
331 ETL_STATIC_ASSERT(N <= Extent, "Array data overflow");
332 ETL_STATIC_ASSERT((etl::is_base_of<TBase, U>::value || etl::is_same<TBase, U>::value), "TBase not a base of the data type");
333 }
334
335 //*************************************************************************
337 //*************************************************************************
338 template <typename U, size_t N>
339 ETL_CONSTEXPR poly_span(const etl::array<U, N>& a) ETL_NOEXCEPT
340 : pbegin(a.data())
341 , element_size(sizeof(U))
342 {
343 ETL_STATIC_ASSERT(N <= Extent, "Array data overflow");
344 ETL_STATIC_ASSERT((etl::is_base_of<TBase, U>::value || etl::is_same<TBase, U>::value), "TBase not a base of the data type");
345 }
346
347#if ETL_USING_STL && ETL_USING_CPP11
348 //*************************************************************************
350 //*************************************************************************
351 template <typename U, size_t N>
352 ETL_CONSTEXPR poly_span(std::array<U, N>& a) ETL_NOEXCEPT
353 : pbegin(a.data())
354 , element_size(sizeof(U))
355 {
356 ETL_STATIC_ASSERT(N <= Extent, "Array data overflow");
357 ETL_STATIC_ASSERT((etl::is_base_of<TBase, U>::value || etl::is_same<TBase, U>::value), "TBase not a base of U");
358 }
359
360 //*************************************************************************
362 //*************************************************************************
363 template <typename U, size_t N>
364 ETL_CONSTEXPR poly_span(const std::array<U, N>& a) ETL_NOEXCEPT
365 : pbegin(a.data())
366 , element_size(sizeof(U))
367 {
368 ETL_STATIC_ASSERT(N <= Extent, "Array data overflow");
369 ETL_STATIC_ASSERT((etl::is_base_of<TBase, U>::value || etl::is_same<TBase, U>::value), "TBase not a base of U");
370 }
371#endif
372
373 //*************************************************************************
375 //*************************************************************************
376 ETL_CONSTEXPR poly_span(const poly_span<TBase, Extent>& other) ETL_NOEXCEPT
377 : pbegin(other.pbegin)
378 , element_size(other.element_size)
379 {
380 }
381
382 //*************************************************************************
384 //*************************************************************************
385 template <typename UBase>
386 ETL_CONSTEXPR poly_span(const poly_span<UBase, Extent>& other) ETL_NOEXCEPT
387 : pbegin(other.pbegin)
388 , element_size(other.element_size)
389 {
390 }
391
392 //*************************************************************************
394 //*************************************************************************
395 ETL_NODISCARD ETL_CONSTEXPR reference front() const ETL_NOEXCEPT
396 {
397 return *pbegin;
398 }
399
400 //*************************************************************************
402 //*************************************************************************
403 ETL_NODISCARD ETL_CONSTEXPR reference back() const ETL_NOEXCEPT
404 {
405 return *element_at(Extent - 1U);
406 }
407
408 //*************************************************************************
410 //*************************************************************************
411 ETL_NODISCARD ETL_CONSTEXPR pointer data() const ETL_NOEXCEPT
412 {
413 return pbegin;
414 }
415
416 //*************************************************************************
418 //*************************************************************************
419 ETL_NODISCARD ETL_CONSTEXPR iterator begin() const ETL_NOEXCEPT
420 {
421 return iterator(pbegin, 0U, element_size);
422 }
423
424 //*************************************************************************
426 //*************************************************************************
427 ETL_NODISCARD ETL_CONSTEXPR iterator end() const ETL_NOEXCEPT
428 {
429 return iterator(pbegin, Extent, element_size);
430 }
431
432 //*************************************************************************
433 // Returns an reverse iterator to the reverse beginning of the poly_span.
434 //*************************************************************************
435 ETL_CONSTEXPR reverse_iterator rbegin() const ETL_NOEXCEPT
436 {
437 return reverse_iterator(end());
438 }
439
440 //*************************************************************************
442 //*************************************************************************
443 ETL_CONSTEXPR reverse_iterator rend() const ETL_NOEXCEPT
444 {
445 return reverse_iterator(begin());
446 }
447
448 //*************************************************************************
450 //*************************************************************************
451 ETL_NODISCARD ETL_CONSTEXPR bool empty() const ETL_NOEXCEPT
452 {
453 return (Extent == 0U);
454 }
455
456 //*************************************************************************
458 //*************************************************************************
459 ETL_NODISCARD ETL_CONSTEXPR size_t size() const ETL_NOEXCEPT
460 {
461 return Extent;
462 }
463
464 //*************************************************************************
466 //*************************************************************************
467 ETL_NODISCARD ETL_CONSTEXPR size_t size_of_element() const ETL_NOEXCEPT
468 {
469 return element_size;
470 }
471
472 //*************************************************************************
474 //*************************************************************************
475 ETL_NODISCARD ETL_CONSTEXPR size_t size_bytes() const ETL_NOEXCEPT
476 {
477 return Extent * element_size;
478 }
479
480 //*************************************************************************
482 //*************************************************************************
483 ETL_CONSTEXPR14 poly_span& operator =(const poly_span& other) ETL_NOEXCEPT
484 {
485 pbegin = other.pbegin;
486 element_size = other.element_size;
487 return *this;
488 }
489
490 //*************************************************************************
492 //*************************************************************************
493 template <typename UBase>
494 ETL_CONSTEXPR14 poly_span& operator =(const poly_span<UBase, Extent>& other) ETL_NOEXCEPT
495 {
496 pbegin = other.pbegin;
497 element_size = other.element_size;
498 return *this;
499 }
500
501 //*************************************************************************
503 //*************************************************************************
504 ETL_CONSTEXPR reference operator[](size_t i) const
505 {
506 return *element_at(i);
507 }
508
509 //*************************************************************************
511 //*************************************************************************
512 template <size_t COUNT>
513 ETL_NODISCARD ETL_CONSTEXPR etl::poly_span<element_type, COUNT> first() const ETL_NOEXCEPT
514 {
515 return etl::poly_span<element_type, COUNT>(pbegin, 0U, COUNT, element_size);
516 }
517
518 //*************************************************************************
520 //*************************************************************************
521 ETL_NODISCARD ETL_CONSTEXPR etl::poly_span<element_type, etl::dynamic_extent> first(size_t count) const
522 {
523 return etl::poly_span<element_type, etl::dynamic_extent>(pbegin, 0U, count, element_size);
524 }
525
526 //*************************************************************************
528 //*************************************************************************
529 template <size_t COUNT>
530 ETL_NODISCARD ETL_CONSTEXPR etl::poly_span<element_type, COUNT> last() const ETL_NOEXCEPT
531 {
532 return etl::poly_span<element_type, COUNT>(pbegin, Extent - COUNT, COUNT, element_size);
533 }
534
535 //*************************************************************************
537 //*************************************************************************
538 ETL_NODISCARD ETL_CONSTEXPR etl::poly_span<element_type, etl::dynamic_extent> last(size_t count) const ETL_NOEXCEPT
539 {
540 return etl::poly_span<element_type, etl::dynamic_extent>(pbegin, Extent - count, count, element_size);
541 }
542
543#if ETL_USING_CPP11
544 //*************************************************************************
546 //*************************************************************************
547 template <size_t OFFSET, size_t COUNT = etl::dynamic_extent>
548 ETL_NODISCARD ETL_CONSTEXPR etl::poly_span<element_type, COUNT != etl::dynamic_extent ? COUNT : Extent - OFFSET> subspan() const ETL_NOEXCEPT
549 {
550 return (COUNT == etl::dynamic_extent) ? etl::poly_span<element_type, COUNT != etl::dynamic_extent ? COUNT : Extent - OFFSET>(pbegin, OFFSET, Extent, element_size)
551 : etl::poly_span<element_type, COUNT != etl::dynamic_extent ? COUNT : Extent - OFFSET>(pbegin, OFFSET, COUNT, element_size);
552 }
553#else
554 //*************************************************************************
556 //*************************************************************************
557 template <size_t OFFSET, size_t COUNT>
558 etl::poly_span<element_type, COUNT != etl::dynamic_extent ? COUNT : Extent - OFFSET> subspan() const
559 {
560 if (COUNT == etl::dynamic_extent)
561 {
562 return etl::poly_span<element_type, COUNT != etl::dynamic_extent ? COUNT : Extent - OFFSET>(pbegin, OFFSET, Extent, element_size);
563 }
564 else
565 {
566 return etl::poly_span<element_type, COUNT != etl::dynamic_extent ? COUNT : Extent - OFFSET>(pbegin, OFFSET, element_size);
567 }
568 }
569#endif
570
571 //*************************************************************************
573 //*************************************************************************
574 ETL_NODISCARD ETL_CONSTEXPR etl::poly_span<element_type, etl::dynamic_extent> subspan(size_t offset, size_t count = etl::dynamic_extent) const ETL_NOEXCEPT
575 {
576 return (count == etl::dynamic_extent) ? etl::poly_span<element_type, etl::dynamic_extent>(pbegin, offset, Extent, element_size)
577 : etl::poly_span<element_type, etl::dynamic_extent>(pbegin, offset, count, element_size);
578 }
579
580 protected:
581
582 //***************************************************************************
583 template <typename TFrom>
585 {
586 typedef typename etl::conditional<etl::is_const<TFrom>::value, const char*, char*>::type type;
587 };
588
589 typedef typename char_ptr_type<TBase>::type char_ptr_t;
590
591 //***************************************************************************
592 pointer element_at(size_t index) const ETL_NOEXCEPT
593 {
594 char_ptr_t base = reinterpret_cast<char_ptr_t>(pbegin);
595 return reinterpret_cast<pointer>(base + (index * element_size));
596 }
597
598 //*************************************************************************
601 //*************************************************************************
602 poly_span(TBase* pbegin_, size_t offset_, size_t /*extent_*/, size_t element_size_) ETL_NOEXCEPT
603 : pbegin(reinterpret_cast<pointer>(reinterpret_cast<char_ptr_t>(pbegin_) + (offset_ * element_size_)))
604 , element_size(element_size_)
605 {
606 }
607
608 private:
609
610 pointer pbegin;
611 size_t element_size;
612 };
613
614 template <typename TBase, size_t Extent>
615 ETL_CONSTANT size_t poly_span<TBase, Extent>::extent;
616
617 //***************************************************************************
619 //***************************************************************************
620 template <typename TBase>
621 class poly_span<TBase, etl::dynamic_extent>
622 {
623 public:
624
625 typedef TBase element_type;
627 typedef size_t size_type;
628 typedef TBase& reference;
629 typedef const TBase& const_reference;
630 typedef TBase* pointer;
631 typedef const TBase* const_pointer;
633 typedef ETL_OR_STD::reverse_iterator<iterator> reverse_iterator;
634
635 static ETL_CONSTANT size_t extent = etl::dynamic_extent;
636
637 template <typename UBase, size_t UExtent>
638 friend class poly_span;
639
640 //*************************************************************************
642 //*************************************************************************
643 ETL_CONSTEXPR poly_span() ETL_NOEXCEPT
644 : pbegin(ETL_NULLPTR)
645 , element_size(0U)
646 , span_extent(0U)
647 {
648 }
649
650 //*************************************************************************
652 //*************************************************************************
653 template <typename TIterator, typename TSize>
654 ETL_CONSTEXPR poly_span(const TIterator begin_, const TSize size_) ETL_NOEXCEPT
655 : pbegin(etl::addressof(*begin_))
656 , element_size(sizeof(typename etl::iterator_traits<TIterator>::value_type))
657 , span_extent(size_)
658 {
659 typedef typename etl::iterator_traits<TIterator>::value_type data_type;
660 typedef typename etl::iterator_traits<TIterator>::iterator_category iterator_category;
661
662 ETL_STATIC_ASSERT((etl::is_same<ETL_OR_STD::random_access_iterator_tag, iterator_category>::value), "Not a random access iterator");
663 ETL_STATIC_ASSERT((etl::is_base_of<TBase, data_type>::value || etl::is_same<TBase, data_type>::value), "TBase not a base of the data type");
664 }
665
666 //*************************************************************************
668 //*************************************************************************
669 template <typename TIterator>
670 ETL_CONSTEXPR poly_span(const TIterator begin_, const TIterator end_)
671 : pbegin(etl::addressof(*begin_))
673 , span_extent(size_t(etl::distance(begin_, end_)))
674 {
675 typedef typename etl::iterator_traits<TIterator>::value_type data_type;
676 typedef typename etl::iterator_traits<TIterator>::iterator_category iterator_category;
677
678 ETL_STATIC_ASSERT((etl::is_same<ETL_OR_STD::random_access_iterator_tag, iterator_category>::value), "Not a random access iterator");
679 ETL_STATIC_ASSERT((etl::is_base_of<TBase, data_type>::value || etl::is_same<TBase, data_type>::value), "TBase not a base of the data type");
680 }
681
682 //*************************************************************************
684 //*************************************************************************
685 template<typename U, size_t N>
686 ETL_CONSTEXPR poly_span(U(&begin_)[N]) ETL_NOEXCEPT
687 : pbegin(begin_)
688 , element_size(sizeof(U))
689 , span_extent(N)
690 {
691 ETL_STATIC_ASSERT((etl::is_base_of<TBase, U>::value || etl::is_same<TBase, U>::value), "TBase not a base of the data type");
692 }
693
694 //*************************************************************************
696 //*************************************************************************
697 template <typename U, size_t N>
698 ETL_CONSTEXPR poly_span(etl::array<U, N>& a) ETL_NOEXCEPT
699 : pbegin(a.data())
700 , element_size(sizeof(U))
701 , span_extent(N)
702 {
703 ETL_STATIC_ASSERT((etl::is_base_of<TBase, U>::value || etl::is_same<TBase, U>::value), "TBase not a base of the data type");
704 }
705
706 //*************************************************************************
708 //*************************************************************************
709 template <typename U, size_t N>
710 ETL_CONSTEXPR poly_span(const etl::array<U, N>& a) ETL_NOEXCEPT
711 : pbegin(a.data())
712 , element_size(sizeof(U))
713 , span_extent(N)
714 {
715 ETL_STATIC_ASSERT((etl::is_base_of<TBase, U>::value || etl::is_same<TBase, U>::value), "TBase not a base of the data type");
716 }
717
718#if ETL_USING_STL && ETL_USING_CPP11
719 //*************************************************************************
721 //*************************************************************************
722 template <typename U, size_t N>
723 ETL_CONSTEXPR poly_span(std::array<U, N>& a) ETL_NOEXCEPT
724 : pbegin(a.data())
725 , element_size(sizeof(U))
726 , span_extent(N)
727 {
728 ETL_STATIC_ASSERT((etl::is_base_of<TBase, U>::value || etl::is_same<TBase, U>::value), "TBase not a base of U");
729 }
730
731 //*************************************************************************
733 //*************************************************************************
734 template <typename U, size_t N>
735 ETL_CONSTEXPR poly_span(const std::array<U, N>& a) ETL_NOEXCEPT
736 : pbegin(a.data())
737 , element_size(sizeof(U))
738 , span_extent(N)
739 {
740 ETL_STATIC_ASSERT((etl::is_base_of<TBase, U>::value || etl::is_same<TBase, U>::value), "TBase not a base of U");
741 }
742#endif
743
744 //*************************************************************************
746 //*************************************************************************
747 ETL_CONSTEXPR poly_span(const poly_span<TBase, etl::dynamic_extent>& other) ETL_NOEXCEPT
748 : pbegin(other.pbegin)
749 , element_size(other.element_size)
750 , span_extent(other.span_extent)
751 {
752 }
753
754 //*************************************************************************
756 //*************************************************************************
757 template <typename UBase>
758 ETL_CONSTEXPR poly_span(const poly_span<UBase, etl::dynamic_extent>& other) ETL_NOEXCEPT
759 : pbegin(other.pbegin)
760 , element_size(other.element_size)
761 , span_extent(other.span_extent)
762 {
763 }
764
765 //*************************************************************************
767 //*************************************************************************
768 ETL_NODISCARD ETL_CONSTEXPR reference front() const ETL_NOEXCEPT
769 {
770 return *pbegin;
771 }
772
773 //*************************************************************************
775 //*************************************************************************
776 ETL_NODISCARD ETL_CONSTEXPR reference back() const ETL_NOEXCEPT
777 {
778 return *element_at(span_extent - 1U);
779 }
780
781 //*************************************************************************
783 //*************************************************************************
784 ETL_NODISCARD ETL_CONSTEXPR pointer data() const ETL_NOEXCEPT
785 {
786 return pbegin;
787 }
788
789 //*************************************************************************
791 //*************************************************************************
792 ETL_NODISCARD ETL_CONSTEXPR iterator begin() const ETL_NOEXCEPT
793 {
794 return iterator(pbegin, 0U, element_size);
795 }
796
797 //*************************************************************************
799 //*************************************************************************
800 ETL_NODISCARD ETL_CONSTEXPR iterator end() const ETL_NOEXCEPT
801 {
802 return iterator(pbegin, span_extent, element_size);
803 }
804
805 //*************************************************************************
806 // Returns an reverse iterator to the reverse beginning of the poly_span.
807 //*************************************************************************
808 ETL_NODISCARD ETL_CONSTEXPR reverse_iterator rbegin() const ETL_NOEXCEPT
809 {
810 return reverse_iterator(end());
811 }
812
813 //*************************************************************************
815 //*************************************************************************
816 ETL_NODISCARD ETL_CONSTEXPR reverse_iterator rend() const ETL_NOEXCEPT
817 {
818 return reverse_iterator(begin());
819 }
820
821 //*************************************************************************
823 //*************************************************************************
824 ETL_NODISCARD ETL_CONSTEXPR bool empty() const ETL_NOEXCEPT
825 {
826 return (span_extent == 0);
827 }
828
829 //*************************************************************************
831 //*************************************************************************
832 ETL_NODISCARD ETL_CONSTEXPR size_t size() const ETL_NOEXCEPT
833 {
834 return span_extent;
835 }
836
837 //*************************************************************************
839 //*************************************************************************
840 ETL_NODISCARD ETL_CONSTEXPR size_t size_of_element() const ETL_NOEXCEPT
841 {
842 return element_size;
843 }
844
845 //*************************************************************************
847 //*************************************************************************
848 ETL_NODISCARD ETL_CONSTEXPR size_t size_bytes() const ETL_NOEXCEPT
849 {
850 return element_size * span_extent;
851 }
852
853 //*************************************************************************
855 //*************************************************************************
856 ETL_CONSTEXPR14 poly_span& operator =(const poly_span& other) ETL_NOEXCEPT
857 {
858 pbegin = other.pbegin;
859 element_size = other.element_size;
860 span_extent = other.span_extent;
861 return *this;
862 }
863
864 //*************************************************************************
866 //*************************************************************************
867 template <typename UBase>
869 {
870 pbegin = other.pbegin;
871 element_size = other.element_size;
872 span_extent = other.span_extent;
873 return *this;
874 }
875
876 //*************************************************************************
878 //*************************************************************************
879 ETL_CONSTEXPR reference operator[](size_t i) const
880 {
881 return *element_at(i);
882 }
883
884 //*************************************************************************
886 //*************************************************************************
887 template <size_t COUNT>
888 ETL_NODISCARD ETL_CONSTEXPR etl::poly_span<element_type, COUNT> first() const ETL_NOEXCEPT
889 {
890 return etl::poly_span<element_type, COUNT>(pbegin, 0U, COUNT, element_size);
891 }
892
893 //*************************************************************************
895 //*************************************************************************
896 ETL_NODISCARD ETL_CONSTEXPR etl::poly_span<element_type, etl::dynamic_extent> first(size_t count) const ETL_NOEXCEPT
897 {
898 return etl::poly_span<element_type, etl::dynamic_extent>(pbegin, 0U, count, element_size);
899 }
900
901 //*************************************************************************
903 //*************************************************************************
904 template <size_t COUNT>
905 ETL_NODISCARD ETL_CONSTEXPR etl::poly_span<element_type, COUNT> last() const ETL_NOEXCEPT
906 {
907 return etl::poly_span<element_type, COUNT>(pbegin, span_extent - COUNT, COUNT, element_size);
908 }
909
910 //*************************************************************************
912 //*************************************************************************
913 ETL_NODISCARD ETL_CONSTEXPR etl::poly_span<element_type, etl::dynamic_extent> last(size_t count) const ETL_NOEXCEPT
914 {
915 return etl::poly_span<element_type, etl::dynamic_extent>(pbegin, span_extent - count, count, element_size);
916 }
917
918#if ETL_USING_CPP11
919 //*************************************************************************
921 //*************************************************************************
922 template <size_t OFFSET, size_t COUNT = etl::dynamic_extent>
924 {
925 return (COUNT == etl::dynamic_extent) ? etl::poly_span<element_type, COUNT != etl::dynamic_extent ? COUNT : etl::dynamic_extent>(pbegin, OFFSET, span_extent, element_size)
926 : etl::poly_span<element_type, COUNT != etl::dynamic_extent ? COUNT : etl::dynamic_extent>(pbegin, OFFSET, COUNT, element_size);
927 }
928#else
929 //*************************************************************************
931 //*************************************************************************
932 template <size_t OFFSET, size_t COUNT>
944#endif
945
946 //*************************************************************************
948 //*************************************************************************
949 ETL_NODISCARD ETL_CONSTEXPR etl::poly_span<element_type, etl::dynamic_extent> subspan(size_t offset, size_t count = etl::dynamic_extent) const ETL_NOEXCEPT
950 {
951 return (count == etl::dynamic_extent) ? etl::poly_span<element_type, etl::dynamic_extent>(pbegin, offset, span_extent - offset, element_size)
952 : etl::poly_span<element_type, etl::dynamic_extent>(pbegin, offset, count, element_size);
953 }
954
955protected:
956
957 //*************************************************************************
959 //*************************************************************************
960 poly_span(TBase* pbegin_, size_t offset_, size_t extent_, size_t element_size_) ETL_NOEXCEPT
961 : pbegin(reinterpret_cast<pointer>(reinterpret_cast<char_ptr_t>(pbegin_) + (offset_ * element_size_)))
962 , element_size(element_size_)
963 , span_extent(extent_)
964 {
965 }
966
967 private:
968
969 //***************************************************************************
970 template <typename TFrom>
971 struct char_ptr_type
972 {
973 typedef typename etl::conditional<etl::is_const<TFrom>::value, const char*, char*>::type type;
974 };
975
976 typedef typename char_ptr_type<TBase>::type char_ptr_t;
977
978 //***************************************************************************
979 pointer element_at(size_t index) const ETL_NOEXCEPT
980 {
981 char_ptr_t base = reinterpret_cast<char_ptr_t>(pbegin);
982 return reinterpret_cast<pointer>(base + (index * element_size));
983 }
984
985 pointer pbegin;
986 size_t element_size;
987 size_t span_extent;
988 };
989
990 template <typename TBase>
991 ETL_CONSTANT size_t poly_span<TBase, etl::dynamic_extent>::extent;
992
993 //*************************************************************************
995 //*************************************************************************
996#if ETL_USING_CPP17
997 template <typename TIterator>
998 poly_span(const TIterator begin_, const TIterator end_)
999 ->poly_span<etl::remove_pointer_t<TIterator>, etl::dynamic_extent>;
1000
1001 template <typename TIterator, typename TSize>
1002 poly_span(const TIterator begin_, const TSize size_)
1003 ->poly_span<etl::remove_pointer_t<TIterator>, etl::dynamic_extent>;
1004
1005 template <typename T, size_t N>
1006 poly_span(T(&)[N])
1007 ->poly_span<T, N>;
1008
1009 template <typename T, size_t N>
1010 poly_span(etl::array<T, N>&)
1011 ->poly_span<T, N>;
1012
1013 template <typename T, size_t N>
1014 poly_span(const etl::array<T, N>&)
1015 ->poly_span<const T, N>;
1016
1017#if ETL_USING_STL
1018 template <typename T, size_t N>
1019 poly_span(std::array<T, N>&)
1020 ->poly_span<T, N>;
1021
1022 template <typename T, size_t N>
1023 poly_span(const std::array<T, N>&)
1024 ->poly_span<const T, N>;
1025#endif
1026#endif
1027
1028 //*************************************************************************
1030 //*************************************************************************
1031#if ETL_USING_8BIT_TYPES
1032 template <typename TBase, size_t Extent>
1033 struct hash<etl::poly_span<TBase, Extent> >
1034 {
1035 size_t operator()(const etl::poly_span<TBase, Extent>& view) const
1036 {
1037 return etl::private_hash::generic_hash<size_t>(reinterpret_cast<const uint8_t*>(view.data()),
1038 reinterpret_cast<const uint8_t*>(view.data() + view.size()));
1039 }
1040 };
1041#endif
1042}
1043
1044#endif
ETL_CONSTEXPR poly_span(const TIterator begin_, const TSize size_) ETL_NOEXCEPT
Construct from iterator + size.
Definition poly_span.h:654
ETL_CONSTEXPR poly_span() ETL_NOEXCEPT
Default constructor.
Definition poly_span.h:643
ETL_NODISCARD ETL_CONSTEXPR reference front() const ETL_NOEXCEPT
Returns a reference to the first element.
Definition poly_span.h:768
ETL_NODISCARD ETL_CONSTEXPR etl::poly_span< element_type, etl::dynamic_extent > last(size_t count) const ETL_NOEXCEPT
Obtains a poly_span that is a view over the last count elements of this poly_span.
Definition poly_span.h:913
ETL_NODISCARD ETL_CONSTEXPR etl::poly_span< element_type, COUNT > last() const ETL_NOEXCEPT
Obtains a poly_span that is a view over the last COUNT elements of this poly_span.
Definition poly_span.h:905
ETL_NODISCARD ETL_CONSTEXPR reverse_iterator rend() const ETL_NOEXCEPT
Returns a reverse iterator to the end of the poly_span.
Definition poly_span.h:816
ETL_NODISCARD ETL_CONSTEXPR iterator begin() const ETL_NOEXCEPT
Returns an iterator to the beginning of the poly_span.
Definition poly_span.h:792
ETL_NODISCARD ETL_CONSTEXPR pointer data() const ETL_NOEXCEPT
Returns a pointer to the first element of the internal storage.
Definition poly_span.h:784
ETL_NODISCARD ETL_CONSTEXPR size_t size() const ETL_NOEXCEPT
Returns the size of the poly_span.
Definition poly_span.h:832
ETL_NODISCARD ETL_CONSTEXPR etl::poly_span< element_type, etl::dynamic_extent > subspan(size_t offset, size_t count=etl::dynamic_extent) const ETL_NOEXCEPT
Obtains a poly_span that is a view from 'offset' over the next 'count' elements of this poly_span.
Definition poly_span.h:949
ETL_NODISCARD ETL_CONSTEXPR bool empty() const ETL_NOEXCEPT
Returns true if the poly_span size is zero.
Definition poly_span.h:824
ETL_NODISCARD ETL_CONSTEXPR size_t size_of_element() const ETL_NOEXCEPT
Returns the size of the type stored in the poly_span.
Definition poly_span.h:840
ETL_NODISCARD ETL_CONSTEXPR etl::poly_span< element_type, COUNT > first() const ETL_NOEXCEPT
Obtains a poly_span that is a view over the first COUNT elements of this poly_span.
Definition poly_span.h:888
ETL_CONSTEXPR poly_span(etl::array< U, N > &a) ETL_NOEXCEPT
Construct from etl::array.
Definition poly_span.h:698
poly_span(TBase *pbegin_, size_t offset_, size_t extent_, size_t element_size_) ETL_NOEXCEPT
Construct from iterator + offset + size + element size.
Definition poly_span.h:960
ETL_CONSTEXPR poly_span(const etl::array< U, N > &a) ETL_NOEXCEPT
Construct from etl::array.
Definition poly_span.h:710
ETL_CONSTEXPR poly_span(const TIterator begin_, const TIterator end_)
Construct from iterators.
Definition poly_span.h:670
ETL_NODISCARD ETL_CONSTEXPR size_t size_bytes() const ETL_NOEXCEPT
Returns the size of the poly_span in bytes.
Definition poly_span.h:848
ETL_CONSTEXPR poly_span(const poly_span< TBase, etl::dynamic_extent > &other) ETL_NOEXCEPT
Copy constructor.
Definition poly_span.h:747
ETL_CONSTEXPR reference operator[](size_t i) const
Returns a reference to the indexed value.
Definition poly_span.h:879
ETL_CONSTEXPR poly_span(U(&begin_)[N]) ETL_NOEXCEPT
Construct from C array.
Definition poly_span.h:686
ETL_NODISCARD ETL_CONSTEXPR reference back() const ETL_NOEXCEPT
Returns a reference to the last element.
Definition poly_span.h:776
ETL_CONSTEXPR poly_span(const poly_span< UBase, etl::dynamic_extent > &other) ETL_NOEXCEPT
Copy constructor.
Definition poly_span.h:758
ETL_NODISCARD ETL_CONSTEXPR etl::poly_span< element_type, etl::dynamic_extent > first(size_t count) const ETL_NOEXCEPT
Obtains a poly_span that is a view over the first count elements of this poly_span.
Definition poly_span.h:896
etl::poly_span< element_type, COUNT !=etl::dynamic_extent ? COUNT :etl::dynamic_extent > subspan() const
Obtains a poly_span that is a view from OFFSET over the next COUNT elements of this poly_span.
Definition poly_span.h:933
ETL_NODISCARD ETL_CONSTEXPR iterator end() const ETL_NOEXCEPT
Returns an iterator to the end of the poly_span.
Definition poly_span.h:800
Poly Span - Fixed Extent.
Definition poly_span.h:254
ETL_NODISCARD ETL_CONSTEXPR size_t size_of_element() const ETL_NOEXCEPT
Returns the size of the type stored in the poly_span.
Definition poly_span.h:467
ETL_NODISCARD ETL_CONSTEXPR iterator end() const ETL_NOEXCEPT
Returns an iterator to the end of the poly_span.
Definition poly_span.h:427
ETL_CONSTEXPR reverse_iterator rend() const ETL_NOEXCEPT
Returns a reverse iterator to the end of the poly_span.
Definition poly_span.h:443
ETL_NODISCARD ETL_CONSTEXPR pointer data() const ETL_NOEXCEPT
Returns a pointer to the first element of the internal storage.
Definition poly_span.h:411
poly_span(TBase *pbegin_, size_t offset_, size_t, size_t element_size_) ETL_NOEXCEPT
Definition poly_span.h:602
ETL_CONSTEXPR14 poly_span & operator=(const poly_span &other) ETL_NOEXCEPT
Assign from a poly_span.
Definition poly_span.h:483
ETL_CONSTEXPR poly_span(U(&begin_)[N]) ETL_NOEXCEPT
Construct from C array.
Definition poly_span.h:315
ETL_NODISCARD ETL_CONSTEXPR bool empty() const ETL_NOEXCEPT
Returns true if the poly_span size is zero.
Definition poly_span.h:451
ETL_NODISCARD ETL_CONSTEXPR reference front() const ETL_NOEXCEPT
Returns a reference to the first element.
Definition poly_span.h:395
ETL_CONSTEXPR poly_span(etl::array< U, N > &a) ETL_NOEXCEPT
Construct from etl::array.
Definition poly_span.h:327
ETL_NODISCARD ETL_CONSTEXPR etl::poly_span< element_type, etl::dynamic_extent > subspan(size_t offset, size_t count=etl::dynamic_extent) const ETL_NOEXCEPT
Obtains a poly_span that is a view from 'offset' over the next 'count' elements of this poly_span.
Definition poly_span.h:574
ETL_CONSTEXPR poly_span(const etl::array< U, N > &a) ETL_NOEXCEPT
Construct from etl::array.
Definition poly_span.h:339
ETL_CONSTEXPR poly_span() ETL_NOEXCEPT
Default constructor.
Definition poly_span.h:276
ETL_NODISCARD ETL_CONSTEXPR etl::poly_span< element_type, etl::dynamic_extent > first(size_t count) const
Obtains a poly_span that is a view over the first count elements of this poly_span.
Definition poly_span.h:521
ETL_CONSTEXPR poly_span(const TIterator begin_, const TSize) ETL_NOEXCEPT
Construct from iterator + size.
Definition poly_span.h:286
ETL_NODISCARD ETL_CONSTEXPR iterator begin() const ETL_NOEXCEPT
Returns an iterator to the beginning of the poly_span.
Definition poly_span.h:419
etl::poly_span< element_type, COUNT !=etl::dynamic_extent ? COUNT :Extent - OFFSET > subspan() const
Obtains a poly_span that is a view from OFFSET over the next COUNT elements of this poly_span.
Definition poly_span.h:558
ETL_NODISCARD ETL_CONSTEXPR reference back() const ETL_NOEXCEPT
Returns a reference to the last element.
Definition poly_span.h:403
ETL_NODISCARD ETL_CONSTEXPR size_t size_bytes() const ETL_NOEXCEPT
Returns the size of the poly_span in bytes.
Definition poly_span.h:475
ETL_NODISCARD ETL_CONSTEXPR etl::poly_span< element_type, COUNT > last() const ETL_NOEXCEPT
Obtains a poly_span that is a view over the last COUNT elements of this poly_span.
Definition poly_span.h:530
ETL_NODISCARD ETL_CONSTEXPR size_t size() const ETL_NOEXCEPT
Returns the size of the poly_span.
Definition poly_span.h:459
ETL_CONSTEXPR poly_span(const poly_span< TBase, Extent > &other) ETL_NOEXCEPT
Copy constructor.
Definition poly_span.h:376
ETL_NODISCARD ETL_CONSTEXPR etl::poly_span< element_type, etl::dynamic_extent > last(size_t count) const ETL_NOEXCEPT
Obtains a poly_span that is a view over the last count elements of this poly_span.
Definition poly_span.h:538
ETL_CONSTEXPR reference operator[](size_t i) const
Returns a reference to the indexed value.
Definition poly_span.h:504
ETL_CONSTEXPR poly_span(const poly_span< UBase, Extent > &other) ETL_NOEXCEPT
Copy constructor.
Definition poly_span.h:386
ETL_CONSTEXPR poly_span(const TIterator begin_, const TIterator)
Construct from iterators.
Definition poly_span.h:300
ETL_NODISCARD ETL_CONSTEXPR etl::poly_span< element_type, COUNT > first() const ETL_NOEXCEPT
Obtains a poly_span that is a view over the first COUNT elements of this poly_span.
Definition poly_span.h:513
Definition poly_span.h:67
Definition iterator.h:228
ETL_CONSTEXPR14 bool operator==(const etl::expected< TValue, TError > &lhs, const etl::expected< TValue2, TError2 > &rhs)
Equivalence operators.
Definition expected.h:968
ETL_CONSTEXPR17 etl::enable_if<!etl::is_same< T, etl::nullptr_t >::value, T >::type * addressof(T &t)
Definition addressof.h:52
extent
Definition type_traits_generator.h:1197
is_base_of
Definition type_traits_generator.h:1247
is_same
Definition type_traits_generator.h:1036
bitset_ext
Definition absolute.h:38
Definition iterator.h:63
pair holds two objects of arbitrary type
Definition utility.h:164
Definition poly_span.h:585