Embedded Template Library  1.0
intrusive_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_LIST_INCLUDED
32 #define ETL_INTRUSIVE_LIST_INCLUDED
33 
34 #include "platform.h"
35 
36 #include "private/minmax_push.h"
37 
38 #include <stddef.h>
39 
40 #include "platform.h"
41 #include "nullptr.h"
42 #include "type_traits.h"
43 #include "exception.h"
44 #include "error_handler.h"
45 #include "intrusive_links.h"
46 #include "static_assert.h"
47 #include "algorithm.h"
48 #include "iterator.h"
49 
50 #include "algorithm.h"
51 #include "iterator.h"
52 #include "functional.h"
53 
54 #undef ETL_FILE
55 #define ETL_FILE "21"
56 
57 namespace etl
58 {
59  //***************************************************************************
62  //***************************************************************************
64  {
65  public:
66 
67  intrusive_list_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
68  : exception(reason_, file_name_, line_number_)
69  {
70  }
71  };
72 
73  //***************************************************************************
76  //***************************************************************************
78  {
79  public:
80 
81  intrusive_list_empty(string_type file_name_, numeric_type line_number_)
82  : intrusive_list_exception(ETL_ERROR_TEXT("intrusive_list:empty", ETL_FILE"A"), file_name_, line_number_)
83  {
84  }
85  };
86 
87  //***************************************************************************
90  //***************************************************************************
92  {
93  public:
94 
95  intrusive_list_iterator_exception(string_type file_name_, numeric_type line_number_)
96  : intrusive_list_exception(ETL_ERROR_TEXT("intrusive_list:iterator", ETL_FILE"B"), file_name_, line_number_)
97  {
98  }
99  };
100 
101  //***************************************************************************
104  //***************************************************************************
106  {
107  public:
108 
109  intrusive_list_unsorted(string_type file_name_, numeric_type line_number_)
110  : intrusive_list_exception(ETL_ERROR_TEXT("intrusive_list:unsorted", ETL_FILE"C"), file_name_, line_number_)
111  {
112  }
113  };
114 
115  //***************************************************************************
118  //***************************************************************************
119  template <typename TLink>
121  {
122  public:
123 
124  // Node typedef.
125  typedef TLink link_type;
126 
127  //*************************************************************************
131  //*************************************************************************
132  template <typename TIterator>
133  void assign(TIterator first, TIterator last)
134  {
135 #if defined(ETL_DEBUG)
136  intmax_t d = etl::distance(first, last);
137  ETL_ASSERT(d >= 0, ETL_ERROR(intrusive_list_iterator_exception));
138 #endif
139 
140  initialise();
141 
142  link_type* p_last_link = &terminal_link;
143 
144  // Add all of the elements.
145  while (first != last)
146  {
147  link_type& link = *first++;
148  etl::link_splice<link_type>(p_last_link, link);
149  p_last_link = &link;
150  ++current_size;
151  }
152  }
153 
154  //*************************************************************************
156  //*************************************************************************
157  void push_front(link_type& value)
158  {
159  insert_link(terminal_link, value);
160  }
161 
162  //*************************************************************************
164  //*************************************************************************
165  void pop_front()
166  {
167 #if defined(ETL_CHECK_PUSH_POP)
168  ETL_ASSERT(!empty(), ETL_ERROR(intrusive_list_empty));
169 #endif
171  }
172 
173  //*************************************************************************
175  //*************************************************************************
176  void push_back(link_type& value)
177  {
178  insert_link(terminal_link.link_type::etl_previous, value);
179  }
180 
181  //*************************************************************************
183  //*************************************************************************
184  void pop_back()
185  {
186 #if defined(ETL_CHECK_PUSH_POP)
187  ETL_ASSERT(!empty(), ETL_ERROR(intrusive_list_empty));
188 #endif
190  }
191 
192  //*************************************************************************
194  //*************************************************************************
195  void clear()
196  {
197  initialise();
198  }
199 
200  //*************************************************************************
202  //*************************************************************************
203  void reverse()
204  {
205  if (is_trivial_list())
206  {
207  return;
208  }
209 
210  link_type* pnode = terminal_link.etl_next;
211 
212  while (pnode != &terminal_link)
213  {
214  pnode->reverse();
215  pnode = pnode->etl_previous; // Now we've reversed it, we must go to the previous node.
216  }
217 
218  // Terminal node.
219  pnode->reverse();
220  }
221 
222  //*************************************************************************
224  //*************************************************************************
225  bool empty() const
226  {
227  return (terminal_link.link_type::etl_next == &terminal_link);
228  }
229 
230  //*************************************************************************
232  //*************************************************************************
233  size_t size() const
234  {
235  return current_size;
236  }
237 
238  protected:
239 
241  link_type terminal_link;
242 
243  size_t current_size;
244 
245  //*************************************************************************
247  //*************************************************************************
249  {
250  }
251 
252  //*************************************************************************
254  //*************************************************************************
255  bool is_trivial_list() const
256  {
257  return (terminal_link.link_type::etl_next == &terminal_link) || (terminal_link.link_type::etl_next->etl_next == &terminal_link);
258  }
259 
260  //*************************************************************************
262  //*************************************************************************
263  void insert_link(link_type& previous, link_type& new_link)
264  {
265  // Connect to the intrusive_list.
266  etl::link_splice<link_type>(previous, new_link);
267  ++current_size;
268  }
269 
270  //*************************************************************************
272  //*************************************************************************
273  void insert_link(link_type* previous, link_type& new_link)
274  {
275  // Connect to the intrusive_list.
276  etl::link_splice<link_type>(previous, new_link);
277  ++current_size;
278  }
279 
280  //*************************************************************************
282  //*************************************************************************
283  void insert_link(link_type& previous, link_type* new_link)
284  {
285  // Connect to the intrusive_list.
286  etl::link_splice<link_type>(previous, new_link);
287  ++current_size;
288  }
289 
290  //*************************************************************************
292  //*************************************************************************
293  void insert_link(link_type* previous, link_type* new_link)
294  {
295  // Connect to the intrusive_list.
296  etl::link_splice<link_type>(previous, new_link);
297  ++current_size;
298  }
299 
300  //*************************************************************************
302  //*************************************************************************
303  void remove_link(link_type& link)
304  {
305  etl::unlink<link_type>(link);
306  --current_size;
307  }
308 
309  //*************************************************************************
311  //*************************************************************************
312  void remove_link(link_type* link)
313  {
314  etl::unlink<link_type>(*link);
315  --current_size;
316  }
317 
318  //*************************************************************************
320  //*************************************************************************
321  link_type* get_head()
322  {
323  return terminal_link.etl_next;
324  }
325 
326  //*************************************************************************
328  //*************************************************************************
329  const link_type* get_head() const
330  {
331  return terminal_link.etl_next;
332  }
333 
334  //*************************************************************************
336  //*************************************************************************
337  link_type* get_tail()
338  {
339  return terminal_link.etl_previous;
340  }
341 
342  //*************************************************************************
344  //*************************************************************************
345  const link_type* get_tail() const
346  {
347  return terminal_link.etl_previous;
348  }
349 
350  //*************************************************************************
352  //*************************************************************************
353  void initialise()
354  {
355  etl::link(terminal_link, terminal_link);
356  current_size = 0;
357  }
358  };
359 
360  //***************************************************************************
364  //***************************************************************************
365  template <typename TValue, typename TLink = etl::bidirectional_link<0> >
367  {
368  public:
369 
370  // Node typedef.
371  typedef typename etl::intrusive_list_base<TLink>::link_type link_type;
372 
374 
375  // STL style typedefs.
376  typedef TValue value_type;
377  typedef value_type* pointer;
378  typedef const value_type* const_pointer;
379  typedef value_type& reference;
380  typedef const value_type& const_reference;
381  typedef size_t size_type;
382 
383  //*************************************************************************
385  //*************************************************************************
386  class iterator : public etl::iterator<ETL_OR_STD::bidirectional_iterator_tag, value_type>
387  {
388  public:
389 
390  friend class intrusive_list;
391  friend class const_iterator;
392 
393  iterator()
394  : p_value(ETL_NULLPTR)
395  {
396  }
397 
398  iterator(value_type& value)
399  : p_value(&value)
400  {
401  }
402 
403  iterator(const iterator& other)
404  : p_value(other.p_value)
405  {
406  }
407 
408  iterator& operator ++()
409  {
410  // Read the appropriate 'etl_next'.
411  p_value = static_cast<value_type*>(p_value->link_type::etl_next);
412  return *this;
413  }
414 
415  iterator operator ++(int)
416  {
417  iterator temp(*this);
418  // Read the appropriate 'etl_next'.
419  p_value = static_cast<value_type*>(p_value->link_type::etl_next);
420  return temp;
421  }
422 
423  iterator& operator --()
424  {
425  // Read the appropriate 'etl_previous'.
426  p_value = static_cast<value_type*>(p_value->link_type::etl_previous);
427  return *this;
428  }
429 
430  iterator operator --(int)
431  {
432  iterator temp(*this);
433  // Read the appropriate 'etl_previous'.
434  p_value = static_cast<value_type*>(p_value->link_type::etl_previous);
435  return temp;
436  }
437 
438  iterator& operator =(const iterator& other)
439  {
440  p_value = other.p_value;
441  return *this;
442  }
443 
444  reference operator *()
445  {
446  return *p_value;
447  }
448 
449  const_reference operator *() const
450  {
451  return *p_value;
452  }
453 
454  pointer operator &()
455  {
456  return p_value;
457  }
458 
459  const_pointer operator &() const
460  {
461  return p_value;
462  }
463 
464  pointer operator ->()
465  {
466  return p_value;
467  }
468 
469  const_pointer operator ->() const
470  {
471  return p_value;
472  }
473 
474  friend bool operator == (const iterator& lhs, const iterator& rhs)
475  {
476  return lhs.p_value == rhs.p_value;
477  }
478 
479  friend bool operator != (const iterator& lhs, const iterator& rhs)
480  {
481  return !(lhs == rhs);
482  }
483 
484  private:
485 
486  value_type* p_value;
487  };
488 
489  //*************************************************************************
491  //*************************************************************************
492  class const_iterator : public etl::iterator<ETL_OR_STD::bidirectional_iterator_tag, const value_type>
493  {
494  public:
495 
496  friend class intrusive_list;
497 
499  : p_value(ETL_NULLPTR)
500  {
501  }
502 
503  const_iterator(const value_type& value)
504  : p_value(&value)
505  {
506  }
507 
508  const_iterator(const typename intrusive_list::iterator& other)
509  : p_value(other.p_value)
510  {
511  }
512 
513  const_iterator(const const_iterator& other)
514  : p_value(other.p_value)
515  {
516  }
517 
518  const_iterator& operator ++()
519  {
520  // Read the appropriate 'etl_next'.
521  p_value = static_cast<value_type*>(p_value->link_type::etl_next);
522  return *this;
523  }
524 
525  const_iterator operator ++(int)
526  {
527  const_iterator temp(*this);
528  // Read the appropriate 'etl_next'.
529  p_value = static_cast<value_type*>(p_value->link_type::etl_next);
530  return temp;
531  }
532 
533  const_iterator& operator --()
534  {
535  // Read the appropriate 'etl_previous'.
536  p_value = static_cast<value_type*>(p_value->link_type::etl_previous);
537  return *this;
538  }
539 
540  const_iterator operator --(int)
541  {
542  const_iterator temp(*this);
543  // Read the appropriate 'etl_previous'.
544  p_value = static_cast<value_type*>(p_value->link_type::etl_previous);
545  return temp;
546  }
547 
548  const_iterator& operator =(const const_iterator& other)
549  {
550  p_value = other.p_value;
551  return *this;
552  }
553 
554  const_reference operator *() const
555  {
556  return *p_value;
557  }
558 
559  const_pointer operator &() const
560  {
561  return p_value;
562  }
563 
564  const_pointer operator ->() const
565  {
566  return p_value;
567  }
568 
569  friend bool operator == (const const_iterator& lhs, const const_iterator& rhs)
570  {
571  return lhs.p_value == rhs.p_value;
572  }
573 
574  friend bool operator != (const const_iterator& lhs, const const_iterator& rhs)
575  {
576  return !(lhs == rhs);
577  }
578 
579  private:
580 
581  const value_type* p_value;
582  };
583 
584  typedef typename etl::iterator_traits<iterator>::difference_type difference_type;
585 
586  //*************************************************************************
588  //*************************************************************************
590  {
591  this->initialise();
592  }
593 
594  //*************************************************************************
596  //*************************************************************************
598  {
599  this->clear();
600  }
601 
602  //*************************************************************************
604  //*************************************************************************
605  template <typename TIterator>
606  intrusive_list(TIterator first, TIterator last)
607  {
608  this->assign(first, last);
609  }
610 
611  //*************************************************************************
613  //*************************************************************************
615  {
616  return iterator(static_cast<value_type&>(*this->get_head()));
617  }
618 
619  //*************************************************************************
621  //*************************************************************************
623  {
624  return const_iterator(static_cast<const value_type&>(*this->get_head()));
625  }
626 
627  //*************************************************************************
629  //*************************************************************************
631  {
632  return const_iterator(static_cast<const value_type&>(*this->get_head()));
633  }
634 
635  //*************************************************************************
637  //*************************************************************************
639  {
640  return iterator(static_cast<value_type&>(this->terminal_link));
641  }
642 
643  //*************************************************************************
645  //*************************************************************************
647  {
648  return const_iterator(static_cast<const value_type&>(this->terminal_link));
649  }
650 
651  //*************************************************************************
653  //*************************************************************************
655  {
656  return const_iterator(static_cast<const value_type&>(this->terminal_link));
657  }
658 
659  //*************************************************************************
661  //*************************************************************************
662  reference front()
663  {
664  return *static_cast<value_type*>(this->get_head());
665  }
666 
667  //*************************************************************************
669  //*************************************************************************
670  const_reference front() const
671  {
672  return *static_cast<const value_type*>(this->get_head());
673  }
674 
675  //*************************************************************************
677  //*************************************************************************
678  reference back()
679  {
680  return *static_cast<value_type*>(this->get_tail());
681  }
682 
683  //*************************************************************************
685  //*************************************************************************
686  const_reference back() const
687  {
688  return *static_cast<const value_type*>(this->get_tail());
689  }
690 
691  //*************************************************************************
693  //*************************************************************************
694  iterator insert(iterator position, value_type& value)
695  {
696  this->insert_link(position.p_value->link_type::etl_previous, value);
697  return iterator(value);
698  }
699 
700  //*************************************************************************
702  //*************************************************************************
703  template <typename TIterator>
704  void insert(iterator position, TIterator first, TIterator last)
705  {
706  while (first != last)
707  {
708  // Set up the next free link.
709  this->insert_link(*position.p_value->link_type::etl_previous, *first++);
710  }
711  }
712 
713  //*************************************************************************
715  //*************************************************************************
717  {
718  iterator next(position);
719  ++next;
720 
721  this->remove_link(*position.p_value);
722 
723  return next;
724  }
725 
726  //*************************************************************************
729  //*************************************************************************
731  {
732  link_type* p_first = first.p_value;
733  link_type* p_last = last.p_value;
734 
735  // Join the ends.
736  etl::link<link_type>(p_first->etl_previous, p_last);
737 
738  this->current_size -= etl::distance(first, last);
739 
740  if (p_last == &this->terminal_link)
741  {
742  return end();
743  }
744  else
745  {
746  return iterator(*static_cast<value_type*>(p_last));
747  }
748  }
749 
750  //*************************************************************************
753  //*************************************************************************
754  template <typename TIsEqual>
755  void unique(TIsEqual isEqual)
756  {
757  if (this->empty())
758  {
759  return;
760  }
761 
762  iterator i_item = begin();
763  ++i_item;
764  iterator i_previous = begin();
765 
766  while (i_item != end())
767  {
768  if (isEqual(*i_previous, *i_item))
769  {
770  i_item = erase(i_item);
771  }
772  else
773  {
774  i_previous = i_item;
775  ++i_item;
776  }
777  }
778  }
779 
780  //*************************************************************************
782  //*************************************************************************
783  void sort()
784  {
786  }
787 
788  //*************************************************************************
812  //*************************************************************************
813  template <typename TCompare>
814  void sort(TCompare compare)
815  {
816  iterator i_left;
817  iterator i_right;
818  iterator i_node;
819  iterator i_head;
820  iterator i_tail;
821  int list_size = 1;
822  int number_of_merges;
823  int left_size;
824  int right_size;
825 
826  if (this->is_trivial_list())
827  {
828  return;
829  }
830 
831  while (true)
832  {
833  i_left = begin();
834  i_head = end();
835  i_tail = end();
836 
837  number_of_merges = 0; // Count the number of merges we do in this pass.
838 
839  while (i_left != end())
840  {
841  ++number_of_merges; // There exists a merge to be done.
842  i_right = i_left;
843  left_size = 0;
844 
845  // Step 'list_size' places along from left
846  for (int i = 0; i < list_size; ++i)
847  {
848  ++left_size;
849  ++i_right;
850 
851  if (i_right == end())
852  {
853  break;
854  }
855  }
856 
857  // If right hasn't fallen off end, we have two lists to merge.
858  right_size = list_size;
859 
860  // Now we have two lists. Merge them.
861  while (left_size > 0 || (right_size > 0 && i_right != end()))
862  {
863  // Decide whether the next node of merge comes from left or right.
864  if (left_size == 0)
865  {
866  // Left is empty. The node must come from right.
867  i_node = i_right++;
868  --right_size;
869  }
870  else if (right_size == 0 || i_right == end())
871  {
872  // Right is empty. The node must come from left.
873  i_node = i_left++;
874  --left_size;
875  }
876  else if (!compare(*i_right, *i_left))
877  {
878  // First node of left is lower or same. The node must come from left.
879  i_node = i_left++;
880  --left_size;
881  }
882  else
883  {
884  // First node of right is lower. The node must come from right.
885  i_node = i_right;
886  ++i_right;
887  --right_size;
888  }
889 
890  // Add the next node to the merged head.
891  if (i_head == end())
892  {
893  etl::link<link_type>(i_head.p_value, i_node.p_value);
894  i_head = i_node;
895  i_tail = i_node;
896  }
897  else
898  {
899  etl::link<link_type>(i_tail.p_value, i_node.p_value);
900  i_tail = i_node;
901  }
902 
903  etl::link<link_type>(i_tail.p_value, this->terminal_link);
904  }
905 
906  // Now left has stepped `list_size' places along, and right has too.
907  i_left = i_right;
908  }
909 
910  // If we have done only one merge, we're finished.
911  if (number_of_merges <= 1) // Allow for number_of_merges == 0, the empty head case
912  {
913  return;
914  }
915 
916  // Otherwise repeat, merging lists twice the size
917  list_size *= 2;
918  }
919  }
920 
921  //*************************************************************************
922  // Removes the values specified.
923  //*************************************************************************
924  void remove(const_reference value)
925  {
926  iterator i_item = begin();
927 
928  while (i_item != end())
929  {
930  if (*i_item == value)
931  {
932  i_item = erase(i_item);
933  }
934  else
935  {
936  ++i_item;
937  }
938  }
939  }
940 
941  //*************************************************************************
943  //*************************************************************************
944  template <typename TPredicate>
945  void remove_if(TPredicate predicate)
946  {
947  iterator i_item = begin();
948 
949  while (i_item != end())
950  {
951  if (predicate(*i_item))
952  {
953  i_item = erase(i_item);
954  }
955  else
956  {
957  ++i_item;
958  }
959  }
960  }
961 
962  //*************************************************************************
964  //*************************************************************************
965  void splice(iterator position, list_type& other)
966  {
967  // No point splicing to ourself!
968  if (&other != this)
969  {
970  if (!other.empty())
971  {
972  link_type& first = *other.get_head();
973  link_type& last = *other.get_tail();
974 
975  if (&other != this)
976  {
977  this->current_size += other.size();
978  }
979 
980  link_type& after = *position.p_value;
981  link_type& before = *after.etl_previous;
982 
983  etl::link<link_type>(before, first);
984  etl::link<link_type>(last, after);
985 
986  other.initialise();
987  }
988  }
989  }
990 
991  //*************************************************************************
993  //*************************************************************************
994  void splice(iterator position, list_type& other, iterator isource)
995  {
996  link_type& before = *position.p_value->link_type::etl_previous;
997 
998  etl::unlink<link_type>(*isource.p_value);
999  etl::link_splice<link_type>(before, *isource.p_value);
1000 
1001  if (&other != this)
1002  {
1003  ++this->current_size;
1004  --other.current_size;
1005  }
1006  }
1007 
1008  //*************************************************************************
1010  //*************************************************************************
1011  void splice(iterator position, list_type& other, iterator begin_, iterator end_)
1012  {
1013  if (!other.empty())
1014  {
1015  if (&other != this)
1016  {
1017  size_t n = etl::distance(begin_, end_);
1018  this->current_size += n;
1019  other.current_size -= n;
1020  }
1021 
1022  link_type& first = *begin_.p_value;
1023  link_type& last = *end_.p_value->link_type::etl_previous;
1024 
1025  // Unlink from the source list.
1026  etl::unlink(first, last);
1027 
1028  // Fix our links.
1029  link_type& before = *position.p_value->link_type::etl_previous;
1030 
1031  etl::link_splice<link_type>(before, first, last);
1032  }
1033  }
1034 
1035  //*************************************************************************
1037  //*************************************************************************
1038  void merge(list_type& other)
1039  {
1040  merge(other, etl::less<value_type>());
1041  }
1042 
1043  //*************************************************************************
1045  //*************************************************************************
1046  template <typename TCompare>
1047  void merge(list_type& other, TCompare compare)
1048  {
1049  if ((this != &other) && !other.empty())
1050  {
1051 #if defined(ETL_DEBUG)
1052  ETL_ASSERT(etl::is_sorted(other.begin(), other.end(), compare), ETL_ERROR(intrusive_list_unsorted));
1054 #endif
1055 
1056  value_type* other_begin = static_cast<value_type*>(other.get_head());
1057  value_type* other_end = static_cast<value_type*>(&other.terminal_link);
1058 
1059  value_type* this_begin = static_cast<value_type*>(this->get_head());
1060  value_type* this_end = static_cast<value_type*>(&this->terminal_link);
1061 
1062  while ((this_begin != this_end) && (other_begin != other_end))
1063  {
1064  // Find the place to insert.
1065  while ((this_begin != this_end) && !(compare(*other_begin, *this_begin)))
1066  {
1067  this_begin = static_cast<value_type*>(this_begin->link_type::etl_next);
1068  }
1069 
1070  // Insert.
1071  if (this_begin != this_end)
1072  {
1073  while ((other_begin != other_end) && (compare(*other_begin, *this_begin)))
1074  {
1075  value_type* value = other_begin;
1076  other_begin = static_cast<value_type*>(other_begin->link_type::etl_next);
1077  etl::link_splice<link_type>(*this_begin->link_type::etl_previous, *value);
1078  }
1079  }
1080  }
1081 
1082  // Any left over?
1083  if ((this_begin == this_end) && (other_begin != other_end))
1084  {
1085  etl::link_splice<link_type>(*this->get_tail(), *other_begin, *other_end->link_type::etl_previous);
1086  }
1087 
1088  this->current_size += other.size();
1089 
1090  other.initialise();
1091  }
1092  }
1093 
1094  private:
1095 
1096  // Disabled.
1097  intrusive_list(const intrusive_list& other);
1098  intrusive_list& operator = (const intrusive_list& rhs);
1099  };
1100 }
1101 
1102 #include "private/minmax_pop.h"
1103 
1104 #undef ETL_FILE
1105 
1106 #endif
const_iterator
Definition: intrusive_list.h:493
iterator.
Definition: intrusive_list.h:387
Definition: intrusive_list.h:121
void remove_link(link_type &link)
Remove a link.
Definition: intrusive_list.h:303
size_t size() const
Returns the number of elements.
Definition: intrusive_list.h:233
void insert_link(link_type &previous, link_type &new_link)
Insert a link.
Definition: intrusive_list.h:263
~intrusive_list_base()
Destructor.
Definition: intrusive_list.h:248
void assign(TIterator first, TIterator last)
Definition: intrusive_list.h:133
link_type * get_tail()
Get the tail link.
Definition: intrusive_list.h:337
size_t current_size
Counts the number of elements in the list.
Definition: intrusive_list.h:243
void remove_link(link_type *link)
Remove a link.
Definition: intrusive_list.h:312
const link_type * get_tail() const
Get the tail link.
Definition: intrusive_list.h:345
void insert_link(link_type &previous, link_type *new_link)
Insert a link.
Definition: intrusive_list.h:283
void pop_back()
Removes a value from the back of the intrusive_list.
Definition: intrusive_list.h:184
bool empty() const
Returns true if the list has no elements.
Definition: intrusive_list.h:225
void initialise()
Initialise the intrusive_list.
Definition: intrusive_list.h:353
void reverse()
Reverses the list.
Definition: intrusive_list.h:203
void insert_link(link_type *previous, link_type *new_link)
Insert a link.
Definition: intrusive_list.h:293
link_type terminal_link
The link that acts as the intrusive_list start & end.
Definition: intrusive_list.h:241
void insert_link(link_type *previous, link_type &new_link)
Insert a link.
Definition: intrusive_list.h:273
void clear()
Clears the intrusive_list.
Definition: intrusive_list.h:195
void push_front(link_type &value)
Pushes a value to the front of the intrusive_list.
Definition: intrusive_list.h:157
void push_back(link_type &value)
Pushes a value to the back of the intrusive_list.
Definition: intrusive_list.h:176
const link_type * get_head() const
Get the head link.
Definition: intrusive_list.h:329
void pop_front()
Removes a value from the front of the intrusive_list.
Definition: intrusive_list.h:165
link_type * get_head()
Get the head link.
Definition: intrusive_list.h:321
bool is_trivial_list() const
Is the intrusive_list a trivial length?
Definition: intrusive_list.h:255
Definition: intrusive_list.h:78
Definition: intrusive_list.h:64
Definition: intrusive_list.h:92
Definition: intrusive_list.h:106
Definition: intrusive_list.h:367
iterator erase(iterator first, iterator last)
Definition: intrusive_list.h:730
~intrusive_list()
Destructor.
Definition: intrusive_list.h:597
const_iterator end() const
Gets the end of the intrusive_list.
Definition: intrusive_list.h:646
reference back()
Gets a reference to the last element.
Definition: intrusive_list.h:678
intrusive_list(TIterator first, TIterator last)
Constructor from range.
Definition: intrusive_list.h:606
iterator begin()
Gets the beginning of the intrusive_list.
Definition: intrusive_list.h:614
void unique(TIsEqual isEqual)
Definition: intrusive_list.h:755
const_iterator begin() const
Gets the beginning of the intrusive_list.
Definition: intrusive_list.h:622
void splice(iterator position, list_type &other)
Splice another list into this one.
Definition: intrusive_list.h:965
void splice(iterator position, list_type &other, iterator begin_, iterator end_)
Splice a range of elements from another list into this one.
Definition: intrusive_list.h:1011
void insert(iterator position, TIterator first, TIterator last)
Inserts a range of values to the intrusive_list after the specified position.
Definition: intrusive_list.h:704
reference front()
Gets a reference to the first element.
Definition: intrusive_list.h:662
void merge(list_type &other, TCompare compare)
Merge another list into this one. Both lists should be sorted.
Definition: intrusive_list.h:1047
void sort(TCompare compare)
Definition: intrusive_list.h:814
void splice(iterator position, list_type &other, iterator isource)
Splice an element from another list into this one.
Definition: intrusive_list.h:994
intrusive_list()
Constructor.
Definition: intrusive_list.h:589
const_iterator cend() const
Gets the end of the intrusive_list.
Definition: intrusive_list.h:654
iterator erase(iterator position)
Erases the value at the specified position.
Definition: intrusive_list.h:716
const_iterator cbegin() const
Gets the beginning of the intrusive_list.
Definition: intrusive_list.h:630
void remove_if(TPredicate predicate)
Removes according to a predicate.
Definition: intrusive_list.h:945
void sort()
Sort using in-place merge sort algorithm.
Definition: intrusive_list.h:783
iterator insert(iterator position, value_type &value)
Inserts a value to the intrusive_list before the specified position.
Definition: intrusive_list.h:694
const_reference front() const
Gets a const reference to the first element.
Definition: intrusive_list.h:670
iterator end()
Gets the end of the intrusive_list.
Definition: intrusive_list.h:638
const_reference back() const
Gets a const reference to the last element.
Definition: intrusive_list.h:686
void merge(list_type &other)
Merge another list into this one. Both lists should be sorted.
Definition: intrusive_list.h:1038
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