31#ifndef ETL_INTRUSIVE_FORWARD_LIST_INCLUDED
32#define ETL_INTRUSIVE_FORWARD_LIST_INCLUDED
54 class intrusive_forward_list_exception :
public exception
58 intrusive_forward_list_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
59 :
exception(reason_, file_name_, line_number_)
68 class intrusive_forward_list_empty :
public intrusive_forward_list_exception
72 intrusive_forward_list_empty(string_type file_name_, numeric_type line_number_)
73 : intrusive_forward_list_exception(ETL_ERROR_TEXT(
"intrusive_forward_list:empty", ETL_INTRUSIVE_FORWARD_LIST_FILE_ID
"A"), file_name_, line_number_)
82 class intrusive_forward_list_iterator_exception :
public intrusive_forward_list_exception
86 intrusive_forward_list_iterator_exception(string_type file_name_, numeric_type line_number_)
87 : intrusive_forward_list_exception(ETL_ERROR_TEXT(
"intrusive_forward_list:iterator", ETL_INTRUSIVE_FORWARD_LIST_FILE_ID
"B"), file_name_, line_number_)
96 class intrusive_forward_list_index_exception :
public intrusive_forward_list_exception
100 intrusive_forward_list_index_exception(string_type file_name_, numeric_type line_number_)
101 : intrusive_forward_list_exception(ETL_ERROR_TEXT(
"intrusive_forward_list:bounds", ETL_INTRUSIVE_FORWARD_LIST_FILE_ID
"C"), file_name_, line_number_)
110 class intrusive_forward_list_unsorted :
public intrusive_forward_list_exception
114 intrusive_forward_list_unsorted(string_type file_name_, numeric_type line_number_)
115 : intrusive_forward_list_exception(ETL_ERROR_TEXT(
"intrusive_forward_list:unsorted", ETL_INTRUSIVE_FORWARD_LIST_FILE_ID
"D"), file_name_, line_number_)
124 class intrusive_forward_list_value_is_already_linked :
public intrusive_forward_list_exception
128 intrusive_forward_list_value_is_already_linked(string_type file_name_, numeric_type line_number_)
129 : intrusive_forward_list_exception(ETL_ERROR_TEXT(
"intrusive_forward_list:value is already linked", ETL_INTRUSIVE_FORWARD_LIST_FILE_ID
"E"), file_name_, line_number_)
138 template <
typename TLink>
144 typedef TLink link_type;
152 link_type* p_unlink =
start.etl_next;
156 link_type* p_next = p_unlink->etl_next;
168 template <
typename TIterator>
169 void assign(TIterator first, TIterator last)
171#if ETL_IS_DEBUG_BUILD
172 intmax_t d = etl::distance(first, last);
178 link_type* p_last = &
start;
181 while (first != last)
183 link_type& value = *first++;
187 value.etl_next = p_last->etl_next;
188 p_last->etl_next = &value;
225 link_type* current =
start.etl_next;
226 link_type* next =
start.etl_next;
230 next = next->etl_next;
231 current->etl_next = previous;
236 etl::link<link_type>(
start, previous);
301 return (
size() <= 1U);
310 etl::link_splice<link_type>(position, link);
319 link_type* p_next = link.etl_next;
321 if (p_next != &this->terminator)
323 link_type* p_unlinked = etl::unlink_after<link_type>(link);
324 if (p_unlinked != ETL_NULLPTR)
337 return start.etl_next;
345 return start.etl_next;
363 link_type* p_link =
start.etl_next;
364 link_type* p_previous =
const_cast<link_type*
>(&
start);
366 while (p_link != ETL_NULLPTR)
368 if (search_link == p_link)
374 p_link = p_link->link_type::etl_next;
387 link_type* result = ETL_NULLPTR;
391 if (p_previous != ETL_NULLPTR)
393 link_type* p_next = link->etl_next;
397 if (p_next != &this->terminator)
411 link_type* p_after = p_first->etl_next;
414 etl::link<link_type>(p_first, p_last);
417 link_type* p_unlink = p_after;
419 while (p_unlink != p_last)
421 link_type* p_next = p_unlink->etl_next;
426 if (p_after == &this->terminator)
437 template <
typename TLink>
445 template <
typename TValue,
typename TLink>
451 typedef typename etl::intrusive_forward_list_base<TLink>::link_type link_type;
454 typedef TValue value_type;
455 typedef value_type* pointer;
456 typedef const value_type* const_pointer;
457 typedef value_type& reference;
458 typedef const value_type& const_reference;
459 typedef size_t size_type;
463 typedef TValue node_type;
468 class iterator :
public etl::iterator<ETL_OR_STD::forward_iterator_tag, value_type>
472 friend class intrusive_forward_list;
473 friend class const_iterator;
476 : p_value(ETL_NULLPTR)
480 iterator(
const iterator& other)
481 : p_value(other.p_value)
485 iterator& operator ++()
488 p_value = p_value->etl_next;
492 iterator operator ++(
int)
494 iterator temp(*
this);
496 p_value = p_value->etl_next;
500 iterator& operator =(
const iterator& other)
502 p_value = other.p_value;
509 return *
static_cast<pointer
>(p_value);
513 pointer operator &()
const
515 return static_cast<pointer
>(p_value);
518 pointer operator ->()
const
520 return static_cast<pointer
>(p_value);
523 friend bool operator == (
const iterator& lhs,
const iterator& rhs)
525 return lhs.p_value == rhs.p_value;
528 friend bool operator != (
const iterator& lhs,
const iterator& rhs)
530 return !(lhs == rhs);
535 iterator(link_type* value)
546 class const_iterator :
public etl::iterator<ETL_OR_STD::forward_iterator_tag, const value_type>
550 friend class intrusive_forward_list;
553 : p_value(ETL_NULLPTR)
558 : p_value(other.p_value)
562 const_iterator(
const const_iterator& other)
563 : p_value(other.p_value)
567 const_iterator& operator ++()
570 p_value = p_value->etl_next;
574 const_iterator operator ++(
int)
576 const_iterator temp(*
this);
578 p_value = p_value->etl_next;
582 const_iterator& operator =(
const const_iterator& other)
584 p_value = other.p_value;
588 const_reference operator *()
const
590 return *
static_cast<const value_type*
>(p_value);
593 const_pointer operator &()
const
595 return static_cast<const value_type*
>(p_value);
598 const_pointer operator ->()
const
600 return static_cast<const value_type*
>(p_value);
603 friend bool operator == (
const const_iterator& lhs,
const const_iterator& rhs)
605 return lhs.p_value == rhs.p_value;
608 friend bool operator != (
const const_iterator& lhs,
const const_iterator& rhs)
610 return !(lhs == rhs);
615 const_iterator(
const link_type* value)
620 const link_type* p_value;
623 typedef typename etl::iterator_traits<iterator>::difference_type difference_type;
642 template <
typename TIterator>
645 this->
assign(first, last);
652 template <
typename... TLinks>
655 ETL_STATIC_ASSERT((etl::is_base_of_all<link_type, TLinks...>::value),
"Mixed link types");
658 this->
start.etl_next = &first;
677 return const_iterator(this->
get_head());
685 return iterator(&this->
start);
693 return const_iterator(&this->
start);
701 return const_iterator(this->
get_head());
715 const_iterator
end()
const
733 return *
static_cast<pointer
>(this->
get_head());
741 return *
static_cast<const value_type*
>(this->
get_head());
752 return iterator(&value);
758 template <
typename TIterator>
761 while (first != last)
777 iterator next(position);
796 if (first !=
end() && (first != last))
800 link_type* p_first = first.p_value;
801 link_type* p_last = last.p_value;
804 if (p_after == ETL_NULLPTR)
822 node_type*
erase(
const node_type& node)
824 return static_cast<node_type*
>(this->
remove_link(
const_cast<node_type*
>(&node)));
830 node_type*
erase(
const node_type* p_node)
832 return static_cast<node_type*
>(this->
remove_link(
const_cast<node_type*
>(p_node)));
839 template <
typename TIsEqual>
848 link_type* current = last->etl_next;
853 if (isEqual(*
static_cast<pointer
>(current), *
static_cast<pointer
>(last)))
863 current = last->etl_next;
900 template <
typename TCompare>
909 int number_of_merges;
924 number_of_merges = 0;
926 while (i_left !=
end())
933 for (
int i = 0; i < list_size; ++i)
939 if (i_right ==
end())
946 right_size = list_size;
949 while (left_size > 0 || (right_size > 0 && i_right !=
end()))
959 else if (right_size == 0 || i_right ==
end())
966 else if (!
compare(*i_right, *i_left))
984 etl::link<link_type>(i_head.p_value, i_link.p_value);
990 etl::link<link_type>(i_tail.p_value, i_link.p_value);
1002 if (number_of_merges <= 1)
1015 void remove(const_reference value)
1020 while (i_item !=
end())
1022 if (*i_item == value)
1037 template <
typename TPredicate>
1040 iterator i_item =
begin();
1043 while (i_item !=
end())
1045 if (predicate(*i_item))
1067 link_type& first = *other.
get_head();
1074 link_type& before = *position.p_value;
1075 link_type& after = *position.p_value->etl_next;
1077 etl::link<link_type>(before, first);
1079 link_type* last = &before;
1082 last = last->etl_next;
1085 etl::link<link_type>(last, after);
1097 link_type& before = *position.p_value;
1099 etl::unlink<link_type>(*isource.p_value);
1100 etl::link_splice<link_type>(before, *isource.p_value);
1118 size_t n = etl::distance(begin_, end_) - 1;
1123 link_type* first = begin_.p_value;
1124 link_type* last = first;
1126 while (last->etl_next != end_.p_value)
1128 last = last->etl_next;
1132 link_type* first_next = first->etl_next;
1133 etl::unlink_after(*first, *last);
1136 link_type* before = position.p_value;
1138 etl::link_splice<link_type>(*before, *first_next, *last);
1153 template <
typename TCompare>
1156 if ((
this != &other) && !other.
empty())
1158#if ETL_IS_DEBUG_BUILD
1163 link_type* other_begin = other.
get_head();
1164 link_type* other_terminal = &other.
terminator;
1166 link_type* before = &this->
start;
1167 link_type* before_next = get_next(before);
1170 while ((before->etl_next != terminal) && (other_begin != other_terminal))
1173 while ((before_next != terminal) && !(
compare(*
static_cast<pointer
>(other_begin), *
static_cast<pointer
>(before_next))))
1175 before = before_next;
1176 before_next = get_next(before_next);
1180 if (before_next != terminal)
1182 while ((other_begin != other_terminal) && (
compare(*
static_cast<pointer
>(other_begin), *
static_cast<pointer
>(before_next))))
1184 link_type* value = other_begin;
1185 other_begin = get_next(other_begin);
1186 etl::link_splice<link_type>(*before, *value);
1187 before = get_next(before);
1193 if (before_next == terminal)
1195 while (other_begin != other_terminal)
1197 link_type* value = other_begin;
1198 other_begin = get_next(other_begin);
1199 etl::link_splice<link_type>(*before, *value);
1200 before = get_next(before);
1216 const_iterator i_item =
begin();
1218 while (i_item !=
end())
1220 if (*i_item == value)
1237 template <
typename... TLinks>
1242 ((current->etl_next = &links, current = &links, ++count), ...);
1246#elif ETL_USING_CPP11
1250 link_type* make_linked_list(
size_t& count, link_type& first)
1259 template <
typename... TLinks>
1260 link_type* make_linked_list(
size_t& count, link_type& first, link_type& next, TLinks&... links)
1263 first.etl_next = &next;
1264 return make_linked_list(count, next,
static_cast<link_type&
>(links)...);
1271 link_type* get_next(link_type* link)
const
1273 return link->etl_next;
iterator.
Definition intrusive_forward_list.h:469
Definition intrusive_forward_list.h:140
bool contains_node(const link_type &search_link) const
Definition intrusive_forward_list.h:259
bool is_trivial_list() const
Is the intrusive_forward_list a trivial length?
Definition intrusive_forward_list.h:299
link_type start
Definition intrusive_forward_list.h:275
void reverse()
Reverses the intrusive_forward_list.
Definition intrusive_forward_list.h:217
void insert_link_after(link_type &position, link_type &link)
Insert a link.
Definition intrusive_forward_list.h:307
~intrusive_forward_list_base()
Destructor.
Definition intrusive_forward_list.h:291
bool empty() const
Returns true if the list has no elements.
Definition intrusive_forward_list.h:242
static link_type terminator
Definition intrusive_forward_list.h:276
size_t current_size
Definition intrusive_forward_list.h:278
intrusive_forward_list_base()
Constructor.
Definition intrusive_forward_list.h:283
link_type * remove_link(link_type *link)
Definition intrusive_forward_list.h:385
bool contains_node(const link_type *search_link) const
Definition intrusive_forward_list.h:268
void initialise()
Initialise the intrusive_forward_list.
Definition intrusive_forward_list.h:351
void pop_front()
Removes a value from the front of the intrusive_forward_list.
Definition intrusive_forward_list.h:207
link_type * is_link_in_list(const link_type *search_link) const
Definition intrusive_forward_list.h:361
link_type * get_head()
Get the head link.
Definition intrusive_forward_list.h:335
const link_type * get_head() const
Get the head link.
Definition intrusive_forward_list.h:343
void disconnect_link_after(link_type &link)
Remove a link.
Definition intrusive_forward_list.h:317
void assign(TIterator first, TIterator last)
Definition intrusive_forward_list.h:169
size_t size() const
Returns the number of elements.
Definition intrusive_forward_list.h:250
void push_front(link_type &value)
Pushes a value to the front of the intrusive_forward_list.
Definition intrusive_forward_list.h:197
void clear()
Clears the intrusive_forward_list.
Definition intrusive_forward_list.h:149
link_type * remove_link_range_after(link_type *p_first, link_type *p_last)
Remove a range of elements.
Definition intrusive_forward_list.h:409
Definition intrusive_forward_list.h:69
Definition intrusive_forward_list.h:83
Definition intrusive_forward_list.h:111
Definition intrusive_forward_list.h:125
Definition intrusive_forward_list.h:447
const_iterator before_begin() const
Gets before the beginning of the intrusive_forward_list.
Definition intrusive_forward_list.h:691
bool contains(const_reference value) const
Definition intrusive_forward_list.h:1214
iterator erase_after(iterator first, iterator last)
Erases a range of elements.
Definition intrusive_forward_list.h:794
void sort(TCompare compare)
Definition intrusive_forward_list.h:901
const_iterator cbegin() const
Gets the beginning of the intrusive_forward_list.
Definition intrusive_forward_list.h:699
void splice_after(iterator position, etl::intrusive_forward_list< TValue, TLink > &other)
Splice another list into this one.
Definition intrusive_forward_list.h:1060
~intrusive_forward_list()
Destructor.
Definition intrusive_forward_list.h:635
void unique(TIsEqual isEqual)
Definition intrusive_forward_list.h:840
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:1112
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:1095
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:759
intrusive_forward_list(TIterator first, TIterator last, typename etl::enable_if<!etl::is_integral< TIterator >::value, int >::type=0)
Constructor from range.
Definition intrusive_forward_list.h:643
void remove_if(TPredicate predicate)
Removes according to a predicate.
Definition intrusive_forward_list.h:1038
iterator erase_after(iterator position)
Erases the value at the specified position.
Definition intrusive_forward_list.h:775
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:747
const_iterator begin() const
Gets the beginning of the intrusive_forward_list.
Definition intrusive_forward_list.h:675
void merge(list_type &other, TCompare compare)
Merge another list into this one. Both lists should be sorted.
Definition intrusive_forward_list.h:1154
iterator end()
Gets the end of the intrusive_forward_list.
Definition intrusive_forward_list.h:707
iterator before_begin()
Gets before the beginning of the intrusive_forward_list.
Definition intrusive_forward_list.h:683
const_iterator end() const
Gets the end of the intrusive_forward_list.
Definition intrusive_forward_list.h:715
const_reference front() const
Gets a const reference to the first element.
Definition intrusive_forward_list.h:739
const_iterator cend() const
Gets the end of the intrusive_forward_list.
Definition intrusive_forward_list.h:723
void merge(list_type &other)
Merge another list into this one. Both lists should be sorted.
Definition intrusive_forward_list.h:1145
void sort()
Sort using in-place merge sort algorithm.
Definition intrusive_forward_list.h:870
intrusive_forward_list()
Constructor.
Definition intrusive_forward_list.h:628
iterator begin()
Gets the beginning of the intrusive_forward_list.
Definition intrusive_forward_list.h:667
node_type * erase(const node_type *p_node)
Erases the specified node.
Definition intrusive_forward_list.h:830
node_type * erase(const node_type &node)
Erases the specified node.
Definition intrusive_forward_list.h:822
reference front()
Gets a reference to the first element.
Definition intrusive_forward_list.h:731
ETL_CONSTEXPR14 bool operator==(const etl::expected< TValue, TError > &lhs, const etl::expected< TValue2, TError2 > &rhs)
Equivalence operators.
Definition expected.h:962
ETL_NODISCARD ETL_CONSTEXPR14 bool is_sorted(TIterator begin, TIterator end)
Definition algorithm.h:1709
ETL_CONSTEXPR14 TIterator remove(TIterator first, TIterator last, const T &value)
Definition algorithm.h:2300
#define ETL_ASSERT(b, e)
Definition error_handler.h:356
ETL_CONSTEXPR exception(string_type reason_, string_type, numeric_type line_)
Constructor.
Definition exception.h:69
enable_if
Definition type_traits_generator.h:1254
bitset_ext
Definition absolute.h:39
ETL_CONSTEXPR14 enable_if<!etl::is_specialization< TRep2, etl::chrono::duration >::value, etl::chrono::duration< typenameetl::common_type< TRep1, TRep2 >::type, TPeriod1 > >::type operator*(const etl::chrono::duration< TRep1, TPeriod1 > &lhs, const TRep2 &rhs) ETL_NOEXCEPT
Operator *.
Definition duration.h:545
iterator
Definition iterator.h:399
Definition functional.h:170