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_,
83 class intrusive_forward_list_iterator_exception :
public intrusive_forward_list_exception
87 intrusive_forward_list_iterator_exception(string_type file_name_, numeric_type line_number_)
88 : intrusive_forward_list_exception(ETL_ERROR_TEXT(
"intrusive_forward_list:iterator", ETL_INTRUSIVE_FORWARD_LIST_FILE_ID
"B"), file_name_,
98 class intrusive_forward_list_index_exception :
public intrusive_forward_list_exception
102 intrusive_forward_list_index_exception(string_type file_name_, numeric_type line_number_)
103 : intrusive_forward_list_exception(ETL_ERROR_TEXT(
"intrusive_forward_list:bounds", ETL_INTRUSIVE_FORWARD_LIST_FILE_ID
"C"), file_name_,
113 class intrusive_forward_list_unsorted :
public intrusive_forward_list_exception
117 intrusive_forward_list_unsorted(string_type file_name_, numeric_type line_number_)
118 : intrusive_forward_list_exception(ETL_ERROR_TEXT(
"intrusive_forward_list:unsorted", ETL_INTRUSIVE_FORWARD_LIST_FILE_ID
"D"), file_name_,
128 class intrusive_forward_list_value_is_already_linked :
public intrusive_forward_list_exception
132 intrusive_forward_list_value_is_already_linked(string_type file_name_, numeric_type line_number_)
133 : intrusive_forward_list_exception(ETL_ERROR_TEXT(
"intrusive_forward_list:value is already linked", ETL_INTRUSIVE_FORWARD_LIST_FILE_ID
"E"),
134 file_name_, line_number_)
143 template <
typename TLink>
149 typedef TLink link_type;
157 link_type* p_unlink =
start.etl_next;
161 link_type* p_next = p_unlink->etl_next;
174 template <
typename TIterator>
175 void assign(TIterator first, TIterator last)
177#if ETL_IS_DEBUG_BUILD
178 intmax_t d = etl::distance(first, last);
184 link_type* p_last = &
start;
187 while (first != last)
189 link_type& value = *first++;
193 value.etl_next = p_last->etl_next;
194 p_last->etl_next = &value;
231 link_type* current =
start.etl_next;
233 link_type* next =
start.etl_next;
238 next = next->etl_next;
239 current->etl_next = previous;
244 etl::link<link_type>(
start, previous);
311 return (
size() <= 1U);
320 etl::link_splice<link_type>(position, link);
329 link_type* p_next = link.etl_next;
331 if (p_next != &this->terminator)
333 link_type* p_unlinked = etl::unlink_after<link_type>(link);
334 if (p_unlinked != ETL_NULLPTR)
347 return start.etl_next;
355 return start.etl_next;
373 link_type* p_link =
start.etl_next;
374 link_type* p_previous =
const_cast<link_type*
>(&
start);
376 while (p_link != ETL_NULLPTR)
378 if (search_link == p_link)
384 p_link = p_link->link_type::etl_next;
397 link_type* result = ETL_NULLPTR;
401 if (p_previous != ETL_NULLPTR)
403 link_type* p_next = link->etl_next;
407 if (p_next != &this->terminator)
421 link_type* p_after = p_first->etl_next;
424 etl::link<link_type>(p_first, p_last);
427 link_type* p_unlink = p_after;
429 while (p_unlink != p_last)
431 link_type* p_next = p_unlink->etl_next;
436 if (p_after == &this->terminator)
447 template <
typename TLink>
455 template <
typename TValue,
typename TLink>
461 typedef typename etl::intrusive_forward_list_base<TLink>::link_type link_type;
464 typedef TValue value_type;
465 typedef value_type* pointer;
466 typedef const value_type* const_pointer;
467 typedef value_type& reference;
468 typedef const value_type& const_reference;
469 typedef size_t size_type;
473 typedef TValue node_type;
478 class iterator :
public etl::iterator<ETL_OR_STD::forward_iterator_tag, value_type>
482 friend class intrusive_forward_list;
483 friend class const_iterator;
486 : p_value(ETL_NULLPTR)
490 iterator(
const iterator& other)
491 : p_value(other.p_value)
495 iterator& operator++()
498 p_value = p_value->etl_next;
502 iterator operator++(
int)
504 iterator temp(*
this);
506 p_value = p_value->etl_next;
510 iterator& operator=(
const iterator& other)
512 p_value = other.p_value;
519 return *
static_cast<pointer
>(p_value);
523 pointer operator&()
const
525 return static_cast<pointer
>(p_value);
528 pointer operator->()
const
530 return static_cast<pointer
>(p_value);
533 friend bool operator==(
const iterator& lhs,
const iterator& rhs)
535 return lhs.p_value == rhs.p_value;
538 friend bool operator!=(
const iterator& lhs,
const iterator& rhs)
540 return !(lhs == rhs);
545 iterator(link_type* value)
556 class const_iterator :
public etl::iterator<ETL_OR_STD::forward_iterator_tag, const value_type>
560 friend class intrusive_forward_list;
563 : p_value(ETL_NULLPTR)
568 : p_value(other.p_value)
572 const_iterator(
const const_iterator& other)
573 : p_value(other.p_value)
577 const_iterator& operator++()
580 p_value = p_value->etl_next;
584 const_iterator operator++(
int)
586 const_iterator temp(*
this);
588 p_value = p_value->etl_next;
592 const_iterator& operator=(
const const_iterator& other)
594 p_value = other.p_value;
598 const_reference operator*()
const
600 return *
static_cast<const value_type*
>(p_value);
603 const_pointer operator&()
const
605 return static_cast<const value_type*
>(p_value);
608 const_pointer operator->()
const
610 return static_cast<const value_type*
>(p_value);
613 friend bool operator==(
const const_iterator& lhs,
const const_iterator& rhs)
615 return lhs.p_value == rhs.p_value;
618 friend bool operator!=(
const const_iterator& lhs,
const const_iterator& rhs)
620 return !(lhs == rhs);
625 const_iterator(
const link_type* value)
630 const link_type* p_value;
633 typedef typename etl::iterator_traits<iterator>::difference_type difference_type;
648 template <
typename TIterator>
651 this->
assign(first, last);
658 template <
typename... TLinks>
661 ETL_STATIC_ASSERT((etl::is_base_of_all<link_type, TLinks...>::value),
"Mixed link types");
664 this->
start.etl_next = &first;
683 return const_iterator(this->
get_head());
691 return iterator(&this->
start);
699 return const_iterator(&this->
start);
707 return const_iterator(this->
get_head());
721 const_iterator
end()
const
742 return *
static_cast<pointer
>(this->
get_head());
753 return *
static_cast<const value_type*
>(this->
get_head());
765 return iterator(&value);
772 template <
typename TIterator>
775 while (first != last)
791 iterator next(position);
810 if (first !=
end() && (first != last))
812 this->
current_size -=
static_cast<size_t>(etl::distance(first, last) - 1);
814 link_type* p_first = first.p_value;
815 link_type* p_last = last.p_value;
818 if (p_after == ETL_NULLPTR)
836 node_type*
erase(
const node_type& node)
838 return static_cast<node_type*
>(this->
remove_link(
const_cast<node_type*
>(&node)));
844 node_type*
erase(
const node_type* p_node)
846 return static_cast<node_type*
>(this->
remove_link(
const_cast<node_type*
>(p_node)));
853 template <
typename TIsEqual>
862 link_type* current = last->etl_next;
867 if (isEqual(*
static_cast<pointer
>(current), *
static_cast<pointer
>(last)))
877 current = last->etl_next;
914 template <
typename TCompare>
923 int number_of_merges;
938 number_of_merges = 0;
940 while (i_left !=
end())
947 for (
int i = 0; i < list_size; ++i)
953 if (i_right ==
end())
960 right_size = list_size;
963 while (left_size > 0 || (right_size > 0 && i_right !=
end()))
973 else if (right_size == 0 || i_right ==
end())
980 else if (!
compare(*i_right, *i_left))
999 etl::link<link_type>(i_head.p_value, i_link.p_value);
1005 etl::link<link_type>(i_tail.p_value, i_link.p_value);
1009 i_tail.p_value->etl_next = &this->
terminator;
1017 if (number_of_merges <= 1)
1030 void remove(const_reference value)
1035 while (i_item !=
end())
1037 if (*i_item == value)
1052 template <
typename TPredicate>
1055 iterator i_item =
begin();
1058 while (i_item !=
end())
1060 if (predicate(*i_item))
1082 link_type& first = *other.
get_head();
1089 link_type& before = *position.p_value;
1090 link_type& after = *position.p_value->etl_next;
1092 etl::link<link_type>(before, first);
1094 link_type* last = &before;
1097 last = last->etl_next;
1100 etl::link<link_type>(last, after);
1112 link_type& before = *position.p_value;
1114 etl::unlink<link_type>(*isource.p_value);
1115 etl::link_splice<link_type>(before, *isource.p_value);
1133 size_t n =
static_cast<size_t>(etl::distance(begin_, end_) - 1);
1138 link_type* first = begin_.p_value;
1139 link_type* last = first;
1141 while (last->etl_next != end_.p_value)
1143 last = last->etl_next;
1147 link_type* first_next = first->etl_next;
1148 etl::unlink_after(*first, *last);
1151 link_type* before = position.p_value;
1153 etl::link_splice<link_type>(*before, *first_next, *last);
1168 template <
typename TCompare>
1171 if ((
this != &other) && !other.
empty())
1173#if ETL_IS_DEBUG_BUILD
1178 link_type* other_begin = other.
get_head();
1179 link_type* other_terminal = &other.
terminator;
1181 link_type* before = &this->
start;
1182 link_type* before_next = get_next(before);
1185 while ((before->etl_next != terminal) && (other_begin != other_terminal))
1188 while ((before_next != terminal) && !(
compare(*
static_cast<pointer
>(other_begin), *
static_cast<pointer
>(before_next))))
1190 before = before_next;
1191 before_next = get_next(before_next);
1195 if (before_next != terminal)
1197 while ((other_begin != other_terminal) && (
compare(*
static_cast<pointer
>(other_begin), *
static_cast<pointer
>(before_next))))
1199 link_type* value = other_begin;
1200 other_begin = get_next(other_begin);
1201 etl::link_splice<link_type>(*before, *value);
1202 before = get_next(before);
1208 if (before_next == terminal)
1210 while (other_begin != other_terminal)
1212 link_type* value = other_begin;
1213 other_begin = get_next(other_begin);
1214 etl::link_splice<link_type>(*before, *value);
1215 before = get_next(before);
1231 const_iterator i_item =
begin();
1233 while (i_item !=
end())
1235 if (*i_item == value)
1252 template <
typename... TLinks>
1257 ((current->etl_next = &links, current = &links, ++count), ...);
1261#elif ETL_USING_CPP11
1265 link_type* make_linked_list(
size_t& count, link_type& first)
1274 template <
typename... TLinks>
1275 link_type* make_linked_list(
size_t& count, link_type& first, link_type& next, TLinks&... links)
1278 first.etl_next = &next;
1279 return make_linked_list(count, next,
static_cast<link_type&
>(links)...);
1286 link_type* get_next(link_type* link)
const
1288 return link->etl_next;
iterator.
Definition intrusive_forward_list.h:479
Definition intrusive_forward_list.h:145
bool contains_node(const link_type &search_link) const
Definition intrusive_forward_list.h:267
bool is_trivial_list() const
Is the intrusive_forward_list a trivial length?
Definition intrusive_forward_list.h:309
link_type start
Definition intrusive_forward_list.h:283
void reverse()
Reverses the intrusive_forward_list.
Definition intrusive_forward_list.h:223
void insert_link_after(link_type &position, link_type &link)
Insert a link.
Definition intrusive_forward_list.h:317
~intrusive_forward_list_base()
Destructor.
Definition intrusive_forward_list.h:301
bool empty() const
Returns true if the list has no elements.
Definition intrusive_forward_list.h:250
static link_type terminator
Definition intrusive_forward_list.h:285
size_t current_size
Definition intrusive_forward_list.h:288
intrusive_forward_list_base()
Constructor.
Definition intrusive_forward_list.h:293
link_type * remove_link(link_type *link)
Definition intrusive_forward_list.h:395
bool contains_node(const link_type *search_link) const
Definition intrusive_forward_list.h:276
void initialise()
Initialise the intrusive_forward_list.
Definition intrusive_forward_list.h:361
void pop_front()
Removes a value from the front of the intrusive_forward_list.
Definition intrusive_forward_list.h:213
link_type * is_link_in_list(const link_type *search_link) const
Definition intrusive_forward_list.h:371
link_type * get_head()
Get the head link.
Definition intrusive_forward_list.h:345
const link_type * get_head() const
Get the head link.
Definition intrusive_forward_list.h:353
void disconnect_link_after(link_type &link)
Remove a link.
Definition intrusive_forward_list.h:327
void assign(TIterator first, TIterator last)
Definition intrusive_forward_list.h:175
size_t size() const
Returns the number of elements.
Definition intrusive_forward_list.h:258
void push_front(link_type &value)
Pushes a value to the front of the intrusive_forward_list.
Definition intrusive_forward_list.h:203
void clear()
Clears the intrusive_forward_list.
Definition intrusive_forward_list.h:154
link_type * remove_link_range_after(link_type *p_first, link_type *p_last)
Remove a range of elements.
Definition intrusive_forward_list.h:419
Definition intrusive_forward_list.h:69
Definition intrusive_forward_list.h:84
Definition intrusive_forward_list.h:114
Definition intrusive_forward_list.h:129
Definition intrusive_forward_list.h:457
const_iterator before_begin() const
Gets before the beginning of the intrusive_forward_list.
Definition intrusive_forward_list.h:697
bool contains(const_reference value) const
Definition intrusive_forward_list.h:1229
iterator erase_after(iterator first, iterator last)
Erases a range of elements.
Definition intrusive_forward_list.h:808
void sort(TCompare compare)
Definition intrusive_forward_list.h:915
const_iterator cbegin() const
Gets the beginning of the intrusive_forward_list.
Definition intrusive_forward_list.h:705
void splice_after(iterator position, etl::intrusive_forward_list< TValue, TLink > &other)
Splice another list into this one.
Definition intrusive_forward_list.h:1075
~intrusive_forward_list()
Destructor.
Definition intrusive_forward_list.h:643
void unique(TIsEqual isEqual)
Definition intrusive_forward_list.h:854
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:1127
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:1110
void insert_after(iterator position, TIterator first, TIterator last)
Definition intrusive_forward_list.h:773
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:649
void remove_if(TPredicate predicate)
Removes according to a predicate.
Definition intrusive_forward_list.h:1053
iterator erase_after(iterator position)
Erases the value at the specified position.
Definition intrusive_forward_list.h:789
iterator insert_after(iterator position, value_type &value)
Definition intrusive_forward_list.h:760
const_iterator begin() const
Gets the beginning of the intrusive_forward_list.
Definition intrusive_forward_list.h:681
void merge(list_type &other, TCompare compare)
Merge another list into this one. Both lists should be sorted.
Definition intrusive_forward_list.h:1169
iterator end()
Gets the end of the intrusive_forward_list.
Definition intrusive_forward_list.h:713
iterator before_begin()
Gets before the beginning of the intrusive_forward_list.
Definition intrusive_forward_list.h:689
const_iterator end() const
Gets the end of the intrusive_forward_list.
Definition intrusive_forward_list.h:721
const_reference front() const
Definition intrusive_forward_list.h:750
const_iterator cend() const
Gets the end of the intrusive_forward_list.
Definition intrusive_forward_list.h:729
void merge(list_type &other)
Merge another list into this one. Both lists should be sorted.
Definition intrusive_forward_list.h:1160
void sort()
Sort using in-place merge sort algorithm.
Definition intrusive_forward_list.h:884
intrusive_forward_list()
Constructor.
Definition intrusive_forward_list.h:638
iterator begin()
Gets the beginning of the intrusive_forward_list.
Definition intrusive_forward_list.h:673
node_type * erase(const node_type *p_node)
Erases the specified node.
Definition intrusive_forward_list.h:844
node_type * erase(const node_type &node)
Erases the specified node.
Definition intrusive_forward_list.h:836
reference front()
Definition intrusive_forward_list.h:739
ETL_NODISCARD ETL_CONSTEXPR14 bool is_sorted(TIterator begin, TIterator end)
Definition algorithm.h:1660
ETL_CONSTEXPR14 TIterator remove(TIterator first, TIterator last, const T &value)
Definition algorithm.h:2344
ETL_CONSTEXPR14 bool operator!=(const etl::bitset< Active_Bits, TElement > &lhs, const etl::bitset< Active_Bits, TElement > &rhs) ETL_NOEXCEPT
Definition bitset_new.h:2529
#define ETL_ASSERT(b, e)
Definition error_handler.h:511
ETL_EXCEPTION_CONSTEXPR exception(string_type reason_, string_type, numeric_type)
Constructor.
Definition exception.h:81
bitset_ext
Definition absolute.h:40
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:541
iterator
Definition iterator.h:424
Definition functional.h:201