Embedded Template Library 1.0
Loading...
Searching...
No Matches
forward_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_FORWARD_LIST_INCLUDED
32#define ETL_FORWARD_LIST_INCLUDED
33
34#include "platform.h"
35#include "algorithm.h"
36#include "iterator.h"
37#include "functional.h"
38#include "utility.h"
39#include "pool.h"
40#include "exception.h"
41#include "error_handler.h"
42#include "debug_count.h"
43#include "nullptr.h"
44#include "type_traits.h"
45#include "memory.h"
46#include "iterator.h"
47#include "static_assert.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 forward_list_exception : public etl::exception
68 {
69 public:
70
71 forward_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 forward_list_full : public etl::forward_list_exception
82 {
83 public:
84
85 forward_list_full(string_type file_name_, numeric_type line_number_)
86 : etl::forward_list_exception(ETL_ERROR_TEXT("forward_list:full", ETL_FORWARD_LIST_FILE_ID"A"), file_name_, line_number_)
87 {
88 }
89 };
90
91 //***************************************************************************
94 //***************************************************************************
95 class forward_list_empty : public etl::forward_list_exception
96 {
97 public:
98
99 forward_list_empty(string_type file_name_, numeric_type line_number_)
100 : etl::forward_list_exception(ETL_ERROR_TEXT("forward_list:empty", ETL_FORWARD_LIST_FILE_ID"B"), file_name_, line_number_)
101 {
102 }
103 };
104
105 //***************************************************************************
108 //***************************************************************************
109 class forward_list_iterator : public etl::forward_list_exception
110 {
111 public:
112
113 forward_list_iterator(string_type file_name_, numeric_type line_number_)
114 : etl::forward_list_exception(ETL_ERROR_TEXT("forward_list:iterator", ETL_FORWARD_LIST_FILE_ID"C"), file_name_, line_number_)
115 {
116 }
117 };
118
119 //***************************************************************************
122 //***************************************************************************
123 class forward_list_no_pool : public forward_list_exception
124 {
125 public:
126
127 forward_list_no_pool(string_type file_name_, numeric_type line_number_)
128 : forward_list_exception(ETL_ERROR_TEXT("list:no pool", ETL_FORWARD_LIST_FILE_ID"D"), file_name_, line_number_)
129 {
130 }
131 };
132
133 //***************************************************************************
136 //***************************************************************************
138 {
139 protected:
140
141 //*************************************************************************
143 //*************************************************************************
144 struct node_t
145 {
146 node_t()
147 : next(ETL_NULLPTR)
148 {
149 }
150
151 node_t* next;
152 };
153
154 public:
155
156 typedef size_t size_type;
157
158 //*************************************************************************
160 //*************************************************************************
161 bool has_shared_pool() const
162 {
163 return pool_is_shared;
164 }
165
166 //*************************************************************************
168 //*************************************************************************
170 {
171 return MAX_SIZE;
172 }
173
174 //*************************************************************************
176 //*************************************************************************
178 {
179 return MAX_SIZE;
180 }
181
182 //*************************************************************************
184 //*************************************************************************
186 {
187 if (has_shared_pool())
188 {
189 // We have to count what we actually own.
190 size_type count = 0;
191
192 node_t* p_node = start_node.next;
193
194 while (p_node != ETL_NULLPTR)
195 {
196 ++count;
197 p_node = p_node->next;
198 }
199
200 return count;
201 }
202 else
203 {
204 return p_node_pool->size();
205 }
206 }
207
208 //*************************************************************************
210 //*************************************************************************
211 bool empty() const
212 {
213 return (start_node.next == ETL_NULLPTR);
214 }
215
216 //*************************************************************************
218 //*************************************************************************
219 bool full() const
220 {
221 ETL_ASSERT(p_node_pool != ETL_NULLPTR, ETL_ERROR(forward_list_no_pool));
222 return p_node_pool->full();
223 }
224
225 //*************************************************************************
228 //*************************************************************************
229 size_t available() const
230 {
231 ETL_ASSERT(p_node_pool != ETL_NULLPTR, ETL_ERROR(forward_list_no_pool));
232 return p_node_pool->available();
233 }
234
235 //*************************************************************************
237 //*************************************************************************
238 void reverse()
239 {
240 if (is_trivial_list())
241 {
242 return;
243 }
244
245 node_t* p_last = &start_node;
246 node_t* p_current = p_last->next;
247 node_t* p_next = p_current->next;
248
249 p_current->next = ETL_NULLPTR;
250
251 while (p_next != ETL_NULLPTR)
252 {
253 p_last = p_current;
254 p_current = p_next;
255 p_next = p_current->next;
256
257 p_current->next = p_last;
258 }
259
260 join(&start_node, p_current);
261 }
262
263 protected:
264
265 //*************************************************************************
267 //*************************************************************************
268 forward_list_base(bool pool_is_shared_)
269 : p_node_pool(ETL_NULLPTR),
270 MAX_SIZE(0),
271 pool_is_shared(pool_is_shared_)
272 {
273 }
274
275 //*************************************************************************
277 //*************************************************************************
278 forward_list_base(etl::ipool& node_pool_, size_type max_size_, bool pool_is_shared_)
279 : p_node_pool(&node_pool_),
280 MAX_SIZE(max_size_),
281 pool_is_shared(pool_is_shared_)
282 {
283 }
284
285 //*************************************************************************
287 //*************************************************************************
289 {
290 }
291
292 //*************************************************************************
294 //*************************************************************************
296 {
297 return start_node.next;
298 }
299
300 //*************************************************************************
302 //*************************************************************************
303 const node_t* get_head() const
304 {
305 return start_node.next;
306 }
307
308 //*************************************************************************
310 //*************************************************************************
311 inline void insert_node_after(node_t& position, node_t& node)
312 {
313 // Connect to the forward_list.
314 join(&node, position.next);
315 join(&position, &node);
316 }
317
318 //*************************************************************************
320 //*************************************************************************
321 bool is_trivial_list() const
322 {
323 return (size() < 2);
324 }
325
326 //*************************************************************************
328 //*************************************************************************
329 void join(node_t* left, node_t* right)
330 {
331 left->next = right;
332 }
333
334 //*************************************************************************
336 //*************************************************************************
337 void set_node_pool(etl::ipool& node_pool_)
338 {
339 p_node_pool = &node_pool_;
340 MAX_SIZE = p_node_pool->max_size();
341 }
342
343 //*************************************************************************
345 //*************************************************************************
347 {
348 return p_node_pool;
349 }
350
356 };
357
358 //***************************************************************************
361 //***************************************************************************
362 template <typename T>
364 {
365 public:
366
367 typedef T value_type;
368 typedef T* pointer;
369 typedef const T* const_pointer;
370 typedef T& reference;
371 typedef const T& const_reference;
372 typedef size_t size_type;
373
374#if ETL_USING_CPP11
375 typedef T&& rvalue_reference;
376#endif
377
378 protected:
379
380 //*************************************************************************
382 //*************************************************************************
383 struct data_node_t : public node_t
384 {
385 explicit data_node_t(const T& value_)
386 : value(value_)
387 {}
388
389 T value;
390 };
391
392 public:
393
394 //*************************************************************************
396 //*************************************************************************
397 class iterator : public etl::iterator<ETL_OR_STD::forward_iterator_tag, T>
398 {
399 public:
400
401 friend class iforward_list;
402 friend class const_iterator;
403
404 iterator()
405 : p_node(ETL_NULLPTR)
406 {
407 }
408
409 iterator(node_t* node)
410 : p_node(node)
411 {
412 }
413
414 iterator(const iterator& other)
415 : p_node(other.p_node)
416 {
417 }
418
419 iterator& operator ++()
420 {
421 p_node = p_node->next;
422 return *this;
423 }
424
425 iterator operator ++(int)
426 {
427 iterator temp(*this);
428 p_node = p_node->next;
429 return temp;
430 }
431
432 iterator operator =(const iterator& other)
433 {
434 p_node = other.p_node;
435 return *this;
436 }
437
438 reference operator *() const
439 {
440 return iforward_list::data_cast(p_node)->value;
441 }
442
443 pointer operator &() const
444 {
445 return &(iforward_list::data_cast(p_node)->value);
446 }
447
448 pointer operator ->() const
449 {
450 return &(iforward_list::data_cast(p_node)->value);
451 }
452
453 friend bool operator == (const iterator& lhs, const iterator& rhs)
454 {
455 return lhs.p_node == rhs.p_node;
456 }
457
458 friend bool operator != (const iterator& lhs, const iterator& rhs)
459 {
460 return !(lhs == rhs);
461 }
462
463 private:
464
465 node_t* p_node;
466 };
467
468 //*************************************************************************
470 //*************************************************************************
471 class const_iterator : public etl::iterator<ETL_OR_STD::forward_iterator_tag, const T>
472 {
473 public:
474
475 friend class iforward_list;
476
477 const_iterator()
478 : p_node(ETL_NULLPTR)
479 {
480 }
481
482 const_iterator(node_t* node)
483 : p_node(node)
484 {
485 }
486
487 const_iterator(const node_t* node)
488 : p_node(node)
489 {
490 }
491
492 const_iterator(const typename iforward_list::iterator& other)
493 : p_node(other.p_node)
494 {
495 }
496
497 const_iterator(const const_iterator& other)
498 : p_node(other.p_node)
499 {
500 }
501
502 const_iterator& operator ++()
503 {
504 p_node = p_node->next;
505 return *this;
506 }
507
508 const_iterator operator ++(int)
509 {
510 const_iterator temp(*this);
511 p_node = p_node->next;
512 return temp;
513 }
514
515 const_iterator& operator =(const const_iterator& other)
516 {
517 p_node = other.p_node;
518 return *this;
519 }
520
521 const_reference operator *() const
522 {
523 return iforward_list::data_cast(p_node)->value;
524 }
525
526 const_pointer operator &() const
527 {
528 return &(iforward_list::data_cast(p_node)->value);
529 }
530
531 const_pointer operator ->() const
532 {
533 return &(iforward_list::data_cast(p_node)->value);
534 }
535
536 friend bool operator == (const const_iterator& lhs, const const_iterator& rhs)
537 {
538 return lhs.p_node == rhs.p_node;
539 }
540
541 friend bool operator != (const const_iterator& lhs, const const_iterator& rhs)
542 {
543 return !(lhs == rhs);
544 }
545
546 private:
547
548 const node_t* p_node;
549 };
550
551 typedef typename etl::iterator_traits<iterator>::difference_type difference_type;
552
553 //*************************************************************************
555 //*************************************************************************
556 iterator begin()
557 {
558 return iterator(get_head());
559 }
560
561 //*************************************************************************
563 //*************************************************************************
564 const_iterator begin() const
565 {
566 return const_iterator(get_head());
567 }
568
569 //*************************************************************************
571 //*************************************************************************
572 iterator before_begin()
573 {
574 return iterator(&start_node);
575 }
576
577 //*************************************************************************
579 //*************************************************************************
580 const_iterator before_begin() const
581 {
582 return const_iterator(&start_node);
583 }
584
585 //*************************************************************************
587 //*************************************************************************
588 const_iterator cbegin() const
589 {
590 return const_iterator(get_head());
591 }
592
593 //*************************************************************************
595 //*************************************************************************
596 iterator end()
597 {
598 return iterator();
599 }
600
601 //*************************************************************************
603 //*************************************************************************
604 const_iterator end() const
605 {
606 return const_iterator();
607 }
608
609 //*************************************************************************
611 //*************************************************************************
612 const_iterator cend() const
613 {
614 return const_iterator();
615 }
616
617 //*************************************************************************
619 //*************************************************************************
620 void clear()
621 {
622 initialise();
623 }
624
625 //*************************************************************************
627 //*************************************************************************
628 reference front()
629 {
630 return data_cast(*get_head()).value;
631 }
632
633 //*************************************************************************
635 //*************************************************************************
636 const_reference front() const
637 {
638 return data_cast(*get_head()).value;
639 }
640
641 //*************************************************************************
645 //*************************************************************************
646 template <typename TIterator>
647 void assign(TIterator first, TIterator last, typename etl::enable_if<!etl::is_integral<TIterator>::value, int>::type = 0)
648 {
649#if ETL_IS_DEBUG_BUILD
650 difference_type d = etl::distance(first, last);
651 ETL_ASSERT(d >= 0, ETL_ERROR(forward_list_iterator));
652#endif
653
654 initialise();
655
656 node_t* p_last_node = &start_node;
657
658 // Add all of the elements.
659 while (first != last)
660 {
661 ETL_ASSERT(!full(), ETL_ERROR(forward_list_full));
662
663 data_node_t& data_node = allocate_data_node(*first);
664 ++first;
665 join(p_last_node, &data_node);
666 data_node.next = ETL_NULLPTR;
667 p_last_node = &data_node;
668 }
669 }
670
671 //*************************************************************************
673 //*************************************************************************
674 void assign(size_t n, const T& value)
675 {
676 ETL_ASSERT(n <= MAX_SIZE, ETL_ERROR(forward_list_full));
677
678 initialise();
679
680 node_t* p_last_node = &start_node;
681
682 // Add all of the elements.
683 while (size() < n)
684 {
685 data_node_t& data_node = allocate_data_node(value);
686 join(p_last_node, &data_node);
687 data_node.next = ETL_NULLPTR;
688 p_last_node = &data_node;
689 }
690 }
691
692 //*************************************************************************
694 //*************************************************************************
695 void push_front(const T& value)
696 {
697 ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(!full(), ETL_ERROR(forward_list_full));
698
699 data_node_t& data_node = allocate_data_node(value);
700 insert_node_after(start_node, data_node);
701 }
702
703#if ETL_USING_CPP11
704 //*************************************************************************
706 //*************************************************************************
707 void push_front(rvalue_reference value)
708 {
709 ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(!full(), ETL_ERROR(forward_list_full));
710
711 data_node_t& data_node = allocate_data_node(etl::move(value));
712 insert_node_after(start_node, data_node);
713 }
714#endif
715
716#if ETL_USING_CPP11 && ETL_NOT_USING_STLPORT && !defined(ETL_FORWARD_LIST_FORCE_CPP03_IMPLEMENTATION)
717 //*************************************************************************
719 //*************************************************************************
720 template <typename ... Args>
721 reference emplace_front(Args && ... args)
722 {
723 ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(forward_list_full));
724
725 data_node_t* p_data_node = allocate_data_node();
726 ::new (&(p_data_node->value)) T(etl::forward<Args>(args)...);
727 ETL_INCREMENT_DEBUG_COUNT;
728 insert_node_after(start_node, *p_data_node);
729 return front();
730 }
731#else
732 //*************************************************************************
734 //*************************************************************************
735 reference emplace_front()
736 {
737 ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(forward_list_full));
738
739 data_node_t* p_data_node = allocate_data_node();
740 ::new (&(p_data_node->value)) T();
741 ETL_INCREMENT_DEBUG_COUNT;
742 insert_node_after(start_node, *p_data_node);
743 return front();
744 }
745
746 //*************************************************************************
748 //*************************************************************************
749 template <typename T1>
750 reference emplace_front(const T1& value1)
751 {
752 ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(forward_list_full));
753
754 data_node_t* p_data_node = allocate_data_node();
755 ::new (&(p_data_node->value)) T(value1);
756 ETL_INCREMENT_DEBUG_COUNT;
757 insert_node_after(start_node, *p_data_node);
758 return front();
759 }
760
761 //*************************************************************************
763 //*************************************************************************
764 template <typename T1, typename T2>
765 reference emplace_front(const T1& value1, const T2& value2)
766 {
767 ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(forward_list_full));
768
769 data_node_t* p_data_node = allocate_data_node();
770 ::new (&(p_data_node->value)) T(value1, value2);
771 ETL_INCREMENT_DEBUG_COUNT;
772 insert_node_after(start_node, *p_data_node);
773 return front();
774 }
775
776 //*************************************************************************
778 //*************************************************************************
779 template <typename T1, typename T2, typename T3>
780 reference emplace_front(const T1& value1, const T2& value2, const T3& value3)
781 {
782 ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(forward_list_full));
783
784 data_node_t* p_data_node = allocate_data_node();
785 ::new (&(p_data_node->value)) T(value1, value2, value3);
786 ETL_INCREMENT_DEBUG_COUNT;
787 insert_node_after(start_node, *p_data_node);
788 return front();
789 }
790
791 //*************************************************************************
793 //*************************************************************************
794 template <typename T1, typename T2, typename T3, typename T4>
795 reference emplace_front(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
796 {
797 ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(forward_list_full));
798
799 data_node_t* p_data_node = allocate_data_node();
800 ::new (&(p_data_node->value)) T(value1, value2, value3, value4);
801 ETL_INCREMENT_DEBUG_COUNT;
802 insert_node_after(start_node, *p_data_node);
803 return front();
804 }
805#endif // ETL_USING_CPP11 && ETL_NOT_USING_STLPORT
806
807 //*************************************************************************
809 //*************************************************************************
811 {
812 ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(!empty(), ETL_ERROR(forward_list_empty));
813
814 remove_node_after(start_node);
815 }
816
817 //*************************************************************************
819 //*************************************************************************
820 void resize(size_t n)
821 {
822 resize(n, T());
823 }
824
825 //*************************************************************************
829 //*************************************************************************
830 void resize(size_t n, T value)
831 {
832 ETL_ASSERT(n <= MAX_SIZE, ETL_ERROR(forward_list_full));
833
834 if (n == 0U)
835 {
836 clear();
837 }
838 else if (empty())
839 {
840 assign(n, value);
841 }
842 else
843 {
844 size_t i = 0UL;
845 iterator i_node = begin();
846 iterator i_last_node;
847
848 // Find where we're currently at.
849 while ((i < n) && (i_node != end()))
850 {
851 ++i;
852 i_last_node = i_node;
853 ++i_node;
854 }
855
856 if (i_node != end())
857 {
858 // Reduce.
859 erase_after(i_last_node, end());
860 }
861 else if (i_node == end())
862 {
863 // Increase.
864 while (i < n)
865 {
866 i_last_node = insert_after(i_last_node, value);
867 ++i;
868 }
869 }
870 }
871 }
872
873 //*************************************************************************
875 //*************************************************************************
876 iterator insert_after(const_iterator position, const T& value)
877 {
878 ETL_ASSERT(!full(), ETL_ERROR(forward_list_full));
879
880 data_node_t& data_node = allocate_data_node(value);
881 insert_node_after(*to_iterator(position).p_node, data_node);
882
883 return iterator(&data_node);
884 }
885
886#if ETL_USING_CPP11 && ETL_NOT_USING_STLPORT && !defined(ETL_FORWARD_LIST_FORCE_CPP03_IMPLEMENTATION)
887 //*************************************************************************
889 //*************************************************************************
890 template <typename ... Args>
891 iterator emplace_after(const_iterator position, Args && ... args)
892 {
893 ETL_ASSERT(!full(), ETL_ERROR(forward_list_full));
894
895 data_node_t* p_data_node = allocate_data_node();
896 ::new (&(p_data_node->value)) T(etl::forward<Args>(args)...);
897 ETL_INCREMENT_DEBUG_COUNT;
898 insert_node_after(*to_iterator(position).p_node, *p_data_node);
899
900 return iterator(p_data_node);
901 }
902#else
903 //*************************************************************************
905 //*************************************************************************
906 iterator emplace_after(const_iterator position)
907 {
908 ETL_ASSERT(!full(), ETL_ERROR(forward_list_full));
909
910 data_node_t* p_data_node = allocate_data_node();
911 ::new (&(p_data_node->value)) T();
912 ETL_INCREMENT_DEBUG_COUNT;
913 insert_node_after(*to_iterator(position).p_node, *p_data_node);
914
915 return iterator(p_data_node);
916 }
917
918 //*************************************************************************
920 //*************************************************************************
921 template <typename T1>
922 iterator emplace_after(const_iterator position, const T1& value1)
923 {
924 ETL_ASSERT(!full(), ETL_ERROR(forward_list_full));
925
926 data_node_t* p_data_node = allocate_data_node();
927 ::new (&(p_data_node->value)) T(value1);
928 ETL_INCREMENT_DEBUG_COUNT;
929 insert_node_after(*to_iterator(position).p_node, *p_data_node);
930
931 return iterator(p_data_node);
932 }
933
934 //*************************************************************************
936 //*************************************************************************
937 template <typename T1, typename T2>
938 iterator emplace_after(const_iterator position, const T1& value1, const T2& value2)
939 {
940 ETL_ASSERT(!full(), ETL_ERROR(forward_list_full));
941
942 data_node_t* p_data_node = allocate_data_node();
943 ::new (&(p_data_node->value)) T(value1, value2);
944 ETL_INCREMENT_DEBUG_COUNT;
945 insert_node_after(*to_iterator(position).p_node, *p_data_node);
946
947 return iterator(p_data_node);
948 }
949
950 //*************************************************************************
952 //*************************************************************************
953 template <typename T1, typename T2, typename T3>
954 iterator emplace_after(const_iterator position, const T1& value1, const T2& value2, const T3& value3)
955 {
956 ETL_ASSERT(!full(), ETL_ERROR(forward_list_full));
957
958 data_node_t* p_data_node = allocate_data_node();
959 ::new (&(p_data_node->value)) T(value1, value2, value3);
960 ETL_INCREMENT_DEBUG_COUNT;
961 insert_node_after(*to_iterator(position).p_node, *p_data_node);
962
963 return iterator(p_data_node);
964 }
965
966 //*************************************************************************
968 //*************************************************************************
969 template <typename T1, typename T2, typename T3, typename T4>
970 iterator emplace_after(const_iterator position, const T1& value1, const T2& value2, const T3& value3, const T4& value4)
971 {
972 ETL_ASSERT(!full(), ETL_ERROR(forward_list_full));
973
974 data_node_t* p_data_node = allocate_data_node();
975 ::new (&(p_data_node->value)) T(value1, value2, value3, value4);
976 ETL_INCREMENT_DEBUG_COUNT;
977 insert_node_after(*to_iterator(position).p_node, *p_data_node);
978
979 return iterator(p_data_node);
980 }
981#endif // ETL_USING_CPP11 && ETL_NOT_USING_STLPORT
982
983 //*************************************************************************
985 //*************************************************************************
986 iterator insert_after(const_iterator position, size_t n, const T& value)
987 {
988 ETL_ASSERT(!full(), ETL_ERROR(forward_list_full));
989
990 for (size_t i = 0UL; !full() && (i < n); ++i)
991 {
992 // Set up the next free node.
993 data_node_t& data_node = allocate_data_node(value);
994 insert_node_after(*to_iterator(position).p_node, data_node);
995 }
996
997 if (n > 0U)
998 {
999 ++position;
1000 }
1001
1002 return to_iterator(position);
1003 }
1004
1005 //*************************************************************************
1007 //*************************************************************************
1008 template <typename TIterator>
1009 iterator insert_after(const_iterator position, TIterator first, TIterator last, typename etl::enable_if<!etl::is_integral<TIterator>::value, int>::type = 0)
1010 {
1011#if ETL_IS_DEBUG_BUILD
1012 difference_type d = etl::distance(first, last);
1013 ETL_ASSERT((d + size()) <= MAX_SIZE, ETL_ERROR(forward_list_full));
1014#endif
1015
1016 while (first != last)
1017 {
1018 // Set up the next free node.
1019 data_node_t& data_node = allocate_data_node(*first);
1020 ++first;
1021 insert_node_after(*to_iterator(position).p_node, data_node);
1022 ++position;
1023 }
1024
1025 return to_iterator(position);
1026 }
1027
1028 //*************************************************************************
1030 //*************************************************************************
1031 iterator erase_after(iterator position)
1032 {
1033 iterator next(position);
1034 if (next != end())
1035 {
1036 ++next;
1037 if (next != end())
1038 {
1039 ++next;
1040 remove_node_after(*position.p_node);
1041 }
1042 }
1043
1044 return next;
1045 }
1046
1047 //*************************************************************************
1049 //*************************************************************************
1050 iterator erase_after(const_iterator position)
1051 {
1052 iterator next(position);
1053 if (next != end())
1054 {
1055 ++next;
1056 if (next != end())
1057 {
1058 ++next;
1059 remove_node_after(*position.p_node);
1060 }
1061 }
1062
1063 return next;
1064 }
1065
1066 //*************************************************************************
1068 //*************************************************************************
1069 iterator erase_after(const_iterator first, const_iterator last)
1070 {
1071 if (first != end() && (first != last))
1072 {
1073 node_t* p_first = to_iterator(first).p_node;
1074 node_t* p_last = to_iterator(last).p_node;
1075 node_t* p_next = p_first->next;
1076
1077 // Join the ends.
1078 join(p_first, p_last);
1079
1080 p_first = p_next;
1081
1082 // Erase the ones in between.
1083 while (p_first != p_last)
1084 {
1085 p_next = p_first->next; // Remember the next node.
1086 destroy_data_node(static_cast<data_node_t&>(*p_first)); // Destroy the pool object.
1087 p_first = p_next; // Move to the next node.
1088 }
1089
1090 if (p_next == ETL_NULLPTR)
1091 {
1092 return end();
1093 }
1094 else
1095 {
1096 return iterator(p_last);
1097 }
1098 }
1099 else
1100 {
1101 return end();
1102 }
1103 }
1104
1105 //*************************************************************************
1108 //*************************************************************************
1109 void move_after(const_iterator from_before, const_iterator to_before)
1110 {
1111 if (from_before == to_before) // Can't move to after yourself!
1112 {
1113 return;
1114 }
1115
1116 node_t* p_from_before = const_cast<node_t*>(from_before.p_node); // We're not changing the value, just it's position.
1117 node_t* p_to_before = const_cast<node_t*>(to_before.p_node); // We're not changing the value, just it's position.
1118
1119 node_t* p_from = p_from_before->next;
1120
1121 // Disconnect from the list.
1122 join(p_from_before, p_from->next);
1123
1124 // Attach it to the new position.
1125 join(p_from, p_to_before->next);
1126 join(p_to_before, p_from);
1127 }
1128
1129 //*************************************************************************
1132 //*************************************************************************
1133 void move_after(const_iterator first_before, const_iterator last, const_iterator to_before)
1134 {
1135 if ((first_before == to_before) || (last == to_before))
1136 {
1137 return; // Can't more to before yourself!
1138 }
1139
1140//#if ETL_IS_DEBUG_BUILD
1141 // Check that we are not doing an illegal move!
1142 for (const_iterator item = first_before; item != last; ++item)
1143 {
1144 ETL_ASSERT(item != to_before, ETL_ERROR(forward_list_iterator));
1145 }
1146//#endif
1147
1148 node_t* p_first_before = const_cast<node_t*>(first_before.p_node); // We're not changing the value, just it's position.
1149 node_t* p_last = const_cast<node_t*>(last.p_node); // We're not changing the value, just it's position.
1150 node_t* p_to_before = const_cast<node_t*>(to_before.p_node); // We're not changing the value, just it's position.
1151 node_t* p_first = p_first_before->next;
1152 node_t* p_final = p_first_before;
1153
1154 // Find the last node that will be moved.
1155 while (p_final->next != p_last)
1156 {
1157 p_final = p_final->next;
1158 }
1159
1160 // Disconnect from the list.
1161 join(p_first_before, p_final->next);
1162
1163 // Attach it to the new position.
1164 join(p_final, p_to_before->next);
1165 join(p_to_before, p_first);
1166 }
1167
1168 //*************************************************************************
1171 //*************************************************************************
1172 void unique()
1173 {
1175 }
1176
1177 //*************************************************************************
1180 //*************************************************************************
1181 template <typename TIsEqual>
1182 void unique(TIsEqual isEqual)
1183 {
1184 if (empty())
1185 {
1186 return;
1187 }
1188
1189 node_t* last = get_head();
1190 node_t* current = last->next;
1191
1192 while (current != ETL_NULLPTR)
1193 {
1194 // Is this value the same as the last?
1195 if (isEqual(data_cast(current)->value, data_cast(last)->value))
1196 {
1197 remove_node_after(*last);
1198 }
1199 else
1200 {
1201 // Move on one.
1202 last = current;
1203 }
1204
1205 current = last->next;
1206 }
1207 }
1208
1209 //*************************************************************************
1212 //*************************************************************************
1213 void sort()
1214 {
1215 sort(etl::less<T>());
1216 }
1217
1218 //*************************************************************************
1242 //*************************************************************************
1243 template <typename TCompare>
1244 void sort(TCompare compare)
1245 {
1246 iterator p_left;
1247 iterator p_right;
1248 iterator p_node;
1249 iterator p_head;
1250 iterator p_tail;
1251 int list_size = 1;
1252 int number_of_merges;
1253 int left_size;
1254 int right_size;
1255
1256 if (is_trivial_list())
1257 {
1258 return;
1259 }
1260
1261 while (true)
1262 {
1263 p_left = begin();
1264 p_head = before_begin();
1265 p_tail = before_begin();
1266
1267 number_of_merges = 0; // Count the number of merges we do in this pass.
1268
1269 while (p_left != end())
1270 {
1271 ++number_of_merges; // There exists a merge to be done.
1272 p_right = p_left;
1273 left_size = 0;
1274
1275 // Step 'list_size' places along from left
1276 for (int i = 0; i < list_size; ++i)
1277 {
1278 ++left_size;
1279
1280 ++p_right;
1281
1282 if (p_right == end())
1283 {
1284 break;
1285 }
1286 }
1287
1288 // If right hasn't fallen off end, we have two lists to merge.
1289 right_size = list_size;
1290
1291 // Now we have two lists. Merge them.
1292 while (left_size > 0 || (right_size > 0 && p_right != end()))
1293 {
1294 // Decide whether the next node of merge comes from left or right.
1295 if (left_size == 0)
1296 {
1297 // Left is empty. The node must come from right.
1298 p_node = p_right;
1299 ++p_right;
1300 --right_size;
1301 }
1302 else if (right_size == 0 || p_right == end())
1303 {
1304 // Right is empty. The node must come from left.
1305 p_node = p_left;
1306 ++p_left;
1307 --left_size;
1308 }
1309 else if (!compare(*p_right, *p_left))
1310 {
1311 // First node of left is lower or same. The node must come from left.
1312 p_node = p_left;
1313 ++p_left;
1314 --left_size;
1315 }
1316 else
1317 {
1318 // First node of right is lower. The node must come from right.
1319 p_node = p_right;
1320 ++p_right;
1321 --right_size;
1322 }
1323
1324 // Add the next node to the merged head.
1325 if (p_head == before_begin())
1326 {
1327 join(p_head.p_node, p_node.p_node);
1328 p_head = p_node;
1329 p_tail = p_node;
1330 }
1331 else
1332 {
1333 join(p_tail.p_node, p_node.p_node);
1334 p_tail = p_node;
1335 }
1336
1337 p_tail.p_node->next = ETL_NULLPTR;
1338 }
1339
1340 // Now left has stepped `list_size' places along, and right has too.
1341 p_left = p_right;
1342 }
1343
1344 // If we have done only one merge, we're finished.
1345 if (number_of_merges <= 1) // Allow for number_of_merges == 0, the empty head case
1346 {
1347 return;
1348 }
1349
1350 // Otherwise repeat, merging lists twice the size
1351 list_size *= 2;
1352 }
1353 }
1354
1355 //*************************************************************************
1356 // Removes the values specified.
1357 //*************************************************************************
1358 void remove(const T& value)
1359 {
1360 iterator i_item = begin();
1361 iterator i_last_item = before_begin();
1362
1363 while (i_item != end())
1364 {
1365 if (*i_item == value)
1366 {
1367 i_item = erase_after(i_last_item);
1368 }
1369 else
1370 {
1371 ++i_item;
1372 ++i_last_item;
1373 }
1374 }
1375 }
1376
1377 //*************************************************************************
1379 //*************************************************************************
1380 template <typename TPredicate>
1381 void remove_if(TPredicate predicate)
1382 {
1383 iterator i_item = begin();
1384 iterator i_last_item = before_begin();
1385
1386 while (i_item != end())
1387 {
1388 if (predicate(*i_item))
1389 {
1390 i_item = erase_after(i_last_item);
1391 }
1392 else
1393 {
1394 ++i_item;
1395 ++i_last_item;
1396 }
1397 }
1398 }
1399
1400 //*************************************************************************
1402 //*************************************************************************
1404 {
1405 if (&rhs != this)
1406 {
1407 assign(rhs.cbegin(), rhs.cend());
1408 }
1409
1410 return *this;
1411 }
1412
1413#if ETL_USING_CPP11
1414 //*************************************************************************
1416 //*************************************************************************
1418 {
1419 move_container(etl::move(rhs));
1420
1421 return *this;
1422 }
1423#endif
1424
1425 protected:
1426
1427 //*************************************************************************
1429 //*************************************************************************
1430 iforward_list(bool pool_is_shared_)
1431 : forward_list_base(pool_is_shared_)
1432 {
1433 }
1434
1435 //*************************************************************************
1437 //*************************************************************************
1438 iforward_list(etl::ipool& node_pool, size_t max_size_, bool pool_is_shared_)
1439 : forward_list_base(node_pool, max_size_, pool_is_shared_)
1440 {
1441 }
1442
1443 //*************************************************************************
1445 //*************************************************************************
1447 {
1448 if (!empty())
1449 {
1450 if (etl::is_trivially_destructible<T>::value && !has_shared_pool())
1451 {
1452 ETL_ASSERT(p_node_pool != ETL_NULLPTR, ETL_ERROR(forward_list_no_pool));
1453 p_node_pool->release_all();
1454 ETL_RESET_DEBUG_COUNT;
1455 }
1456 else
1457 {
1458 node_t* p_first = start_node.next;
1459 node_t* p_next;
1460
1461 // Erase the ones in between.
1462 while (p_first != ETL_NULLPTR)
1463 {
1464 p_next = p_first->next; // Remember the next node.
1465 destroy_data_node(static_cast<data_node_t&>(*p_first)); // Destroy the pool object.
1466 p_first = p_next; // Move to the next node.
1467 }
1468 }
1469 }
1470
1471 start_node.next = ETL_NULLPTR;
1472 }
1473
1474 //*************************************************************************
1476 //*************************************************************************
1477 data_node_t& allocate_data_node(const_reference value)
1478 {
1479 data_node_t* p_node = allocate_data_node();
1480 ::new (&(p_node->value)) T(value);
1481 ETL_INCREMENT_DEBUG_COUNT;
1482
1483 return *p_node;
1484 }
1485
1486#if ETL_USING_CPP11
1487 //*************************************************************************
1489 //*************************************************************************
1490 data_node_t& allocate_data_node(rvalue_reference value)
1491 {
1492 data_node_t* p_node = allocate_data_node();
1493 ::new (&(p_node->value)) T(etl::move(value));
1494 ETL_INCREMENT_DEBUG_COUNT;
1495
1496 return *p_node;
1497 }
1498#endif
1499
1500#if ETL_USING_CPP11
1501 //*************************************************************************
1503 //*************************************************************************
1504 void move_container(iforward_list&& rhs)
1505 {
1506 if (&rhs != this)
1507 {
1508 this->initialise();
1509
1510 if (!rhs.empty())
1511 {
1512 // Are we using the same pool?
1513 if (this->get_node_pool() == rhs.get_node_pool())
1514 {
1515 // Just link the nodes to this list.
1516 this->start_node.next = rhs.start_node.next;
1517
1518 ETL_SET_DEBUG_COUNT(ETL_OBJECT_GET_DEBUG_COUNT(rhs));
1519
1520 ETL_OBJECT_RESET_DEBUG_COUNT(rhs);
1521 rhs.start_node.next = ETL_NULLPTR;
1522 }
1523 else
1524 {
1525 node_t* p_last_node = &this->start_node;
1526
1527 // Add all of the elements.
1528 etl::iforward_list<T>::iterator first = rhs.begin();
1529 etl::iforward_list<T>::iterator last = rhs.end();
1530
1531 while (first != last)
1532 {
1533 ETL_ASSERT(!full(), ETL_ERROR(forward_list_full));
1534
1535 data_node_t& data_node = this->allocate_data_node(etl::move(*first));
1536 ++first;
1537 join(p_last_node, &data_node);
1538 data_node.next = ETL_NULLPTR;
1539 p_last_node = &data_node;
1540 }
1541
1542 rhs.initialise();
1543 }
1544 }
1545 }
1546 }
1547#endif
1548
1549 private:
1550
1551 //*************************************************************************
1553 //*************************************************************************
1554 static data_node_t* data_cast(node_t* p_node)
1555 {
1556 return static_cast<data_node_t*>(p_node);
1557 }
1558
1559 //*************************************************************************
1561 //*************************************************************************
1562 static data_node_t& data_cast(node_t& node)
1563 {
1564 return static_cast<data_node_t&>(node);
1565 }
1566
1567 //*************************************************************************
1569 //*************************************************************************
1570 static const data_node_t* data_cast(const node_t* p_node)
1571 {
1572 return static_cast<const data_node_t*>(p_node);
1573 }
1574
1575 //*************************************************************************
1577 //*************************************************************************
1578 static const data_node_t& data_cast(const node_t& node)
1579 {
1580 return static_cast<const data_node_t&>(node);
1581 }
1582
1583 //*************************************************************************
1585 //*************************************************************************
1586 void remove_node_after(node_t& node)
1587 {
1588 // The node to erase.
1589 node_t* p_node = node.next;
1590
1591 if (p_node != ETL_NULLPTR)
1592 {
1593 // Disconnect the node from the forward_list.
1594 join(&node, p_node->next);
1595
1596 // Destroy the pool object.
1597 destroy_data_node(static_cast<data_node_t&>(*p_node));
1598 }
1599 }
1600
1601 //*************************************************************************
1603 //*************************************************************************
1605 {
1606 data_node_t* (etl::ipool::*func)() = &etl::ipool::allocate<data_node_t>;
1607 return (p_node_pool->*func)();
1608 }
1609
1610 //*************************************************************************
1612 //*************************************************************************
1613 void destroy_data_node(data_node_t& node)
1614 {
1615 node.value.~T();
1616 p_node_pool->release(&node);
1617 ETL_DECREMENT_DEBUG_COUNT;
1618 }
1619
1620 // Disable copy construction.
1622
1623 //*************************************************************************
1625 //*************************************************************************
1626#if defined(ETL_POLYMORPHIC_FORWARD_LIST) || defined(ETL_POLYMORPHIC_CONTAINERS)
1627 public:
1628 virtual ~iforward_list()
1629 {
1630 }
1631#else
1632 protected:
1634 {
1635 }
1636#endif
1637
1638 private:
1639
1640 //*************************************************************************
1642 //*************************************************************************
1643 iterator to_iterator(const_iterator itr) const
1644 {
1645 return iterator(const_cast<node_t*>(itr.p_node));
1646 }
1647 };
1648
1649 //*************************************************************************
1652 //*************************************************************************
1653 template <typename T, const size_t MAX_SIZE_>
1655 {
1656 public:
1657
1658 ETL_STATIC_ASSERT((MAX_SIZE_ > 0U), "Zero capacity etl::forward_list is not valid");
1659
1660 static ETL_CONSTANT size_t MAX_SIZE = MAX_SIZE_;
1661
1662 public:
1663
1664 typedef T value_type;
1665 typedef T* pointer;
1666 typedef const T* const_pointer;
1667 typedef T& reference;
1668 typedef const T& const_reference;
1669 typedef size_t size_type;
1670
1671 //*************************************************************************
1673 //*************************************************************************
1675 : etl::iforward_list<T>(node_pool, MAX_SIZE, false)
1676 {
1677 this->initialise();
1678 }
1679
1680 //*************************************************************************
1682 //*************************************************************************
1683 explicit forward_list(size_t initial_size, const T& value = T())
1684 : etl::iforward_list<T>(node_pool, MAX_SIZE, false)
1685 {
1686 this->assign(initial_size, value);
1687 }
1688
1689 //*************************************************************************
1691 //*************************************************************************
1693 : etl::iforward_list<T>(node_pool, MAX_SIZE, false)
1694 {
1695 this->assign(other.cbegin(), other.cend());
1696 }
1697
1698#if ETL_USING_CPP11
1699 //*************************************************************************
1701 //*************************************************************************
1702 forward_list(forward_list&& other)
1703 : etl::iforward_list<T>(node_pool, MAX_SIZE, false)
1704 {
1705 this->move_container(etl::move(other));
1706 }
1707#endif
1708
1709 //*************************************************************************
1711 //*************************************************************************
1712 template <typename TIterator>
1713 forward_list(TIterator first, TIterator last, typename etl::enable_if<!etl::is_integral<TIterator>::value, int>::type = 0)
1714 : etl::iforward_list<T>(node_pool, MAX_SIZE, false)
1715 {
1716 this->assign(first, last);
1717 }
1718
1719#if ETL_HAS_INITIALIZER_LIST
1720 //*************************************************************************
1722 //*************************************************************************
1723 forward_list(std::initializer_list<T> init)
1724 : etl::iforward_list<T>(node_pool, MAX_SIZE, false)
1725 {
1726 this->assign(init.begin(), init.end());
1727 }
1728#endif
1729
1730 //*************************************************************************
1732 //*************************************************************************
1734 {
1735 this->initialise();
1736 }
1737
1738 //*************************************************************************
1740 //*************************************************************************
1741 forward_list& operator = (const forward_list& rhs)
1742 {
1743 if (&rhs != this)
1744 {
1745 this->assign(rhs.cbegin(), rhs.cend());
1746 }
1747
1748 return *this;
1749 }
1750
1751#if ETL_USING_CPP11
1752 //*************************************************************************
1754 //*************************************************************************
1755 forward_list& operator = (forward_list&& rhs)
1756 {
1757
1758 this->move_container(etl::move(rhs));
1759
1760 return *this;
1761 }
1762#endif
1763
1764 private:
1765
1768 };
1769
1770 template <typename T, const size_t MAX_SIZE_>
1771 ETL_CONSTANT size_t forward_list<T, MAX_SIZE_>::MAX_SIZE;
1772
1773 //*************************************************************************
1775 //*************************************************************************
1776#if ETL_USING_CPP17 && ETL_HAS_INITIALIZER_LIST
1777 template <typename... T>
1778 forward_list(T...) ->forward_list<typename etl::common_type_t<T...>, sizeof...(T)>;
1779#endif
1780
1781 //*************************************************************************
1783 //*************************************************************************
1784#if ETL_USING_CPP11 && ETL_HAS_INITIALIZER_LIST
1785 template <typename... T>
1786 constexpr auto make_forward_list(T&&... t) -> etl::forward_list<typename etl::common_type_t<T...>, sizeof...(T)>
1787 {
1788 return { etl::forward<T>(t)... };
1789 }
1790#endif
1791
1792 //*************************************************************************
1795 //*************************************************************************
1796 template <typename T>
1798 {
1799 public:
1800
1801 typedef T value_type;
1802 typedef T* pointer;
1803 typedef const T* const_pointer;
1804 typedef T& reference;
1805 typedef const T& const_reference;
1806 typedef size_t size_type;
1807
1808 typedef typename etl::iforward_list<T>::data_node_t pool_type;
1809
1810 //*************************************************************************
1812 //*************************************************************************
1814 : etl::iforward_list<T>(true)
1815 {
1816 }
1817
1818 //*************************************************************************
1820 //*************************************************************************
1821 explicit forward_list_ext(etl::ipool& node_pool)
1822 : etl::iforward_list<T>(node_pool, node_pool.max_size(), true)
1823 {
1824 this->initialise();
1825 }
1826
1827 //*************************************************************************
1829 //*************************************************************************
1830 explicit forward_list_ext(size_t initial_size, etl::ipool& node_pool)
1831 : etl::iforward_list<T>(node_pool, node_pool.max_size(), true)
1832 {
1833 this->assign(initial_size, T());
1834 }
1835
1836 //*************************************************************************
1838 //*************************************************************************
1839 explicit forward_list_ext(size_t initial_size, const T& value, etl::ipool& node_pool)
1840 : etl::iforward_list<T>(node_pool, node_pool.max_size(), true)
1841 {
1842 this->assign(initial_size, value);
1843 }
1844
1845 //*************************************************************************
1847 //*************************************************************************
1849 : etl::iforward_list<T>(*other.p_node_pool, other.p_node_pool->max_size(), true)
1850 {
1851 this->assign(other.cbegin(), other.cend());
1852 }
1853
1854 //*************************************************************************
1856 //*************************************************************************
1858 : etl::iforward_list<T>(node_pool, node_pool.max_size(), true)
1859 {
1860 this->assign(other.cbegin(), other.cend());
1861 }
1862
1863#if ETL_USING_CPP11
1864 //*************************************************************************
1866 //*************************************************************************
1868 : etl::iforward_list<T>(*other.p_node_pool, other.p_node_pool->max_size(), true)
1869 {
1870 this->move_container(etl::move(other));
1871 }
1872
1873 //*************************************************************************
1875 //*************************************************************************
1876 forward_list_ext(forward_list_ext&& other, etl::ipool& node_pool)
1877 : etl::iforward_list<T>(node_pool, node_pool.max_size(), true)
1878 {
1879 this->move_container(etl::move(other));
1880 }
1881#endif
1882
1883 //*************************************************************************
1885 //*************************************************************************
1886 template <typename TIterator>
1887 forward_list_ext(TIterator first, TIterator last, etl::ipool& node_pool, typename etl::enable_if<!etl::is_integral<TIterator>::value, int>::type = 0)
1888 : etl::iforward_list<T>(node_pool, node_pool.max_size(), true)
1889 {
1890 this->assign(first, last);
1891 }
1892
1893#if ETL_HAS_INITIALIZER_LIST
1894 //*************************************************************************
1896 //*************************************************************************
1897 forward_list_ext(std::initializer_list<T> init, etl::ipool& node_pool)
1898 : etl::iforward_list<T>(node_pool, node_pool.max_size(), true)
1899 {
1900 this->assign(init.begin(), init.end());
1901 }
1902#endif
1903
1904 //*************************************************************************
1906 //*************************************************************************
1908 {
1909 this->initialise();
1910 }
1911
1912 //*************************************************************************
1914 //*************************************************************************
1915 forward_list_ext& operator = (const forward_list_ext& rhs)
1916 {
1917 if (&rhs != this)
1918 {
1919 this->assign(rhs.cbegin(), rhs.cend());
1920 }
1921
1922 return *this;
1923 }
1924
1925#if ETL_USING_CPP11
1926 //*************************************************************************
1928 //*************************************************************************
1929 forward_list_ext& operator = (forward_list_ext&& rhs)
1930 {
1931 this->move_container(etl::move(rhs));
1932
1933 return *this;
1934 }
1935#endif
1936
1937 //*************************************************************************
1939 //*************************************************************************
1941 {
1942 // Clear the list of any current elements.
1943 if (this->get_node_pool() != ETL_NULLPTR)
1944 {
1945 this->clear();
1946 }
1947
1948 this->set_node_pool(pool);
1949 }
1950
1951 //*************************************************************************
1953 //*************************************************************************
1955 {
1956 return *this->p_node_pool;
1957 }
1958 };
1959
1960 //*************************************************************************
1965 //*************************************************************************
1966 template <typename T>
1968 {
1969 return (lhs.size() == rhs.size()) &&
1970 etl::equal(lhs.begin(), lhs.end(), rhs.begin());
1971 }
1972
1973 //*************************************************************************
1978 //*************************************************************************
1979 template <typename T>
1981 {
1982 return !(lhs == rhs);
1983 }
1984
1985 //*************************************************************************
1991 //*************************************************************************
1992 template <typename T>
1994 {
1995 return etl::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
1996 }
1997
1998 //*************************************************************************
2004 //*************************************************************************
2005 template <typename T>
2007 {
2008 return (rhs < lhs);
2009 }
2010
2011 //*************************************************************************
2017 //*************************************************************************
2018 template <typename T>
2020 {
2021 return !(lhs > rhs);
2022 }
2023
2024 //*************************************************************************
2030 //*************************************************************************
2031 template <typename T>
2033 {
2034 return !(lhs < rhs);
2035 }
2036}
2037
2038#include "private/minmax_pop.h"
2039
2040#endif
Template deduction guides.
Definition forward_list.h:1798
void set_pool(etl::ipool &pool)
Set the pool instance.
Definition forward_list.h:1940
etl::ipool & get_pool() const
Get the pool instance.
Definition forward_list.h:1954
forward_list_ext()
Default constructor.
Definition forward_list.h:1813
forward_list_ext(etl::ipool &node_pool)
Default constructor.
Definition forward_list.h:1821
forward_list_ext(size_t initial_size, const T &value, etl::ipool &node_pool)
Construct from size and value.
Definition forward_list.h:1839
forward_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 forward_list.h:1887
forward_list_ext(const forward_list_ext &other)
Copy constructor. Implicit pool.
Definition forward_list.h:1848
forward_list_ext(size_t initial_size, etl::ipool &node_pool)
Construct from size.
Definition forward_list.h:1830
forward_list_ext(const forward_list_ext &other, etl::ipool &node_pool)
Copy constructor. Explicit pool.
Definition forward_list.h:1857
~forward_list_ext()
Destructor.
Definition forward_list.h:1907
Definition forward_list.h:1655
~forward_list()
Destructor.
Definition forward_list.h:1733
forward_list(size_t initial_size, const T &value=T())
Construct from size and value.
Definition forward_list.h:1683
forward_list(const forward_list &other)
Copy constructor.
Definition forward_list.h:1692
forward_list()
Default constructor.
Definition forward_list.h:1674
forward_list(TIterator first, TIterator last, typename etl::enable_if<!etl::is_integral< TIterator >::value, int >::type=0)
Construct from range.
Definition forward_list.h:1713
iterator.
Definition forward_list.h:398
ETL_CONSTEXPR14 bool operator==(const etl::expected< TValue, TError > &lhs, const etl::expected< TValue2, TError2 > &rhs)
Equivalence operators.
Definition expected.h:962
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
Definition exception.h:47
iterator end()
Gets the end of the forward_list.
Definition forward_list.h:596
void resize(size_t n)
Resizes the forward_list.
Definition forward_list.h:820
reference emplace_front(const T1 &value1)
Emplaces a value to the front of the list..
Definition forward_list.h:750
size_type MAX_SIZE
The maximum size of the forward_list.
Definition forward_list.h:353
void unique(TIsEqual isEqual)
Definition forward_list.h:1182
void assign(TIterator first, TIterator last, typename etl::enable_if<!etl::is_integral< TIterator >::value, int >::type=0)
Definition forward_list.h:647
iforward_list & operator=(const iforward_list &rhs)
Assignment operator.
Definition forward_list.h:1403
iterator emplace_after(const_iterator position, const T1 &value1)
Emplaces a value to the forward_list after the specified position.
Definition forward_list.h:922
forward_list_base(bool pool_is_shared_)
The constructor that is called from derived classes.
Definition forward_list.h:268
reference emplace_front(const T1 &value1, const T2 &value2, const T3 &value3)
Emplaces a value to the front of the list..
Definition forward_list.h:780
const_iterator cbegin() const
Gets the beginning of the forward_list.
Definition forward_list.h:588
iterator before_begin()
Gets before the beginning of the forward_list.
Definition forward_list.h:572
iterator erase_after(iterator position)
Erases the value at the specified position.
Definition forward_list.h:1031
void insert_node_after(node_t &position, node_t &node)
Insert a node.
Definition forward_list.h:311
iterator erase_after(const_iterator position)
Erases the value at the specified position.
Definition forward_list.h:1050
iterator emplace_after(const_iterator position, const T1 &value1, const T2 &value2, const T3 &value3, const T4 &value4)
Emplaces a value to the forward_list after the specified position.
Definition forward_list.h:970
void unique()
Definition forward_list.h:1172
node_t start_node
The node that acts as the forward_list start.
Definition forward_list.h:351
iterator insert_after(const_iterator position, size_t n, const T &value)
Inserts 'n' copies of a value to the forward_list after the specified position.
Definition forward_list.h:986
size_type max_size() const
Gets the maximum possible size of the forward_list.
Definition forward_list.h:169
forward_list_base(etl::ipool &node_pool_, size_type max_size_, bool pool_is_shared_)
The constructor that is called from derived classes.
Definition forward_list.h:278
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 forward_list.h:795
void resize(size_t n, T value)
Definition forward_list.h:830
iforward_list(etl::ipool &node_pool, size_t max_size_, bool pool_is_shared_)
Constructor.
Definition forward_list.h:1438
size_t available() const
Definition forward_list.h:229
ETL_DECLARE_DEBUG_COUNT
Internal debugging.
Definition forward_list.h:355
size_type capacity() const
Gets the maximum possible size of the forward_list.
Definition forward_list.h:177
void clear()
Clears the forward_list.
Definition forward_list.h:620
iterator emplace_after(const_iterator position)
Emplaces a value to the forward_list after the specified position.
Definition forward_list.h:906
iterator emplace_after(const_iterator position, const T1 &value1, const T2 &value2)
Emplaces a value to the forward_list after the specified position.
Definition forward_list.h:938
node_t * get_head()
Get the head node.
Definition forward_list.h:295
const_iterator before_begin() const
Gets before the beginning of the forward_list.
Definition forward_list.h:580
etl::ipool * get_node_pool()
Get the node pool instance.
Definition forward_list.h:346
void reverse()
Reverses the forward_list.
Definition forward_list.h:238
const_iterator cend() const
Gets the end of the forward_list.
Definition forward_list.h:612
const_iterator begin() const
Gets the beginning of the forward_list.
Definition forward_list.h:564
void join(node_t *left, node_t *right)
Join two nodes.
Definition forward_list.h:329
size_t size_type
The type used for determining the size of forward_list.
Definition forward_list.h:156
reference front()
Gets a reference to the first element.
Definition forward_list.h:628
void move_after(const_iterator first_before, const_iterator last, const_iterator to_before)
Definition forward_list.h:1133
bool pool_is_shared
If true then the pool is shared between lists.
Definition forward_list.h:354
void push_front(const T &value)
Pushes a value to the front of the forward_list.
Definition forward_list.h:695
iterator insert_after(const_iterator position, const T &value)
Inserts a value to the forward_list after the specified position.
Definition forward_list.h:876
reference emplace_front(const T1 &value1, const T2 &value2)
Emplaces a value to the front of the list..
Definition forward_list.h:765
iterator emplace_after(const_iterator position, const T1 &value1, const T2 &value2, const T3 &value3)
Emplaces a value to the forward_list after the specified position.
Definition forward_list.h:954
void sort()
Definition forward_list.h:1213
void sort(TCompare compare)
Definition forward_list.h:1244
void initialise()
Initialise the forward_list.
Definition forward_list.h:1446
etl::ipool * p_node_pool
The pool of data nodes used in the list.
Definition forward_list.h:352
const_reference front() const
Gets a const reference to the first element.
Definition forward_list.h:636
void remove_if(TPredicate predicate)
Removes according to a predicate.
Definition forward_list.h:1381
bool has_shared_pool() const
true if the list has a shared pool.
Definition forward_list.h:161
bool full() const
Checks to see if the forward_list is full.
Definition forward_list.h:219
void pop_front()
Removes a value from the front of the forward_list.
Definition forward_list.h:810
iterator insert_after(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 forward_list after the specified position.
Definition forward_list.h:1009
~forward_list_base()
Destructor.
Definition forward_list.h:288
iterator erase_after(const_iterator first, const_iterator last)
Erases a range of elements.
Definition forward_list.h:1069
bool empty() const
Checks to see if the forward_list is empty.
Definition forward_list.h:211
void assign(size_t n, const T &value)
Assigns 'n' copies of a value to the forward_list.
Definition forward_list.h:674
void set_node_pool(etl::ipool &node_pool_)
Set the node pool instance.
Definition forward_list.h:337
void move_after(const_iterator from_before, const_iterator to_before)
Definition forward_list.h:1109
~iforward_list()
Destructor.
Definition forward_list.h:1633
reference emplace_front()
Emplaces a value to the front of the list..
Definition forward_list.h:735
size_type size() const
Gets the size of the forward_list.
Definition forward_list.h:185
data_node_t & allocate_data_node(const_reference value)
Allocate a data_node_t.
Definition forward_list.h:1477
const_iterator end() const
Gets the end of the forward_list.
Definition forward_list.h:604
iterator begin()
Gets the beginning of the forward_list.
Definition forward_list.h:556
iforward_list(bool pool_is_shared_)
Constructor.
Definition forward_list.h:1430
const node_t * get_head() const
Get the head node.
Definition forward_list.h:303
bool is_trivial_list() const
Is the forward_list a trivial length?
Definition forward_list.h:321
Definition forward_list.h:138
Definition forward_list.h:96
Definition forward_list.h:68
Definition forward_list.h:82
Definition forward_list.h:110
Definition forward_list.h:364
Definition forward_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
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 node element in the forward_list.
Definition forward_list.h:145
The data node element in the forward_list.
Definition forward_list.h:384
iterator
Definition iterator.h:399
Definition functional.h:170