31#ifndef ETL_INTRUSIVE_LIST_INCLUDED
32#define ETL_INTRUSIVE_LIST_INCLUDED
42#include "static_assert.h"
59 intrusive_list_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
60 :
exception(reason_, file_name_, line_number_)
69 class intrusive_list_empty :
public intrusive_list_exception
73 intrusive_list_empty(string_type file_name_, numeric_type line_number_)
74 : intrusive_list_exception(ETL_ERROR_TEXT(
"intrusive_list:empty", ETL_INTRUSIVE_LIST_FILE_ID
"A"), file_name_, line_number_)
83 class intrusive_list_iterator_exception :
public intrusive_list_exception
87 intrusive_list_iterator_exception(string_type file_name_, numeric_type line_number_)
88 : intrusive_list_exception(ETL_ERROR_TEXT(
"intrusive_list:iterator", ETL_INTRUSIVE_LIST_FILE_ID
"B"), file_name_, line_number_)
97 class intrusive_list_unsorted :
public intrusive_list_exception
101 intrusive_list_unsorted(string_type file_name_, numeric_type line_number_)
102 : intrusive_list_exception(ETL_ERROR_TEXT(
"intrusive_list:unsorted", ETL_INTRUSIVE_LIST_FILE_ID
"C"), file_name_, line_number_)
111 class intrusive_list_value_is_already_linked :
public intrusive_list_exception
115 intrusive_list_value_is_already_linked(string_type file_name_, numeric_type line_number_)
116 : intrusive_list_exception(ETL_ERROR_TEXT(
"intrusive_list:value is already linked", ETL_INTRUSIVE_LIST_FILE_ID
"D"), file_name_, line_number_)
125 template <
typename TLink>
131 typedef TLink link_type;
138 template <
typename TIterator>
139 void assign(TIterator first, TIterator last)
141#if ETL_IS_DEBUG_BUILD
142 intmax_t d = etl::distance(first, last);
151 while (first != last)
153 link_type& link = *first++;
154 etl::link_splice<link_type>(p_last_link, link);
210 link_type* p_next = p_unlink->etl_next;
233 pnode = pnode->etl_previous;
301 etl::link_splice<link_type>(previous, new_link);
311 etl::link_splice<link_type>(previous, new_link);
321 etl::link_splice<link_type>(previous, new_link);
331 etl::link_splice<link_type>(previous, new_link);
340 etl::unlink<link_type>(link);
349 etl::unlink<link_type>(*link);
403 if (search_link == p_link)
408 p_link = p_link->link_type::etl_next;
421 link_type* result = ETL_NULLPTR;
425 link_type* p_next = link->etl_next;
444 etl::link<link_type>(p_first->etl_previous, p_last);
446 while (p_first != p_last)
448 link_type* p_next = p_first->etl_next;
469 template <
typename TValue,
typename TLink>
475 typedef typename etl::intrusive_list_base<TLink>::link_type link_type;
479 typedef TValue node_type;
482 typedef TValue value_type;
483 typedef value_type* pointer;
484 typedef const value_type* const_pointer;
485 typedef value_type& reference;
486 typedef const value_type& const_reference;
487 typedef size_t size_type;
492 class iterator :
public etl::iterator<ETL_OR_STD::bidirectional_iterator_tag, value_type>
496 friend class intrusive_list;
497 friend class const_iterator;
500 : p_value(ETL_NULLPTR)
504 iterator(
const iterator& other)
505 : p_value(other.p_value)
509 iterator& operator++()
512 p_value = p_value->etl_next;
516 iterator operator++(
int)
518 iterator temp(*
this);
520 p_value = p_value->etl_next;
524 iterator& operator--()
527 p_value = p_value->etl_previous;
531 iterator operator--(
int)
533 iterator temp(*
this);
535 p_value = p_value->etl_previous;
539 iterator& operator=(
const iterator& other)
541 p_value = other.p_value;
548 return *
static_cast<pointer
>(p_value);
552 pointer operator&()
const
554 return static_cast<pointer
>(p_value);
557 pointer operator->()
const
559 return static_cast<pointer
>(p_value);
562 friend bool operator==(
const iterator& lhs,
const iterator& rhs)
564 return lhs.p_value == rhs.p_value;
567 friend bool operator!=(
const iterator& lhs,
const iterator& rhs)
569 return !(lhs == rhs);
574 iterator(link_type* value)
585 class const_iterator :
public etl::iterator<ETL_OR_STD::bidirectional_iterator_tag, const value_type>
589 friend class intrusive_list;
592 : p_value(ETL_NULLPTR)
597 : p_value(other.p_value)
601 const_iterator(
const const_iterator& other)
602 : p_value(other.p_value)
606 const_iterator& operator++()
609 p_value = p_value->etl_next;
613 const_iterator operator++(
int)
615 const_iterator temp(*
this);
617 p_value = p_value->etl_next;
621 const_iterator& operator--()
624 p_value = p_value->etl_previous;
628 const_iterator operator--(
int)
630 const_iterator temp(*
this);
632 p_value = p_value->etl_previous;
636 const_iterator& operator=(
const const_iterator& other)
638 p_value = other.p_value;
642 const_reference operator*()
const
644 return *
static_cast<const_pointer
>(p_value);
647 const_pointer operator&()
const
649 return static_cast<const_pointer
>(p_value);
652 const_pointer operator->()
const
654 return static_cast<const_pointer
>(p_value);
657 friend bool operator==(
const const_iterator& lhs,
const const_iterator& rhs)
659 return lhs.p_value == rhs.p_value;
662 friend bool operator!=(
const const_iterator& lhs,
const const_iterator& rhs)
664 return !(lhs == rhs);
669 const_iterator(
const link_type* value)
674 const link_type* p_value;
677 typedef typename etl::iterator_traits<iterator>::difference_type difference_type;
698 template <
typename TIterator>
699 intrusive_list(TIterator first, TIterator last,
typename etl::enable_if<!etl::is_integral<TIterator>::value,
int>
::type = 0)
701 this->
assign(first, last);
708 template <
typename... TLinks>
711 ETL_STATIC_ASSERT((etl::is_base_of_all<link_type, TLinks...>::value),
"Mixed link types");
778 return *
static_cast<pointer
>(this->
get_head());
789 return *
static_cast<const_pointer
>(this->
get_head());
800 return *
static_cast<pointer
>(this->
get_tail());
811 return *
static_cast<const_pointer
>(this->
get_tail());
819 this->
insert_link(position.p_value->link_type::etl_previous, value);
827 template <
typename TIterator>
830 while (first != last)
833 this->
insert_link(*position.p_value->link_type::etl_previous, *first);
870 const link_type* cp_first = first.p_value;
871 const link_type* cp_last = last.p_value;
873 link_type* p_first =
const_cast<link_type*
>(cp_first);
874 link_type* p_last =
const_cast<link_type*
>(cp_last);
876 this->
current_size -=
static_cast<size_t>(etl::distance(first, last));
880 if (p_last == ETL_NULLPTR)
886 return iterator(
static_cast<pointer
>(p_last));
893 node_type*
erase(
const node_type& node)
895 return static_cast<node_type*
>(this->
remove_link(
const_cast<node_type*
>(&node)));
901 node_type*
erase(
const node_type* p_node)
903 return static_cast<node_type*
>(this->
remove_link(
const_cast<node_type*
>(p_node)));
910 template <
typename TIsEqual>
922 while (i_item !=
end())
924 if (isEqual(*i_previous, *i_item))
926 i_item =
erase(i_item);
969 template <
typename TCompare>
978 int number_of_merges;
993 number_of_merges = 0;
995 while (i_left !=
end())
1002 for (
int i = 0; i < list_size; ++i)
1007 if (i_right ==
end())
1014 right_size = list_size;
1017 while (left_size > 0 || (right_size > 0 && i_right !=
end()))
1026 else if (right_size == 0 || i_right ==
end())
1032 else if (!
compare(*i_right, *i_left))
1048 if (i_head ==
end())
1050 etl::link<link_type>(i_head.p_value, i_node.p_value);
1056 etl::link<link_type>(i_tail.p_value, i_node.p_value);
1060 etl::link<link_type>(i_tail.p_value, this->terminal_link);
1068 if (number_of_merges <= 1)
1081 void remove(const_reference value)
1085 while (i_item !=
end())
1087 if (*i_item == value)
1089 i_item =
erase(i_item);
1101 template <
typename TPredicate>
1106 while (i_item !=
end())
1108 if (predicate(*i_item))
1110 i_item =
erase(i_item);
1129 link_type& first = *other.
get_head();
1130 link_type& last = *other.
get_tail();
1137 link_type& after = *position.p_value;
1138 link_type& before = *after.etl_previous;
1140 etl::link<link_type>(before, first);
1141 etl::link<link_type>(last, after);
1153 link_type& before = *position.p_value->link_type::etl_previous;
1155 etl::unlink<link_type>(*isource.p_value);
1156 etl::link_splice<link_type>(before, *isource.p_value);
1174 size_t n =
static_cast<size_t>(etl::distance(begin_, end_));
1179 link_type& first = *begin_.p_value;
1180 link_type& last = *end_.p_value->link_type::etl_previous;
1183 etl::unlink(first, last);
1186 link_type& before = *position.p_value->link_type::etl_previous;
1188 etl::link_splice<link_type>(before, first, last);
1203 template <
typename TCompare>
1206 if ((
this != &other) && !other.
empty())
1208#if ETL_IS_DEBUG_BUILD
1213 link_type* other_begin = other.
get_head();
1216 link_type* this_begin = this->
get_head();
1219 while ((this_begin != this_end) && (other_begin != other_end))
1222 while ((this_begin != this_end) && !(
compare(*
static_cast<pointer
>(other_begin), *
static_cast<pointer
>(this_begin))))
1224 this_begin = this_begin->etl_next;
1228 if (this_begin != this_end)
1230 while ((other_begin != other_end) && (
compare(*
static_cast<pointer
>(other_begin), *
static_cast<pointer
>(this_begin))))
1232 link_type* value = other_begin;
1233 other_begin = other_begin->etl_next;
1234 etl::link_splice<link_type>(*this_begin->etl_previous, *value);
1240 if ((this_begin == this_end) && (other_begin != other_end))
1242 etl::link_splice<link_type>(*this->
get_tail(), *other_begin, *other_end->etl_previous);
1259 while (i_item !=
end())
1261 if (*i_item == value)
1278 template <
typename... TLinks>
1281 TLink* current = &first;
1283 ((current->etl_next = &links,
static_cast<TLink&
>(links).etl_previous = current, current = &links, ++count), ...);
1287#elif ETL_USING_CPP11
1291 link_type* make_linked_list(
size_t& count, link_type& first)
1301 template <
typename... TLinks>
1302 link_type* make_linked_list(
size_t& count, link_type& first, link_type& next, TLinks&... links)
1305 first.etl_next = &next;
1306 next.etl_previous = &first;
1308 return make_linked_list(count, next,
static_cast<link_type&
>(links)...);
const_iterator
Definition intrusive_list.h:586
iterator.
Definition intrusive_list.h:493
Definition intrusive_list.h:127
void disconnect_link(link_type *link)
Remove a link.
Definition intrusive_list.h:347
size_t size() const
Returns the number of elements.
Definition intrusive_list.h:252
link_type * get_tail()
Get the tail link.
Definition intrusive_list.h:372
void insert_link(link_type &previous, link_type &new_link)
Insert a link.
Definition intrusive_list.h:298
~intrusive_list_base()
Destructor.
Definition intrusive_list.h:285
void assign(TIterator first, TIterator last)
Definition intrusive_list.h:139
bool contains_node(const link_type *search_link) const
Definition intrusive_list.h:270
size_t current_size
Definition intrusive_list.h:280
bool is_link_in_list(const link_type *search_link) const
Tests if the link is in this list.
Definition intrusive_list.h:397
void disconnect_link(link_type &link)
Remove a link.
Definition intrusive_list.h:338
void insert_link(link_type &previous, link_type *new_link)
Insert a link.
Definition intrusive_list.h:318
void pop_back()
Removes a value from the back of the intrusive_list.
Definition intrusive_list.h:193
link_type * get_head()
Get the head link.
Definition intrusive_list.h:356
bool empty() const
Returns true if the list has no elements.
Definition intrusive_list.h:244
link_type * remove_link_range(link_type *p_first, link_type *p_last)
Removes a range of links.
Definition intrusive_list.h:441
void initialise()
Initialise the intrusive_list.
Definition intrusive_list.h:388
void reverse()
Reverses the list.
Definition intrusive_list.h:221
void insert_link(link_type *previous, link_type *new_link)
Insert a link.
Definition intrusive_list.h:328
const link_type * get_head() const
Get the head link.
Definition intrusive_list.h:364
link_type terminal_link
Definition intrusive_list.h:278
void insert_link(link_type *previous, link_type &new_link)
Insert a link.
Definition intrusive_list.h:308
void clear()
Clears the intrusive_list.
Definition intrusive_list.h:203
void push_front(link_type &value)
Pushes a value to the front of the intrusive_list.
Definition intrusive_list.h:163
void push_back(link_type &value)
Pushes a value to the back of the intrusive_list.
Definition intrusive_list.h:183
void pop_front()
Removes a value from the front of the intrusive_list.
Definition intrusive_list.h:173
bool contains_node(const link_type &search_link) const
Definition intrusive_list.h:261
const link_type * get_tail() const
Get the tail link.
Definition intrusive_list.h:380
bool is_trivial_list() const
Is the intrusive_list a trivial length?
Definition intrusive_list.h:290
link_type * remove_link(link_type *link)
Definition intrusive_list.h:419
Definition intrusive_list.h:70
Definition intrusive_list.h:84
Definition intrusive_list.h:98
Definition intrusive_list.h:112
~intrusive_list()
Destructor.
Definition intrusive_list.h:690
const_iterator end() const
Gets the end of the intrusive_list.
Definition intrusive_list.h:757
reference back()
Definition intrusive_list.h:797
iterator begin()
Gets the beginning of the intrusive_list.
Definition intrusive_list.h:725
node_type * erase(const node_type &node)
Erases the specified node.
Definition intrusive_list.h:893
void unique(TIsEqual isEqual)
Definition intrusive_list.h:911
const_iterator begin() const
Gets the beginning of the intrusive_list.
Definition intrusive_list.h:733
void splice(iterator position, list_type &other)
Splice another list into this one.
Definition intrusive_list.h:1122
iterator erase(const_iterator position)
Erases the value at the specified position.
Definition intrusive_list.h:854
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:1168
reference front()
Definition intrusive_list.h:775
void insert(const_iterator position, TIterator first, TIterator last)
Definition intrusive_list.h:828
void merge(list_type &other, TCompare compare)
Merge another list into this one. Both lists should be sorted.
Definition intrusive_list.h:1204
bool contains(const_reference value) const
Definition intrusive_list.h:1255
void sort(TCompare compare)
Definition intrusive_list.h:970
void splice(iterator position, list_type &other, iterator isource)
Splice an element from another list into this one.
Definition intrusive_list.h:1151
intrusive_list()
Constructor.
Definition intrusive_list.h:682
iterator erase(const_iterator first, const_iterator last)
Definition intrusive_list.h:868
const_iterator cend() const
Gets the end of the intrusive_list.
Definition intrusive_list.h:765
iterator erase(iterator position)
Erases the value at the specified position.
Definition intrusive_list.h:841
const_iterator cbegin() const
Gets the beginning of the intrusive_list.
Definition intrusive_list.h:741
void remove_if(TPredicate predicate)
Removes according to a predicate.
Definition intrusive_list.h:1102
void sort()
Sort using in-place merge sort algorithm.
Definition intrusive_list.h:939
iterator insert(const_iterator position, value_type &value)
Inserts a value to the intrusive_list before the specified position.
Definition intrusive_list.h:817
const_reference front() const
Definition intrusive_list.h:786
iterator end()
Gets the end of the intrusive_list.
Definition intrusive_list.h:749
node_type * erase(const node_type *p_node)
Erases the specified node.
Definition intrusive_list.h:901
intrusive_list(TIterator first, TIterator last, typename etl::enable_if<!etl::is_integral< TIterator >::value, int >::type=0)
Constructor from range.
Definition intrusive_list.h:699
const_reference back() const
Definition intrusive_list.h:808
void merge(list_type &other)
Merge another list into this one. Both lists should be sorted.
Definition intrusive_list.h:1195
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