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 "array.h"
39#include "hash.h"
40#include "integral_limits.h"
41#include "iterator.h"
42#include "memory.h"
43#include "nullptr.h"
44#include "type_traits.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>
66 class iterator
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 //*****************************************
97 iterator& operator=(const iterator& rhs)
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 //*****************************************
118 iterator& operator++()
119 {
120 ptr = reinterpret_cast<pointer>(reinterpret_cast<char*>(ptr) + element_size);
121 return *this;
122 }
123
124 //*****************************************
125 iterator operator++(int)
126 {
127 iterator temp(*this);
128 ptr = reinterpret_cast<pointer>(reinterpret_cast<char*>(ptr) + element_size);
129 return temp;
130 }
131
132 //*****************************************
133 iterator& operator--()
134 {
135 ptr = reinterpret_cast<pointer>(reinterpret_cast<char*>(ptr) - element_size);
136 return *this;
137 }
138
139 //*****************************************
140 iterator operator--(int)
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 {
200 iterator temp(lhs);
201 temp += offset;
202 return temp;
203 }
204
205 //***************************************************
206 friend iterator operator+(difference_type offset, const iterator& rhs)
207 {
208 iterator temp(rhs);
209 temp += offset;
210 return temp;
211 }
212
213 //***************************************************
214 friend iterator operator-(const iterator& lhs, difference_type offset)
215 {
216 iterator temp(lhs);
217 temp -= offset;
218 return temp;
219 }
220
221 //***************************************************
222 friend iterator operator-(difference_type offset, const iterator& rhs)
223 {
224 iterator temp(rhs);
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 } // namespace private_poly_span
248
249 //***************************************************************************
251 //***************************************************************************
252 template <typename TBase, size_t Extent = etl::dynamic_extent>
253 class poly_span
254 {
255 public:
256
257 typedef TBase element_type;
258 typedef typename etl::remove_cv<TBase>::type value_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;
264 typedef private_poly_span::iterator<TBase> iterator;
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),
293 "Not a random access iterator");
294 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");
295 }
296
297 //*************************************************************************
299 //*************************************************************************
300 template <typename TIterator>
301 ETL_CONSTEXPR poly_span(const TIterator begin_, const TIterator /*end_*/)
302 : pbegin(etl::addressof(*begin_))
303 , element_size(sizeof(typename etl::iterator_traits<TIterator>::value_type))
304 {
305 typedef typename etl::iterator_traits<TIterator>::value_type data_type;
306 typedef typename etl::iterator_traits<TIterator>::iterator_category iterator_category;
307
308 ETL_STATIC_ASSERT((etl::is_same<ETL_OR_STD::random_access_iterator_tag, iterator_category>::value), "Not a random access iterator");
309 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");
310 }
311
312 //*************************************************************************
314 //*************************************************************************
315 template <typename U, size_t Size>
316 ETL_CONSTEXPR poly_span(U (&begin_)[Size]) ETL_NOEXCEPT
317 : pbegin(begin_)
318 , element_size(sizeof(U))
319 {
320 ETL_STATIC_ASSERT(Size <= Extent, "Array data overflow");
321 ETL_STATIC_ASSERT((etl::is_base_of<TBase, U>::value || etl::is_same<TBase, U>::value), "TBase not a base of the data type");
322 }
323
324 //*************************************************************************
326 //*************************************************************************
327 template <typename U, size_t Size>
328 ETL_CONSTEXPR poly_span(etl::array<U, Size>& a) ETL_NOEXCEPT
329 : pbegin(a.data())
330 , element_size(sizeof(U))
331 {
332 ETL_STATIC_ASSERT(Size <= Extent, "Array data overflow");
333 ETL_STATIC_ASSERT((etl::is_base_of<TBase, U>::value || etl::is_same<TBase, U>::value), "TBase not a base of the data type");
334 }
335
336 //*************************************************************************
338 //*************************************************************************
339 template <typename U, size_t Size>
340 ETL_CONSTEXPR poly_span(const etl::array<U, Size>& a) ETL_NOEXCEPT
341 : pbegin(a.data())
342 , element_size(sizeof(U))
343 {
344 ETL_STATIC_ASSERT(Size <= Extent, "Array data overflow");
345 ETL_STATIC_ASSERT((etl::is_base_of<TBase, U>::value || etl::is_same<TBase, U>::value), "TBase not a base of the data type");
346 }
347
348#if ETL_USING_STL && ETL_USING_CPP11
349 //*************************************************************************
351 //*************************************************************************
352 template <typename U, size_t Size>
353 ETL_CONSTEXPR poly_span(std::array<U, Size>& a) ETL_NOEXCEPT
354 : pbegin(a.data())
355 , element_size(sizeof(U))
356 {
357 ETL_STATIC_ASSERT(Size <= Extent, "Array data overflow");
358 ETL_STATIC_ASSERT((etl::is_base_of<TBase, U>::value || etl::is_same<TBase, U>::value), "TBase not a base of U");
359 }
360
361 //*************************************************************************
363 //*************************************************************************
364 template <typename U, size_t Size>
365 ETL_CONSTEXPR poly_span(const std::array<U, Size>& a) ETL_NOEXCEPT
366 : pbegin(a.data())
367 , element_size(sizeof(U))
368 {
369 ETL_STATIC_ASSERT(Size <= Extent, "Array data overflow");
370 ETL_STATIC_ASSERT((etl::is_base_of<TBase, U>::value || etl::is_same<TBase, U>::value), "TBase not a base of U");
371 }
372#endif
373
374 //*************************************************************************
376 //*************************************************************************
377 ETL_CONSTEXPR poly_span(const poly_span<TBase, Extent>& other) ETL_NOEXCEPT
378 : pbegin(other.pbegin)
379 , element_size(other.element_size)
380 {
381 }
382
383 //*************************************************************************
385 //*************************************************************************
386 template <typename UBase>
387 ETL_CONSTEXPR poly_span(const poly_span<UBase, Extent>& other) ETL_NOEXCEPT
388 : pbegin(other.pbegin)
389 , element_size(other.element_size)
390 {
391 }
392
393 //*************************************************************************
395 //*************************************************************************
396 ETL_NODISCARD ETL_CONSTEXPR reference front() const ETL_NOEXCEPT
397 {
398 return *pbegin;
399 }
400
401 //*************************************************************************
403 //*************************************************************************
404 ETL_NODISCARD ETL_CONSTEXPR reference back() const ETL_NOEXCEPT
405 {
406 return *element_at(Extent - 1U);
407 }
408
409 //*************************************************************************
411 //*************************************************************************
412 ETL_NODISCARD ETL_CONSTEXPR pointer data() const ETL_NOEXCEPT
413 {
414 return pbegin;
415 }
416
417 //*************************************************************************
419 //*************************************************************************
420 ETL_NODISCARD ETL_CONSTEXPR iterator begin() const ETL_NOEXCEPT
421 {
422 return iterator(pbegin, 0U, element_size);
423 }
424
425 //*************************************************************************
427 //*************************************************************************
428 ETL_NODISCARD ETL_CONSTEXPR iterator end() const ETL_NOEXCEPT
429 {
430 return iterator(pbegin, Extent, element_size);
431 }
432
433 //*************************************************************************
434 // Returns an reverse iterator to the reverse beginning of the poly_span.
435 //*************************************************************************
436 ETL_CONSTEXPR reverse_iterator rbegin() const ETL_NOEXCEPT
437 {
438 return reverse_iterator(end());
439 }
440
441 //*************************************************************************
443 //*************************************************************************
444 ETL_CONSTEXPR reverse_iterator rend() const ETL_NOEXCEPT
445 {
446 return reverse_iterator(begin());
447 }
448
449 //*************************************************************************
451 //*************************************************************************
452 ETL_NODISCARD ETL_CONSTEXPR bool empty() const ETL_NOEXCEPT
453 {
454 return (Extent == 0U);
455 }
456
457 //*************************************************************************
459 //*************************************************************************
460 ETL_NODISCARD ETL_CONSTEXPR size_t size() const ETL_NOEXCEPT
461 {
462 return Extent;
463 }
464
465 //*************************************************************************
467 //*************************************************************************
468 ETL_NODISCARD ETL_CONSTEXPR size_t size_of_element() const ETL_NOEXCEPT
469 {
470 return element_size;
471 }
472
473 //*************************************************************************
475 //*************************************************************************
476 ETL_NODISCARD ETL_CONSTEXPR size_t size_bytes() const ETL_NOEXCEPT
477 {
478 return Extent * element_size;
479 }
480
481 //*************************************************************************
483 //*************************************************************************
484 ETL_CONSTEXPR14 poly_span& operator=(const poly_span& other) ETL_NOEXCEPT
485 {
486 pbegin = other.pbegin;
487 element_size = other.element_size;
488 return *this;
489 }
490
491 //*************************************************************************
493 //*************************************************************************
494 template <typename UBase>
495 ETL_CONSTEXPR14 poly_span& operator=(const poly_span<UBase, Extent>& other) ETL_NOEXCEPT
496 {
497 pbegin = other.pbegin;
498 element_size = other.element_size;
499 return *this;
500 }
501
502 //*************************************************************************
504 //*************************************************************************
505 ETL_CONSTEXPR reference operator[](size_t i) const
506 {
507 return *element_at(i);
508 }
509
510 //*************************************************************************
513 //*************************************************************************
514 template <size_t COUNT>
515 ETL_NODISCARD ETL_CONSTEXPR etl::poly_span<element_type, COUNT> first() const ETL_NOEXCEPT
516 {
517 return etl::poly_span<element_type, COUNT>(pbegin, 0U, COUNT, element_size);
518 }
519
520 //*************************************************************************
523 //*************************************************************************
524 ETL_NODISCARD ETL_CONSTEXPR etl::poly_span<element_type, etl::dynamic_extent> first(size_t count) const
525 {
526 return etl::poly_span<element_type, etl::dynamic_extent>(pbegin, 0U, count, element_size);
527 }
528
529 //*************************************************************************
532 //*************************************************************************
533 template <size_t COUNT>
534 ETL_NODISCARD ETL_CONSTEXPR etl::poly_span<element_type, COUNT> last() const ETL_NOEXCEPT
535 {
536 return etl::poly_span<element_type, COUNT>(pbegin, Extent - COUNT, COUNT, element_size);
537 }
538
539 //*************************************************************************
542 //*************************************************************************
543 ETL_NODISCARD ETL_CONSTEXPR etl::poly_span<element_type, etl::dynamic_extent> last(size_t count) const ETL_NOEXCEPT
544 {
545 return etl::poly_span<element_type, etl::dynamic_extent>(pbegin, Extent - count, count, element_size);
546 }
547
548#if ETL_USING_CPP11
549 //*************************************************************************
552 //*************************************************************************
553 template <size_t OFFSET, size_t COUNT = etl::dynamic_extent>
554 ETL_NODISCARD ETL_CONSTEXPR etl::poly_span< element_type, COUNT != etl::dynamic_extent ? COUNT : Extent - OFFSET> subspan() const ETL_NOEXCEPT
555 {
556 return (COUNT == etl::dynamic_extent) ? etl::poly_span < element_type,
557 COUNT != etl::dynamic_extent ? COUNT : Extent - OFFSET > (pbegin, OFFSET, Extent, element_size) : etl::poly_span < element_type,
558 COUNT != etl::dynamic_extent ? COUNT : Extent - OFFSET > (pbegin, OFFSET, COUNT, element_size);
559 }
560#else
561 //*************************************************************************
564 //*************************************************************************
565 template <size_t OFFSET, size_t COUNT>
566 etl::poly_span<element_type, COUNT != etl::dynamic_extent ? COUNT : Extent - OFFSET> subspan() const
567 {
568 if (COUNT == etl::dynamic_extent)
569 {
570 return etl::poly_span < element_type, COUNT != etl::dynamic_extent ? COUNT : Extent - OFFSET > (pbegin, OFFSET, Extent, element_size);
571 }
572 else
573 {
574 return etl::poly_span < element_type, COUNT != etl::dynamic_extent ? COUNT : Extent - OFFSET > (pbegin, OFFSET, element_size);
575 }
576 }
577#endif
578
579 //*************************************************************************
582 //*************************************************************************
583 ETL_NODISCARD ETL_CONSTEXPR etl::poly_span<element_type, etl::dynamic_extent> subspan(size_t offset, size_t count = etl::dynamic_extent) const
584 ETL_NOEXCEPT
585 {
586 return (count == etl::dynamic_extent) ? etl::poly_span<element_type, etl::dynamic_extent>(pbegin, offset, Extent, element_size)
587 : etl::poly_span<element_type, etl::dynamic_extent>(pbegin, offset, count, element_size);
588 }
589
590 protected:
591
592 //***************************************************************************
593 template <typename TFrom>
595 {
596 typedef typename etl::conditional<etl::is_const<TFrom>::value, const char*, char*>::type type;
597 };
598
599 typedef typename char_ptr_type<TBase>::type char_ptr_t;
600
601 //***************************************************************************
602 pointer element_at(size_t index) const ETL_NOEXCEPT
603 {
604 char_ptr_t base = reinterpret_cast<char_ptr_t>(pbegin);
605 return reinterpret_cast<pointer>(base + (index * element_size));
606 }
607
608 //*************************************************************************
611 //*************************************************************************
612 poly_span(TBase* pbegin_, size_t offset_, size_t /*extent_*/, size_t element_size_) ETL_NOEXCEPT
613 : pbegin(reinterpret_cast<pointer>(reinterpret_cast<char_ptr_t>(pbegin_) + (offset_ * element_size_)))
614 , element_size(element_size_)
615 {
616 }
617
618 private:
619
620 pointer pbegin;
621 size_t element_size;
622 };
623
624 template <typename TBase, size_t Extent>
625 ETL_CONSTANT size_t poly_span<TBase, Extent>::extent;
626
627 //***************************************************************************
629 //***************************************************************************
630 template <typename TBase>
631 class poly_span<TBase, etl::dynamic_extent>
632 {
633 public:
634
635 typedef TBase element_type;
636 typedef typename etl::remove_cv<TBase>::type value_type;
637 typedef size_t size_type;
638 typedef TBase& reference;
639 typedef const TBase& const_reference;
640 typedef TBase* pointer;
641 typedef const TBase* const_pointer;
643 typedef ETL_OR_STD::reverse_iterator<iterator> reverse_iterator;
644
645 static ETL_CONSTANT size_t extent = etl::dynamic_extent;
646
647 template <typename UBase, size_t UExtent>
648 friend class poly_span;
649
650 //*************************************************************************
652 //*************************************************************************
653 ETL_CONSTEXPR poly_span() ETL_NOEXCEPT
654 : pbegin(ETL_NULLPTR)
655 , element_size(0U)
656 , span_extent(0U)
657 {
658 }
659
660 //*************************************************************************
662 //*************************************************************************
663 template <typename TIterator, typename TSize>
664 ETL_CONSTEXPR poly_span(const TIterator begin_, const TSize size_) ETL_NOEXCEPT
665 : pbegin(etl::addressof(*begin_))
666 , element_size(sizeof(typename etl::iterator_traits<TIterator>::value_type))
667 , span_extent(size_)
668 {
669 typedef typename etl::iterator_traits<TIterator>::value_type data_type;
670 typedef typename etl::iterator_traits<TIterator>::iterator_category iterator_category;
671
672 ETL_STATIC_ASSERT((etl::is_same<ETL_OR_STD::random_access_iterator_tag, iterator_category>::value), "Not a random access iterator");
673 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");
674 }
675
676 //*************************************************************************
678 //*************************************************************************
679 template <typename TIterator>
680 ETL_CONSTEXPR poly_span(const TIterator begin_, const TIterator end_)
681 : pbegin(etl::addressof(*begin_))
682 , element_size(sizeof(typename etl::iterator_traits<TIterator>::value_type))
683 , span_extent(size_t(etl::distance(begin_, end_)))
684 {
685 typedef typename etl::iterator_traits<TIterator>::value_type data_type;
686 typedef typename etl::iterator_traits<TIterator>::iterator_category iterator_category;
687
688 ETL_STATIC_ASSERT((etl::is_same<ETL_OR_STD::random_access_iterator_tag, iterator_category>::value), "Not a random access iterator");
689 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");
690 }
691
692 //*************************************************************************
694 //*************************************************************************
695 template <typename U, size_t Size>
696 ETL_CONSTEXPR poly_span(U (&begin_)[Size]) ETL_NOEXCEPT
697 : pbegin(begin_)
698 , element_size(sizeof(U))
699 , span_extent(Size)
700 {
701 ETL_STATIC_ASSERT((etl::is_base_of<TBase, U>::value || etl::is_same<TBase, U>::value), "TBase not a base of the data type");
702 }
703
704 //*************************************************************************
706 //*************************************************************************
707 template <typename U, size_t Size>
708 ETL_CONSTEXPR poly_span(etl::array<U, Size>& a) ETL_NOEXCEPT
709 : pbegin(a.data())
710 , element_size(sizeof(U))
711 , span_extent(Size)
712 {
713 ETL_STATIC_ASSERT((etl::is_base_of<TBase, U>::value || etl::is_same<TBase, U>::value), "TBase not a base of the data type");
714 }
715
716 //*************************************************************************
718 //*************************************************************************
719 template <typename U, size_t Size>
720 ETL_CONSTEXPR poly_span(const etl::array<U, Size>& a) ETL_NOEXCEPT
721 : pbegin(a.data())
722 , element_size(sizeof(U))
723 , span_extent(Size)
724 {
725 ETL_STATIC_ASSERT((etl::is_base_of<TBase, U>::value || etl::is_same<TBase, U>::value), "TBase not a base of the data type");
726 }
727
728#if ETL_USING_STL && ETL_USING_CPP11
729 //*************************************************************************
731 //*************************************************************************
732 template <typename U, size_t Size>
733 ETL_CONSTEXPR poly_span(std::array<U, Size>& a) ETL_NOEXCEPT
734 : pbegin(a.data())
735 , element_size(sizeof(U))
736 , span_extent(Size)
737 {
738 ETL_STATIC_ASSERT((etl::is_base_of<TBase, U>::value || etl::is_same<TBase, U>::value), "TBase not a base of U");
739 }
740
741 //*************************************************************************
743 //*************************************************************************
744 template <typename U, size_t Size>
745 ETL_CONSTEXPR poly_span(const std::array<U, Size>& a) ETL_NOEXCEPT
746 : pbegin(a.data())
747 , element_size(sizeof(U))
748 , span_extent(Size)
749 {
750 ETL_STATIC_ASSERT((etl::is_base_of<TBase, U>::value || etl::is_same<TBase, U>::value), "TBase not a base of U");
751 }
752#endif
753
754 //*************************************************************************
756 //*************************************************************************
757 ETL_CONSTEXPR poly_span(const poly_span<TBase, etl::dynamic_extent>& other) ETL_NOEXCEPT
758 : pbegin(other.pbegin)
759 , element_size(other.element_size)
760 , span_extent(other.span_extent)
761 {
762 }
763
764 //*************************************************************************
766 //*************************************************************************
767 template <typename UBase>
768 ETL_CONSTEXPR poly_span(const poly_span<UBase, etl::dynamic_extent>& other) ETL_NOEXCEPT
769 : pbegin(other.pbegin)
770 , element_size(other.element_size)
771 , span_extent(other.span_extent)
772 {
773 }
774
775 //*************************************************************************
777 //*************************************************************************
778 ETL_NODISCARD ETL_CONSTEXPR reference front() const ETL_NOEXCEPT
779 {
780 return *pbegin;
781 }
782
783 //*************************************************************************
785 //*************************************************************************
786 ETL_NODISCARD ETL_CONSTEXPR reference back() const ETL_NOEXCEPT
787 {
788 return *element_at(span_extent - 1U);
789 }
790
791 //*************************************************************************
793 //*************************************************************************
794 ETL_NODISCARD ETL_CONSTEXPR pointer data() const ETL_NOEXCEPT
795 {
796 return pbegin;
797 }
798
799 //*************************************************************************
801 //*************************************************************************
802 ETL_NODISCARD ETL_CONSTEXPR iterator begin() const ETL_NOEXCEPT
803 {
804 return iterator(pbegin, 0U, element_size);
805 }
806
807 //*************************************************************************
809 //*************************************************************************
810 ETL_NODISCARD ETL_CONSTEXPR iterator end() const ETL_NOEXCEPT
811 {
812 return iterator(pbegin, span_extent, element_size);
813 }
814
815 //*************************************************************************
816 // Returns an reverse iterator to the reverse beginning of the poly_span.
817 //*************************************************************************
818 ETL_NODISCARD ETL_CONSTEXPR reverse_iterator rbegin() const ETL_NOEXCEPT
819 {
820 return reverse_iterator(end());
821 }
822
823 //*************************************************************************
825 //*************************************************************************
826 ETL_NODISCARD ETL_CONSTEXPR reverse_iterator rend() const ETL_NOEXCEPT
827 {
828 return reverse_iterator(begin());
829 }
830
831 //*************************************************************************
833 //*************************************************************************
834 ETL_NODISCARD ETL_CONSTEXPR bool empty() const ETL_NOEXCEPT
835 {
836 return (span_extent == 0);
837 }
838
839 //*************************************************************************
841 //*************************************************************************
842 ETL_NODISCARD ETL_CONSTEXPR size_t size() const ETL_NOEXCEPT
843 {
844 return span_extent;
845 }
846
847 //*************************************************************************
849 //*************************************************************************
850 ETL_NODISCARD ETL_CONSTEXPR size_t size_of_element() const ETL_NOEXCEPT
851 {
852 return element_size;
853 }
854
855 //*************************************************************************
857 //*************************************************************************
858 ETL_NODISCARD ETL_CONSTEXPR size_t size_bytes() const ETL_NOEXCEPT
859 {
860 return element_size * span_extent;
861 }
862
863 //*************************************************************************
865 //*************************************************************************
866 ETL_CONSTEXPR14 poly_span& operator=(const poly_span& other) ETL_NOEXCEPT
867 {
868 pbegin = other.pbegin;
869 element_size = other.element_size;
870 span_extent = other.span_extent;
871 return *this;
872 }
873
874 //*************************************************************************
876 //*************************************************************************
877 template <typename UBase>
878 ETL_CONSTEXPR14 poly_span& operator=(const poly_span<UBase, etl::dynamic_extent>& other) ETL_NOEXCEPT
879 {
880 pbegin = other.pbegin;
881 element_size = other.element_size;
882 span_extent = other.span_extent;
883 return *this;
884 }
885
886 //*************************************************************************
888 //*************************************************************************
889 ETL_CONSTEXPR reference operator[](size_t i) const
890 {
891 return *element_at(i);
892 }
893
894 //*************************************************************************
897 //*************************************************************************
898 template <size_t COUNT>
899 ETL_NODISCARD ETL_CONSTEXPR etl::poly_span<element_type, COUNT> first() const ETL_NOEXCEPT
900 {
901 return etl::poly_span<element_type, COUNT>(pbegin, 0U, COUNT, element_size);
902 }
903
904 //*************************************************************************
907 //*************************************************************************
908 ETL_NODISCARD ETL_CONSTEXPR etl::poly_span<element_type, etl::dynamic_extent> first(size_t count) const ETL_NOEXCEPT
909 {
910 return etl::poly_span<element_type, etl::dynamic_extent>(pbegin, 0U, count, element_size);
911 }
912
913 //*************************************************************************
916 //*************************************************************************
917 template <size_t COUNT>
918 ETL_NODISCARD ETL_CONSTEXPR etl::poly_span<element_type, COUNT> last() const ETL_NOEXCEPT
919 {
920 return etl::poly_span<element_type, COUNT>(pbegin, span_extent - COUNT, COUNT, element_size);
921 }
922
923 //*************************************************************************
926 //*************************************************************************
927 ETL_NODISCARD ETL_CONSTEXPR etl::poly_span<element_type, etl::dynamic_extent> last(size_t count) const ETL_NOEXCEPT
928 {
929 return etl::poly_span<element_type, etl::dynamic_extent>(pbegin, span_extent - count, count, element_size);
930 }
931
932#if ETL_USING_CPP11
933 //*************************************************************************
936 //*************************************************************************
937 template <size_t OFFSET, size_t COUNT = etl::dynamic_extent>
939 {
940 return (COUNT == etl::dynamic_extent) ? etl::poly_span < element_type,
941 COUNT != etl::dynamic_extent ? COUNT : etl::dynamic_extent > (pbegin, OFFSET, span_extent, element_size) : etl::poly_span < element_type,
942 COUNT != etl::dynamic_extent ? COUNT : etl::dynamic_extent > (pbegin, OFFSET, COUNT, element_size);
943 }
944#else
945 //*************************************************************************
948 //*************************************************************************
949 template <size_t OFFSET, size_t COUNT>
951 {
952 if (COUNT == etl::dynamic_extent)
953 {
954 return etl::poly_span < element_type,
955 COUNT != etl::dynamic_extent ? COUNT : etl::dynamic_extent > (pbegin, OFFSET, span_extent, element_size);
956 }
957 else
958 {
959 return etl::poly_span < element_type,
960 COUNT != etl::dynamic_extent ? COUNT : etl::dynamic_extent > (pbegin, OFFSET, span_extent, element_size);
961 }
962 }
963#endif
964
965 //*************************************************************************
968 //*************************************************************************
969 ETL_NODISCARD ETL_CONSTEXPR etl::poly_span<element_type, etl::dynamic_extent> subspan(size_t offset, size_t count = etl::dynamic_extent) const
970 ETL_NOEXCEPT
971 {
972 return (count == etl::dynamic_extent) ? etl::poly_span<element_type, etl::dynamic_extent>(pbegin, offset, span_extent - offset, element_size)
973 : etl::poly_span<element_type, etl::dynamic_extent>(pbegin, offset, count, element_size);
974 }
975
976 protected:
977
978 //*************************************************************************
980 //*************************************************************************
981 poly_span(TBase* pbegin_, size_t offset_, size_t extent_, size_t element_size_) ETL_NOEXCEPT
982 : pbegin(reinterpret_cast<pointer>(reinterpret_cast<char_ptr_t>(pbegin_) + (offset_ * element_size_)))
983 , element_size(element_size_)
984 , span_extent(extent_)
985 {
986 }
987
988 private:
989
990 //***************************************************************************
991 template <typename TFrom>
992 struct char_ptr_type
993 {
994 typedef typename etl::conditional<etl::is_const<TFrom>::value, const char*, char*>::type type;
995 };
996
997 typedef typename char_ptr_type<TBase>::type char_ptr_t;
998
999 //***************************************************************************
1000 pointer element_at(size_t index) const ETL_NOEXCEPT
1001 {
1002 char_ptr_t base = reinterpret_cast<char_ptr_t>(pbegin);
1003 return reinterpret_cast<pointer>(base + (index * element_size));
1004 }
1005
1006 pointer pbegin;
1007 size_t element_size;
1008 size_t span_extent;
1009 };
1010
1011 template <typename TBase>
1012 ETL_CONSTANT size_t poly_span<TBase, etl::dynamic_extent>::extent;
1013
1014 //*************************************************************************
1016 //*************************************************************************
1017#if ETL_USING_CPP17
1018 template <typename TIterator>
1019 poly_span(const TIterator begin_, const TIterator end_) -> poly_span<etl::remove_pointer_t<TIterator>, etl::dynamic_extent>;
1020
1021 template <typename TIterator, typename TSize>
1022 poly_span(const TIterator begin_, const TSize size_) -> poly_span<etl::remove_pointer_t<TIterator>, etl::dynamic_extent>;
1023
1024 template <typename T, size_t Size>
1025 poly_span(T (&)[Size]) -> poly_span<T, Size>;
1026
1027 template <typename T, size_t Size>
1028 poly_span(etl::array<T, Size>&) -> poly_span<T, Size>;
1029
1030 template <typename T, size_t Size>
1031 poly_span(const etl::array<T, Size>&) -> poly_span<const T, Size>;
1032
1033 #if ETL_USING_STL
1034 template <typename T, size_t Size>
1035 poly_span(std::array<T, Size>&) -> poly_span<T, Size>;
1036
1037 template <typename T, size_t Size>
1038 poly_span(const std::array<T, Size>&) -> poly_span<const T, Size>;
1039 #endif
1040#endif
1041
1042 //*************************************************************************
1044 //*************************************************************************
1045#if ETL_USING_8BIT_TYPES
1046 template <typename TBase, size_t Extent>
1047 struct hash<etl::poly_span<TBase, Extent> >
1048 {
1049 size_t operator()(const etl::poly_span<TBase, Extent>& view) const
1050 {
1051 return etl::private_hash::generic_hash<size_t>(reinterpret_cast<const uint8_t*>(view.data()),
1052 reinterpret_cast<const uint8_t*>(view.data() + view.size()));
1053 }
1054 };
1055#endif
1056} // namespace etl
1057
1058#endif
ETL_CONSTEXPR poly_span(const TIterator begin_, const TSize size_) ETL_NOEXCEPT
Construct from iterator + size.
Definition poly_span.h:664
ETL_CONSTEXPR poly_span() ETL_NOEXCEPT
Default constructor.
Definition poly_span.h:653
ETL_NODISCARD ETL_CONSTEXPR reference front() const ETL_NOEXCEPT
Returns a reference to the first element.
Definition poly_span.h:778
ETL_NODISCARD ETL_CONSTEXPR etl::poly_span< element_type, etl::dynamic_extent > last(size_t count) const ETL_NOEXCEPT
Definition poly_span.h:927
ETL_NODISCARD ETL_CONSTEXPR etl::poly_span< element_type, COUNT > last() const ETL_NOEXCEPT
Definition poly_span.h:918
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:826
ETL_NODISCARD ETL_CONSTEXPR iterator begin() const ETL_NOEXCEPT
Returns an iterator to the beginning of the poly_span.
Definition poly_span.h:802
ETL_CONSTEXPR14 poly_span & operator=(const poly_span &other) ETL_NOEXCEPT
Assign from a poly_span.
Definition poly_span.h:866
ETL_NODISCARD ETL_CONSTEXPR pointer data() const ETL_NOEXCEPT
Returns a pointer to the first element of the internal storage.
Definition poly_span.h:794
ETL_NODISCARD ETL_CONSTEXPR size_t size() const ETL_NOEXCEPT
Returns the size of the poly_span.
Definition poly_span.h:842
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
Definition poly_span.h:969
ETL_NODISCARD ETL_CONSTEXPR bool empty() const ETL_NOEXCEPT
Returns true if the poly_span size is zero.
Definition poly_span.h:834
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:850
ETL_NODISCARD ETL_CONSTEXPR etl::poly_span< element_type, COUNT > first() const ETL_NOEXCEPT
Definition poly_span.h:899
ETL_CONSTEXPR poly_span(U(&begin_)[Size]) ETL_NOEXCEPT
Construct from C array.
Definition poly_span.h:696
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:981
ETL_CONSTEXPR poly_span(const TIterator begin_, const TIterator end_)
Construct from iterators.
Definition poly_span.h:680
ETL_NODISCARD ETL_CONSTEXPR size_t size_bytes() const ETL_NOEXCEPT
Returns the size of the poly_span in bytes.
Definition poly_span.h:858
ETL_CONSTEXPR poly_span(const etl::array< U, Size > &a) ETL_NOEXCEPT
Construct from etl::array.
Definition poly_span.h:720
ETL_CONSTEXPR poly_span(const poly_span< TBase, etl::dynamic_extent > &other) ETL_NOEXCEPT
Copy constructor.
Definition poly_span.h:757
ETL_CONSTEXPR reference operator[](size_t i) const
Returns a reference to the indexed value.
Definition poly_span.h:889
ETL_CONSTEXPR14 poly_span & operator=(const poly_span< UBase, etl::dynamic_extent > &other) ETL_NOEXCEPT
Assign from a poly_span.
Definition poly_span.h:878
ETL_NODISCARD ETL_CONSTEXPR reference back() const ETL_NOEXCEPT
Returns a reference to the last element.
Definition poly_span.h:786
ETL_CONSTEXPR poly_span(const poly_span< UBase, etl::dynamic_extent > &other) ETL_NOEXCEPT
Copy constructor.
Definition poly_span.h:768
ETL_NODISCARD ETL_CONSTEXPR etl::poly_span< element_type, etl::dynamic_extent > first(size_t count) const ETL_NOEXCEPT
Definition poly_span.h:908
ETL_CONSTEXPR poly_span(etl::array< U, Size > &a) ETL_NOEXCEPT
Construct from etl::array.
Definition poly_span.h:708
etl::poly_span< element_type, COUNT !=etl::dynamic_extent ? COUNT :etl::dynamic_extent > subspan() const
Definition poly_span.h:950
ETL_NODISCARD ETL_CONSTEXPR iterator end() const ETL_NOEXCEPT
Returns an iterator to the end of the poly_span.
Definition poly_span.h:810
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:468
ETL_NODISCARD ETL_CONSTEXPR iterator end() const ETL_NOEXCEPT
Returns an iterator to the end of the poly_span.
Definition poly_span.h:428
ETL_CONSTEXPR reverse_iterator rend() const ETL_NOEXCEPT
Returns a reverse iterator to the end of the poly_span.
Definition poly_span.h:444
ETL_NODISCARD ETL_CONSTEXPR pointer data() const ETL_NOEXCEPT
Returns a pointer to the first element of the internal storage.
Definition poly_span.h:412
poly_span(TBase *pbegin_, size_t offset_, size_t, size_t element_size_) ETL_NOEXCEPT
Definition poly_span.h:612
ETL_CONSTEXPR14 poly_span & operator=(const poly_span &other) ETL_NOEXCEPT
Assign from a poly_span.
Definition poly_span.h:484
ETL_NODISCARD ETL_CONSTEXPR bool empty() const ETL_NOEXCEPT
Returns true if the poly_span size is zero.
Definition poly_span.h:452
ETL_NODISCARD ETL_CONSTEXPR reference front() const ETL_NOEXCEPT
Returns a reference to the first element.
Definition poly_span.h:396
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
Definition poly_span.h:583
ETL_CONSTEXPR poly_span() ETL_NOEXCEPT
Default constructor.
Definition poly_span.h:276
ETL_CONSTEXPR poly_span(U(&begin_)[Size]) ETL_NOEXCEPT
Construct from C array.
Definition poly_span.h:316
ETL_NODISCARD ETL_CONSTEXPR etl::poly_span< element_type, etl::dynamic_extent > first(size_t count) const
Definition poly_span.h:524
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:420
etl::poly_span< element_type, COUNT !=etl::dynamic_extent ? COUNT :Extent - OFFSET > subspan() const
Definition poly_span.h:566
ETL_NODISCARD ETL_CONSTEXPR reference back() const ETL_NOEXCEPT
Returns a reference to the last element.
Definition poly_span.h:404
ETL_NODISCARD ETL_CONSTEXPR size_t size_bytes() const ETL_NOEXCEPT
Returns the size of the poly_span in bytes.
Definition poly_span.h:476
ETL_NODISCARD ETL_CONSTEXPR etl::poly_span< element_type, COUNT > last() const ETL_NOEXCEPT
Definition poly_span.h:534
ETL_CONSTEXPR poly_span(const etl::array< U, Size > &a) ETL_NOEXCEPT
Construct from etl::array.
Definition poly_span.h:340
ETL_CONSTEXPR poly_span(etl::array< U, Size > &a) ETL_NOEXCEPT
Construct from etl::array.
Definition poly_span.h:328
ETL_NODISCARD ETL_CONSTEXPR size_t size() const ETL_NOEXCEPT
Returns the size of the poly_span.
Definition poly_span.h:460
ETL_CONSTEXPR14 poly_span & operator=(const poly_span< UBase, Extent > &other) ETL_NOEXCEPT
Assign from a poly_span.
Definition poly_span.h:495
ETL_CONSTEXPR poly_span(const poly_span< TBase, Extent > &other) ETL_NOEXCEPT
Copy constructor.
Definition poly_span.h:377
ETL_NODISCARD ETL_CONSTEXPR etl::poly_span< element_type, etl::dynamic_extent > last(size_t count) const ETL_NOEXCEPT
Definition poly_span.h:543
ETL_CONSTEXPR reference operator[](size_t i) const
Returns a reference to the indexed value.
Definition poly_span.h:505
ETL_CONSTEXPR poly_span(const poly_span< UBase, Extent > &other) ETL_NOEXCEPT
Copy constructor.
Definition poly_span.h:387
ETL_CONSTEXPR poly_span(const TIterator begin_, const TIterator)
Construct from iterators.
Definition poly_span.h:301
ETL_NODISCARD ETL_CONSTEXPR etl::poly_span< element_type, COUNT > first() const ETL_NOEXCEPT
Definition poly_span.h:515
Definition poly_span.h:67
Definition iterator.h:252
Definition array.h:88
ETL_CONSTEXPR14 bool operator!=(const etl::bitset< Active_Bits, TElement > &lhs, const etl::bitset< Active_Bits, TElement > &rhs) ETL_NOEXCEPT
Definition bitset_new.h:2529
ETL_CONSTEXPR17 etl::enable_if<!etl::is_same< T, etl::nullptr_t >::value, T >::type * addressof(T &t)
Definition addressof.h:52
bitset_ext
Definition absolute.h:40
ETL_CONSTEXPR TContainer::reverse_iterator rbegin(TContainer &container)
Definition iterator.h:1089
Definition iterator.h:74
Definition poly_span.h:595