Embedded Template Library 1.0
Loading...
Searching...
No Matches
multi_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) 2021 John Wellbelove
11
12Permission is hereby granted, free of charge, to any person obtaining a copy
13of this software and associated documentation files(the "Software"), to deal
14in the Software without restriction, including without limitation the rights
15to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
16copies of the Software, and to permit persons to whom the Software is
17furnished to do so, subject to the following conditions :
18
19The above copyright notice and this permission notice shall be included in all
20copies or substantial portions of the Software.
21
22THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
25AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28SOFTWARE.
29******************************************************************************/
30
31#ifndef ETL_MULTI_SPAN_INCLUDED
32#define ETL_MULTI_SPAN_INCLUDED
33
34#include "platform.h"
35#include "algorithm.h"
36#include "iterator.h"
37#include "span.h"
38#include "vector.h"
39
43
44namespace etl
45{
46 template <typename T>
48 {
49 public:
50
51 typedef T element_type;
52 typedef typename etl::remove_cv<T>::type value_type;
53 typedef size_t size_type;
54 typedef T& reference;
55 typedef const T& const_reference;
56 typedef T* pointer;
57 typedef const T* const_pointer;
58
59 typedef etl::span<T> span_type;
60 typedef etl::span<const span_type> span_list_type;
61
62 //*************************************************************************
64 //*************************************************************************
65 class iterator : public etl::iterator<ETL_OR_STD::bidirectional_iterator_tag, element_type>
66 {
67 public:
68
69 friend class multi_span;
70 friend class const_iterator;
71
72 //*****************************************
73 ETL_CONSTEXPR14 iterator()
74 : p_span_list(ETL_NULLPTR)
75 , p_current_span(ETL_NULLPTR)
76 , p_value(ETL_NULLPTR)
77 {
78 }
79
80 //*****************************************
81 ETL_CONSTEXPR14 iterator(const iterator& other)
82 : p_span_list(other.p_span_list)
83 , p_current_span(other.p_current_span)
84 , p_value(other.p_value)
85 {
86 }
87
88 //*****************************************
89 ETL_CONSTEXPR14 iterator& operator=(const iterator& rhs)
90 {
91 p_span_list = rhs.p_span_list;
92 p_current_span = rhs.p_current_span;
93 p_value = rhs.p_value;
94
95 return *this;
96 }
97
98 //*****************************************
99 ETL_CONSTEXPR14 iterator& operator++()
100 {
101 if (p_current_span != p_span_list->end())
102 {
103 ++p_value;
104
105 if (p_value == p_current_span->end())
106 {
107 do {
108 ++p_current_span;
109 } while ((p_current_span != p_span_list->end()) && p_current_span->empty());
110
111 if (p_current_span != p_span_list->end())
112 {
113 p_value = p_current_span->begin();
114 }
115 else
116 {
117 p_value = ETL_NULLPTR;
118 }
119 }
120 }
121
122 return *this;
123 }
124
125 //*****************************************
126 ETL_CONSTEXPR14 iterator operator++(int)
127 {
128 iterator temp = *this;
129
130 operator++();
131
132 return temp;
133 }
134
135 //*****************************************
136 ETL_CONSTEXPR14 iterator& operator--()
137 {
138 if (p_current_span == p_span_list->end())
139 {
140 --p_current_span;
141 p_value = p_current_span->end();
142 --p_value;
143 }
144 else if ((p_current_span != p_span_list->begin()) || (p_value != p_current_span->begin()))
145 {
146 if (p_value == p_current_span->begin())
147 {
148 do {
149 --p_current_span;
150 } while ((p_current_span != p_span_list->begin()) && p_current_span->empty());
151
152 p_value = p_current_span->end();
153 --p_value;
154 }
155 else
156 {
157 --p_value;
158 }
159 }
160 else
161 {
162 p_value = ETL_NULLPTR;
163 }
164
165 return *this;
166 }
167
168 //*****************************************
169 ETL_CONSTEXPR14 iterator operator--(int)
170 {
171 iterator temp = *this;
172
173 operator--();
174
175 return temp;
176 }
177
178 //*************************************************************************
180 //*************************************************************************
181 ETL_CONSTEXPR14 reference operator*()
182 {
183 return *p_value;
184 }
185
186 //*************************************************************************
188 //*************************************************************************
189 ETL_CONSTEXPR14 const_reference operator*() const
190 {
191 return *p_value;
192 }
193
194 //*************************************************************************
196 //*************************************************************************
197 ETL_CONSTEXPR14 pointer operator->()
198 {
199 return p_value;
200 }
201
202 //*************************************************************************
204 //*************************************************************************
205 ETL_CONSTEXPR14 const_pointer operator->() const
206 {
207 return p_value;
208 }
209
210 //*************************************************************************
212 //*************************************************************************
213 ETL_CONSTEXPR14 friend bool operator==(const iterator& lhs, const iterator& rhs)
214 {
215 return (lhs.p_current_span == rhs.p_current_span) && (lhs.p_value == rhs.p_value);
216 }
217
218 //*************************************************************************
220 //*************************************************************************
221 ETL_CONSTEXPR14 friend bool operator!=(const iterator& lhs, const iterator& rhs)
222 {
223 return !(lhs == rhs);
224 }
225
226 private:
227
228 typedef const span_type* span_pointer;
229 typedef const span_list_type* span_list_pointer;
230 typedef typename span_list_type::iterator span_list_iterator;
231
232 //*****************************************
233 ETL_CONSTEXPR14 iterator(const span_list_type& span_list_, span_list_iterator p_current_span_)
234 : p_span_list(&span_list_)
235 , p_current_span(p_current_span_)
236 , p_value(ETL_NULLPTR)
237 {
238 if (p_current_span != p_span_list->end())
239 {
240 while ((p_current_span != p_span_list->end()) && p_current_span->empty())
241 {
242 ++p_current_span;
243 }
244
245 if (p_current_span != p_span_list->end())
246 {
247 p_value = p_current_span->begin();
248 }
249 else
250 {
251 p_value = ETL_NULLPTR;
252 }
253 }
254 }
255
256 span_list_pointer p_span_list;
257 span_pointer p_current_span;
258 pointer p_value;
259 };
260
261 //*************************************************************************
263 //*************************************************************************
264 class const_iterator : public etl::iterator<ETL_OR_STD::bidirectional_iterator_tag, const element_type>
265 {
266 public:
267
268 friend class multi_span;
269
270 //*****************************************
271 ETL_CONSTEXPR14 const_iterator()
272 : p_span_list(ETL_NULLPTR)
273 , p_current_span(ETL_NULLPTR)
274 , p_value(ETL_NULLPTR)
275 {
276 }
277
278 //*****************************************
279 ETL_CONSTEXPR14 const_iterator(const const_iterator& other)
280 : p_span_list(other.p_span_list)
281 , p_current_span(other.p_current_span)
282 , p_value(other.p_value)
283 {
284 }
285
286 //*****************************************
287 ETL_CONSTEXPR14 const_iterator& operator=(const const_iterator& rhs)
288 {
289 p_span_list = rhs.p_span_list;
290 p_current_span = rhs.p_current_span;
291 p_value = rhs.p_value;
292
293 return *this;
294 }
295
296 //*****************************************
297 ETL_CONSTEXPR14 const_iterator(const etl::multi_span<T>::iterator& other)
298 : p_span_list(other.p_span_list)
299 , p_current_span(other.p_current_span)
300 , p_value(other.p_value)
301 {
302 }
303
304 //*****************************************
305 ETL_CONSTEXPR14 const_iterator& operator=(const etl::multi_span<T>::iterator& rhs)
306 {
307 p_span_list = rhs.p_span_list;
308 p_current_span = rhs.p_current_span;
309 p_value = rhs.p_value;
310
311 return *this;
312 }
313
314 //*****************************************
315 ETL_CONSTEXPR14 const_iterator& operator++()
316 {
317 if (p_current_span != p_span_list->end())
318 {
319 ++p_value;
320
321 if (p_value == p_current_span->end())
322 {
323 do {
324 ++p_current_span;
325 } while ((p_current_span != p_span_list->end()) && p_current_span->empty());
326
327 if (p_current_span != p_span_list->end())
328 {
329 p_value = p_current_span->begin();
330 }
331 else
332 {
333 p_value = ETL_NULLPTR;
334 }
335 }
336 }
337
338 return *this;
339 }
340
341 //*****************************************
342 ETL_CONSTEXPR14 const_iterator operator++(int)
343 {
344 const_iterator temp = *this;
345
346 operator++();
347
348 return temp;
349 }
350
351 //*****************************************
352 ETL_CONSTEXPR14 const_iterator& operator--()
353 {
354 if (p_current_span == p_span_list->end())
355 {
356 --p_current_span;
357 p_value = p_current_span->end();
358 --p_value;
359 }
360 else if ((p_current_span != p_span_list->begin()) || (p_value != p_current_span->begin()))
361 {
362 if (p_value == p_current_span->begin())
363 {
364 do {
365 --p_current_span;
366 } while ((p_current_span != p_span_list->begin()) && p_current_span->empty());
367
368 p_value = p_current_span->end();
369 --p_value;
370 }
371 else
372 {
373 --p_value;
374 }
375 }
376 else
377 {
378 p_value = ETL_NULLPTR;
379 }
380
381 return *this;
382 }
383
384 //*****************************************
385 ETL_CONSTEXPR14 const_iterator operator--(int)
386 {
387 const_iterator temp = *this;
388
389 operator--();
390
391 return temp;
392 }
393
394 //*************************************************************************
396 //*************************************************************************
397 ETL_CONSTEXPR14 const_reference operator*() const
398 {
399 return *p_value;
400 }
401
402 //*************************************************************************
404 //*************************************************************************
405 ETL_CONSTEXPR14 const_pointer operator->() const
406 {
407 return p_value;
408 }
409
410 //*************************************************************************
412 //*************************************************************************
413 ETL_CONSTEXPR14 friend bool operator==(const const_iterator& lhs, const const_iterator& rhs)
414 {
415 return (lhs.p_current_span == rhs.p_current_span) && (lhs.p_value == rhs.p_value);
416 }
417
418 //*************************************************************************
420 //*************************************************************************
421 ETL_CONSTEXPR14 friend bool operator!=(const const_iterator& lhs, const const_iterator& rhs)
422 {
423 return !(lhs == rhs);
424 }
425
426 private:
427
428 typedef const span_type* span_pointer;
429 typedef const span_list_type* span_list_pointer;
430 typedef const typename span_list_type::iterator span_list_iterator;
431
432 //*****************************************
433 ETL_CONSTEXPR14 const_iterator(const span_list_type& span_list_, span_list_iterator p_current_span_)
434 : p_span_list(&span_list_)
435 , p_current_span(p_current_span_)
436 , p_value(ETL_NULLPTR)
437 {
438 if (p_current_span != p_span_list->end())
439 {
440 while ((p_current_span != p_span_list->end()) && p_current_span->empty())
441 {
442 ++p_current_span;
443 }
444
445 if (p_current_span != p_span_list->end())
446 {
447 p_value = p_current_span->begin();
448 }
449 else
450 {
451 p_value = ETL_NULLPTR;
452 }
453 }
454 }
455
456 span_list_pointer p_span_list;
457 span_pointer p_current_span;
458 const_pointer p_value;
459 };
460
461 typedef ETL_OR_STD::reverse_iterator<iterator> reverse_iterator;
462 typedef ETL_OR_STD::reverse_iterator<const_iterator> const_reverse_iterator;
463
464 //*************************************************************************
466 //*************************************************************************
467 ETL_CONSTEXPR14 multi_span(span_list_type span_list_)
468 : span_list(span_list_)
469 {
470 }
471
472 //*************************************************************************
475 //*************************************************************************
476 template <typename TContainer>
477 ETL_CONSTEXPR14 multi_span(TContainer& a) ETL_NOEXCEPT
478 : span_list(a.data(), a.data() + a.size())
479 {
480 }
481
482 //*************************************************************************
485 //*************************************************************************
486 template <typename TContainer>
487 ETL_CONSTEXPR14 multi_span(const TContainer& a) ETL_NOEXCEPT
488 : span_list(a.data(), a.data() + a.size())
489 {
490 }
491
492 //*************************************************************************
494 //*************************************************************************
495 template <typename TIterator>
496 ETL_CONSTEXPR14 multi_span(TIterator begin_, TIterator end_)
497 : span_list(etl::to_address(begin_), etl::distance(begin_, end_))
498 {
499 }
500
501 //*************************************************************************
503 //*************************************************************************
504 template <typename TIterator>
505 ETL_CONSTEXPR14 multi_span(TIterator begin_, size_t length_)
506 : span_list(etl::to_address(begin_), length_)
507 {
508 }
509
510 //*************************************************************************
512 //*************************************************************************
513 ETL_CONSTEXPR14 multi_span(const multi_span& other)
514 : span_list(other.span_list)
515 {
516 }
517
518 //*************************************************************************
520 //*************************************************************************
521 ETL_CONSTEXPR14 multi_span& operator=(const multi_span& other)
522 {
523 span_list = other.span_list;
524
525 return *this;
526 }
527
528 //*************************************************************************
530 //*************************************************************************
531 ETL_CONSTEXPR14 iterator begin() const
532 {
533 return iterator(span_list, span_list.begin());
534 }
535
536 //*************************************************************************
538 //*************************************************************************
539 ETL_CONSTEXPR14 const_iterator cbegin() const
540 {
541 return const_iterator(span_list, span_list.cbegin());
542 }
543
544 //*************************************************************************
546 //*************************************************************************
547 ETL_CONSTEXPR14 iterator end() const
548 {
549 return iterator(span_list, span_list.end());
550 }
551
552 //*************************************************************************
554 //*************************************************************************
555 ETL_CONSTEXPR14 const_iterator cend() const
556 {
557 return const_iterator(span_list, span_list.cend());
558 }
559
560 //*************************************************************************
562 //*************************************************************************
563 ETL_CONSTEXPR14 reverse_iterator rbegin() const
564 {
565 return reverse_iterator(end());
566 }
567
568 //*************************************************************************
570 //*************************************************************************
571 ETL_CONSTEXPR14 reverse_iterator crbegin() const
572 {
573 return const_reverse_iterator(cend());
574 }
575
576 //*************************************************************************
578 //*************************************************************************
579 ETL_CONSTEXPR14 reverse_iterator rend() const
580 {
581 return reverse_iterator(begin());
582 }
583
584 //*************************************************************************
586 //*************************************************************************
587 ETL_CONSTEXPR14 const_reverse_iterator crend() const
588 {
589 return const_reverse_iterator(cbegin());
590 }
591
592 //*************************************************************************
594 //*************************************************************************
595 ETL_CONSTEXPR14 reference operator[](size_t i) const
596 {
597 // Find the span in the span list.
598 size_t number_of_spans = span_list.size();
599
600 size_t index = 0;
601
602 while ((i >= span_list[index].size()) && (index < number_of_spans))
603 {
604 i -= span_list[index].size();
605 ++index;
606 }
607
608 return span_list[index][i];
609 }
610
611 //*************************************************************************
613 //*************************************************************************
614 ETL_CONSTEXPR14 size_t size() const ETL_NOEXCEPT
615 {
616 size_t total_n_spans = 0U;
617
618 for (typename span_list_type::iterator itr = span_list.begin(); itr != span_list.end(); ++itr)
619 {
620 total_n_spans += itr->size();
621 }
622
623 return total_n_spans;
624 }
625
626 //*************************************************************************
628 //*************************************************************************
629 ETL_CONSTEXPR14 bool empty() const ETL_NOEXCEPT
630 {
631 if (span_list.empty())
632 {
633 return true;
634 }
635 else
636 {
637 return size() == 0U;
638 }
639 }
640
641 //*************************************************************************
643 //*************************************************************************
644 ETL_CONSTEXPR14 size_t size_bytes() const ETL_NOEXCEPT
645 {
646 size_t total_n_spans_bytes = 0U;
647
648 for (typename span_list_type::iterator itr = span_list.begin(); itr != span_list.end(); ++itr)
649 {
650 total_n_spans_bytes += itr->size_bytes();
651 }
652
653 return total_n_spans_bytes;
654 }
655
656 //*************************************************************************
658 //*************************************************************************
659 ETL_CONSTEXPR14 size_t size_spans() const ETL_NOEXCEPT
660 {
661 return span_list.size();
662 }
663
664 private:
665
666 span_list_type span_list;
667 };
668} // namespace etl
669
670#endif
Const Iterator.
Definition multi_span.h:265
ETL_CONSTEXPR14 friend bool operator==(const const_iterator &lhs, const const_iterator &rhs)
== operator
Definition multi_span.h:413
ETL_CONSTEXPR14 friend bool operator!=(const const_iterator &lhs, const const_iterator &rhs)
!= operator
Definition multi_span.h:421
ETL_CONSTEXPR14 const_reference operator*() const
Definition multi_span.h:397
ETL_CONSTEXPR14 const_pointer operator->() const
-> operator
Definition multi_span.h:405
Iterator.
Definition multi_span.h:66
ETL_CONSTEXPR14 reference operator*()
Definition multi_span.h:181
ETL_CONSTEXPR14 friend bool operator==(const iterator &lhs, const iterator &rhs)
== operator
Definition multi_span.h:213
ETL_CONSTEXPR14 const_reference operator*() const
Definition multi_span.h:189
ETL_CONSTEXPR14 pointer operator->()
-> operator
Definition multi_span.h:197
ETL_CONSTEXPR14 const_pointer operator->() const
-> operator
Definition multi_span.h:205
ETL_CONSTEXPR14 friend bool operator!=(const iterator &lhs, const iterator &rhs)
!= operator
Definition multi_span.h:221
ETL_CONSTEXPR14 multi_span(TIterator begin_, size_t length_)
Constructor.
Definition multi_span.h:505
ETL_CONSTEXPR14 multi_span(const multi_span &other)
Copy Constructor.
Definition multi_span.h:513
ETL_CONSTEXPR14 size_t size_spans() const ETL_NOEXCEPT
Returns the number of spans in the multi_span.
Definition multi_span.h:659
ETL_CONSTEXPR14 reference operator[](size_t i) const
Returns a reference to the indexed value.
Definition multi_span.h:595
ETL_CONSTEXPR14 size_t size() const ETL_NOEXCEPT
Returns the number of elements in the multi_span.
Definition multi_span.h:614
ETL_CONSTEXPR14 multi_span & operator=(const multi_span &other)
Assignment operator.
Definition multi_span.h:521
ETL_CONSTEXPR14 multi_span(const TContainer &a) ETL_NOEXCEPT
Definition multi_span.h:487
ETL_CONSTEXPR14 multi_span(TIterator begin_, TIterator end_)
Constructor.
Definition multi_span.h:496
ETL_CONSTEXPR14 multi_span(span_list_type span_list_)
Constructor.
Definition multi_span.h:467
ETL_CONSTEXPR14 size_t size_bytes() const ETL_NOEXCEPT
Returns the size of the multi_span.
Definition multi_span.h:644
ETL_CONSTEXPR14 multi_span(TContainer &a) ETL_NOEXCEPT
Definition multi_span.h:477
ETL_CONSTEXPR14 bool empty() const ETL_NOEXCEPT
Returns true if the multi_span size is zero.
Definition multi_span.h:629
Span - Fixed Extent.
Definition span.h:208
ETL_NODISCARD ETL_CONSTEXPR iterator end() const ETL_NOEXCEPT
Returns an iterator to the end of the span.
Definition span.h:508
bitset_ext
Definition absolute.h:40
ETL_CONSTEXPR TContainer::reverse_iterator rend(TContainer &container)
Definition iterator.h:1119
ETL_CONSTEXPR TContainer::const_reverse_iterator crbegin(const TContainer &container)
Definition iterator.h:1109
ETL_CONSTEXPR TContainer::reverse_iterator rbegin(TContainer &container)
Definition iterator.h:1089
ETL_CONSTEXPR TContainer::const_iterator cbegin(const TContainer &container)
Definition iterator.h:987
ETL_CONSTEXPR T * to_address(T *p) ETL_NOEXCEPT
Definition memory.h:62
ETL_CONSTEXPR TContainer::iterator begin(TContainer &container)
Definition iterator.h:967
ETL_CONSTEXPR TContainer::const_reverse_iterator crend(const TContainer &container)
Definition iterator.h:1139
ETL_CONSTEXPR TContainer::const_iterator cend(const TContainer &container)
Definition iterator.h:1017
ETL_CONSTEXPR TContainer::iterator end(TContainer &container)
Definition iterator.h:997
iterator
Definition iterator.h:424