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 "iterator.h"
36#include "algorithm.h"
37#include "vector.h"
38#include "span.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;
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 {
109 ++p_current_span;
110 } while ((p_current_span != p_span_list->end()) && p_current_span->empty());
111
112 if (p_current_span != p_span_list->end())
113 {
114 p_value = p_current_span->begin();
115 }
116 else
117 {
118 p_value = ETL_NULLPTR;
119 }
120 }
121 }
122
123 return *this;
124 }
125
126 //*****************************************
127 ETL_CONSTEXPR14 iterator operator ++(int)
128 {
129 iterator temp = *this;
130
131 operator ++();
132
133 return temp;
134 }
135
136 //*****************************************
137 ETL_CONSTEXPR14 iterator& operator --()
138 {
139 if (p_current_span == p_span_list->end())
140 {
141 --p_current_span;
142 p_value = p_current_span->end();
143 --p_value;
144 }
145 else if ((p_current_span != p_span_list->begin()) || (p_value != p_current_span->begin()))
146 {
147 if (p_value == p_current_span->begin())
148 {
149 do
150 {
151 --p_current_span;
152 } while ((p_current_span != p_span_list->begin()) && p_current_span->empty());
153
154 p_value = p_current_span->end();
155 --p_value;
156 }
157 else
158 {
159 --p_value;
160 }
161 }
162 else
163 {
164 p_value = ETL_NULLPTR;
165 }
166
167 return *this;
168 }
169
170 //*****************************************
171 ETL_CONSTEXPR14 iterator operator --(int)
172 {
173 iterator temp = *this;
174
175 operator --();
176
177 return temp;
178 }
179
180 //*************************************************************************
182 //*************************************************************************
183 ETL_CONSTEXPR14 reference operator *()
184 {
185 return *p_value;
186 }
187
188 //*************************************************************************
190 //*************************************************************************
191 ETL_CONSTEXPR14 const_reference operator *() const
192 {
193 return *p_value;
194 }
195
196 //*************************************************************************
198 //*************************************************************************
199 ETL_CONSTEXPR14 pointer operator ->()
200 {
201 return p_value;
202 }
203
204 //*************************************************************************
206 //*************************************************************************
207 ETL_CONSTEXPR14 const_pointer operator ->() const
208 {
209 return p_value;
210 }
211
212 //*************************************************************************
214 //*************************************************************************
215 ETL_CONSTEXPR14 friend bool operator ==(const iterator& lhs, const iterator& rhs)
216 {
217 return (lhs.p_current_span == rhs.p_current_span) && (lhs.p_value == rhs.p_value);
218 }
219
220 //*************************************************************************
222 //*************************************************************************
223 ETL_CONSTEXPR14 friend bool operator !=(const iterator& lhs, const iterator& rhs)
224 {
225 return !(lhs == rhs);
226 }
227
228 private:
229
230 typedef const span_type* span_pointer;
231 typedef const span_list_type* span_list_pointer;
232 typedef typename span_list_type::iterator span_list_iterator;
233
234 //*****************************************
235 ETL_CONSTEXPR14 iterator(const span_list_type& span_list_, span_list_iterator p_current_span_)
236 : p_span_list(&span_list_)
237 , p_current_span(p_current_span_)
238 , p_value(ETL_NULLPTR)
239 {
240 if (p_current_span != p_span_list->end())
241 {
242 while ((p_current_span != p_span_list->end()) && p_current_span->empty())
243 {
244 ++p_current_span;
245 }
246
247 if (p_current_span != p_span_list->end())
248 {
249 p_value = p_current_span->begin();
250 }
251 else
252 {
253 p_value = ETL_NULLPTR;
254 }
255 }
256 }
257
258 span_list_pointer p_span_list;
259 span_pointer p_current_span;
260 pointer p_value;
261 };
262
263 //*************************************************************************
265 //*************************************************************************
266 class const_iterator : public etl::iterator<ETL_OR_STD::bidirectional_iterator_tag, const element_type>
267 {
268 public:
269
270 friend class multi_span;
271
272 //*****************************************
273 ETL_CONSTEXPR14 const_iterator()
274 : p_span_list(ETL_NULLPTR)
275 , p_current_span(ETL_NULLPTR)
276 , p_value(ETL_NULLPTR)
277 {
278 }
279
280 //*****************************************
281 ETL_CONSTEXPR14 const_iterator(const const_iterator& other)
282 : p_span_list(other.p_span_list)
283 , p_current_span(other.p_current_span)
284 , p_value(other.p_value)
285 {
286 }
287
288 //*****************************************
289 ETL_CONSTEXPR14 const_iterator& operator =(const const_iterator& rhs)
290 {
291 p_span_list = rhs.p_span_list;
292 p_current_span = rhs.p_current_span;
293 p_value = rhs.p_value;
294
295 return *this;
296 }
297
298 //*****************************************
300 : p_span_list(other.p_span_list)
301 , p_current_span(other.p_current_span)
302 , p_value(other.p_value)
303 {
304 }
305
306 //*****************************************
308 {
309 p_span_list = rhs.p_span_list;
310 p_current_span = rhs.p_current_span;
311 p_value = rhs.p_value;
312
313 return *this;
314 }
315
316 //*****************************************
317 ETL_CONSTEXPR14 const_iterator& operator ++()
318 {
319 if (p_current_span != p_span_list->end())
320 {
321 ++p_value;
322
323 if (p_value == p_current_span->end())
324 {
325 do
326 {
327 ++p_current_span;
328 } while ((p_current_span != p_span_list->end()) && p_current_span->empty());
329
330 if (p_current_span != p_span_list->end())
331 {
332 p_value = p_current_span->begin();
333 }
334 else
335 {
336 p_value = ETL_NULLPTR;
337 }
338 }
339 }
340
341 return *this;
342 }
343
344 //*****************************************
345 ETL_CONSTEXPR14 const_iterator operator ++(int)
346 {
347 const_iterator temp = *this;
348
349 operator ++();
350
351 return temp;
352 }
353
354 //*****************************************
355 ETL_CONSTEXPR14 const_iterator& operator --()
356 {
357 if (p_current_span == p_span_list->end())
358 {
359 --p_current_span;
360 p_value = p_current_span->end();
361 --p_value;
362 }
363 else if ((p_current_span != p_span_list->begin()) || (p_value != p_current_span->begin()))
364 {
365 if (p_value == p_current_span->begin())
366 {
367 do
368 {
369 --p_current_span;
370 } while ((p_current_span != p_span_list->begin()) && p_current_span->empty());
371
372 p_value = p_current_span->end();
373 --p_value;
374 }
375 else
376 {
377 --p_value;
378 }
379 }
380 else
381 {
382 p_value = ETL_NULLPTR;
383 }
384
385 return *this;
386 }
387
388 //*****************************************
389 ETL_CONSTEXPR14 const_iterator operator --(int)
390 {
391 const_iterator temp = *this;
392
393 operator --();
394
395 return temp;
396 }
397
398 //*************************************************************************
400 //*************************************************************************
401 ETL_CONSTEXPR14 const_reference operator *() const
402 {
403 return *p_value;
404 }
405
406 //*************************************************************************
408 //*************************************************************************
409 ETL_CONSTEXPR14 const_pointer operator ->() const
410 {
411 return p_value;
412 }
413
414 //*************************************************************************
416 //*************************************************************************
417 ETL_CONSTEXPR14 friend bool operator ==(const const_iterator& lhs, const const_iterator& rhs)
418 {
419 return (lhs.p_current_span == rhs.p_current_span) && (lhs.p_value == rhs.p_value);
420 }
421
422 //*************************************************************************
424 //*************************************************************************
425 ETL_CONSTEXPR14 friend bool operator !=(const const_iterator& lhs, const const_iterator& rhs)
426 {
427 return !(lhs == rhs);
428 }
429
430 private:
431
432 typedef const span_type* span_pointer;
433 typedef const span_list_type* span_list_pointer;
434 typedef const typename span_list_type::iterator span_list_iterator;
435
436 //*****************************************
437 ETL_CONSTEXPR14 const_iterator(const span_list_type& span_list_, span_list_iterator p_current_span_)
438 : p_span_list(&span_list_)
439 , p_current_span(p_current_span_)
440 , p_value(ETL_NULLPTR)
441 {
442 if (p_current_span != p_span_list->end())
443 {
444 while ((p_current_span != p_span_list->end()) && p_current_span->empty())
445 {
446 ++p_current_span;
447 }
448
449 if (p_current_span != p_span_list->end())
450 {
451 p_value = p_current_span->begin();
452 }
453 else
454 {
455 p_value = ETL_NULLPTR;
456 }
457 }
458 }
459
460 span_list_pointer p_span_list;
461 span_pointer p_current_span;
462 const_pointer p_value;
463 };
464
465 typedef ETL_OR_STD::reverse_iterator<iterator> reverse_iterator;
466 typedef ETL_OR_STD::reverse_iterator<const_iterator> const_reverse_iterator;
467
468 //*************************************************************************
470 //*************************************************************************
472 : span_list(span_list_)
473 {
474 }
475
476 //*************************************************************************
479 //*************************************************************************
480 template <typename TContainer>
481 ETL_CONSTEXPR14 multi_span(TContainer& a) ETL_NOEXCEPT
482 : span_list(a.data(), a.data() + a.size())
483 {
484 }
485
486 //*************************************************************************
489 //*************************************************************************
490 template <typename TContainer>
491 ETL_CONSTEXPR14 multi_span(const TContainer& a) ETL_NOEXCEPT
492 : span_list(a.data(), a.data() + a.size())
493 {
494 }
495
496 //*************************************************************************
498 //*************************************************************************
499 template <typename TIterator>
501 : span_list(etl::to_address(begin_), etl::distance(begin_, end_))
502 {
503 }
504
505 //*************************************************************************
507 //*************************************************************************
508 template <typename TIterator>
509 ETL_CONSTEXPR14 multi_span(TIterator begin_, size_t length_)
510 : span_list(etl::to_address(begin_), length_)
511 {
512 }
513
514 //*************************************************************************
516 //*************************************************************************
517 ETL_CONSTEXPR14 multi_span(const multi_span& other)
518 : span_list(other.span_list)
519 {
520 }
521
522 //*************************************************************************
524 //*************************************************************************
525 ETL_CONSTEXPR14 multi_span& operator =(const multi_span & other)
526 {
527 span_list = other.span_list;
528
529 return *this;
530 }
531
532 //*************************************************************************
534 //*************************************************************************
535 ETL_CONSTEXPR14 iterator begin() const
536 {
537 return iterator(span_list, span_list.begin());
538 }
539
540 //*************************************************************************
542 //*************************************************************************
543 ETL_CONSTEXPR14 const_iterator cbegin() const
544 {
545 return const_iterator(span_list, span_list.cbegin());
546 }
547
548 //*************************************************************************
550 //*************************************************************************
551 ETL_CONSTEXPR14 iterator end() const
552 {
553 return iterator(span_list, span_list.end());
554 }
555
556 //*************************************************************************
558 //*************************************************************************
559 ETL_CONSTEXPR14 const_iterator cend() const
560 {
561 return const_iterator(span_list, span_list.cend());
562 }
563
564 //*************************************************************************
566 //*************************************************************************
567 ETL_CONSTEXPR14 reverse_iterator rbegin() const
568 {
569 return reverse_iterator(end());
570 }
571
572 //*************************************************************************
574 //*************************************************************************
575 ETL_CONSTEXPR14 reverse_iterator crbegin() const
576 {
577 return const_reverse_iterator(cend());
578 }
579
580 //*************************************************************************
582 //*************************************************************************
583 ETL_CONSTEXPR14 reverse_iterator rend() const
584 {
585 return reverse_iterator(begin());
586 }
587
588 //*************************************************************************
590 //*************************************************************************
591 ETL_CONSTEXPR14 const_reverse_iterator crend() const
592 {
593 return const_reverse_iterator(cbegin());
594 }
595
596 //*************************************************************************
598 //*************************************************************************
599 ETL_CONSTEXPR14 reference operator[](size_t i) const
600 {
601 // Find the span in the span list.
602 size_t number_of_spans = span_list.size();
603
604 size_t index = 0;
605
606 while ((i >= span_list[index].size()) && (index < number_of_spans))
607 {
608 i -= span_list[index].size();
609 ++index;
610 }
611
612 return span_list[index][i];
613 }
614
615 //*************************************************************************
617 //*************************************************************************
618 ETL_CONSTEXPR14 size_t size() const ETL_NOEXCEPT
619 {
620 size_t total_n_spans = 0U;
621
622 for (typename span_list_type::iterator itr = span_list.begin();
623 itr != span_list.end();
624 ++itr)
625 {
626 total_n_spans += itr->size();
627 }
628
629 return total_n_spans;
630 }
631
632 //*************************************************************************
634 //*************************************************************************
635 ETL_CONSTEXPR14 bool empty() const ETL_NOEXCEPT
636 {
637 if (span_list.empty())
638 {
639 return true;
640 }
641 else
642 {
643 return size() == 0U;
644 }
645 }
646
647 //*************************************************************************
649 //*************************************************************************
650 ETL_CONSTEXPR14 size_t size_bytes() const ETL_NOEXCEPT
651 {
652 size_t total_n_spans_bytes = 0U;
653
654 for (typename span_list_type::iterator itr = span_list.begin();
655 itr != span_list.end();
656 ++itr)
657 {
658 total_n_spans_bytes += itr->size_bytes();
659 }
660
661 return total_n_spans_bytes;
662 }
663
664 //*************************************************************************
666 //*************************************************************************
667 ETL_CONSTEXPR14 size_t size_spans() const ETL_NOEXCEPT
668 {
669 return span_list.size();
670 }
671
672 private:
673
674 span_list_type span_list;
675 };
676}
677
678#endif
679
Const Iterator.
Definition multi_span.h:267
ETL_CONSTEXPR14 friend bool operator==(const const_iterator &lhs, const const_iterator &rhs)
== operator
Definition multi_span.h:417
ETL_CONSTEXPR14 friend bool operator!=(const const_iterator &lhs, const const_iterator &rhs)
!= operator
Definition multi_span.h:425
ETL_CONSTEXPR14 const_reference operator*() const
Definition multi_span.h:401
ETL_CONSTEXPR14 const_pointer operator->() const
-> operator
Definition multi_span.h:409
Iterator.
Definition multi_span.h:66
ETL_CONSTEXPR14 reference operator*()
Definition multi_span.h:183
ETL_CONSTEXPR14 friend bool operator==(const iterator &lhs, const iterator &rhs)
== operator
Definition multi_span.h:215
ETL_CONSTEXPR14 pointer operator->()
-> operator
Definition multi_span.h:199
ETL_CONSTEXPR14 friend bool operator!=(const iterator &lhs, const iterator &rhs)
!= operator
Definition multi_span.h:223
Definition multi_span.h:48
ETL_CONSTEXPR14 multi_span(TIterator begin_, size_t length_)
Constructor.
Definition multi_span.h:509
ETL_CONSTEXPR14 multi_span(const multi_span &other)
Copy Constructor.
Definition multi_span.h:517
ETL_CONSTEXPR14 size_t size_spans() const ETL_NOEXCEPT
Returns the number of spans in the multi_span.
Definition multi_span.h:667
ETL_CONSTEXPR14 reference operator[](size_t i) const
Returns a reference to the indexed value.
Definition multi_span.h:599
ETL_CONSTEXPR14 size_t size() const ETL_NOEXCEPT
Returns the number of elements in the multi_span.
Definition multi_span.h:618
ETL_CONSTEXPR14 multi_span & operator=(const multi_span &other)
Assignment operator.
Definition multi_span.h:525
ETL_CONSTEXPR14 multi_span(const TContainer &a) ETL_NOEXCEPT
Definition multi_span.h:491
ETL_CONSTEXPR14 multi_span(TIterator begin_, TIterator end_)
Constructor.
Definition multi_span.h:500
ETL_CONSTEXPR14 multi_span(span_list_type span_list_)
Constructor.
Definition multi_span.h:471
ETL_CONSTEXPR14 size_t size_bytes() const ETL_NOEXCEPT
Returns the size of the multi_span.
Definition multi_span.h:650
ETL_CONSTEXPR14 multi_span(TContainer &a) ETL_NOEXCEPT
Definition multi_span.h:481
ETL_CONSTEXPR14 bool empty() const ETL_NOEXCEPT
Returns true if the multi_span size is zero.
Definition multi_span.h:635
ETL_NODISCARD ETL_CONSTEXPR const_iterator cbegin() const ETL_NOEXCEPT
Returns a const iterator to the beginning of the span.
Definition span.h:193
ETL_NODISCARD ETL_CONSTEXPR iterator begin() const ETL_NOEXCEPT
Returns an iterator to the beginning of the span.
Definition span.h:201
ETL_NODISCARD ETL_CONSTEXPR bool empty() const ETL_NOEXCEPT
Returns true if the span size is zero.
Definition span.h:273
ETL_NODISCARD ETL_CONSTEXPR const_iterator cend() const ETL_NOEXCEPT
Returns a const iterator to the end of the span.
Definition span.h:217
ETL_NODISCARD ETL_CONSTEXPR size_t size() const ETL_NOEXCEPT
Returns the size of the span.
Definition span.h:281
ETL_NODISCARD ETL_CONSTEXPR iterator end() const ETL_NOEXCEPT
Returns an iterator to the end of the span.
Definition span.h:225
bitset_ext
Definition absolute.h:38
ETL_CONSTEXPR T * to_address(T *p)
Definition memory.h:62
iterator
Definition iterator.h:399
pair holds two objects of arbitrary type
Definition utility.h:164