Embedded Template Library  1.0
intrusive_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) 2016 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_INTRUSIVE_FORWARD_LIST_INCLUDED
32 #define ETL_INTRUSIVE_FORWARD_LIST_INCLUDED
33 
34 #include "platform.h"
35 
36 #include "algorithm.h"
37 #include "iterator.h"
38 #include "functional.h"
39 
40 #include "private/minmax_push.h"
41 
42 #include <stddef.h>
43 
44 #include "platform.h"
45 #include "nullptr.h"
46 #include "type_traits.h"
47 #include "exception.h"
48 #include "error_handler.h"
49 #include "intrusive_links.h"
50 #include "algorithm.h"
51 #include "iterator.h"
52 
53 #undef ETL_FILE
54 #define ETL_FILE "20"
55 
56 namespace etl
57 {
58  //***************************************************************************
61  //***************************************************************************
63  {
64  public:
65 
66  intrusive_forward_list_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
67  : exception(reason_, file_name_, line_number_)
68  {
69  }
70  };
71 
72  //***************************************************************************
75  //***************************************************************************
77  {
78  public:
79 
80  intrusive_forward_list_empty(string_type file_name_, numeric_type line_number_)
81  : intrusive_forward_list_exception(ETL_ERROR_TEXT("intrusive_forward_list:empty", ETL_FILE"A"), file_name_, line_number_)
82  {
83  }
84  };
85 
86  //***************************************************************************
89  //***************************************************************************
91  {
92  public:
93 
94  intrusive_forward_list_iterator_exception(string_type file_name_, numeric_type line_number_)
95  : intrusive_forward_list_exception(ETL_ERROR_TEXT("intrusive_forward_list:iterator", ETL_FILE"B"), file_name_, line_number_)
96  {
97  }
98  };
99 
100  //***************************************************************************
103  //***************************************************************************
105  {
106  public:
107 
108  intrusive_forward_list_index_exception(string_type file_name_, numeric_type line_number_)
109  : intrusive_forward_list_exception(ETL_ERROR_TEXT("intrusive_forward_list:bounds", ETL_FILE"C"), file_name_, line_number_)
110  {
111  }
112  };
113 
114  //***************************************************************************
117  //***************************************************************************
119  {
120  public:
121 
122  intrusive_forward_list_unsorted(string_type file_name_, numeric_type line_number_)
123  : intrusive_forward_list_exception(ETL_ERROR_TEXT("intrusive_forward_list:unsorted", ETL_FILE"D"), file_name_, line_number_)
124  {
125  }
126  };
127 
128  //***************************************************************************
131  //***************************************************************************
132  template <typename TLink>
134  {
135  public:
136 
137  // Node typedef.
138  typedef TLink link_type;
139 
140  //*************************************************************************
142  //*************************************************************************
143  void clear()
144  {
145  initialise();
146  }
147 
148  //*************************************************************************
151  //*************************************************************************
152  template <typename TIterator>
153  void assign(TIterator first, TIterator last)
154  {
155 #if defined(ETL_DEBUG)
156  intmax_t d = etl::distance(first, last);
158 #endif
159 
160  initialise();
161 
162  link_type* p_last_link = &start_link;
163 
164  // Add all of the elements.
165  while (first != last)
166  {
167  link_type& link = *first++;
168  etl::link_splice<link_type>(p_last_link, link);
169  p_last_link = &link;
170  ++current_size;
171  }
172  }
173 
174  //*************************************************************************
176  //*************************************************************************
177  void push_front(link_type& value)
178  {
180  }
181 
182  //*************************************************************************
184  //*************************************************************************
185  void pop_front()
186  {
187 #if defined(ETL_CHECK_PUSH_POP)
189 #endif
191  }
192 
193  //*************************************************************************
195  //*************************************************************************
196  void reverse()
197  {
198  if (is_trivial_list())
199  {
200  return;
201  }
202 
203  link_type* first = ETL_NULLPTR; // To keep first link
204  link_type* second = start_link.etl_next; // To keep second link
205  link_type* track = start_link.etl_next; // Track the list
206 
207  while (track != NULL)
208  {
209  track = track->etl_next; // Track point to next link;
210  second->etl_next = first; // Second link point to first
211  first = second; // Move first link to next
212  second = track; // Move second link to next
213  }
214 
215  etl::link<link_type>(start_link, first);
216  }
217 
218  //*************************************************************************
220  //*************************************************************************
221  bool empty() const
222  {
223  return start_link.etl_next == ETL_NULLPTR;
224  }
225 
226  //*************************************************************************
228  //*************************************************************************
229  size_t size() const
230  {
231  return current_size;
232  }
233 
234  protected:
235 
236  link_type start_link;
237 
238  size_t current_size;
239 
240  //*************************************************************************
242  //*************************************************************************
244  {
245  }
246 
247  //*************************************************************************
249  //*************************************************************************
250  bool is_trivial_list() const
251  {
252  return (start_link.link_type::etl_next == ETL_NULLPTR) || (start_link.link_type::etl_next->etl_next == ETL_NULLPTR);
253  }
254 
255  //*************************************************************************
257  //*************************************************************************
258  void insert_link_after(link_type& position, link_type& link)
259  {
260  // Connect to the intrusive_forward_list.
261  etl::link_splice<link_type>(position, link);
262  ++current_size;
263  }
264 
265  //*************************************************************************
267  //*************************************************************************
268  void remove_link_after(link_type& link)
269  {
270  link_type* p_next = link.etl_next;
271 
272  if (p_next != ETL_NULLPTR)
273  {
274  etl::unlink_after<link_type>(link);
275  --current_size;
276  }
277  }
278 
279  //*************************************************************************
281  //*************************************************************************
282  link_type* get_head()
283  {
284  return start_link.etl_next;
285  }
286 
287  //*************************************************************************
289  //*************************************************************************
290  const link_type* get_head() const
291  {
292  return start_link.etl_next;
293  }
294 
295  //*************************************************************************
297  //*************************************************************************
298  void initialise()
299  {
300  start_link.etl_next = ETL_NULLPTR;
301  current_size = 0;
302  }
303  };
304 
305  //***************************************************************************
309  //***************************************************************************
310  template <typename TValue, typename TLink = etl::forward_link<0> >
312  {
313  public:
314 
315  // Node typedef.
316  typedef typename etl::intrusive_forward_list_base<TLink>::link_type link_type;
317 
318  // STL style typedefs.
319  typedef TValue value_type;
320  typedef value_type* pointer;
321  typedef const value_type* const_pointer;
322  typedef value_type& reference;
323  typedef const value_type& const_reference;
324  typedef size_t size_type;
325 
327 
328  //*************************************************************************
330  //*************************************************************************
331  class iterator : public etl::iterator<ETL_OR_STD::forward_iterator_tag, value_type>
332  {
333  public:
334 
335  friend class intrusive_forward_list;
336  friend class const_iterator;
337 
338  iterator()
339  : p_value(ETL_NULLPTR)
340  {
341  }
342 
343  iterator(value_type* value)
344  : p_value(value)
345  {
346  }
347 
348  iterator(const iterator& other)
349  : p_value(other.p_value)
350  {
351  }
352 
353  iterator& operator ++()
354  {
355  // Read the appropriate 'etl_next'.
356  p_value = static_cast<value_type*>(p_value->link_type::etl_next);
357  return *this;
358  }
359 
360  iterator operator ++(int)
361  {
362  iterator temp(*this);
363  // Read the appropriate 'etl_next'.
364  p_value = static_cast<value_type*>(p_value->link_type::etl_next);
365  return temp;
366  }
367 
368  iterator& operator =(const iterator& other)
369  {
370  p_value = other.p_value;
371  return *this;
372  }
373 
374  reference operator *()
375  {
376  return *p_value;
377  }
378 
379  const_reference operator *() const
380  {
381  return *p_value;
382  }
383 
384  pointer operator &()
385  {
386  return p_value;
387  }
388 
389  const_pointer operator &() const
390  {
391  return p_value;
392  }
393 
394  pointer operator ->()
395  {
396  return p_value;
397  }
398 
399  const_pointer operator ->() const
400  {
401  return p_value;
402  }
403 
404  friend bool operator == (const iterator& lhs, const iterator& rhs)
405  {
406  return lhs.p_value == rhs.p_value;
407  }
408 
409  friend bool operator != (const iterator& lhs, const iterator& rhs)
410  {
411  return !(lhs == rhs);
412  }
413 
414  private:
415 
416  value_type* p_value;
417  };
418 
419  //*************************************************************************
421  //*************************************************************************
422  class const_iterator : public etl::iterator<ETL_OR_STD::forward_iterator_tag, const value_type>
423  {
424  public:
425 
426  friend class intrusive_forward_list;
427 
429  : p_value(ETL_NULLPTR)
430  {
431  }
432 
433  const_iterator(const value_type* value)
434  : p_value(value)
435  {
436  }
437 
438  const_iterator(const typename intrusive_forward_list::iterator& other)
439  : p_value(other.p_value)
440  {
441  }
442 
443  const_iterator(const const_iterator& other)
444  : p_value(other.p_value)
445  {
446  }
447 
448  const_iterator& operator ++()
449  {
450  // Read the appropriate 'etl_next'.
451  p_value = static_cast<value_type*>(p_value->link_type::etl_next);
452  return *this;
453  }
454 
455  const_iterator operator ++(int)
456  {
457  const_iterator temp(*this);
458  // Read the appropriate 'etl_next'.
459  p_value = static_cast<value_type*>(p_value->link_type::etl_next);
460  return temp;
461  }
462 
463  const_iterator& operator =(const const_iterator& other)
464  {
465  p_value = other.p_value;
466  return *this;
467  }
468 
469  const_reference operator *() const
470  {
471  return *p_value;
472  }
473 
474  const_pointer operator &() const
475  {
476  return p_value;
477  }
478 
479  const_pointer operator ->() const
480  {
481  return p_value;
482  }
483 
484  friend bool operator == (const const_iterator& lhs, const const_iterator& rhs)
485  {
486  return lhs.p_value == rhs.p_value;
487  }
488 
489  friend bool operator != (const const_iterator& lhs, const const_iterator& rhs)
490  {
491  return !(lhs == rhs);
492  }
493 
494  private:
495 
496  const value_type* p_value;
497  };
498 
499  typedef typename etl::iterator_traits<iterator>::difference_type difference_type;
500 
501  //*************************************************************************
503  //*************************************************************************
505  {
506  this->initialise();
507  }
508 
509  //*************************************************************************
511  //*************************************************************************
513  {
514  this->clear();
515  }
516 
517  //*************************************************************************
519  //*************************************************************************
520  template <typename TIterator>
521  intrusive_forward_list(TIterator first, TIterator last)
522  {
523  this->assign(first, last);
524  }
525 
526  //*************************************************************************
528  //*************************************************************************
530  {
531  return iterator(static_cast<value_type*>(this->get_head()));
532  }
533 
534  //*************************************************************************
536  //*************************************************************************
538  {
539  return const_iterator(static_cast<const value_type*>(this->get_head()));
540  }
541 
542  //*************************************************************************
544  //*************************************************************************
546  {
547  return iterator(&(static_cast<value_type&>(this->start_link)));
548  }
549 
550  //*************************************************************************
552  //*************************************************************************
554  {
555  return const_iterator(&(static_cast<const value_type&>(this->start_link)));
556  }
557 
558  //*************************************************************************
560  //*************************************************************************
562  {
563  return const_iterator(static_cast<const value_type*>(this->get_head()));
564  }
565 
566  //*************************************************************************
568  //*************************************************************************
570  {
571  return iterator();
572  }
573 
574  //*************************************************************************
576  //*************************************************************************
578  {
579  return const_iterator();
580  }
581 
582  //*************************************************************************
584  //*************************************************************************
586  {
587  return const_iterator();
588  }
589 
590  //*************************************************************************
592  //*************************************************************************
593  reference front()
594  {
595  return static_cast<value_type&>(*(this->get_head()));
596  }
597 
598  //*************************************************************************
600  //*************************************************************************
601  const_reference front() const
602  {
603  return static_cast<const value_type&>(*(this->get_head()));
604  }
605 
606  //*************************************************************************
608  //*************************************************************************
609  iterator insert_after(iterator position, value_type& value)
610  {
611  this->insert_link_after(*position.p_value, value);
612  return iterator(&value);
613  }
614 
615  //*************************************************************************
617  //*************************************************************************
618  template <typename TIterator>
619  void insert_after(iterator position, TIterator first, TIterator last)
620  {
621  while (first != last)
622  {
623  // Set up the next free link.
624  this->insert_link_after(*position.p_value, *first++);
625  ++position;
626  }
627  }
628 
629  //*************************************************************************
631  //*************************************************************************
633  {
634  iterator next(position);
635  if (next != end())
636  {
637  ++next;
638  if (next != end())
639  {
640  ++next;
641  this->remove_link_after(*position.p_value);
642  }
643  }
644 
645  return next;
646  }
647 
648  //*************************************************************************
650  //*************************************************************************
652  {
653  if (first != end() && (first != last))
654  {
655  this->current_size -= etl::distance(first, last) - 1;
656 
657  link_type* p_first = first.p_value;
658  link_type* p_last = last.p_value;
659  link_type* p_next = p_first->etl_next;
660 
661  // Join the ends.
662  etl::link<link_type>(p_first, p_last);
663 
664  if (p_next == ETL_NULLPTR)
665  {
666  return end();
667  }
668  else
669  {
670  return last;
671  }
672  }
673  else
674  {
675  return last;
676  }
677  }
678 
679  //*************************************************************************
682  //*************************************************************************
683  template <typename TIsEqual>
684  void unique(TIsEqual isEqual)
685  {
686  if (this->empty())
687  {
688  return;
689  }
690 
691  link_type* last = this->get_head();
692  link_type* current = last->etl_next;
693 
694  while (current != ETL_NULLPTR)
695  {
696  // Is this value the same as the last?
697  if (isEqual(*static_cast<value_type*>(current), *static_cast<value_type*>(last)))
698  {
699  this->remove_link_after(*last);
700  }
701  else
702  {
703  // Move on one.
704  last = current;
705  }
706 
707  current = last->etl_next;
708  }
709  }
710 
711  //*************************************************************************
713  //*************************************************************************
714  void sort()
715  {
717  }
718 
719  //*************************************************************************
743  //*************************************************************************
744  template <typename TCompare>
745  void sort(TCompare compare)
746  {
747  iterator i_left;
748  iterator i_right;
749  iterator i_link;
750  iterator i_head;
751  iterator i_tail;
752  int list_size = 1;
753  int number_of_merges;
754  int left_size;
755  int right_size;
756 
757  if (this->is_trivial_list())
758  {
759  return;
760  }
761 
762  while (true)
763  {
764  i_left = begin();
765  i_head = before_begin();
766  i_tail = before_begin();
767 
768  number_of_merges = 0; // Count the number of merges we do in this pass.
769 
770  while (i_left != end())
771  {
772  ++number_of_merges; // There exists a merge to be done.
773  i_right = i_left;
774  left_size = 0;
775 
776  // Step 'list_size' places along from left
777  for (int i = 0; i < list_size; ++i)
778  {
779  ++left_size;
780 
781  ++i_right;
782 
783  if (i_right == end())
784  {
785  break;
786  }
787  }
788 
789  // If right hasn't fallen off end, we have two lists to merge.
790  right_size = list_size;
791 
792  // Now we have two lists. Merge them.
793  while (left_size > 0 || (right_size > 0 && i_right != end()))
794  {
795  // Decide whether the next link of merge comes from left or right.
796  if (left_size == 0)
797  {
798  // Left is empty. The link must come from right.
799  i_link = i_right;
800  ++i_right;
801  --right_size;
802  }
803  else if (right_size == 0 || i_right == end())
804  {
805  // Right is empty. The link must come from left.
806  i_link = i_left;
807  ++i_left;
808  --left_size;
809  }
810  else if (!compare(*i_right, *i_left))
811  {
812  // First link of left is lower or same. The link must come from left.
813  i_link = i_left;
814  ++i_left;
815  --left_size;
816  }
817  else
818  {
819  // First link of right is lower. The link must come from right.
820  i_link = i_right;
821  ++i_right;
822  --right_size;
823  }
824 
825  // Add the next link to the merged head.
826  if (i_head == before_begin())
827  {
828  etl::link<link_type>(i_head.p_value, i_link.p_value);
829  i_head = i_link;
830  i_tail = i_link;
831  }
832  else
833  {
834  etl::link<link_type>(i_tail.p_value, i_link.p_value);
835  i_tail = i_link;
836  }
837 
838  i_tail.p_value->link_type::etl_next = ETL_NULLPTR;
839  }
840 
841  // Now left has stepped `list_size' places along, and right has too.
842  i_left = i_right;
843  }
844 
845  // If we have done only one merge, we're finished.
846  if (number_of_merges <= 1) // Allow for number_of_merges == 0, the empty head case
847  {
848  return;
849  }
850 
851  // Otherwise repeat, merging lists twice the size
852  list_size *= 2;
853  }
854  }
855 
856  //*************************************************************************
857  // Removes the values specified.
858  //*************************************************************************
859  void remove(const_reference value)
860  {
861  iterator i_item = begin();
862  iterator i_last_item = before_begin();
863 
864  while (i_item != end())
865  {
866  if (*i_item == value)
867  {
868  i_item = erase_after(i_last_item);
869  }
870  else
871  {
872  ++i_item;
873  ++i_last_item;
874  }
875  }
876  }
877 
878  //*************************************************************************
880  //*************************************************************************
881  template <typename TPredicate>
882  void remove_if(TPredicate predicate)
883  {
884  iterator i_item = begin();
885  iterator i_last_item = before_begin();
886 
887  while (i_item != end())
888  {
889  if (predicate(*i_item))
890  {
891  i_item = erase_after(i_last_item);
892  }
893  else
894  {
895  ++i_item;
896  ++i_last_item;
897  }
898  }
899  }
900 
901  //*************************************************************************
903  //*************************************************************************
905  {
906  // No point splicing to ourself!
907  if (&other != this)
908  {
909  if (!other.empty())
910  {
911  link_type& first = *other.get_head();
912 
913  if (&other != this)
914  {
915  this->current_size += other.size();
916  }
917 
918  link_type& before = *position.p_value;
919  link_type& after = *position.p_value->link_type::etl_next;
920 
921  etl::link<link_type>(before, first);
922 
923  link_type* last = &before;
924  while (last->link_type::etl_next != ETL_NULLPTR)
925  {
926  last = last->link_type::etl_next;
927  }
928 
929  etl::link<link_type>(last, after);
930 
931  other.initialise();
932  }
933  }
934  }
935 
936  //*************************************************************************
938  //*************************************************************************
940  {
941  link_type& before = *position.p_value;
942 
943  etl::unlink<link_type>(*isource.p_value);
944  etl::link_splice<link_type>(before, *isource.p_value);
945 
946  if (&other != this)
947  {
948  ++this->current_size;
949  --other.current_size;
950  }
951  }
952 
953  //*************************************************************************
955  //*************************************************************************
957  {
958  if (!other.empty())
959  {
960  if (&other != this)
961  {
962  size_t n = etl::distance(begin_, end_) - 1;
963  this->current_size += n;
964  other.current_size -= n;
965  }
966 
967  link_type* first = begin_.p_value;
968  link_type* last = first;
969 
970  while (last->link_type::etl_next != end_.p_value)
971  {
972  last = last->link_type::etl_next;
973  }
974 
975  // Unlink from the source list.
976  link_type* first_next = first->link_type::etl_next;
977  etl::unlink_after(*first, *last);
978 
979  // Fix our links.
980  link_type* before = position.p_value;
981 
982  etl::link_splice<link_type>(*before, *first_next, *last);
983  }
984  }
985 
986  //*************************************************************************
988  //*************************************************************************
989  void merge(list_type& other)
990  {
991  merge(other, etl::less<value_type>());
992  }
993 
994  //*************************************************************************
996  //*************************************************************************
997  template <typename TCompare>
998  void merge(list_type& other, TCompare compare)
999  {
1000  if ((this != &other) && !other.empty())
1001  {
1002 #if defined(ETL_DEBUG)
1005 #endif
1006 
1007  value_type* other_begin = static_cast<value_type*>(other.get_head());
1008  value_type* other_terminal = ETL_NULLPTR;
1009 
1010  value_type* before = static_cast<value_type*>(&this->start_link);
1011  value_type* before_next = get_next(before);
1012  value_type* terminal = ETL_NULLPTR;
1013 
1014  while ((before->link_type::etl_next != terminal) && (other_begin != other_terminal))
1015  {
1016  // Find the place to insert.
1017  while ((before_next != terminal) && !(compare(*other_begin, *before_next)))
1018  {
1019  before = before_next;
1020  before_next = get_next(before_next);
1021  }
1022 
1023  // Insert.
1024  if (before_next != terminal)
1025  {
1026  while ((other_begin != other_terminal) && (compare(*other_begin, *before_next)))
1027  {
1028  value_type* value = other_begin;
1029  other_begin = get_next(other_begin);
1030  etl::link_splice<link_type>(*before, *value);
1031  before = get_next(before);
1032  }
1033  }
1034  }
1035 
1036  // Any left over?
1037  if (before_next == terminal)
1038  {
1039  while (other_begin != other_terminal)
1040  {
1041  value_type* value = other_begin;
1042  other_begin = get_next(other_begin);
1043  etl::link_splice<link_type>(*before, *value);
1044  before = get_next(before);
1045  }
1046  }
1047 
1048  this->current_size += other.size();
1049 
1050  other.initialise();
1051  }
1052  }
1053 
1054  private:
1055 
1056  //*************************************************************************
1058  //*************************************************************************
1059  value_type* get_next(link_type* link) const
1060  {
1061  return static_cast<value_type*>(link->etl_next);
1062  }
1063 
1064  // Disabled.
1066  intrusive_forward_list& operator = (const intrusive_forward_list& rhs);
1067  };
1068 }
1069 
1070 #include "private/minmax_pop.h"
1071 
1072 #undef ETL_FILE
1073 
1074 #endif
const_iterator
Definition: intrusive_forward_list.h:423
iterator.
Definition: intrusive_forward_list.h:332
Definition: intrusive_forward_list.h:134
link_type * get_head()
Get the head link.
Definition: intrusive_forward_list.h:282
bool is_trivial_list() const
Is the intrusive_forward_list a trivial length?
Definition: intrusive_forward_list.h:250
void reverse()
Reverses the intrusive_forward_list.
Definition: intrusive_forward_list.h:196
void insert_link_after(link_type &position, link_type &link)
Insert a link.
Definition: intrusive_forward_list.h:258
~intrusive_forward_list_base()
Destructor.
Definition: intrusive_forward_list.h:243
bool empty() const
Returns true if the list has no elements.
Definition: intrusive_forward_list.h:221
link_type start_link
The link that acts as the intrusive_forward_list start.
Definition: intrusive_forward_list.h:236
size_t current_size
Counts the number of elements in the list.
Definition: intrusive_forward_list.h:238
void remove_link_after(link_type &link)
Remove a link.
Definition: intrusive_forward_list.h:268
void initialise()
Initialise the intrusive_forward_list.
Definition: intrusive_forward_list.h:298
void pop_front()
Removes a value from the front of the intrusive_forward_list.
Definition: intrusive_forward_list.h:185
void assign(TIterator first, TIterator last)
Definition: intrusive_forward_list.h:153
size_t size() const
Returns the number of elements.
Definition: intrusive_forward_list.h:229
void push_front(link_type &value)
Pushes a value to the front of the intrusive_forward_list.
Definition: intrusive_forward_list.h:177
const link_type * get_head() const
Get the head link.
Definition: intrusive_forward_list.h:290
void clear()
Clears the intrusive_forward_list.
Definition: intrusive_forward_list.h:143
Definition: intrusive_forward_list.h:77
Definition: intrusive_forward_list.h:63
Definition: intrusive_forward_list.h:105
Definition: intrusive_forward_list.h:91
Definition: intrusive_forward_list.h:119
Definition: intrusive_forward_list.h:312
const_iterator before_begin() const
Gets before the beginning of the intrusive_forward_list.
Definition: intrusive_forward_list.h:553
iterator erase_after(iterator first, iterator last)
Erases a range of elements.
Definition: intrusive_forward_list.h:651
void sort(TCompare compare)
Definition: intrusive_forward_list.h:745
const_iterator cbegin() const
Gets the beginning of the intrusive_forward_list.
Definition: intrusive_forward_list.h:561
void splice_after(iterator position, etl::intrusive_forward_list< TValue, TLink > &other)
Splice another list into this one.
Definition: intrusive_forward_list.h:904
~intrusive_forward_list()
Destructor.
Definition: intrusive_forward_list.h:512
void unique(TIsEqual isEqual)
Definition: intrusive_forward_list.h:684
void splice_after(iterator position, etl::intrusive_forward_list< TValue, TLink > &other, iterator begin_, iterator end_)
Splice a range of elements from another list into this one.
Definition: intrusive_forward_list.h:956
void splice_after(iterator position, etl::intrusive_forward_list< TValue, TLink > &other, iterator isource)
Splice an element from another list into this one.
Definition: intrusive_forward_list.h:939
void insert_after(iterator position, TIterator first, TIterator last)
Inserts a range of values to the intrusive_forward_list after the specified position.
Definition: intrusive_forward_list.h:619
void remove_if(TPredicate predicate)
Removes according to a predicate.
Definition: intrusive_forward_list.h:882
iterator erase_after(iterator position)
Erases the value at the specified position.
Definition: intrusive_forward_list.h:632
iterator insert_after(iterator position, value_type &value)
Inserts a value to the intrusive_forward_list after the specified position.
Definition: intrusive_forward_list.h:609
const_iterator begin() const
Gets the beginning of the intrusive_forward_list.
Definition: intrusive_forward_list.h:537
intrusive_forward_list(TIterator first, TIterator last)
Constructor from range.
Definition: intrusive_forward_list.h:521
void merge(list_type &other, TCompare compare)
Merge another list into this one. Both lists should be sorted.
Definition: intrusive_forward_list.h:998
iterator end()
Gets the end of the intrusive_forward_list.
Definition: intrusive_forward_list.h:569
iterator before_begin()
Gets before the beginning of the intrusive_forward_list.
Definition: intrusive_forward_list.h:545
const_iterator end() const
Gets the end of the intrusive_forward_list.
Definition: intrusive_forward_list.h:577
const_reference front() const
Gets a const reference to the first element.
Definition: intrusive_forward_list.h:601
const_iterator cend() const
Gets the end of the intrusive_forward_list.
Definition: intrusive_forward_list.h:585
void merge(list_type &other)
Merge another list into this one. Both lists should be sorted.
Definition: intrusive_forward_list.h:989
void sort()
Sort using in-place merge sort algorithm.
Definition: intrusive_forward_list.h:714
intrusive_forward_list()
Constructor.
Definition: intrusive_forward_list.h:504
iterator begin()
Gets the beginning of the intrusive_forward_list.
Definition: intrusive_forward_list.h:529
reference front()
Gets a reference to the first element.
Definition: intrusive_forward_list.h:593
ETL_NODISCARD bool is_sorted(TIterator begin, TIterator end)
Definition: algorithm.h:1923
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
Definition: absolute.h:37
bool operator!=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:594
bool operator==(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:582
Definition: compare.h:52
iterator
Definition: iterator.h:422
Definition: functional.h:112