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