Embedded Template Library  1.0
forward_list.h
Go to the documentation of this file.
1 
3 /******************************************************************************
4 The MIT License(MIT)
5 
6 Embedded Template Library.
7 https://github.com/ETLCPP/etl
8 https://www.etlcpp.com
9 
10 Copyright(c) 2014 jwellbelove
11 
12 Permission is hereby granted, free of charge, to any person obtaining a copy
13 of this software and associated documentation files(the "Software"), to deal
14 in the Software without restriction, including without limitation the rights
15 to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
16 copies of the Software, and to permit persons to whom the Software is
17 furnished to do so, subject to the following conditions :
18 
19 The above copyright notice and this permission notice shall be included in all
20 copies or substantial portions of the Software.
21 
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
25 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28 SOFTWARE.
29 ******************************************************************************/
30 
31 #ifndef ETL_FORWARD_LIST_INCLUDED
32 #define ETL_FORWARD_LIST_INCLUDED
33 
34 #include <stddef.h>
35 
36 #include "platform.h"
37 #include "algorithm.h"
38 #include "iterator.h"
39 #include "functional.h"
40 #include "utility.h"
41 #include "pool.h"
42 #include "container.h"
43 #include "exception.h"
44 #include "error_handler.h"
45 #include "debug_count.h"
46 #include "nullptr.h"
47 #include "type_traits.h"
48 #include "memory.h"
49 #include "iterator.h"
50 #include "static_assert.h"
51 #include "placement_new.h"
52 
53 #if ETL_CPP11_SUPPORTED && ETL_NOT_USING_STLPORT && ETL_USING_STL
54  #include <initializer_list>
55 #endif
56 
57 #include "private/minmax_push.h"
58 
59 #undef ETL_FILE
60 #define ETL_FILE "6"
61 
62 //*****************************************************************************
66 //*****************************************************************************
67 
68 namespace etl
69 {
70  //***************************************************************************
73  //***************************************************************************
75  {
76  public:
77 
78  forward_list_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
79  : exception(reason_, file_name_, line_number_)
80  {
81  }
82  };
83 
84  //***************************************************************************
87  //***************************************************************************
89  {
90  public:
91 
92  forward_list_full(string_type file_name_, numeric_type line_number_)
93  : etl::forward_list_exception(ETL_ERROR_TEXT("forward_list:full", ETL_FILE"A"), file_name_, line_number_)
94  {
95  }
96  };
97 
98  //***************************************************************************
101  //***************************************************************************
103  {
104  public:
105 
106  forward_list_empty(string_type file_name_, numeric_type line_number_)
107  : etl::forward_list_exception(ETL_ERROR_TEXT("forward_list:empty", ETL_FILE"B"), file_name_, line_number_)
108  {
109  }
110  };
111 
112  //***************************************************************************
115  //***************************************************************************
117  {
118  public:
119 
120  forward_list_iterator(string_type file_name_, numeric_type line_number_)
121  : etl::forward_list_exception(ETL_ERROR_TEXT("forward_list:iterator", ETL_FILE"C"), file_name_, line_number_)
122  {
123  }
124  };
125 
126  //***************************************************************************
129  //***************************************************************************
131  {
132  public:
133 
134  forward_list_no_pool(string_type file_name_, numeric_type line_number_)
135  : forward_list_exception(ETL_ERROR_TEXT("list:no pool", ETL_FILE"D"), file_name_, line_number_)
136  {
137  }
138  };
139 
140  //***************************************************************************
143  //***************************************************************************
145  {
146  protected:
147 
148  //*************************************************************************
150  //*************************************************************************
151  struct node_t
152  {
153  node_t()
154  : next(ETL_NULLPTR)
155  {
156  }
157 
158  node_t* next;
159  };
160 
161  public:
162 
163  typedef size_t size_type;
164 
165  //*************************************************************************
167  //*************************************************************************
168  bool has_shared_pool() const
169  {
170  return pool_is_shared;
171  }
172 
173  //*************************************************************************
175  //*************************************************************************
177  {
178  return MAX_SIZE;
179  }
180 
181  //*************************************************************************
183  //*************************************************************************
185  {
186  return MAX_SIZE;
187  }
188 
189  //*************************************************************************
191  //*************************************************************************
192  size_type size() const
193  {
194  if (has_shared_pool())
195  {
196  // We have to count what we actually own.
197  size_type count = 0;
198 
199  node_t* p_node = start_node.next;
200 
201  while (p_node != ETL_NULLPTR)
202  {
203  ++count;
204  p_node = p_node->next;
205  }
206 
207  return count;
208  }
209  else
210  {
211  return p_node_pool->size();
212  }
213  }
214 
215  //*************************************************************************
217  //*************************************************************************
218  bool empty() const
219  {
220  return (start_node.next == ETL_NULLPTR);
221  }
222 
223  //*************************************************************************
225  //*************************************************************************
226  bool full() const
227  {
228  ETL_ASSERT(p_node_pool != ETL_NULLPTR, ETL_ERROR(forward_list_no_pool));
229  return p_node_pool->full();
230  }
231 
232  //*************************************************************************
235  //*************************************************************************
236  size_t available() const
237  {
238  ETL_ASSERT(p_node_pool != ETL_NULLPTR, ETL_ERROR(forward_list_no_pool));
239  return p_node_pool->available();
240  }
241 
242  //*************************************************************************
244  //*************************************************************************
245  void reverse()
246  {
247  if (is_trivial_list())
248  {
249  return;
250  }
251 
252  node_t* p_last = &start_node;
253  node_t* p_current = p_last->next;
254  node_t* p_next = p_current->next;
255 
256  p_current->next = ETL_NULLPTR;
257 
258  while (p_next != ETL_NULLPTR)
259  {
260  p_last = p_current;
261  p_current = p_next;
262  p_next = p_current->next;
263 
264  p_current->next = p_last;
265  }
266 
267  join(&start_node, p_current);
268  }
269 
270  protected:
271 
272  //*************************************************************************
274  //*************************************************************************
275  forward_list_base(bool pool_is_shared_)
276  : p_node_pool(ETL_NULLPTR),
277  MAX_SIZE(0),
278  pool_is_shared(pool_is_shared_)
279  {
280  }
281 
282  //*************************************************************************
284  //*************************************************************************
285  forward_list_base(etl::ipool& node_pool_, size_type max_size_, bool pool_is_shared_)
286  : p_node_pool(&node_pool_),
287  MAX_SIZE(max_size_),
288  pool_is_shared(pool_is_shared_)
289  {
290  }
291 
292  //*************************************************************************
294  //*************************************************************************
296  {
297  }
298 
299  //*************************************************************************
301  //*************************************************************************
303  {
304  return start_node.next;
305  }
306 
307  //*************************************************************************
309  //*************************************************************************
310  const node_t* get_head() const
311  {
312  return start_node.next;
313  }
314 
315  //*************************************************************************
317  //*************************************************************************
318  inline void insert_node_after(node_t& position, node_t& node)
319  {
320  // Connect to the forward_list.
321  join(&node, position.next);
322  join(&position, &node);
323  }
324 
325  //*************************************************************************
327  //*************************************************************************
328  bool is_trivial_list() const
329  {
330  return (size() < 2);
331  }
332 
333  //*************************************************************************
335  //*************************************************************************
336  void join(node_t* left, node_t* right)
337  {
338  left->next = right;
339  }
340 
341  //*************************************************************************
343  //*************************************************************************
344  void set_node_pool(etl::ipool& node_pool_)
345  {
346  p_node_pool = &node_pool_;
348  }
349 
350  //*************************************************************************
352  //*************************************************************************
354  {
355  return p_node_pool;
356  }
357 
362  ETL_DECLARE_DEBUG_COUNT
363  };
364 
365  //***************************************************************************
368  //***************************************************************************
369  template <typename T>
371  {
372  public:
373 
374  typedef T value_type;
375  typedef T* pointer;
376  typedef const T* const_pointer;
377  typedef T& reference;
378  typedef const T& const_reference;
379  typedef size_t size_type;
380 
381 #if ETL_CPP11_SUPPORTED
382  typedef T&& rvalue_reference;
383 #endif
384 
385  protected:
386 
387  //*************************************************************************
389  //*************************************************************************
390  struct data_node_t : public node_t
391  {
392  explicit data_node_t(const T& value_)
393  : value(value_)
394  {}
395 
396  T value;
397  };
398 
399  public:
400 
401  //*************************************************************************
403  //*************************************************************************
404  class iterator : public etl::iterator<ETL_OR_STD::forward_iterator_tag, T>
405  {
406  public:
407 
408  friend class iforward_list;
409  friend class const_iterator;
410 
411  iterator()
412  : p_node(ETL_NULLPTR)
413  {
414  }
415 
416  iterator(node_t* node)
417  : p_node(node)
418  {
419  }
420 
421  iterator(const iterator& other)
422  : p_node(other.p_node)
423  {
424  }
425 
426  iterator& operator ++()
427  {
428  p_node = p_node->next;
429  return *this;
430  }
431 
432  iterator operator ++(int)
433  {
434  iterator temp(*this);
435  p_node = p_node->next;
436  return temp;
437  }
438 
439  iterator operator =(const iterator& other)
440  {
441  p_node = other.p_node;
442  return *this;
443  }
444 
445  reference operator *()
446  {
447  return iforward_list::data_cast(p_node)->value;
448  }
449 
450  const_reference operator *() const
451  {
452  return iforward_list::data_cast(p_node)->value;
453  }
454 
455  pointer operator &()
456  {
457  return &(iforward_list::data_cast(p_node)->value);
458  }
459 
460  const_pointer operator &() const
461  {
462  return &(iforward_list::data_cast(p_node)->value);
463  }
464 
465  pointer operator ->()
466  {
467  return &(iforward_list::data_cast(p_node)->value);
468  }
469 
470  const_pointer operator ->() const
471  {
472  return &(iforward_list::data_cast(p_node)->value);
473  }
474 
475  friend bool operator == (const iterator& lhs, const iterator& rhs)
476  {
477  return lhs.p_node == rhs.p_node;
478  }
479 
480  friend bool operator != (const iterator& lhs, const iterator& rhs)
481  {
482  return !(lhs == rhs);
483  }
484 
485  private:
486 
487  node_t* p_node;
488  };
489 
490  //*************************************************************************
492  //*************************************************************************
493  class const_iterator : public etl::iterator<ETL_OR_STD::forward_iterator_tag, const T>
494  {
495  public:
496 
497  friend class iforward_list;
498 
500  : p_node(ETL_NULLPTR)
501  {
502  }
503 
504  const_iterator(node_t* node)
505  : p_node(node)
506  {
507  }
508 
509  const_iterator(const node_t* node)
510  : p_node(node)
511  {
512  }
513 
514  const_iterator(const typename iforward_list::iterator& other)
515  : p_node(other.p_node)
516  {
517  }
518 
519  const_iterator(const const_iterator& other)
520  : p_node(other.p_node)
521  {
522  }
523 
524  const_iterator& operator ++()
525  {
526  p_node = p_node->next;
527  return *this;
528  }
529 
530  const_iterator operator ++(int)
531  {
532  const_iterator temp(*this);
533  p_node = p_node->next;
534  return temp;
535  }
536 
537  const_iterator& operator =(const const_iterator& other)
538  {
539  p_node = other.p_node;
540  return *this;
541  }
542 
543  const_reference operator *() const
544  {
545  return iforward_list::data_cast(p_node)->value;
546  }
547 
548  const_pointer operator &() const
549  {
550  return &(iforward_list::data_cast(p_node)->value);
551  }
552 
553  const_pointer operator ->() const
554  {
555  return &(iforward_list::data_cast(p_node)->value);
556  }
557 
558  friend bool operator == (const const_iterator& lhs, const const_iterator& rhs)
559  {
560  return lhs.p_node == rhs.p_node;
561  }
562 
563  friend bool operator != (const const_iterator& lhs, const const_iterator& rhs)
564  {
565  return !(lhs == rhs);
566  }
567 
568  private:
569 
570  const node_t* p_node;
571  };
572 
573  typedef typename etl::iterator_traits<iterator>::difference_type difference_type;
574 
575  //*************************************************************************
577  //*************************************************************************
579  {
580  return iterator(get_head());
581  }
582 
583  //*************************************************************************
585  //*************************************************************************
587  {
588  return const_iterator(get_head());
589  }
590 
591  //*************************************************************************
593  //*************************************************************************
595  {
596  return iterator(&start_node);
597  }
598 
599  //*************************************************************************
601  //*************************************************************************
603  {
604  return const_iterator(&start_node);
605  }
606 
607  //*************************************************************************
609  //*************************************************************************
611  {
612  return const_iterator(get_head());
613  }
614 
615  //*************************************************************************
617  //*************************************************************************
619  {
620  return iterator();
621  }
622 
623  //*************************************************************************
625  //*************************************************************************
627  {
628  return const_iterator();
629  }
630 
631  //*************************************************************************
633  //*************************************************************************
635  {
636  return const_iterator();
637  }
638 
639  //*************************************************************************
641  //*************************************************************************
642  void clear()
643  {
644  initialise();
645  }
646 
647  //*************************************************************************
649  //*************************************************************************
650  reference front()
651  {
652  return data_cast(*get_head()).value;
653  }
654 
655  //*************************************************************************
657  //*************************************************************************
658  const_reference front() const
659  {
660  return data_cast(*get_head()).value;
661  }
662 
663  //*************************************************************************
667  //*************************************************************************
668  template <typename TIterator>
669  void assign(TIterator first, TIterator last)
670  {
671 #if defined(ETL_DEBUG)
672  difference_type d = etl::distance(first, last);
673  ETL_ASSERT(d >= 0, ETL_ERROR(forward_list_iterator));
674 #endif
675 
676  initialise();
677 
678  node_t* p_last_node = &start_node;
679 
680  // Add all of the elements.
681  while (first != last)
682  {
683  ETL_ASSERT(!full(), ETL_ERROR(forward_list_full));
684 
685  data_node_t& data_node = allocate_data_node(*first++);
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 assign(size_t n, const T& value)
696  {
697  ETL_ASSERT(n <= MAX_SIZE, ETL_ERROR(forward_list_full));
698 
699  initialise();
700 
701  node_t* p_last_node = &start_node;
702 
703  // Add all of the elements.
704  while (size() < n)
705  {
706  data_node_t& data_node = allocate_data_node(value);
707  join(p_last_node, &data_node);
708  data_node.next = ETL_NULLPTR;
709  p_last_node = &data_node;
710  }
711  }
712 
713  //*************************************************************************
715  //*************************************************************************
716  void push_front(const T& value)
717  {
718 #if defined(ETL_CHECK_PUSH_POP)
719  ETL_ASSERT(!full(), ETL_ERROR(forward_list_full));
720 #endif
721 
722  data_node_t& data_node = allocate_data_node(value);
723  insert_node_after(start_node, data_node);
724  }
725 
726 #if ETL_CPP11_SUPPORTED
727  //*************************************************************************
729  //*************************************************************************
730  void push_front(rvalue_reference value)
731  {
732 #if defined(ETL_CHECK_PUSH_POP)
733  ETL_ASSERT(!full(), ETL_ERROR(forward_list_full));
734 #endif
735 
736  data_node_t& data_node = allocate_data_node(etl::move(value));
737  insert_node_after(start_node, data_node);
738  }
739 #endif
740 
741 #if ETL_CPP11_SUPPORTED && ETL_NOT_USING_STLPORT
742  //*************************************************************************
744  //*************************************************************************
745  template <typename ... Args>
746  void emplace_front(Args && ... args)
747  {
748 #if defined(ETL_CHECK_PUSH_POP)
749  ETL_ASSERT(!full(), ETL_ERROR(forward_list_full));
750 #endif
751  data_node_t* p_data_node = create_data_node();
752  ::new (&(p_data_node->value)) T(etl::forward<Args>(args)...);
753  ETL_INCREMENT_DEBUG_COUNT
754  insert_node_after(start_node, *p_data_node);
755  }
756 #else
757  //*************************************************************************
759  //*************************************************************************
760  template <typename T1>
761  void emplace_front(const T1& value1)
762  {
763 #if defined(ETL_CHECK_PUSH_POP)
764  ETL_ASSERT(!full(), ETL_ERROR(forward_list_full));
765 #endif
766  data_node_t* p_data_node = create_data_node();
767  ::new (&(p_data_node->value)) T(value1);
768  ETL_INCREMENT_DEBUG_COUNT
769  insert_node_after(start_node, *p_data_node);
770  }
771 
772  //*************************************************************************
774  //*************************************************************************
775  template <typename T1, typename T2>
776  void emplace_front(const T1& value1, const T2& value2)
777  {
778 #if defined(ETL_CHECK_PUSH_POP)
779  ETL_ASSERT(!full(), ETL_ERROR(forward_list_full));
780 #endif
781  data_node_t* p_data_node = create_data_node();
782  ::new (&(p_data_node->value)) T(value1, value2);
783  ETL_INCREMENT_DEBUG_COUNT
784  insert_node_after(start_node, *p_data_node);
785  }
786 
787  //*************************************************************************
789  //*************************************************************************
790  template <typename T1, typename T2, typename T3>
791  void emplace_front(const T1& value1, const T2& value2, const T3& value3)
792  {
793 #if defined(ETL_CHECK_PUSH_POP)
794  ETL_ASSERT(!full(), ETL_ERROR(forward_list_full));
795 #endif
796  data_node_t* p_data_node = create_data_node();
797  ::new (&(p_data_node->value)) T(value1, value2, value3);
798  ETL_INCREMENT_DEBUG_COUNT
799  insert_node_after(start_node, *p_data_node);
800  }
801 
802  //*************************************************************************
804  //*************************************************************************
805  template <typename T1, typename T2, typename T3, typename T4>
806  void emplace_front(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
807  {
808 #if defined(ETL_CHECK_PUSH_POP)
809  ETL_ASSERT(!full(), ETL_ERROR(forward_list_full));
810 #endif
811  data_node_t* p_data_node = create_data_node();
812  ::new (&(p_data_node->value)) T(value1, value2, value3, value4);
813  ETL_INCREMENT_DEBUG_COUNT
814  insert_node_after(start_node, *p_data_node);
815  }
816 #endif // ETL_CPP11_SUPPORTED && ETL_NOT_USING_STLPORT
817 
818  //*************************************************************************
820  //*************************************************************************
821  void pop_front()
822  {
823 #if defined(ETL_CHECK_PUSH_POP)
824  ETL_ASSERT(!empty(), ETL_ERROR(forward_list_empty));
825 #endif
826  remove_node_after(start_node);
827  }
828 
829  //*************************************************************************
831  //*************************************************************************
832  void resize(size_t n)
833  {
834  resize(n, T());
835  }
836 
837  //*************************************************************************
841  //*************************************************************************
842  void resize(size_t n, T value)
843  {
844  ETL_ASSERT(n <= MAX_SIZE, ETL_ERROR(forward_list_full));
845 
846  if (n == 0U)
847  {
848  clear();
849  }
850  else if (empty())
851  {
852  assign(n, value);
853  }
854  else
855  {
856  size_t i = 0;
857  iterator i_node = begin();
858  iterator i_last_node;
859 
860  // Find where we're currently at.
861  while ((i < n) && (i_node != end()))
862  {
863  ++i;
864  i_last_node = i_node;
865  ++i_node;
866  }
867 
868  if (i_node != end())
869  {
870  // Reduce.
871  erase_after(i_last_node, end());
872  }
873  else if (i_node == end())
874  {
875  // Increase.
876  while (i < n)
877  {
878  i_last_node = insert_after(i_last_node, value);
879  ++i;
880  }
881  }
882  }
883  }
884 
885  //*************************************************************************
887  //*************************************************************************
888  iterator insert_after(iterator position, const T& value)
889  {
890  ETL_ASSERT(!full(), ETL_ERROR(forward_list_full));
891 
892  data_node_t& data_node = allocate_data_node(value);
893  insert_node_after(*position.p_node, data_node);
894 
895  return iterator(&data_node);
896  }
897 
898 #if ETL_CPP11_SUPPORTED && ETL_NOT_USING_STLPORT
899  //*************************************************************************
901  //*************************************************************************
902  template <typename ... Args>
903  iterator emplace_after(iterator position, Args && ... args)
904  {
905  ETL_ASSERT(!full(), ETL_ERROR(forward_list_full));
906 
907  data_node_t* p_data_node = create_data_node();
908  ::new (&(p_data_node->value)) T(etl::forward<Args>(args)...);
909  ETL_INCREMENT_DEBUG_COUNT
910  insert_node_after(*position.p_node, *p_data_node);
911 
912  return iterator(p_data_node);
913  }
914 #else
915  //*************************************************************************
917  //*************************************************************************
918  template <typename T1>
919  iterator emplace_after(iterator position, const T1& value1)
920  {
921  ETL_ASSERT(!full(), ETL_ERROR(forward_list_full));
922 
923  data_node_t* p_data_node = create_data_node();
924  ::new (&(p_data_node->value)) T(value1);
925  ETL_INCREMENT_DEBUG_COUNT
926  insert_node_after(*position.p_node, *p_data_node);
927 
928  return iterator(p_data_node);
929  }
930 
931  //*************************************************************************
933  //*************************************************************************
934  template <typename T1, typename T2>
935  iterator emplace_after(iterator position, const T1& value1, const T2& value2)
936  {
937  ETL_ASSERT(!full(), ETL_ERROR(forward_list_full));
938 
939  data_node_t* p_data_node = create_data_node();
940  ::new (&(p_data_node->value)) T(value1, value2);
941  ETL_INCREMENT_DEBUG_COUNT
942  insert_node_after(*position.p_node, *p_data_node);
943 
944  return iterator(p_data_node);
945  }
946 
947  //*************************************************************************
949  //*************************************************************************
950  template <typename T1, typename T2, typename T3>
951  iterator emplace_after(iterator position, const T1& value1, const T2& value2, const T3& value3)
952  {
953  ETL_ASSERT(!full(), ETL_ERROR(forward_list_full));
954 
955  data_node_t* p_data_node = create_data_node();
956  ::new (&(p_data_node->value)) T(value1, value2, value3);
957  ETL_INCREMENT_DEBUG_COUNT
958  insert_node_after(*position.p_node, *p_data_node);
959 
960  return iterator(p_data_node);
961  }
962 
963  //*************************************************************************
965  //*************************************************************************
966  template <typename T1, typename T2, typename T3, typename T4>
967  iterator emplace_after(iterator position, const T1& value1, const T2& value2, const T3& value3, const T4& value4)
968  {
969  ETL_ASSERT(!full(), ETL_ERROR(forward_list_full));
970 
971  data_node_t* p_data_node = create_data_node();
972  ::new (&(p_data_node->value)) T(value1, value2, value3, value4);
973  ETL_INCREMENT_DEBUG_COUNT
974  insert_node_after(*position.p_node, *p_data_node);
975 
976  return iterator(p_data_node);
977  }
978 #endif // ETL_CPP11_SUPPORTED && ETL_NOT_USING_STLPORT
979 
980  //*************************************************************************
982  //*************************************************************************
983  void insert_after(iterator position, size_t n, const T& value)
984  {
985  ETL_ASSERT(!full(), ETL_ERROR(forward_list_full));
986 
987  for (size_t i = 0; !full() && (i < n); ++i)
988  {
989  // Set up the next free node.
990  data_node_t& data_node = allocate_data_node(value);
991  insert_node_after(*position.p_node, data_node);
992  }
993  }
994 
995  //*************************************************************************
997  //*************************************************************************
998  template <typename TIterator>
999  void insert_after(iterator position, TIterator first, TIterator last)
1000  {
1001 #if defined(ETL_DEBUG)
1002  difference_type d = etl::distance(first, last);
1003  ETL_ASSERT((d + size()) <= MAX_SIZE, ETL_ERROR(forward_list_full));
1004 #endif
1005 
1006  while (first != last)
1007  {
1008  // Set up the next free node.
1009  data_node_t& data_node = allocate_data_node(*first++);
1010  insert_node_after(*position.p_node, data_node);
1011  ++position;
1012  }
1013  }
1014 
1015  //*************************************************************************
1017  //*************************************************************************
1019  {
1020  iterator next(position);
1021  if (next != end())
1022  {
1023  ++next;
1024  if (next != end())
1025  {
1026  ++next;
1027  remove_node_after(*position.p_node);
1028  }
1029  }
1030 
1031  return next;
1032  }
1033 
1034  //*************************************************************************
1036  //*************************************************************************
1038  {
1039  if (first != end() && (first != last))
1040  {
1041  node_t* p_first = first.p_node;
1042  node_t* p_last = last.p_node;
1043  node_t* p_next = p_first->next;
1044 
1045  // Join the ends.
1046  join(p_first, p_last);
1047 
1048  p_first = p_next;
1049 
1050  // Erase the ones in between.
1051  while (p_first != p_last)
1052  {
1053  p_next = p_first->next; // Remember the next node.
1054  destroy_data_node(static_cast<data_node_t&>(*p_first)); // Destroy the pool object.
1055  p_first = p_next; // Move to the next node.
1056  }
1057 
1058  if (p_next == ETL_NULLPTR)
1059  {
1060  return end();
1061  }
1062  else
1063  {
1064  return iterator(p_last);
1065  }
1066  }
1067  else
1068  {
1069  return end();
1070  }
1071  }
1072 
1073  //*************************************************************************
1076  //*************************************************************************
1077  void move_after(const_iterator from_before, const_iterator to_before)
1078  {
1079  if (from_before == to_before) // Can't move to after yourself!
1080  {
1081  return;
1082  }
1083 
1084  node_t* p_from_before = const_cast<node_t*>(from_before.p_node); // We're not changing the value, just it's position.
1085  node_t* p_to_before = const_cast<node_t*>(to_before.p_node); // We're not changing the value, just it's position.
1086 
1087  node_t* p_from = p_from_before->next;
1088 
1089  // Disconnect from the list.
1090  join(p_from_before, p_from->next);
1091 
1092  // Attach it to the new position.
1093  join(p_from, p_to_before->next);
1094  join(p_to_before, p_from);
1095  }
1096 
1097  //*************************************************************************
1100  //*************************************************************************
1101  void move_after(const_iterator first_before, const_iterator last, const_iterator to_before)
1102  {
1103  if ((first_before == to_before) || (last == to_before))
1104  {
1105  return; // Can't more to before yourself!
1106  }
1107 
1108 #if defined(ETL_DEBUG)
1109  // Check that we are not doing an illegal move!
1110  for (const_iterator item = first_before; item != last; ++item)
1111  {
1112  ETL_ASSERT(item != to_before, ETL_ERROR(forward_list_iterator));
1113  }
1114 #endif
1115 
1116  node_t* p_first_before = const_cast<node_t*>(first_before.p_node); // We're not changing the value, just it's position.
1117  node_t* p_last = const_cast<node_t*>(last.p_node); // We're not changing the value, just it's position.
1118  node_t* p_to_before = const_cast<node_t*>(to_before.p_node); // We're not changing the value, just it's position.
1119  node_t* p_first = p_first_before->next;
1120  node_t* p_final = p_first_before;
1121 
1122  // Find the last node that will be moved.
1123  while (p_final->next != p_last)
1124  {
1125  p_final = p_final->next;
1126  }
1127 
1128  // Disconnect from the list.
1129  join(p_first_before, p_final->next);
1130 
1131  // Attach it to the new position.
1132  join(p_final, p_to_before->next);
1133  join(p_to_before, p_first);
1134  }
1135 
1136  //*************************************************************************
1139  //*************************************************************************
1140  void unique()
1141  {
1143  }
1144 
1145  //*************************************************************************
1148  //*************************************************************************
1149  template <typename TIsEqual>
1150  void unique(TIsEqual isEqual)
1151  {
1152  if (empty())
1153  {
1154  return;
1155  }
1156 
1157  node_t* last = get_head();
1158  node_t* current = last->next;
1159 
1160  while (current != ETL_NULLPTR)
1161  {
1162  // Is this value the same as the last?
1163  if (isEqual(data_cast(current)->value, data_cast(last)->value))
1164  {
1165  remove_node_after(*last);
1166  }
1167  else
1168  {
1169  // Move on one.
1170  last = current;
1171  }
1172 
1173  current = last->next;
1174  }
1175  }
1176 
1177  //*************************************************************************
1180  //*************************************************************************
1181  void sort()
1182  {
1183  sort(etl::less<T>());
1184  }
1185 
1186  //*************************************************************************
1210  //*************************************************************************
1211  template <typename TCompare>
1212  void sort(TCompare compare)
1213  {
1214  iterator p_left;
1215  iterator p_right;
1216  iterator p_node;
1217  iterator p_head;
1218  iterator p_tail;
1219  int list_size = 1;
1220  int number_of_merges;
1221  int left_size;
1222  int right_size;
1223 
1224  if (is_trivial_list())
1225  {
1226  return;
1227  }
1228 
1229  while (true)
1230  {
1231  p_left = begin();
1232  p_head = before_begin();
1233  p_tail = before_begin();
1234 
1235  number_of_merges = 0; // Count the number of merges we do in this pass.
1236 
1237  while (p_left != end())
1238  {
1239  ++number_of_merges; // There exists a merge to be done.
1240  p_right = p_left;
1241  left_size = 0;
1242 
1243  // Step 'list_size' places along from left
1244  for (int i = 0; i < list_size; ++i)
1245  {
1246  ++left_size;
1247 
1248  ++p_right;
1249 
1250  if (p_right == end())
1251  {
1252  break;
1253  }
1254  }
1255 
1256  // If right hasn't fallen off end, we have two lists to merge.
1257  right_size = list_size;
1258 
1259  // Now we have two lists. Merge them.
1260  while (left_size > 0 || (right_size > 0 && p_right != end()))
1261  {
1262  // Decide whether the next node of merge comes from left or right.
1263  if (left_size == 0)
1264  {
1265  // Left is empty. The node must come from right.
1266  p_node = p_right;
1267  ++p_right;
1268  --right_size;
1269  }
1270  else if (right_size == 0 || p_right == end())
1271  {
1272  // Right is empty. The node must come from left.
1273  p_node = p_left;
1274  ++p_left;
1275  --left_size;
1276  }
1277  else if (!compare(*p_right, *p_left))
1278  {
1279  // First node of left is lower or same. The node must come from left.
1280  p_node = p_left;
1281  ++p_left;
1282  --left_size;
1283  }
1284  else
1285  {
1286  // First node of right is lower. The node must come from right.
1287  p_node = p_right;
1288  ++p_right;
1289  --right_size;
1290  }
1291 
1292  // Add the next node to the merged head.
1293  if (p_head == before_begin())
1294  {
1295  join(p_head.p_node, p_node.p_node);
1296  p_head = p_node;
1297  p_tail = p_node;
1298  }
1299  else
1300  {
1301  join(p_tail.p_node, p_node.p_node);
1302  p_tail = p_node;
1303  }
1304 
1305  p_tail.p_node->next = ETL_NULLPTR;
1306  }
1307 
1308  // Now left has stepped `list_size' places along, and right has too.
1309  p_left = p_right;
1310  }
1311 
1312  // If we have done only one merge, we're finished.
1313  if (number_of_merges <= 1) // Allow for number_of_merges == 0, the empty head case
1314  {
1315  return;
1316  }
1317 
1318  // Otherwise repeat, merging lists twice the size
1319  list_size *= 2;
1320  }
1321  }
1322 
1323  //*************************************************************************
1324  // Removes the values specified.
1325  //*************************************************************************
1326  void remove(const T& value)
1327  {
1328  iterator i_item = begin();
1329  iterator i_last_item = before_begin();
1330 
1331  while (i_item != end())
1332  {
1333  if (*i_item == value)
1334  {
1335  i_item = erase_after(i_last_item);
1336  }
1337  else
1338  {
1339  ++i_item;
1340  ++i_last_item;
1341  }
1342  }
1343  }
1344 
1345  //*************************************************************************
1347  //*************************************************************************
1348  template <typename TPredicate>
1349  void remove_if(TPredicate predicate)
1350  {
1351  iterator i_item = begin();
1352  iterator i_last_item = before_begin();
1353 
1354  while (i_item != end())
1355  {
1356  if (predicate(*i_item))
1357  {
1358  i_item = erase_after(i_last_item);
1359  }
1360  else
1361  {
1362  ++i_item;
1363  ++i_last_item;
1364  }
1365  }
1366  }
1367 
1368  //*************************************************************************
1370  //*************************************************************************
1372  {
1373  if (&rhs != this)
1374  {
1375  assign(rhs.cbegin(), rhs.cend());
1376  }
1377 
1378  return *this;
1379  }
1380 
1381 #if ETL_CPP11_SUPPORTED
1382  //*************************************************************************
1384  //*************************************************************************
1386  {
1387  move_container(etl::move(rhs));
1388 
1389  return *this;
1390  }
1391 #endif
1392 
1393  protected:
1394 
1395  //*************************************************************************
1397  //*************************************************************************
1398  iforward_list(bool pool_is_shared_)
1399  : forward_list_base(pool_is_shared_)
1400  {
1401  }
1402 
1403  //*************************************************************************
1405  //*************************************************************************
1406  iforward_list(etl::ipool& node_pool, size_t max_size_, bool pool_is_shared_)
1407  : forward_list_base(node_pool, max_size_, pool_is_shared_)
1408  {
1409  }
1410 
1411  //*************************************************************************
1413  //*************************************************************************
1414  void initialise()
1415  {
1416  if (!empty())
1417  {
1419  {
1420  ETL_ASSERT(p_node_pool != ETL_NULLPTR, ETL_ERROR(forward_list_no_pool));
1422  ETL_RESET_DEBUG_COUNT
1423  }
1424  else
1425  {
1426  node_t* p_first = start_node.next;
1427  node_t* p_next;
1428 
1429  // Erase the ones in between.
1430  while (p_first != ETL_NULLPTR)
1431  {
1432  p_next = p_first->next; // Remember the next node.
1433  destroy_data_node(static_cast<data_node_t&>(*p_first)); // Destroy the pool object.
1434  p_first = p_next; // Move to the next node.
1435  }
1436  }
1437  }
1438 
1439  start_node.next = ETL_NULLPTR;
1440  }
1441 
1442  //*************************************************************************
1444  //*************************************************************************
1445  data_node_t& allocate_data_node(const_reference value)
1446  {
1447  data_node_t* p_node = create_data_node();
1448  ::new (&(p_node->value)) T(value);
1449  ETL_INCREMENT_DEBUG_COUNT
1450 
1451  return *p_node;
1452  }
1453 
1454 #if ETL_CPP11_SUPPORTED
1455  //*************************************************************************
1457  //*************************************************************************
1458  data_node_t& allocate_data_node(rvalue_reference value)
1459  {
1460  data_node_t* p_node = create_data_node();
1461  ::new (&(p_node->value)) T(etl::move(value));
1462  ETL_INCREMENT_DEBUG_COUNT
1463 
1464  return *p_node;
1465  }
1466 #endif
1467 
1468 #if ETL_CPP11_SUPPORTED
1469  //*************************************************************************
1471  //*************************************************************************
1472  void move_container(iforward_list&& rhs)
1473  {
1474  if (&rhs != this)
1475  {
1476  this->initialise();
1477 
1478  if (!rhs.empty())
1479  {
1480  node_t* p_last_node = &this->start_node;
1481  node_t* p_rhs_node = rhs.start_node.next;
1482 
1483  // Are we using the same pool?
1484  if (this->get_node_pool() == rhs.get_node_pool())
1485  {
1486  // Just link the nodes to the new forward_list.
1487  do
1488  {
1489  node_t* p_node = p_rhs_node;
1490  p_rhs_node = p_rhs_node->next;
1491 
1492  insert_node_after(*p_last_node, *p_node);
1493 
1494  p_last_node = p_node;
1495 
1496  ETL_INCREMENT_DEBUG_COUNT;
1497 
1498  } while (p_rhs_node != ETL_NULLPTR);
1499 
1500  ETL_OBJECT_RESET_DEBUG_COUNT(rhs);
1501  rhs.start_node.next = ETL_NULLPTR;
1502  }
1503  else
1504  {
1505  // Add all of the elements.
1506  etl::iforward_list<T>::iterator first = rhs.begin();
1507  etl::iforward_list<T>::iterator last = rhs.end();
1508 
1509  while (first != last)
1510  {
1511  ETL_ASSERT(!full(), ETL_ERROR(forward_list_full));
1512 
1513  data_node_t& data_node = this->allocate_data_node(etl::move(*first++));
1514  join(p_last_node, &data_node);
1515  data_node.next = ETL_NULLPTR;
1516  p_last_node = &data_node;
1517  }
1518 
1519  rhs.initialise();
1520  }
1521  }
1522  }
1523  }
1524 #endif
1525 
1526  private:
1527 
1528  //*************************************************************************
1530  //*************************************************************************
1531  static data_node_t* data_cast(node_t* p_node)
1532  {
1533  return static_cast<data_node_t*>(p_node);
1534  }
1535 
1536  //*************************************************************************
1538  //*************************************************************************
1539  static data_node_t& data_cast(node_t& node)
1540  {
1541  return static_cast<data_node_t&>(node);
1542  }
1543 
1544  //*************************************************************************
1546  //*************************************************************************
1547  static const data_node_t* data_cast(const node_t* p_node)
1548  {
1549  return static_cast<const data_node_t*>(p_node);
1550  }
1551 
1552  //*************************************************************************
1554  //*************************************************************************
1555  static const data_node_t& data_cast(const node_t& node)
1556  {
1557  return static_cast<const data_node_t&>(node);
1558  }
1559 
1560  //*************************************************************************
1562  //*************************************************************************
1563  void remove_node_after(node_t& node)
1564  {
1565  // The node to erase.
1566  node_t* p_node = node.next;
1567 
1568  if (p_node != ETL_NULLPTR)
1569  {
1570  // Disconnect the node from the forward_list.
1571  join(&node, p_node->next);
1572 
1573  // Destroy the pool object.
1574  destroy_data_node(static_cast<data_node_t&>(*p_node));
1575  }
1576  }
1577 
1578  //*************************************************************************
1580  //*************************************************************************
1581  data_node_t* create_data_node()
1582  {
1583  data_node_t* (etl::ipool::*func)() = &etl::ipool::allocate<data_node_t>;
1584  return (p_node_pool->*func)();
1585  }
1586 
1587  //*************************************************************************
1589  //*************************************************************************
1590  void destroy_data_node(data_node_t& node)
1591  {
1592  node.value.~T();
1593  p_node_pool->release(&node);
1594  ETL_DECREMENT_DEBUG_COUNT
1595  }
1596 
1597  // Disable copy construction.
1598  iforward_list(const iforward_list&);
1599 
1600  //*************************************************************************
1602  //*************************************************************************
1603 #if defined(ETL_POLYMORPHIC_FORWARD_LIST) || defined(ETL_POLYMORPHIC_CONTAINERS)
1604  public:
1605  virtual ~iforward_list()
1606  {
1607  }
1608 #else
1609  protected:
1611  {
1612  }
1613 #endif
1614  };
1615 
1616  //*************************************************************************
1619  //*************************************************************************
1620  template <typename T, const size_t MAX_SIZE_>
1622  {
1623  public:
1624 
1625  ETL_STATIC_ASSERT((MAX_SIZE_ > 0U), "Zero capacity etl::forward_list is not valid");
1626 
1627  static const size_t MAX_SIZE = MAX_SIZE_;
1628 
1629  public:
1630 
1631  typedef T value_type;
1632  typedef T* pointer;
1633  typedef const T* const_pointer;
1634  typedef T& reference;
1635  typedef const T& const_reference;
1636  typedef size_t size_type;
1637 
1638  //*************************************************************************
1640  //*************************************************************************
1642  : etl::iforward_list<T>(node_pool, MAX_SIZE, false)
1643  {
1644  this->initialise();
1645  }
1646 
1647  //*************************************************************************
1649  //*************************************************************************
1650  explicit forward_list(size_t initial_size, const T& value = T())
1651  : etl::iforward_list<T>(node_pool, MAX_SIZE, false)
1652  {
1653  this->assign(initial_size, value);
1654  }
1655 
1656  //*************************************************************************
1658  //*************************************************************************
1660  : etl::iforward_list<T>(node_pool, MAX_SIZE, false)
1661  {
1662  this->assign(other.cbegin(), other.cend());
1663  }
1664 
1665 #if ETL_CPP11_SUPPORTED
1666  //*************************************************************************
1668  //*************************************************************************
1669  forward_list(forward_list&& other)
1670  : etl::iforward_list<T>(node_pool, MAX_SIZE, false)
1671  {
1672  this->move_container(etl::move(other));
1673  }
1674 #endif
1675 
1676  //*************************************************************************
1678  //*************************************************************************
1679  template <typename TIterator>
1680  forward_list(TIterator first, TIterator last)
1681  : etl::iforward_list<T>(node_pool, MAX_SIZE, false)
1682  {
1683  this->assign(first, last);
1684  }
1685 
1686 #if ETL_CPP11_SUPPORTED && ETL_NOT_USING_STLPORT && ETL_USING_STL
1687  //*************************************************************************
1689  //*************************************************************************
1690  forward_list(std::initializer_list<T> init)
1691  : etl::iforward_list<T>(node_pool, MAX_SIZE, false)
1692  {
1693  this->assign(init.begin(), init.end());
1694  }
1695 #endif
1696 
1697  //*************************************************************************
1699  //*************************************************************************
1701  {
1702  this->initialise();
1703  }
1704 
1705  //*************************************************************************
1707  //*************************************************************************
1709  {
1710  if (&rhs != this)
1711  {
1712  this->assign(rhs.cbegin(), rhs.cend());
1713  }
1714 
1715  return *this;
1716  }
1717 
1718 #if ETL_CPP11_SUPPORTED
1719  //*************************************************************************
1721  //*************************************************************************
1723  {
1724 
1725  this->move_container(etl::move(rhs));
1726 
1727  return *this;
1728  }
1729 #endif
1730 
1731  private:
1732 
1735  };
1736 
1737  //*************************************************************************
1739  //*************************************************************************
1740 #if ETL_CPP17_SUPPORTED && ETL_NOT_USING_STLPORT && ETL_USING_STL
1741  template <typename T, typename... Ts>
1742  forward_list(T, Ts...)
1743  ->forward_list<etl::enable_if_t<(etl::is_same_v<T, Ts> && ...), T>, 1U + sizeof...(Ts)>;
1744 #endif
1745 
1746  //*************************************************************************
1749  //*************************************************************************
1750  template <typename T>
1752  {
1753  public:
1754 
1755  typedef T value_type;
1756  typedef T* pointer;
1757  typedef const T* const_pointer;
1758  typedef T& reference;
1759  typedef const T& const_reference;
1760  typedef size_t size_type;
1761 
1763 
1764  //*************************************************************************
1766  //*************************************************************************
1768  : etl::iforward_list<T>(true)
1769  {
1770  }
1771 
1772  //*************************************************************************
1774  //*************************************************************************
1775  explicit forward_list_ext(etl::ipool& node_pool)
1776  : etl::iforward_list<T>(node_pool, node_pool.max_size(), true)
1777  {
1778  this->initialise();
1779  }
1780 
1781  //*************************************************************************
1783  //*************************************************************************
1784  explicit forward_list_ext(size_t initial_size, etl::ipool& node_pool)
1785  : etl::iforward_list<T>(node_pool, node_pool.max_size(), true)
1786  {
1787  this->assign(initial_size, T());
1788  }
1789 
1790  //*************************************************************************
1792  //*************************************************************************
1793  explicit forward_list_ext(size_t initial_size, const T& value, etl::ipool& node_pool)
1794  : etl::iforward_list<T>(node_pool, node_pool.max_size(), true)
1795  {
1796  this->assign(initial_size, value);
1797  }
1798 
1799  //*************************************************************************
1801  //*************************************************************************
1803  : etl::iforward_list<T>(*other.p_node_pool, other.p_node_pool->max_size(), true)
1804  {
1805  this->assign(other.cbegin(), other.cend());
1806  }
1807 
1808  //*************************************************************************
1810  //*************************************************************************
1812  : etl::iforward_list<T>(node_pool, node_pool.max_size(), true)
1813  {
1814  this->assign(other.cbegin(), other.cend());
1815  }
1816 
1817 #if ETL_CPP11_SUPPORTED
1818  //*************************************************************************
1820  //*************************************************************************
1822  : etl::iforward_list<T>(*other.p_node_pool, other.p_node_pool->max_size(), true)
1823  {
1824  this->move_container(etl::move(other));
1825  }
1826 
1827  //*************************************************************************
1829  //*************************************************************************
1830  forward_list_ext(forward_list_ext&& other, etl::ipool& node_pool)
1831  : etl::iforward_list<T>(node_pool, node_pool.max_size(), true)
1832  {
1833  this->move_container(etl::move(other));
1834  }
1835 #endif
1836 
1837  //*************************************************************************
1839  //*************************************************************************
1840  template <typename TIterator>
1841  forward_list_ext(TIterator first, TIterator last, etl::ipool& node_pool)
1842  : etl::iforward_list<T>(node_pool, node_pool.max_size(), true)
1843  {
1844  this->assign(first, last);
1845  }
1846 
1847 #if ETL_CPP11_SUPPORTED && ETL_NOT_USING_STLPORT && ETL_USING_STL
1848  //*************************************************************************
1850  //*************************************************************************
1851  forward_list_ext(std::initializer_list<T> init, etl::ipool& node_pool)
1852  : etl::iforward_list<T>(node_pool, node_pool.max_size(), true)
1853  {
1854  this->assign(init.begin(), init.end());
1855  }
1856 #endif
1857 
1858  //*************************************************************************
1860  //*************************************************************************
1862  {
1863  this->initialise();
1864  }
1865 
1866  //*************************************************************************
1868  //*************************************************************************
1870  {
1871  if (&rhs != this)
1872  {
1873  this->assign(rhs.cbegin(), rhs.cend());
1874  }
1875 
1876  return *this;
1877  }
1878 
1879 #if ETL_CPP11_SUPPORTED
1880  //*************************************************************************
1882  //*************************************************************************
1884  {
1885  this->move_container(etl::move(rhs));
1886 
1887  return *this;
1888  }
1889 #endif
1890 
1891  //*************************************************************************
1893  //*************************************************************************
1895  {
1896  // Clear the list of any current elements.
1897  if (this->get_node_pool() != ETL_NULLPTR)
1898  {
1899  this->clear();
1900  }
1901 
1902  this->set_node_pool(pool);
1903  }
1904 
1905  //*************************************************************************
1907  //*************************************************************************
1909  {
1910  return *this->p_node_pool;
1911  }
1912  };
1913 
1914  //*************************************************************************
1919  //*************************************************************************
1920  template <typename T>
1922  {
1923  return (lhs.size() == rhs.size()) &&
1924  etl::equal(lhs.begin(), lhs.end(), rhs.begin());
1925  }
1926 
1927  //*************************************************************************
1932  //*************************************************************************
1933  template <typename T>
1935  {
1936  return !(lhs == rhs);
1937  }
1938 
1939  //*************************************************************************
1945  //*************************************************************************
1946  template <typename T>
1948  {
1949  return etl::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
1950  }
1951 
1952  //*************************************************************************
1958  //*************************************************************************
1959  template <typename T>
1961  {
1962  return (rhs < lhs);
1963  }
1964 
1965  //*************************************************************************
1971  //*************************************************************************
1972  template <typename T>
1974  {
1975  return !(lhs > rhs);
1976  }
1977 
1978  //*************************************************************************
1984  //*************************************************************************
1985  template <typename T>
1987  {
1988  return !(lhs < rhs);
1989  }
1990 }
1991 
1992 #include "private/minmax_pop.h"
1993 
1994 #undef ETL_FILE
1995 
1996 #endif
Template deduction guides.
Definition: forward_list.h:1752
void set_pool(etl::ipool &pool)
Set the pool instance.
Definition: forward_list.h:1894
forward_list_ext()
Default constructor.
Definition: forward_list.h:1767
forward_list_ext(etl::ipool &node_pool)
Default constructor.
Definition: forward_list.h:1775
etl::ipool & get_pool() const
Get the pool instance.
Definition: forward_list.h:1908
forward_list_ext(size_t initial_size, const T &value, etl::ipool &node_pool)
Construct from size and value.
Definition: forward_list.h:1793
forward_list_ext(TIterator first, TIterator last, etl::ipool &node_pool)
Construct from range.
Definition: forward_list.h:1841
forward_list_ext(const forward_list_ext &other)
Copy constructor. Implicit pool.
Definition: forward_list.h:1802
forward_list_ext(size_t initial_size, etl::ipool &node_pool)
Construct from size.
Definition: forward_list.h:1784
forward_list_ext(const forward_list_ext &other, etl::ipool &node_pool)
Copy constructor. Explicit pool.
Definition: forward_list.h:1811
~forward_list_ext()
Destructor.
Definition: forward_list.h:1861
Definition: forward_list.h:1622
~forward_list()
Destructor.
Definition: forward_list.h:1700
forward_list(size_t initial_size, const T &value=T())
Construct from size and value.
Definition: forward_list.h:1650
forward_list(const forward_list &other)
Copy constructor.
Definition: forward_list.h:1659
forward_list()
Default constructor.
Definition: forward_list.h:1641
forward_list(TIterator first, TIterator last)
Construct from range.
Definition: forward_list.h:1680
const_iterator
Definition: forward_list.h:494
iterator.
Definition: forward_list.h:405
bitset< MAXN > operator&(const bitset< MAXN > &lhs, const bitset< MAXN > &rhs)
Definition: bitset.h:1157
#define ETL_ASSERT(b, e)
Definition: error_handler.h:290
exception(string_type reason_, string_type file_, numeric_type line_)
Constructor.
Definition: exception.h:67
Definition: exception.h:47
iterator end()
Gets the end of the forward_list.
Definition: forward_list.h:618
void resize(size_t n)
Resizes the forward_list.
Definition: forward_list.h:832
void assign(TIterator first, TIterator last)
Definition: forward_list.h:669
size_type MAX_SIZE
The maximum size of the forward_list.
Definition: forward_list.h:360
void unique(TIsEqual isEqual)
Definition: forward_list.h:1150
forward_list_base(bool pool_is_shared_)
The constructor that is called from derived classes.
Definition: forward_list.h:275
const_iterator cbegin() const
Gets the beginning of the forward_list.
Definition: forward_list.h:610
iterator before_begin()
Gets before the beginning of the forward_list.
Definition: forward_list.h:594
iterator erase_after(iterator position)
Erases the value at the specified position.
Definition: forward_list.h:1018
void insert_node_after(node_t &position, node_t &node)
Insert a node.
Definition: forward_list.h:318
etl::ipool * get_node_pool()
Get the node pool instance.
Definition: forward_list.h:353
void unique()
Definition: forward_list.h:1140
node_t start_node
The node that acts as the forward_list start.
Definition: forward_list.h:358
void emplace_front(const T1 &value1, const T2 &value2, const T3 &value3)
Emplaces a value to the front of the list..
Definition: forward_list.h:791
void emplace_front(const T1 &value1, const T2 &value2)
Emplaces a value to the front of the list..
Definition: forward_list.h:776
void insert_after(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:983
size_type max_size() const
Gets the maximum possible size of the forward_list.
Definition: forward_list.h:176
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:285
void resize(size_t n, T value)
Definition: forward_list.h:842
iforward_list(etl::ipool &node_pool, size_t max_size_, bool pool_is_shared_)
Constructor.
Definition: forward_list.h:1406
size_t available() const
Definition: forward_list.h:236
size_type capacity() const
Gets the maximum possible size of the forward_list.
Definition: forward_list.h:184
void clear()
Clears the forward_list.
Definition: forward_list.h:642
iterator erase_after(iterator first, iterator last)
Erases a range of elements.
Definition: forward_list.h:1037
const_iterator before_begin() const
Gets before the beginning of the forward_list.
Definition: forward_list.h:602
void reverse()
Reverses the forward_list.
Definition: forward_list.h:245
const_iterator cend() const
Gets the end of the forward_list.
Definition: forward_list.h:634
const_iterator begin() const
Gets the beginning of the forward_list.
Definition: forward_list.h:586
void emplace_front(const T1 &value1)
Emplaces a value to the front of the list..
Definition: forward_list.h:761
iterator insert_after(iterator position, const T &value)
Inserts a value to the forward_list after the specified position.
Definition: forward_list.h:888
void join(node_t *left, node_t *right)
Join two nodes.
Definition: forward_list.h:336
size_t size_type
The type used for determining the size of forward_list.
Definition: forward_list.h:163
void insert_after(iterator position, TIterator first, TIterator last)
Inserts a range of values to the forward_list after the specified position.
Definition: forward_list.h:999
reference front()
Gets a reference to the first element.
Definition: forward_list.h:650
void move_after(const_iterator first_before, const_iterator last, const_iterator to_before)
Definition: forward_list.h:1101
iterator emplace_after(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:951
bool pool_is_shared
If true then the pool is shared between lists.
Definition: forward_list.h:361
void push_front(const T &value)
Pushes a value to the front of the forward_list.
Definition: forward_list.h:716
void 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:806
void sort()
Definition: forward_list.h:1181
void sort(TCompare compare)
Definition: forward_list.h:1212
void initialise()
Initialise the forward_list.
Definition: forward_list.h:1414
etl::ipool * p_node_pool
The pool of data nodes used in the list.
Definition: forward_list.h:359
iforward_list & operator=(const iforward_list &rhs)
Assignment operator.
Definition: forward_list.h:1371
const_reference front() const
Gets a const reference to the first element.
Definition: forward_list.h:658
iterator emplace_after(iterator position, const T1 &value1)
Emplaces a value to the forward_list after the specified position.
Definition: forward_list.h:919
void remove_if(TPredicate predicate)
Removes according to a predicate.
Definition: forward_list.h:1349
bool has_shared_pool() const
true if the list has a shared pool.
Definition: forward_list.h:168
iterator emplace_after(iterator position, const T1 &value1, const T2 &value2)
Emplaces a value to the forward_list after the specified position.
Definition: forward_list.h:935
bool full() const
Checks to see if the forward_list is full.
Definition: forward_list.h:226
const node_t * get_head() const
Get the head node.
Definition: forward_list.h:310
void pop_front()
Removes a value from the front of the forward_list.
Definition: forward_list.h:821
node_t * get_head()
Get the head node.
Definition: forward_list.h:302
~forward_list_base()
Destructor.
Definition: forward_list.h:295
bool empty() const
Checks to see if the forward_list is empty.
Definition: forward_list.h:218
void assign(size_t n, const T &value)
Assigns 'n' copies of a value to the forward_list.
Definition: forward_list.h:695
void set_node_pool(etl::ipool &node_pool_)
Set the node pool instance.
Definition: forward_list.h:344
data_node_t & allocate_data_node(const_reference value)
Allocate a data_node_t.
Definition: forward_list.h:1445
void move_after(const_iterator from_before, const_iterator to_before)
Definition: forward_list.h:1077
~iforward_list()
Destructor.
Definition: forward_list.h:1610
iterator emplace_after(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:967
size_type size() const
Gets the size of the forward_list.
Definition: forward_list.h:192
const_iterator end() const
Gets the end of the forward_list.
Definition: forward_list.h:626
iterator begin()
Gets the beginning of the forward_list.
Definition: forward_list.h:578
iforward_list(bool pool_is_shared_)
Constructor.
Definition: forward_list.h:1398
bool is_trivial_list() const
Is the forward_list a trivial length?
Definition: forward_list.h:328
Definition: forward_list.h:145
Definition: forward_list.h:103
Definition: forward_list.h:75
Definition: forward_list.h:89
Definition: forward_list.h:117
Definition: forward_list.h:371
Definition: forward_list.h:131
size_t size() const
Returns the number of allocated items in the pool.
Definition: pool.h:309
void release_all()
Release all objects in the pool.
Definition: pool.h:264
bool full() const
Definition: pool.h:327
size_t max_size() const
Returns the maximum number of items in the pool.
Definition: pool.h:285
void release(const void *const p_object)
Definition: pool.h:255
size_t available() const
Returns the number of free items in the pool.
Definition: pool.h:301
Definition: pool.h:118
Definition: pool.h:617
is_trivially_destructible
Definition: type_traits_generator.h:1171
Definition: absolute.h:37
bool operator>(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:633
bool operator>=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:645
bool operator!=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:594
bool operator!=(const etl::iforward_list< T > &lhs, const etl::iforward_list< T > &rhs)
Definition: forward_list.h:1934
bool operator==(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:582
bool operator==(const etl::iforward_list< T > &lhs, const etl::iforward_list< T > &rhs)
Definition: forward_list.h:1921
bool operator<(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:606
bool operator<=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:621
Definition: compare.h:52
Definition: functional.h:136
The node element in the forward_list.
Definition: forward_list.h:152
The data node element in the forward_list.
Definition: forward_list.h:391
iterator
Definition: iterator.h:422