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