Embedded Template Library 1.0
Loading...
Searching...
No Matches
list.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) 2014 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_LIST_INCLUDED
32#define ETL_LIST_INCLUDED
33
34#include "platform.h"
35#include "algorithm.h"
36#include "iterator.h"
37#include "functional.h"
38#include "pool.h"
39#include "exception.h"
40#include "error_handler.h"
41#include "debug_count.h"
42#include "nullptr.h"
43#include "type_traits.h"
44#include "algorithm.h"
45#include "memory.h"
46#include "static_assert.h"
47#include "parameter_type.h"
48#include "placement_new.h"
49#include "initializer_list.h"
50
51#include <stddef.h>
52
53#include "private/minmax_push.h"
54
55//*****************************************************************************
59//*****************************************************************************
60
61namespace etl
62{
63 //***************************************************************************
66 //***************************************************************************
67 class list_exception : public exception
68 {
69 public:
70
71 list_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
72 : exception(reason_, file_name_, line_number_)
73 {
74 }
75 };
76
77 //***************************************************************************
80 //***************************************************************************
81 class list_full : public list_exception
82 {
83 public:
84
85 list_full(string_type file_name_, numeric_type line_number_)
86 : list_exception(ETL_ERROR_TEXT("list:full", ETL_LIST_FILE_ID"A"), file_name_, line_number_)
87 {
88 }
89 };
90
91 //***************************************************************************
94 //***************************************************************************
95 class list_empty : public list_exception
96 {
97 public:
98
99 list_empty(string_type file_name_, numeric_type line_number_)
100 : list_exception(ETL_ERROR_TEXT("list:empty", ETL_LIST_FILE_ID"B"), file_name_, line_number_)
101 {
102 }
103 };
104
105 //***************************************************************************
108 //***************************************************************************
109 class list_iterator : public list_exception
110 {
111 public:
112
113 list_iterator(string_type file_name_, numeric_type line_number_)
114 : list_exception(ETL_ERROR_TEXT("list:iterator", ETL_LIST_FILE_ID"C"), file_name_, line_number_)
115 {
116 }
117 };
118
119 //***************************************************************************
122 //***************************************************************************
123 class list_unsorted : public list_exception
124 {
125 public:
126
127 list_unsorted(string_type file_name_, numeric_type line_number_)
128 : list_exception(ETL_ERROR_TEXT("list:unsorted", ETL_LIST_FILE_ID"D"), file_name_, line_number_)
129 {
130 }
131 };
132
133 //***************************************************************************
136 //***************************************************************************
137 class list_no_pool : public list_exception
138 {
139 public:
140
141 list_no_pool(string_type file_name_, numeric_type line_number_)
142 : list_exception(ETL_ERROR_TEXT("list:no pool", ETL_LIST_FILE_ID"E"), file_name_, line_number_)
143 {
144 }
145 };
146
147 //***************************************************************************
150 //***************************************************************************
152 {
153 public:
154
155 typedef size_t size_type;
156
157 //*************************************************************************
159 //*************************************************************************
160 struct node_t
161 {
162 //***********************************************************************
164 //***********************************************************************
166 : previous(ETL_NULLPTR),
167 next(ETL_NULLPTR)
168 {
169 }
170
171 //***********************************************************************
173 //***********************************************************************
174 void reverse()
175 {
176 using ETL_OR_STD::swap; // Allow ADL
177
178 swap(previous, next);
179 }
180
181 node_t* previous;
182 node_t* next;
183 };
184
185 //*************************************************************************
187 //*************************************************************************
188 bool has_shared_pool() const
189 {
190 return pool_is_shared;
191 }
192
193 //*************************************************************************
195 //*************************************************************************
196 void reverse()
197 {
198 if (is_trivial_list())
199 {
200 return;
201 }
202
203 node_t* p_node = terminal_node.next;
204
205 while (p_node != &terminal_node)
206 {
207 node_t* p_temp = p_node->previous;
208 p_node->previous = p_node->next;
209 p_node->next = p_temp;
210 p_node = p_node->previous;
211 }
212
213 // Terminal node.
214 node_t* p_temp = p_node->previous;
215 p_node->previous = p_node->next;
216 p_node->next = p_temp;
217 }
218
219 //*************************************************************************
221 //*************************************************************************
223 {
224 return MAX_SIZE;
225 }
226
227 //*************************************************************************
229 //*************************************************************************
231 {
232 return MAX_SIZE;
233 }
234
235 //*************************************************************************
237 //*************************************************************************
239 {
240 if (has_shared_pool())
241 {
242 // We have to count what we actually own.
243 size_type count = 0U;
244
245 node_t* p_node = terminal_node.next;
246
247 while (p_node != &terminal_node)
248 {
249 ++count;
250 p_node = p_node->next;
251 }
252
253 return count;
254 }
255 else
256 {
257 return p_node_pool->size();
258 }
259 }
260
261 //*************************************************************************
263 //*************************************************************************
264 bool empty() const
265 {
266 return (terminal_node.next == &terminal_node);
267 }
268
269 //*************************************************************************
271 //*************************************************************************
272 bool full() const
273 {
274 ETL_ASSERT(p_node_pool != ETL_NULLPTR, ETL_ERROR(list_no_pool));
275 return p_node_pool->full();
276 }
277
278 //*************************************************************************
281 //*************************************************************************
283 {
284 ETL_ASSERT(p_node_pool != ETL_NULLPTR, ETL_ERROR(list_no_pool));
285 return p_node_pool->available();
286 }
287
288 protected:
289
290 //*************************************************************************
292 //*************************************************************************
293 bool is_trivial_list() const
294 {
295 return (size() < 2);
296 }
297
298 //*************************************************************************
300 //*************************************************************************
302 {
303 return *terminal_node.next;
304 }
305
306 //*************************************************************************
308 //*************************************************************************
309 const node_t& get_head() const
310 {
311 return *terminal_node.next;
312 }
313
314 //*************************************************************************
316 //*************************************************************************
318 {
319 return *terminal_node.previous;
320 }
321
322 //*************************************************************************
324 //*************************************************************************
325 const node_t& get_tail() const
326 {
327 return *terminal_node.previous;
328 }
329
330 //*************************************************************************
332 //*************************************************************************
333 void insert_node(node_t& position, node_t& node)
334 {
335 // Connect to the list.
336 join(*position.previous, node);
337 join(node, position);
338 }
339
340 //*************************************************************************
342 //*************************************************************************
343 void join(node_t& left, node_t& right)
344 {
345 left.next = &right;
346 right.previous = &left;
347 }
348
349 //*************************************************************************
351 //*************************************************************************
352 explicit list_base(bool pool_is_shared_)
353 : p_node_pool(ETL_NULLPTR),
354 MAX_SIZE(0),
355 pool_is_shared(pool_is_shared_)
356 {
358 }
359
360 //*************************************************************************
362 //*************************************************************************
363 list_base(etl::ipool& node_pool_, size_type max_size_, bool pool_is_shared_)
364 : p_node_pool(&node_pool_),
365 MAX_SIZE(max_size_),
366 pool_is_shared(pool_is_shared_)
367 {
369 }
370
371 //*************************************************************************
373 //*************************************************************************
374 void set_node_pool(etl::ipool& node_pool_)
375 {
376 p_node_pool = &node_pool_;
377 MAX_SIZE = p_node_pool->max_size();
378 }
379
380 //*************************************************************************
382 //*************************************************************************
384 {
385 return p_node_pool;
386 }
387
388 //*************************************************************************
390 //*************************************************************************
392 {
393 }
394
400 };
401
402 //***************************************************************************
405 //***************************************************************************
406 template <typename T>
407 class ilist : public etl::list_base
408 {
409 public:
410
411 typedef T value_type;
412 typedef T* pointer;
413 typedef const T* const_pointer;
414 typedef T& reference;
415 typedef const T& const_reference;
416#if ETL_USING_CPP11
417 typedef T&& rvalue_reference;
418#endif
419 typedef size_t size_type;
420
421 protected:
422
423 typedef typename etl::parameter_type<T>::type parameter_t;
424
425 //*************************************************************************
427 //*************************************************************************
428 struct data_node_t : public node_t
429 {
430 explicit data_node_t(const T& value_)
431 : value(value_)
432 {
433 }
434
435 T value;
436 };
437
438 private:
439
440 //*************************************************************************
442 //*************************************************************************
443 static data_node_t* data_cast(node_t* p_node)
444 {
445 return reinterpret_cast<data_node_t*>(p_node);
446 }
447
448 //*************************************************************************
450 //*************************************************************************
451 static data_node_t& data_cast(node_t& node)
452 {
453 return reinterpret_cast<data_node_t&>(node);
454 }
455
456 //*************************************************************************
458 //*************************************************************************
459 static const data_node_t* data_cast(const node_t* p_node)
460 {
461 return reinterpret_cast<const data_node_t*>(p_node);
462 }
463
464 //*************************************************************************
466 //*************************************************************************
467 static const data_node_t& data_cast(const node_t& node)
468 {
469 return reinterpret_cast<const data_node_t&>(node);
470 }
471
472 public:
473
474 //*************************************************************************
476 //*************************************************************************
477 class iterator : public etl::iterator<ETL_OR_STD::bidirectional_iterator_tag, T>
478 {
479 public:
480
481 friend class ilist;
482 friend class const_iterator;
483
484 iterator()
485 : p_node(ETL_NULLPTR)
486 {
487 }
488
489 iterator(node_t& node)
490 : p_node(&node)
491 {
492 }
493
494 iterator(const iterator& other)
495 : p_node(other.p_node)
496 {
497 }
498
499 iterator& operator ++()
500 {
501 p_node = p_node->next;
502 return *this;
503 }
504
505 iterator operator ++(int)
506 {
507 iterator temp(*this);
508 p_node = p_node->next;
509 return temp;
510 }
511
512 iterator& operator --()
513 {
514 p_node = p_node->previous;
515 return *this;
516 }
517
518 iterator operator --(int)
519 {
520 iterator temp(*this);
521 p_node = p_node->previous;
522 return temp;
523 }
524
525 iterator& operator =(const iterator& other)
526 {
527 p_node = other.p_node;
528 return *this;
529 }
530
531 reference operator *() const
532 {
533 return ilist::data_cast(p_node)->value;
534 }
535
536 pointer operator &() const
537 {
538 return &(ilist::data_cast(p_node)->value);
539 }
540
541 pointer operator ->() const
542 {
543 return &(ilist::data_cast(p_node)->value);
544 }
545
546 friend bool operator == (const iterator& lhs, const iterator& rhs)
547 {
548 return lhs.p_node == rhs.p_node;
549 }
550
551 friend bool operator != (const iterator& lhs, const iterator& rhs)
552 {
553 return !(lhs == rhs);
554 }
555
556 private:
557
558 node_t* p_node;
559 };
560
561 //*************************************************************************
563 //*************************************************************************
564 class const_iterator : public etl::iterator<ETL_OR_STD::bidirectional_iterator_tag, const T>
565 {
566 public:
567
568 friend class ilist;
569
570 const_iterator()
571 : p_node(ETL_NULLPTR)
572 {
573 }
574
575 const_iterator(node_t& node)
576 : p_node(&node)
577 {
578 }
579
580 const_iterator(const node_t& node)
581 : p_node(&node)
582 {
583 }
584
585 const_iterator(const typename ilist::iterator& other)
586 : p_node(other.p_node)
587 {
588 }
589
590 const_iterator(const const_iterator& other)
591 : p_node(other.p_node)
592 {
593 }
594
595 const_iterator& operator ++()
596 {
597 p_node = p_node->next;
598 return *this;
599 }
600
601 const_iterator operator ++(int)
602 {
603 const_iterator temp(*this);
604 p_node = p_node->next;
605 return temp;
606 }
607
608 const_iterator& operator --()
609 {
610 p_node = p_node->previous;
611 return *this;
612 }
613
614 const_iterator operator --(int)
615 {
616 const_iterator temp(*this);
617 p_node = p_node->previous;
618 return temp;
619 }
620
621 const_iterator& operator =(const const_iterator& other)
622 {
623 p_node = other.p_node;
624 return *this;
625 }
626
627 const_reference operator *() const
628 {
629 return ilist::data_cast(p_node)->value;
630 }
631
632 const_pointer operator &() const
633 {
634 return &(ilist::data_cast(p_node)->value);
635 }
636
637 const_pointer operator ->() const
638 {
639 return &(ilist::data_cast(p_node)->value);
640 }
641
642 friend bool operator == (const const_iterator& lhs, const const_iterator& rhs)
643 {
644 return lhs.p_node == rhs.p_node;
645 }
646
647 friend bool operator != (const const_iterator& lhs, const const_iterator& rhs)
648 {
649 return !(lhs == rhs);
650 }
651
652 private:
653
654 const node_t* p_node;
655 };
656
657 typedef typename etl::iterator_traits<iterator>::difference_type difference_type;
658
659 typedef ETL_OR_STD::reverse_iterator<iterator> reverse_iterator;
660 typedef ETL_OR_STD::reverse_iterator<const_iterator> const_reverse_iterator;
661
662 //*************************************************************************
664 //*************************************************************************
665 iterator begin()
666 {
667 return iterator(get_head());
668 }
669
670 //*************************************************************************
672 //*************************************************************************
673 const_iterator begin() const
674 {
675 return const_iterator(get_head());
676 }
677
678 //*************************************************************************
680 //*************************************************************************
681 iterator end()
682 {
683 return iterator(terminal_node);
684 }
685
686 //*************************************************************************
688 //*************************************************************************
689 const_iterator end() const
690 {
691 return const_iterator(terminal_node);
692 }
693
694 //*************************************************************************
696 //*************************************************************************
697 const_iterator cbegin() const
698 {
699 return const_iterator(get_head());
700 }
701
702 //*************************************************************************
704 //*************************************************************************
705 const_iterator cend() const
706 {
707 return const_iterator(terminal_node);
708 }
709
710 //*************************************************************************
712 //*************************************************************************
713 reverse_iterator rbegin()
714 {
715 return reverse_iterator(terminal_node);
716 }
717
718 //*************************************************************************
720 //*************************************************************************
721 const_reverse_iterator rbegin() const
722 {
723 return const_reverse_iterator(terminal_node);
724 }
725
726 //*************************************************************************
728 //*************************************************************************
729 reverse_iterator rend()
730 {
731 return reverse_iterator(get_head());
732 }
733
734 //*************************************************************************
736 //*************************************************************************
737 const_reverse_iterator rend() const
738 {
739 return const_reverse_iterator(get_head());
740 }
741
742 //*************************************************************************
744 //*************************************************************************
745 const_reverse_iterator crbegin() const
746 {
747 return const_reverse_iterator(terminal_node);
748 }
749
750 //*************************************************************************
752 //*************************************************************************
753 const_reverse_iterator crend() const
754 {
755 return const_reverse_iterator(get_head());
756 }
757
758 //*************************************************************************
760 //*************************************************************************
761 reference front()
762 {
763 return data_cast(get_head()).value;
764 }
765
766 //*************************************************************************
768 //*************************************************************************
769 const_reference front() const
770 {
771 return data_cast(get_head()).value;
772 }
773
774 //*************************************************************************
776 //*************************************************************************
777 reference back()
778 {
779 return data_cast(get_tail()).value;
780 }
781
782 //*************************************************************************
784 //*************************************************************************
785 const_reference back() const
786 {
787 return data_cast(get_tail()).value;
788 }
789
790 //*************************************************************************
794 //*************************************************************************
795 template <typename TIterator>
796 void assign(TIterator first, TIterator last, typename etl::enable_if<!etl::is_integral<TIterator>::value, int>::type = 0)
797 {
798#if ETL_IS_DEBUG_BUILD
799 difference_type d = etl::distance(first, last);
800 ETL_ASSERT(d >= 0, ETL_ERROR(list_iterator));
801 ETL_ASSERT(size_t(d) <= MAX_SIZE, ETL_ERROR(list_full));
802#endif
803 initialise();
804
805 // Add all of the elements.
806 while (first != last)
807 {
808 data_node_t& node = allocate_data_node(*first);
809 join(get_tail(), node);
810 join(node, terminal_node);
811 ++first;
812 }
813 }
814
815 //*************************************************************************
817 //*************************************************************************
818 void assign(size_t n, const T& value)
819 {
820#if ETL_IS_DEBUG_BUILD
821 ETL_ASSERT(n <= MAX_SIZE, ETL_ERROR(list_full));
822#endif
823
824 initialise();
825
826 // Add all of the elements.
827 while (n-- > 0)
828 {
829 data_node_t& node = allocate_data_node(value);
830 join(*terminal_node.previous, node);
831 join(node, terminal_node);
832 }
833 }
834
835 //*************************************************************************
837 //*************************************************************************
838 void push_front(const T& value)
839 {
840 ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(!full(), ETL_ERROR(list_full));
841
842 insert_node(get_head(), allocate_data_node(value));
843 }
844
845#if ETL_USING_CPP11
846 //*************************************************************************
848 //*************************************************************************
849 void push_front(rvalue_reference value)
850 {
851 ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(!full(), ETL_ERROR(list_full));
852
853 insert_node(get_head(), allocate_data_node(etl::move(value)));
854 }
855#endif
856
857#if ETL_USING_CPP11 && ETL_NOT_USING_STLPORT && !defined(ETL_LIST_FORCE_CPP03_IMPLEMENTATION)
858 //*************************************************************************
860 //*************************************************************************
861 template <typename ... Args>
862 reference emplace_front(Args && ... args)
863 {
864
865 ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(list_full));
866
867 ETL_ASSERT(p_node_pool != ETL_NULLPTR, ETL_ERROR(list_no_pool));
868
869 data_node_t* p_data_node = allocate_data_node();
870 ::new (&(p_data_node->value)) T(etl::forward<Args>(args)...);
871 ETL_INCREMENT_DEBUG_COUNT;
872 insert_node(get_head(), *p_data_node);
873 return front();
874 }
875#else
876 //*************************************************************************
878 //*************************************************************************
879 reference emplace_front()
880 {
881 ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(list_full));
882
883 ETL_ASSERT(p_node_pool != ETL_NULLPTR, ETL_ERROR(list_no_pool));
884
885 data_node_t* p_data_node = allocate_data_node();
886 ::new (&(p_data_node->value)) T();
887 ETL_INCREMENT_DEBUG_COUNT;
888 insert_node(get_head(), *p_data_node);
889 return front();
890 }
891
892 //*************************************************************************
894 //*************************************************************************
895 template <typename T1>
896 reference emplace_front(const T1& value1)
897 {
898 ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(list_full));
899
900 ETL_ASSERT(p_node_pool != ETL_NULLPTR, ETL_ERROR(list_no_pool));
901
902 data_node_t* p_data_node = allocate_data_node();
903 ::new (&(p_data_node->value)) T(value1);
904 ETL_INCREMENT_DEBUG_COUNT;
905 insert_node(get_head(), *p_data_node);
906 return front();
907 }
908
909 //*************************************************************************
911 //*************************************************************************
912 template <typename T1, typename T2>
913 reference emplace_front(const T1& value1, const T2& value2)
914 {
915 ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(list_full));
916
917 ETL_ASSERT(p_node_pool != ETL_NULLPTR, ETL_ERROR(list_no_pool));
918
919 data_node_t* p_data_node = allocate_data_node();
920 ::new (&(p_data_node->value)) T(value1, value2);
921 ETL_INCREMENT_DEBUG_COUNT;
922 insert_node(get_head(), *p_data_node);
923 return front();
924 }
925
926 //*************************************************************************
928 //*************************************************************************
929 template <typename T1, typename T2, typename T3>
930 reference emplace_front(const T1& value1, const T2& value2, const T3& value3)
931 {
932 ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(list_full));
933
934 ETL_ASSERT(p_node_pool != ETL_NULLPTR, ETL_ERROR(list_no_pool));
935
936 data_node_t* p_data_node = allocate_data_node();
937 ::new (&(p_data_node->value)) T(value1, value2, value3);
938 ETL_INCREMENT_DEBUG_COUNT;
939 insert_node(get_head(), *p_data_node);
940 return front();
941 }
942
943 //*************************************************************************
945 //*************************************************************************
946 template <typename T1, typename T2, typename T3, typename T4>
947 reference emplace_front(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
948 {
949 ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(list_full));
950
951 ETL_ASSERT(p_node_pool != ETL_NULLPTR, ETL_ERROR(list_no_pool));
952
953 data_node_t* p_data_node = allocate_data_node();
954 ::new (&(p_data_node->value)) T(value1, value2, value3, value4);
955 ETL_INCREMENT_DEBUG_COUNT;
956 insert_node(get_head(), *p_data_node);
957 return front();
958 }
959#endif
960
961 //*************************************************************************
963 //*************************************************************************
965 {
966 ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(!empty(), ETL_ERROR(list_empty));
967
968 node_t& node = get_head();
969 remove_node(node);
970 }
971
972 //*************************************************************************
974 //*************************************************************************
975 void push_back(const T& value)
976 {
977 ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(!full(), ETL_ERROR(list_full));
978
979 insert_node(terminal_node, allocate_data_node(value));
980 }
981
982#if ETL_USING_CPP11
983 //*************************************************************************
985 //*************************************************************************
986 void push_back(rvalue_reference value)
987 {
988 ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(!full(), ETL_ERROR(list_full));
989
990 insert_node(terminal_node, allocate_data_node(etl::move(value)));
991 }
992#endif
993
994 //*************************************************************************
996 //*************************************************************************
997#if ETL_USING_CPP11 && ETL_NOT_USING_STLPORT
998 template <typename ... Args>
999 reference emplace_back(Args && ... args)
1000 {
1001 ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(list_full));
1002
1003 ETL_ASSERT(p_node_pool != ETL_NULLPTR, ETL_ERROR(list_no_pool));
1004
1005 data_node_t* p_data_node = allocate_data_node();
1006 ::new (&(p_data_node->value)) T(etl::forward<Args>(args)...);
1007 ETL_INCREMENT_DEBUG_COUNT;
1008 insert_node(terminal_node, *p_data_node);
1009 return back();
1010 }
1011#else
1012 reference emplace_back()
1013 {
1014 ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(list_full));
1015
1016 ETL_ASSERT(p_node_pool != ETL_NULLPTR, ETL_ERROR(list_no_pool));
1017
1018 data_node_t* p_data_node = allocate_data_node();
1019 ::new (&(p_data_node->value)) T();
1020 ETL_INCREMENT_DEBUG_COUNT;
1021 insert_node(terminal_node, *p_data_node);
1022 return back();
1023 }
1024
1025 template <typename T1>
1026 reference emplace_back(const T1& value1)
1027 {
1028 ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(list_full));
1029
1030 ETL_ASSERT(p_node_pool != ETL_NULLPTR, ETL_ERROR(list_no_pool));
1031
1032 data_node_t* p_data_node = allocate_data_node();
1033 ::new (&(p_data_node->value)) T(value1);
1034 ETL_INCREMENT_DEBUG_COUNT;
1035 insert_node(terminal_node, *p_data_node);
1036 return back();
1037 }
1038
1039 template <typename T1, typename T2>
1040 reference emplace_back(const T1& value1, const T2& value2)
1041 {
1042 ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(list_full));
1043
1044 ETL_ASSERT(p_node_pool != ETL_NULLPTR, ETL_ERROR(list_no_pool));
1045
1046 data_node_t* p_data_node = allocate_data_node();
1047 ::new (&(p_data_node->value)) T(value1, value2);
1048 ETL_INCREMENT_DEBUG_COUNT;
1049 insert_node(terminal_node, *p_data_node);
1050 return back();
1051 }
1052
1053 template <typename T1, typename T2, typename T3>
1054 reference emplace_back(const T1& value1, const T2& value2, const T3& value3)
1055 {
1056 ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(list_full));
1057
1058 ETL_ASSERT(p_node_pool != ETL_NULLPTR, ETL_ERROR(list_no_pool));
1059
1060 data_node_t* p_data_node = allocate_data_node();
1061 ::new (&(p_data_node->value)) T(value1, value2, value3);
1062 ETL_INCREMENT_DEBUG_COUNT;
1063 insert_node(terminal_node, *p_data_node);
1064 return back();
1065 }
1066
1067 template <typename T1, typename T2, typename T3, typename T4>
1068 reference emplace_back(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
1069 {
1070 ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(list_full));
1071
1072 ETL_ASSERT(p_node_pool != ETL_NULLPTR, ETL_ERROR(list_no_pool));
1073
1074 data_node_t* p_data_node = allocate_data_node();
1075 ::new (&(p_data_node->value)) T(value1, value2, value3, value4);
1076 ETL_INCREMENT_DEBUG_COUNT;
1077 insert_node(terminal_node, *p_data_node);
1078 return back();
1079 }
1080#endif
1081
1082 //*************************************************************************
1084 //*************************************************************************
1086 {
1087 ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(!empty(), ETL_ERROR(list_empty));
1088
1089 node_t& node = get_tail();
1090 remove_node(node);
1091 }
1092
1093 //*************************************************************************
1095 //*************************************************************************
1096 iterator insert(const_iterator position, const_reference value)
1097 {
1098 ETL_ASSERT(!full(), ETL_ERROR(list_full));
1099
1100 data_node_t& data_node = allocate_data_node(value);
1101 insert_node(*to_iterator(position).p_node, data_node);
1102
1103 return iterator(data_node);
1104 }
1105
1106#if ETL_USING_CPP11
1107 //*************************************************************************
1109 //*************************************************************************
1110 iterator insert(const_iterator position, rvalue_reference value)
1111 {
1112 ETL_ASSERT(!full(), ETL_ERROR(list_full));
1113
1114 data_node_t& data_node = allocate_data_node(etl::move(value));
1115 insert_node(*to_iterator(position).p_node, data_node);
1116
1117 return iterator(data_node);
1118 }
1119#endif
1120
1121 //*************************************************************************
1123 //*************************************************************************
1124#if ETL_USING_CPP11 && ETL_NOT_USING_STLPORT && !defined(ETL_LIST_FORCE_CPP03_IMPLEMENTATION)
1125 template <typename ... Args>
1126 iterator emplace(const_iterator position, Args&& ... args)
1127 {
1128 ETL_ASSERT(!full(), ETL_ERROR(list_full));
1129 ETL_ASSERT(p_node_pool != ETL_NULLPTR, ETL_ERROR(list_no_pool));
1130
1131 data_node_t* p_data_node = allocate_data_node();
1132 ::new (&(p_data_node->value)) T(etl::forward<Args>(args)...);
1133 ETL_INCREMENT_DEBUG_COUNT;
1134 insert_node(*to_iterator(position).p_node, *p_data_node);
1135
1136 return iterator(*p_data_node);
1137 }
1138#else
1139 iterator emplace(const_iterator position)
1140 {
1141 ETL_ASSERT(!full(), ETL_ERROR(list_full));
1142 ETL_ASSERT(p_node_pool != ETL_NULLPTR, ETL_ERROR(list_no_pool));
1143
1144 data_node_t* p_data_node = allocate_data_node();
1145 ::new (&(p_data_node->value)) T();
1146 ETL_INCREMENT_DEBUG_COUNT;
1147 insert_node(*to_iterator(position).p_node, *p_data_node);
1148
1149 return iterator(*p_data_node);
1150 }
1151
1152 template <typename T1>
1153 iterator emplace(const_iterator position, const T1& value1)
1154 {
1155 ETL_ASSERT(!full(), ETL_ERROR(list_full));
1156 ETL_ASSERT(p_node_pool != ETL_NULLPTR, ETL_ERROR(list_no_pool));
1157
1158 data_node_t* p_data_node = allocate_data_node();
1159 ::new (&(p_data_node->value)) T(value1);
1160 ETL_INCREMENT_DEBUG_COUNT;
1161 insert_node(*to_iterator(position).p_node, *p_data_node);
1162
1163 return iterator(*p_data_node);
1164 }
1165
1166 template <typename T1, typename T2>
1167 iterator emplace(const_iterator position, const T1& value1, const T2& value2)
1168 {
1169 ETL_ASSERT(!full(), ETL_ERROR(list_full));
1170 ETL_ASSERT(p_node_pool != ETL_NULLPTR, ETL_ERROR(list_no_pool));
1171
1172 data_node_t* p_data_node = allocate_data_node();
1173 ::new (&(p_data_node->value)) T(value1, value2);
1174 ETL_INCREMENT_DEBUG_COUNT;
1175 insert_node(*to_iterator(position).p_node, *p_data_node);
1176
1177 return iterator(*p_data_node);
1178 }
1179
1180 template <typename T1, typename T2, typename T3>
1181 iterator emplace(const_iterator position, const T1& value1, const T2& value2, const T3& value3)
1182 {
1183 ETL_ASSERT(!full(), ETL_ERROR(list_full));
1184 ETL_ASSERT(p_node_pool != ETL_NULLPTR, ETL_ERROR(list_no_pool));
1185
1186 data_node_t* p_data_node = allocate_data_node();
1187 ::new (&(p_data_node->value)) T(value1, value2, value3);
1188 ETL_INCREMENT_DEBUG_COUNT;
1189 insert_node(*to_iterator(position).p_node, *p_data_node);
1190
1191 return iterator(*p_data_node);
1192 }
1193
1194 template <typename T1, typename T2, typename T3, typename T4>
1195 iterator emplace(const_iterator position, const T1& value1, const T2& value2, const T3& value3, const T4& value4)
1196 {
1197 ETL_ASSERT(!full(), ETL_ERROR(list_full));
1198 ETL_ASSERT(p_node_pool != ETL_NULLPTR, ETL_ERROR(list_no_pool));
1199
1200 data_node_t* p_data_node = allocate_data_node();
1201 ::new (&(p_data_node->value)) T(value1, value2, value3, value4);
1202 ETL_INCREMENT_DEBUG_COUNT;
1203 insert_node(*to_iterator(position).p_node, *p_data_node);
1204
1205 return iterator(*p_data_node);
1206 }
1207#endif
1208
1209 //*************************************************************************
1211 //*************************************************************************
1212 void insert(const_iterator position, size_t n, const_reference value)
1213 {
1214 for (size_t i = 0UL; i < n; ++i)
1215 {
1216 ETL_ASSERT(!full(), ETL_ERROR(list_full));
1217
1218 // Set up the next free node and insert.
1219 insert_node(*to_iterator(position).p_node, allocate_data_node(value));
1220 }
1221 }
1222
1223 //*************************************************************************
1225 //*************************************************************************
1226 template <typename TIterator>
1227 void insert(const_iterator position, TIterator first, TIterator last, typename etl::enable_if<!etl::is_integral<TIterator>::value, int>::type = 0)
1228 {
1229 while (first != last)
1230 {
1231 ETL_ASSERT(!full(), ETL_ERROR(list_full));
1232
1233 // Set up the next free node and insert.
1234 insert_node(*to_iterator(position).p_node, allocate_data_node(*first));
1235 ++first;
1236 }
1237 }
1238
1239 //*************************************************************************
1241 //*************************************************************************
1242 iterator erase(const_iterator position)
1243 {
1244 iterator position_ = to_iterator(position);
1245
1246 ++position_;
1247 remove_node(*position_.p_node->previous);
1248 return position_;
1249 }
1250
1251 //*************************************************************************
1253 //*************************************************************************
1254 iterator erase(const_iterator first, const_iterator last)
1255 {
1256 iterator first_ = to_iterator(first);
1257 iterator last_ = to_iterator(last);
1258
1259 node_t* p_first = first_.p_node;
1260 node_t* p_last = last_.p_node;
1261 node_t* p_next;
1262
1263 // Join the ends.
1264 join(*(p_first->previous), *p_last);
1265
1266 // Erase the ones in between.
1267 while (p_first != p_last)
1268 {
1269 p_next = p_first->next; // Remember the next node.
1270 destroy_data_node(static_cast<data_node_t&>(*p_first)); // Destroy the current node.
1271 p_first = p_next; // Move to the next node.
1272 }
1273
1274 return last_;
1275 }
1276
1277 //*************************************************************************
1279 //*************************************************************************
1280 void resize(size_t n)
1281 {
1282 resize(n, T());
1283 }
1284
1285 //*************************************************************************
1287 //*************************************************************************
1288 void resize(size_t n, const_reference value)
1289 {
1290 ETL_ASSERT(n <= MAX_SIZE, ETL_ERROR(list_full));
1291
1292 // Zero?
1293 if (n == 0U)
1294 {
1295 clear();
1296 }
1297 // Smaller?
1298 else if (n < size())
1299 {
1300 iterator i_start = end();
1301 etl::advance(i_start, -difference_type(size() - n));
1302 erase(i_start, end());
1303 }
1304 // Larger?
1305 else if (n > size())
1306 {
1307 insert(end(), n - size(), value);
1308 }
1309 }
1310
1311 //*************************************************************************
1313 //*************************************************************************
1314 void clear()
1315 {
1316 initialise();
1317 }
1318
1319 //*************************************************************************
1320 // Removes the values specified.
1321 //*************************************************************************
1322 void remove(const_reference value)
1323 {
1324 iterator iValue = begin();
1325
1326 while (iValue != end())
1327 {
1328 if (value == *iValue)
1329 {
1330 iValue = erase(iValue);
1331 }
1332 else
1333 {
1334 ++iValue;
1335 }
1336 }
1337 }
1338
1339 //*************************************************************************
1341 //*************************************************************************
1342 template <typename TPredicate>
1343 void remove_if(TPredicate predicate)
1344 {
1345 iterator iValue = begin();
1346
1347 while (iValue != end())
1348 {
1349 if (predicate(*iValue))
1350 {
1351 iValue = erase(iValue);
1352 }
1353 else
1354 {
1355 ++iValue;
1356 }
1357 }
1358 }
1359
1360 //*************************************************************************
1363 //*************************************************************************
1364 void unique()
1365 {
1367 }
1368
1369 //*************************************************************************
1372 //*************************************************************************
1373 template <typename TIsEqual>
1374 void unique(TIsEqual isEqual)
1375 {
1376 if (empty())
1377 {
1378 return;
1379 }
1380
1381 iterator i_item = begin();
1382 ++i_item;
1383 iterator i_previous = begin();
1384
1385 while (i_item != end())
1386 {
1387 if (isEqual(*i_previous, *i_item))
1388 {
1389 i_item = erase(i_item);
1390 }
1391 else
1392 {
1393 i_previous = i_item;
1394 ++i_item;
1395 }
1396 }
1397 }
1398
1399 //*************************************************************************
1401 //*************************************************************************
1402 void splice(iterator to, ilist& other)
1403 {
1404 if (&other != this)
1405 {
1406 insert(to, other.begin(), other.end());
1407 other.erase(other.begin(), other.end());
1408 }
1409 }
1410
1411#if ETL_USING_CPP11
1412 //*************************************************************************
1414 //*************************************************************************
1415 void splice(iterator to, ilist&& other)
1416 {
1417 if (&other != this)
1418 {
1419 typename ilist<T>::iterator itr = other.begin();
1420 while (itr != other.end())
1421 {
1422 to = insert(to, etl::move(*itr));
1423 ++itr;
1424 }
1425
1426 other.erase(other.begin(), other.end());
1427 }
1428 }
1429#endif
1430
1431 //*************************************************************************
1433 //*************************************************************************
1434 void splice(iterator to, ilist& other, iterator from)
1435 {
1436 if (&other == this)
1437 {
1438 // Internal move.
1439 move(to, from);
1440 }
1441 else
1442 {
1443 // From another list.
1444 insert(to, *from);
1445 other.erase(from);
1446 }
1447 }
1448
1449#if ETL_USING_CPP11
1450 //*************************************************************************
1452 //*************************************************************************
1453 void splice(iterator to, ilist&& other, iterator from)
1454 {
1455 if (&other == this)
1456 {
1457 // Internal move.
1458 move(to, from);
1459 }
1460 else
1461 {
1462 // From another list.
1463 insert(to, etl::move(*from));
1464 other.erase(from);
1465 }
1466 }
1467#endif
1468
1469 //*************************************************************************
1471 //*************************************************************************
1472 void splice(iterator to, ilist& other, iterator first, iterator last)
1473 {
1474 if (&other == this)
1475 {
1476 // Internal move.
1477 move(to, first, last);
1478 }
1479 else
1480 {
1481 // From another list.
1482 insert(to, first, last);
1483 other.erase(first, last);
1484 }
1485 }
1486
1487#if ETL_USING_CPP11
1488 //*************************************************************************
1490 //*************************************************************************
1491 void splice(iterator to, ilist&& other, iterator first, iterator last)
1492 {
1493 if (&other == this)
1494 {
1495 // Internal move.
1496 move(to, first, last);
1497 }
1498 else
1499 {
1500 // From another list.
1501 ilist::iterator itr = first;
1502 while (itr != last)
1503 {
1504 to = insert(to, etl::move(*itr));
1505 ++itr;
1506 ++to;
1507 }
1508
1509 other.erase(first, last);
1510 }
1511 }
1512#endif
1513
1514 //*************************************************************************
1516 //*************************************************************************
1517 void merge(ilist& other)
1518 {
1519 merge(other, etl::less<value_type>());
1520 }
1521
1522 //*************************************************************************
1524 //*************************************************************************
1525 template <typename TCompare>
1526 void merge(ilist& other, TCompare compare)
1527 {
1528 if ((this != &other) && !other.empty())
1529 {
1530#if ETL_IS_DEBUG_BUILD
1531 ETL_ASSERT(etl::is_sorted(other.begin(), other.end(), compare), ETL_ERROR(list_unsorted));
1533#endif
1534
1535 ilist::iterator other_begin = other.begin();
1536 ilist::iterator other_end = other.end();
1537
1538 ilist::iterator this_begin = begin();
1539 ilist::iterator this_end = end();
1540
1541 while ((this_begin != this_end) && (other_begin != other_end))
1542 {
1543 // Find the place to insert.
1544 while ((this_begin != this_end) && !(compare(*other_begin, *this_begin)))
1545 {
1546 ++this_begin;
1547 }
1548
1549 // Insert.
1550 if (this_begin != this_end)
1551 {
1552 while ((other_begin != other_end) && (compare(*other_begin, *this_begin)))
1553 {
1554 insert(this_begin, *other_begin);
1555 ++other_begin;
1556 }
1557 }
1558 }
1559
1560 // Any left over?
1561 if ((this_begin == this_end) && (other_begin != other_end))
1562 {
1563 insert(this_end, other_begin, other_end);
1564 }
1565
1566 other.clear();
1567 }
1568 }
1569
1570#if ETL_USING_CPP11
1571 //*************************************************************************
1573 //*************************************************************************
1574 void merge(ilist&& other)
1575 {
1576 merge(etl::move(other), etl::less<value_type>());
1577 }
1578
1579 //*************************************************************************
1581 //*************************************************************************
1582 template <typename TCompare>
1583 void merge(ilist&& other, TCompare compare)
1584 {
1585 if (!other.empty())
1586 {
1587#if ETL_IS_DEBUG_BUILD
1588 ETL_ASSERT(etl::is_sorted(other.begin(), other.end(), compare), ETL_ERROR(list_unsorted));
1589 ETL_ASSERT(etl::is_sorted(begin(), end(), compare), ETL_ERROR(list_unsorted));
1590#endif
1591
1592 ilist::iterator other_begin = other.begin();
1593 ilist::iterator other_end = other.end();
1594
1595 ilist::iterator this_begin = begin();
1596 ilist::iterator this_end = end();
1597
1598 while ((this_begin != this_end) && (other_begin != other_end))
1599 {
1600 // Find the place to insert.
1601 while ((this_begin != this_end) && !(compare(*other_begin, *this_begin)))
1602 {
1603 ++this_begin;
1604 }
1605
1606 // Insert.
1607 if (this_begin != this_end)
1608 {
1609 while ((other_begin != other_end) && (compare(*other_begin, *this_begin)))
1610 {
1611 insert(this_begin, etl::move(*other_begin));
1612 ++other_begin;
1613 }
1614 }
1615 }
1616
1617 // Any left over?
1618 if ((this_begin == this_end) && (other_begin != other_end))
1619 {
1620 while (other_begin != other_end)
1621 {
1622 insert(this_end, etl::move(*other_begin));
1623 ++other_begin;
1624 }
1625 }
1626
1627 other.clear();
1628 }
1629 }
1630#endif
1631
1632 //*************************************************************************
1635 //*************************************************************************
1636 void sort()
1637 {
1638 sort(etl::less<T>());
1639 }
1640
1641 //*************************************************************************
1665 //*************************************************************************
1666 template <typename TCompare>
1667 void sort(TCompare compare)
1668 {
1669 iterator i_left;
1670 iterator i_right;
1671 iterator i_node;
1672 iterator i_head;
1673 iterator i_tail;
1674 int list_size = 1;
1675 int number_of_merges;
1676 int left_size;
1677 int right_size;
1678
1679 if (is_trivial_list())
1680 {
1681 return;
1682 }
1683
1684 while (true)
1685 {
1686 i_left = begin();
1687 i_head = end();
1688 i_tail = end();
1689
1690 number_of_merges = 0; // Count the number of merges we do in this pass.
1691
1692 while (i_left != end())
1693 {
1694 ++number_of_merges; // There exists a merge to be done.
1695 i_right = i_left;
1696 left_size = 0;
1697
1698 // Step 'list_size' places along from left
1699 for (int i = 0; i < list_size; ++i)
1700 {
1701 ++left_size;
1702 ++i_right;
1703
1704 if (i_right == end())
1705 {
1706 break;
1707 }
1708 }
1709
1710 // If right hasn't fallen off end, we have two lists to merge.
1711 right_size = list_size;
1712
1713 // Now we have two lists. Merge them.
1714 while (left_size > 0 || (right_size > 0 && i_right != end()))
1715 {
1716 // Decide whether the next node of merge comes from left or right.
1717 if (left_size == 0)
1718 {
1719 // Left is empty. The node must come from right.
1720 i_node = i_right++;
1721 --right_size;
1722 }
1723 else if (right_size == 0 || i_right == end())
1724 {
1725 // Right is empty. The node must come from left.
1726 i_node = i_left++;
1727 --left_size;
1728 }
1729 else if (!compare(*i_right, *i_left))
1730 {
1731 // First node of left is lower or same. The node must come from left.
1732 i_node = i_left++;
1733 --left_size;
1734 }
1735 else
1736 {
1737 // First node of right is lower. The node must come from right.
1738 i_node = i_right;
1739 ++i_right;
1740 --right_size;
1741 }
1742
1743 // Add the next node to the merged head.
1744 if (i_head == end())
1745 {
1746 join(*i_head.p_node, *i_node.p_node);
1747 i_head = i_node;
1748 i_tail = i_node;
1749 }
1750 else
1751 {
1752 join(*i_tail.p_node, *i_node.p_node);
1753 i_tail = i_node;
1754 }
1755
1756 join(*i_tail.p_node, terminal_node);
1757 }
1758
1759 // Now left has stepped `list_size' places along, and right has too.
1760 i_left = i_right;
1761 }
1762
1763 // If we have done only one merge, we're finished.
1764 if (number_of_merges <= 1) // Allow for number_of_merges == 0, the empty head case
1765 {
1766 return;
1767 }
1768
1769 // Otherwise repeat, merging lists twice the size
1770 list_size *= 2;
1771 }
1772 }
1773
1774 //*************************************************************************
1776 //*************************************************************************
1778 {
1779 if (&rhs != this)
1780 {
1781 assign(rhs.cbegin(), rhs.cend());
1782 }
1783
1784 return *this;
1785 }
1786
1787#if ETL_USING_CPP11
1788 //*************************************************************************
1790 //*************************************************************************
1791 ilist& operator = (ilist&& rhs)
1792 {
1793 if (&rhs != this)
1794 {
1795 this->initialise();
1796
1797 iterator itr = rhs.begin();
1798 while (itr != rhs.end())
1799 {
1800 push_back(etl::move(*itr));
1801 ++itr;
1802 }
1803
1804 rhs.initialise();
1805 }
1806
1807 return *this;
1808 }
1809#endif
1810
1811 protected:
1812
1813 //*************************************************************************
1815 //*************************************************************************
1816 ilist(bool pool_is_shared_)
1817 : list_base(pool_is_shared_)
1818 {
1819 }
1820
1821 //*************************************************************************
1823 //*************************************************************************
1824 ilist(etl::ipool& node_pool, size_t max_size_, bool pool_is_shared_)
1825 : list_base(node_pool, max_size_, pool_is_shared_)
1826 {
1827 }
1828
1829 //*************************************************************************
1831 //*************************************************************************
1833 {
1834 if (this->p_node_pool != ETL_NULLPTR)
1835 {
1836 if (!empty())
1837 {
1838 if (etl::is_trivially_destructible<T>::value && !has_shared_pool())
1839 {
1840 ETL_ASSERT(p_node_pool != ETL_NULLPTR, ETL_ERROR(list_no_pool));
1841 p_node_pool->release_all();
1842 ETL_RESET_DEBUG_COUNT;;
1843 }
1844 else
1845 {
1846 node_t* p_first = terminal_node.next;
1847 node_t* p_last = &terminal_node;
1848
1849 while (p_first != p_last)
1850 {
1851 destroy_data_node(static_cast<data_node_t&>(*p_first)); // Destroy the current node.
1852 p_first = p_first->next; // Move to the next node.
1853 }
1854 }
1855 }
1856 }
1857
1859 }
1860
1861#if ETL_USING_CPP11
1862 //*************************************************************************
1864 //*************************************************************************
1865 void move_container(ilist&& rhs)
1866 {
1867 if (&rhs != this)
1868 {
1869 this->initialise();
1870
1871 if (!rhs.empty())
1872 {
1873 // Are we using the same pool?
1874 if (this->get_node_pool() == rhs.get_node_pool())
1875 {
1876 // Just link the nodes to this list.
1877 join(terminal_node, rhs.get_head());
1878 join(rhs.get_tail(), terminal_node);
1879
1880 ETL_SET_DEBUG_COUNT(ETL_OBJECT_GET_DEBUG_COUNT(rhs));
1881
1882 // Clear the rhs.
1883 ETL_OBJECT_RESET_DEBUG_COUNT(rhs);
1884 rhs.join(rhs.terminal_node, rhs.terminal_node);
1885 }
1886 else
1887 {
1888 // Add all of the elements.
1889 etl::ilist<T>::iterator first = rhs.begin();
1890 etl::ilist<T>::iterator last = rhs.end();
1891
1892 while (first != last)
1893 {
1894 ETL_ASSERT(!full(), ETL_ERROR(list_full));
1895
1896 insert_node(terminal_node, this->allocate_data_node(etl::move(*first)));
1897 ++first;
1898 }
1899
1900 rhs.initialise();
1901 }
1902 }
1903 }
1904 }
1905#endif
1906
1907 private:
1908
1909 //*************************************************************************
1912 //*************************************************************************
1913 void move(iterator to, iterator from)
1914 {
1915 if (from == to)
1916 {
1917 return; // Can't more to before yourself!
1918 }
1919
1920 node_t& from_node = *from.p_node;
1921 node_t& to_node = *to.p_node;
1922
1923 // Disconnect the node from the list.
1924 join(*from_node.previous, *from_node.next);
1925
1926 // Attach it to the new position.
1927 join(*to_node.previous, from_node);
1928 join(from_node, to_node);
1929 }
1930
1931 //*************************************************************************
1934 //*************************************************************************
1935 void move(iterator to, iterator first, iterator last)
1936 {
1937 if ((first == to) || (last == to))
1938 {
1939 return; // Can't more to before yourself!
1940 }
1941
1942#if ETL_IS_DEBUG_BUILD
1943 // Check that we are not doing an illegal move!
1944 for (const_iterator item = first; item != last; ++item)
1945 {
1946 ETL_ASSERT(item != to, ETL_ERROR(list_iterator));
1947 }
1948#endif
1949
1950 node_t& first_node = *first.p_node;
1951 node_t& last_node = *last.p_node;
1952 node_t& to_node = *to.p_node;
1953 node_t& final_node = *last_node.previous;
1954
1955 // Disconnect the range from the list.
1956 join(*first_node.previous, last_node);
1957
1958 // Attach it to the new position.
1959 join(*to_node.previous, first_node);
1960 join(final_node, to_node);
1961 }
1962
1963 //*************************************************************************
1965 //*************************************************************************
1966 void remove_node(node_t& node)
1967 {
1968 // Disconnect the node from the list.
1969 join(*node.previous, *node.next);
1970
1971 // Destroy the pool object.
1972 destroy_data_node(static_cast<data_node_t&>(node));
1973 }
1974
1975 //*************************************************************************
1977 //*************************************************************************
1978 data_node_t& allocate_data_node(const_reference value)
1979 {
1980 ETL_ASSERT(p_node_pool != ETL_NULLPTR, ETL_ERROR(list_no_pool));
1981
1982 data_node_t* p_data_node = allocate_data_node();
1983 ::new (&(p_data_node->value)) T(value);
1984 ETL_INCREMENT_DEBUG_COUNT;
1985
1986 return *p_data_node;
1987 }
1988
1989#if ETL_USING_CPP11
1990 //*************************************************************************
1992 //*************************************************************************
1993 data_node_t& allocate_data_node(rvalue_reference value)
1994 {
1995 ETL_ASSERT(p_node_pool != ETL_NULLPTR, ETL_ERROR(list_no_pool));
1996
1997 data_node_t* p_data_node = allocate_data_node();
1998 ::new (&(p_data_node->value)) T(etl::move(value));
1999 ETL_INCREMENT_DEBUG_COUNT;
2000
2001 return *p_data_node;
2002 }
2003#endif
2004
2005 //*************************************************************************
2007 //*************************************************************************
2008 data_node_t* allocate_data_node()
2009 {
2010 data_node_t* (etl::ipool::*func)() = &etl::ipool::allocate<data_node_t>;
2011 return (p_node_pool->*func)();
2012 }
2013
2014 //*************************************************************************
2016 //*************************************************************************
2017 void destroy_data_node(data_node_t& node)
2018 {
2019 ETL_ASSERT(p_node_pool != ETL_NULLPTR, ETL_ERROR(list_no_pool));
2020 node.value.~T();
2021 p_node_pool->release(&node);
2022 ETL_DECREMENT_DEBUG_COUNT;
2023 }
2024
2025 // Disable copy construction.
2026 ilist(const ilist&);
2027
2028#if defined(ETL_POLYMORPHIC_LIST) || defined(ETL_POLYMORPHIC_CONTAINERS)
2029 public:
2030 virtual ~ilist()
2031 {
2032 }
2033#else
2034 protected:
2035 ~ilist()
2036 {
2037 }
2038#endif
2039
2040 private:
2041
2042 //*************************************************************************
2044 //*************************************************************************
2045 iterator to_iterator(const_iterator itr) const
2046 {
2047 return iterator(*(const_cast<node_t*>(itr.p_node)));
2048 }
2049 };
2050
2051 //*************************************************************************
2053 //*************************************************************************
2054 template <typename T, const size_t MAX_SIZE_>
2055 class list : public etl::ilist<T>
2056 {
2057 public:
2058
2059 ETL_STATIC_ASSERT((MAX_SIZE_ > 0U), "Zero capacity etl::list is not valid");
2060
2061 static ETL_CONSTANT size_t MAX_SIZE = MAX_SIZE_;
2062
2063 public:
2064
2065 typedef T value_type;
2066 typedef T* pointer;
2067 typedef const T* const_pointer;
2068 typedef T& reference;
2069 typedef const T& const_reference;
2070#if ETL_USING_CPP11
2071 typedef T&& rvalue_reference;
2072#endif
2073 typedef size_t size_type;
2074
2075 //*************************************************************************
2077 //*************************************************************************
2079 : etl::ilist<T>(node_pool, MAX_SIZE, false)
2080 {
2081 }
2082
2083 //*************************************************************************
2085 //*************************************************************************
2087 {
2088 this->initialise();
2089 }
2090
2091 //*************************************************************************
2093 //*************************************************************************
2094 explicit list(size_t initial_size)
2095 : etl::ilist<T>(node_pool, MAX_SIZE, false)
2096 {
2097 this->assign(initial_size, T());
2098 }
2099
2100 //*************************************************************************
2102 //*************************************************************************
2103 list(size_t initial_size, const T& value)
2104 : etl::ilist<T>(node_pool, MAX_SIZE, false)
2105 {
2106 this->assign(initial_size, value);
2107 }
2108
2109 //*************************************************************************
2111 //*************************************************************************
2112 list(const list& other)
2113 : etl::ilist<T>(node_pool, MAX_SIZE, false)
2114 {
2115 if (this != &other)
2116 {
2117 this->assign(other.cbegin(), other.cend());
2118 }
2119 }
2120
2121#if ETL_USING_CPP11
2122 //*************************************************************************
2124 //*************************************************************************
2125 list(list&& other)
2126 : etl::ilist<T>(node_pool, MAX_SIZE, false)
2127 {
2128 if (this != &other)
2129 {
2130 this->initialise();
2131
2132 typename etl::ilist<T>::iterator itr = other.begin();
2133 while (itr != other.end())
2134 {
2135 this->push_back(etl::move(*itr));
2136 ++itr;
2137 }
2138
2139 other.initialise();
2140 }
2141 }
2142#endif
2143
2144 //*************************************************************************
2146 //*************************************************************************
2147 template <typename TIterator>
2148 list(TIterator first, TIterator last, typename etl::enable_if<!etl::is_integral<TIterator>::value, int>::type = 0)
2149 : ilist<T>(node_pool, MAX_SIZE, false)
2150 {
2151 this->assign(first, last);
2152 }
2153
2154#if ETL_HAS_INITIALIZER_LIST
2155 //*************************************************************************
2157 //*************************************************************************
2158 list(std::initializer_list<T> init)
2159 : ilist<T>(node_pool, MAX_SIZE, false)
2160 {
2161 this->assign(init.begin(), init.end());
2162 }
2163#endif
2164
2165 //*************************************************************************
2167 //*************************************************************************
2168 list& operator = (const list& rhs)
2169 {
2170 if (&rhs != this)
2171 {
2172 this->assign(rhs.cbegin(), rhs.cend());
2173 }
2174
2175 return *this;
2176 }
2177
2178#if ETL_USING_CPP11
2179 //*************************************************************************
2181 //*************************************************************************
2182 list& operator = (list&& rhs)
2183 {
2184 this->move_container(etl::move(rhs));
2185
2186 return *this;
2187 }
2188#endif
2189
2190 private:
2191
2194 };
2195
2196 template <typename T, const size_t MAX_SIZE_>
2197 ETL_CONSTANT size_t list<T, MAX_SIZE_>::MAX_SIZE;
2198
2199 //*************************************************************************
2201 //*************************************************************************
2202#if ETL_USING_CPP17 && ETL_HAS_INITIALIZER_LIST
2203 template <typename... T>
2204 list(T...) -> list<typename etl::common_type_t<T...>,
2205 sizeof...(T)>;
2206#endif
2207
2208 //*************************************************************************
2210 //*************************************************************************
2211#if ETL_USING_CPP11 && ETL_HAS_INITIALIZER_LIST
2212 template <typename... T>
2213 constexpr auto make_list(T... t) -> etl::list<typename etl::common_type_t<T...>, sizeof...(T)>
2214 {
2215 return { etl::forward<T>(t)... };
2216 }
2217#endif
2218
2219 //*************************************************************************
2221 //*************************************************************************
2222 template <typename T>
2223 class list_ext : public etl::ilist<T>
2224 {
2225 public:
2226
2227 typedef T value_type;
2228 typedef T* pointer;
2229 typedef const T* const_pointer;
2230 typedef T& reference;
2231 typedef const T& const_reference;
2232 typedef size_t size_type;
2233
2234 typedef typename etl::ilist<T>::data_node_t pool_type;
2235
2236 //*************************************************************************
2238 //*************************************************************************
2240 : etl::ilist<T>(true)
2241 {
2242 }
2243
2244 //*************************************************************************
2246 //*************************************************************************
2247 explicit list_ext(etl::ipool& node_pool)
2248 : etl::ilist<T>(node_pool, node_pool.max_size(), true)
2249 {
2250 }
2251
2252 //*************************************************************************
2254 //*************************************************************************
2256 {
2257 this->initialise();
2258 }
2259
2260 //*************************************************************************
2262 //*************************************************************************
2263 explicit list_ext(size_t initial_size, etl::ipool& node_pool)
2264 : etl::ilist<T>(node_pool, node_pool.max_size(), true)
2265 {
2266 this->assign(initial_size, T());
2267 }
2268
2269 //*************************************************************************
2271 //*************************************************************************
2272 list_ext(size_t initial_size, const T& value, etl::ipool& node_pool)
2273 : etl::ilist<T>(node_pool, node_pool.max_size(), true)
2274 {
2275 this->assign(initial_size, value);
2276 }
2277
2278 //*************************************************************************
2280 //*************************************************************************
2281 list_ext(const list_ext& other)
2282 : etl::ilist<T>(*other.p_node_pool, other.p_node_pool->max_size(), true)
2283 {
2284 if (this != &other)
2285 {
2286 this->assign(other.cbegin(), other.cend());
2287 }
2288 }
2289
2290 //*************************************************************************
2292 //*************************************************************************
2293 list_ext(const list_ext& other, etl::ipool& node_pool)
2294 : etl::ilist<T>(node_pool, node_pool.max_size(), true)
2295 {
2296 if (this != &other)
2297 {
2298 this->assign(other.cbegin(), other.cend());
2299 }
2300 }
2301
2302#if ETL_USING_CPP11
2303 //*************************************************************************
2305 //*************************************************************************
2306 list_ext(list_ext&& other)
2307 : etl::ilist<T>(*other.p_node_pool, other.p_node_pool->max_size(), true)
2308 {
2309 this->move_container(etl::move(other));
2310 }
2311
2312 //*************************************************************************
2314 //*************************************************************************
2315 list_ext(list_ext&& other, etl::ipool& node_pool)
2316 : etl::ilist<T>(node_pool, node_pool.max_size(), true)
2317 {
2318 this->move_container(etl::move(other));
2319 }
2320#endif
2321
2322 //*************************************************************************
2324 //*************************************************************************
2325 template <typename TIterator>
2326 list_ext(TIterator first, TIterator last, etl::ipool& node_pool, typename etl::enable_if<!etl::is_integral<TIterator>::value, int>::type = 0)
2327 : ilist<T>(node_pool, node_pool.max_size(), true)
2328 {
2329 this->assign(first, last);
2330 }
2331
2332#if ETL_HAS_INITIALIZER_LIST
2333 //*************************************************************************
2335 //*************************************************************************
2336 list_ext(std::initializer_list<T> init, etl::ipool& node_pool)
2337 : ilist<T>(node_pool, node_pool.max_size(), true)
2338 {
2339 this->assign(init.begin(), init.end());
2340 }
2341#endif
2342
2343 //*************************************************************************
2345 //*************************************************************************
2346 list_ext& operator = (const list_ext& rhs)
2347 {
2348 if (&rhs != this)
2349 {
2350 this->assign(rhs.cbegin(), rhs.cend());
2351 }
2352
2353 return *this;
2354 }
2355
2356#if ETL_USING_CPP11
2357 //*************************************************************************
2359 //*************************************************************************
2360 list_ext& operator = (list_ext&& rhs)
2361 {
2362 this->move_container(etl::move(rhs));
2363
2364 return *this;
2365 }
2366#endif
2367
2368 //*************************************************************************
2370 //*************************************************************************
2372 {
2373 // Clear the list of any current elements.
2374 if (this->get_node_pool() != ETL_NULLPTR)
2375 {
2376 this->clear();
2377 }
2378
2379 this->set_node_pool(pool);
2380 }
2381
2382 //*************************************************************************
2384 //*************************************************************************
2386 {
2387 return *this->p_node_pool;
2388 }
2389 };
2390
2391 //*************************************************************************
2396 //*************************************************************************
2397 template <typename T>
2398 bool operator ==(const etl::ilist<T>& lhs, const etl::ilist<T>& rhs)
2399 {
2400 return (lhs.size() == rhs.size()) && etl::equal(lhs.begin(), lhs.end(), rhs.begin());
2401 }
2402
2403 //*************************************************************************
2408 //*************************************************************************
2409 template <typename T>
2410 bool operator !=(const etl::ilist<T>& lhs, const etl::ilist<T>& rhs)
2411 {
2412 return !(lhs == rhs);
2413 }
2414
2415 //*************************************************************************
2421 //*************************************************************************
2422 template <typename T>
2423 bool operator <(const etl::ilist<T>& lhs, const etl::ilist<T>& rhs)
2424 {
2425 return etl::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
2426 }
2427
2428 //*************************************************************************
2434 //*************************************************************************
2435 template <typename T>
2436 bool operator >(const etl::ilist<T>& lhs, const etl::ilist<T>& rhs)
2437 {
2438 return (rhs < lhs);
2439 }
2440
2441 //*************************************************************************
2447 //*************************************************************************
2448 template <typename T>
2449 bool operator <=(const etl::ilist<T>& lhs, const etl::ilist<T>& rhs)
2450 {
2451 return !(lhs > rhs);
2452 }
2453
2454 //*************************************************************************
2460 //*************************************************************************
2461 template <typename T>
2462 bool operator >=(const etl::ilist<T>& lhs, const etl::ilist<T>& rhs)
2463 {
2464 return !(lhs < rhs);
2465 }
2466}
2467
2468#include "private/minmax_pop.h"
2469
2470#endif
const_iterator
Definition list.h:565
iterator.
Definition list.h:478
Template deduction guides.
Definition list.h:2224
list_ext(const list_ext &other, etl::ipool &node_pool)
Copy constructor. Explicit pool.
Definition list.h:2293
list_ext(size_t initial_size, etl::ipool &node_pool)
Construct from size.
Definition list.h:2263
void set_pool(etl::ipool &pool)
Set the pool instance.
Definition list.h:2371
list_ext(size_t initial_size, const T &value, etl::ipool &node_pool)
Construct from size and value.
Definition list.h:2272
list_ext(TIterator first, TIterator last, etl::ipool &node_pool, typename etl::enable_if<!etl::is_integral< TIterator >::value, int >::type=0)
Construct from range.
Definition list.h:2326
list_ext()
Default constructor.
Definition list.h:2239
etl::ipool & get_pool() const
Get the pool instance.
Definition list.h:2385
list_ext(etl::ipool &node_pool)
Default constructor.
Definition list.h:2247
~list_ext()
Destructor.
Definition list.h:2255
list_ext(const list_ext &other)
Copy constructor. Implicit pool.
Definition list.h:2281
A templated list implementation that uses a fixed size buffer.
Definition list.h:2056
~list()
Destructor.
Definition list.h:2086
list(const list &other)
Copy constructor.
Definition list.h:2112
list(size_t initial_size, const T &value)
Construct from size and value.
Definition list.h:2103
list(TIterator first, TIterator last, typename etl::enable_if<!etl::is_integral< TIterator >::value, int >::type=0)
Construct from range.
Definition list.h:2148
list(size_t initial_size)
Construct from size.
Definition list.h:2094
list()
Default constructor.
Definition list.h:2078
ETL_CONSTEXPR14 bool operator==(const etl::expected< TValue, TError > &lhs, const etl::expected< TValue2, TError2 > &rhs)
Equivalence operators.
Definition expected.h:962
ETL_NODISCARD ETL_CONSTEXPR14 bool is_sorted(TIterator begin, TIterator end)
Definition algorithm.h:1709
ETL_CONSTEXPR14 TIterator remove(TIterator first, TIterator last, const T &value)
Definition algorithm.h:2300
#define ETL_ASSERT(b, e)
Definition error_handler.h:356
ETL_CONSTEXPR exception(string_type reason_, string_type, numeric_type line_)
Constructor.
Definition exception.h:69
ilist(etl::ipool &node_pool, size_t max_size_, bool pool_is_shared_)
Constructor.
Definition list.h:1824
const_reverse_iterator rend() const
Gets the reverse end of the list.
Definition list.h:737
void clear()
Clears the list.
Definition list.h:1314
const_iterator cbegin() const
Gets the beginning of the list.
Definition list.h:697
iterator end()
Gets the end of the list.
Definition list.h:681
void push_back(const T &value)
Pushes a value to the back of the list.
Definition list.h:975
iterator emplace(const_iterator position)
Emplaces a value to the list at the specified position.
Definition list.h:1139
ilist(bool pool_is_shared_)
Constructor.
Definition list.h:1816
reference back()
Gets a reference to the last element.
Definition list.h:777
size_t size_type
The type used for determining the size of list.
Definition list.h:155
void reverse()
Reverses the list.
Definition list.h:196
const_reverse_iterator crend() const
Gets the reverse end of the list.
Definition list.h:753
reference emplace_front(const T1 &value1)
Emplaces a value to the front of the list.
Definition list.h:896
void splice(iterator to, ilist &other, iterator from)
Splices an element from another list to this.
Definition list.h:1434
size_type size() const
Gets the size of the list.
Definition list.h:238
void sort(TCompare compare)
Definition list.h:1667
size_type available() const
Definition list.h:282
void splice(iterator to, ilist &other, iterator first, iterator last)
Splices a range of elements from another list to this.
Definition list.h:1472
void join(node_t &left, node_t &right)
Join two nodes.
Definition list.h:343
void insert(const_iterator position, size_t n, const_reference value)
Inserts 'n' copies of a value to the list at the specified position.
Definition list.h:1212
void unique(TIsEqual isEqual)
Definition list.h:1374
void insert(const_iterator position, TIterator first, TIterator last, typename etl::enable_if<!etl::is_integral< TIterator >::value, int >::type=0)
Inserts a range of values to the list at the specified position.
Definition list.h:1227
const_reverse_iterator rbegin() const
Gets the reverse beginning of the list.
Definition list.h:721
list_base(bool pool_is_shared_)
The constructor that is called from derived classes.
Definition list.h:352
etl::ipool * p_node_pool
The pool of data nodes used in the list.
Definition list.h:395
size_type max_size() const
Gets the maximum possible size of the list.
Definition list.h:222
void resize(size_t n)
Resizes the list.
Definition list.h:1280
list_base(etl::ipool &node_pool_, size_type max_size_, bool pool_is_shared_)
The constructor that is called from derived classes.
Definition list.h:363
bool full() const
Checks to see if the list is full.
Definition list.h:272
reverse_iterator rend()
Gets the reverse end of the list.
Definition list.h:729
reverse_iterator rbegin()
Gets the reverse beginning of the list.
Definition list.h:713
reference emplace_front()
Emplaces a value to the front of the list.
Definition list.h:879
ilist & operator=(const ilist &rhs)
Assignment operator.
Definition list.h:1777
iterator insert(const_iterator position, const_reference value)
Inserts a value to the list at the specified position.
Definition list.h:1096
size_type MAX_SIZE
The maximum size of the list.
Definition list.h:397
node_t terminal_node
The node that acts as the list start and end.
Definition list.h:396
void push_front(const T &value)
Pushes a value to the front of the list.
Definition list.h:838
void initialise()
Initialise the list.
Definition list.h:1832
bool pool_is_shared
If true then the pool is shared between lists.
Definition list.h:398
void splice(iterator to, ilist &other)
Splices from another list to this.
Definition list.h:1402
const_iterator end() const
Gets the end of the list.
Definition list.h:689
ETL_DECLARE_DEBUG_COUNT
Internal debugging.
Definition list.h:399
reference front()
Gets a reference to the first element.
Definition list.h:761
void pop_front()
Removes a value from the front of the list.
Definition list.h:964
const_iterator begin() const
Gets the beginning of the list.
Definition list.h:673
void merge(ilist &other)
Merge another list into this one. Both lists should be sorted.
Definition list.h:1517
bool is_trivial_list() const
Is the list a trivial length?
Definition list.h:293
void assign(size_t n, const T &value)
Assigns 'n' copies of a value to the list.
Definition list.h:818
iterator erase(const_iterator first, const_iterator last)
Erases a range of elements.
Definition list.h:1254
reference emplace_front(const T1 &value1, const T2 &value2, const T3 &value3, const T4 &value4)
Emplaces a value to the front of the list.
Definition list.h:947
void set_node_pool(etl::ipool &node_pool_)
Set the node pool instance.
Definition list.h:374
reference emplace_front(const T1 &value1, const T2 &value2, const T3 &value3)
Emplaces a value to the front of the list.
Definition list.h:930
void merge(ilist &other, TCompare compare)
Merge another list into this one. Both lists should be sorted.
Definition list.h:1526
void resize(size_t n, const_reference value)
Resizes the list.
Definition list.h:1288
size_type capacity() const
Gets the maximum possible size of the list.
Definition list.h:230
reference emplace_back()
Emplaces a value to the back of the list.
Definition list.h:1012
bool empty() const
Checks to see if the list is empty.
Definition list.h:264
etl::ipool * get_node_pool()
Get the node pool instance.
Definition list.h:383
iterator begin()
Gets the beginning of the list.
Definition list.h:665
void sort()
Definition list.h:1636
const_reference back() const
Gets a reference to the last element.
Definition list.h:785
void unique()
Definition list.h:1364
const_reference front() const
Gets a const reference to the first element.
Definition list.h:769
node_t & get_head()
Get the head node.
Definition list.h:301
const node_t & get_head() const
Get the head node.
Definition list.h:309
void insert_node(node_t &position, node_t &node)
Insert a node before 'position'.
Definition list.h:333
const node_t & get_tail() const
Get the tail node.
Definition list.h:325
const_iterator cend() const
Gets the end of the list.
Definition list.h:705
const_reverse_iterator crbegin() const
Gets the reverse beginning of the list.
Definition list.h:745
~list_base()
Destructor.
Definition list.h:391
void remove_if(TPredicate predicate)
Removes according to a predicate.
Definition list.h:1343
void assign(TIterator first, TIterator last, typename etl::enable_if<!etl::is_integral< TIterator >::value, int >::type=0)
Definition list.h:796
node_t & get_tail()
Get the tail node.
Definition list.h:317
iterator erase(const_iterator position)
Erases the value at the specified position.
Definition list.h:1242
bool has_shared_pool() const
true if the list has a shared pool.
Definition list.h:188
void pop_back()
Removes a value from the back of the list.
Definition list.h:1085
reference emplace_front(const T1 &value1, const T2 &value2)
Emplaces a value to the front of the list.
Definition list.h:913
Definition list.h:408
Definition list.h:152
Definition list.h:96
Definition list.h:82
Definition list.h:110
Definition list.h:138
Definition list.h:124
T * allocate()
Definition ipool.h:316
Definition ipool.h:103
Definition pool.h:54
enable_if
Definition type_traits_generator.h:1254
bitset_ext
Definition absolute.h:39
ETL_CONSTEXPR14 void swap(etl::typed_storage_ext< T > &lhs, etl::typed_storage_ext< T > &rhs) ETL_NOEXCEPT
Swap two etl::typed_storage_ext.
Definition alignment.h:838
bool operator>(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1190
bool operator>=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1202
bool operator!=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1151
bool operator==(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1139
bool operator<(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1163
bool operator<=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1178
Definition compare.h:51
Definition functional.h:274
The data node element in the list.
Definition list.h:429
iterator
Definition iterator.h:399
Definition functional.h:170
The node element in the list.
Definition list.h:161
void reverse()
Reverses the previous & next pointers.
Definition list.h:174
node_t()
Constructor.
Definition list.h:165
etl::conditional< etl::is_fundamental< T >::value||etl::is_pointer< T >::value, T, constT & >::type type
By default fundamental and pointer types are passed by value.
Definition parameter_type.h:48