31 #ifndef ETL_INTRUSIVE_LIST_INCLUDED
32 #define ETL_INTRUSIVE_LIST_INCLUDED
46 #include "static_assert.h"
68 :
exception(reason_, file_name_, line_number_)
119 template <
typename TLink>
125 typedef TLink link_type;
132 template <
typename TIterator>
133 void assign(TIterator first, TIterator last)
135 #if defined(ETL_DEBUG)
136 intmax_t d = etl::distance(first, last);
145 while (first != last)
147 link_type& link = *first++;
148 etl::link_splice<link_type>(p_last_link, link);
167 #if defined(ETL_CHECK_PUSH_POP)
186 #if defined(ETL_CHECK_PUSH_POP)
215 pnode = pnode->etl_previous;
266 etl::link_splice<link_type>(previous, new_link);
276 etl::link_splice<link_type>(previous, new_link);
286 etl::link_splice<link_type>(previous, new_link);
296 etl::link_splice<link_type>(previous, new_link);
305 etl::unlink<link_type>(link);
314 etl::unlink<link_type>(*link);
365 template <
typename TValue,
typename TLink = etl::b
idirectional_link<0> >
371 typedef typename etl::intrusive_list_base<TLink>::link_type link_type;
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;
394 : p_value(ETL_NULLPTR)
404 : p_value(other.p_value)
411 p_value =
static_cast<value_type*
>(p_value->link_type::etl_next);
419 p_value =
static_cast<value_type*
>(p_value->link_type::etl_next);
426 p_value =
static_cast<value_type*
>(p_value->link_type::etl_previous);
434 p_value =
static_cast<value_type*
>(p_value->link_type::etl_previous);
440 p_value = other.p_value;
444 reference operator *()
449 const_reference operator *()
const
464 pointer operator ->()
469 const_pointer operator ->()
const
476 return lhs.p_value == rhs.p_value;
481 return !(lhs == rhs);
499 : p_value(ETL_NULLPTR)
509 : p_value(other.p_value)
514 : p_value(other.p_value)
521 p_value =
static_cast<value_type*
>(p_value->link_type::etl_next);
529 p_value =
static_cast<value_type*
>(p_value->link_type::etl_next);
536 p_value =
static_cast<value_type*
>(p_value->link_type::etl_previous);
544 p_value =
static_cast<value_type*
>(p_value->link_type::etl_previous);
550 p_value = other.p_value;
554 const_reference operator *()
const
564 const_pointer operator ->()
const
571 return lhs.p_value == rhs.p_value;
576 return !(lhs == rhs);
581 const value_type* p_value;
584 typedef typename etl::iterator_traits<iterator>::difference_type difference_type;
605 template <
typename TIterator>
608 this->
assign(first, last);
664 return *
static_cast<value_type*
>(this->
get_head());
672 return *
static_cast<const value_type*
>(this->
get_head());
680 return *
static_cast<value_type*
>(this->
get_tail());
688 return *
static_cast<const value_type*
>(this->
get_tail());
696 this->
insert_link(position.p_value->link_type::etl_previous, value);
703 template <
typename TIterator>
706 while (first != last)
709 this->
insert_link(*position.p_value->link_type::etl_previous, *first++);
732 link_type* p_first = first.p_value;
733 link_type* p_last = last.p_value;
736 etl::link<link_type>(p_first->etl_previous, p_last);
746 return iterator(*
static_cast<value_type*
>(p_last));
754 template <
typename TIsEqual>
766 while (i_item !=
end())
768 if (isEqual(*i_previous, *i_item))
770 i_item =
erase(i_item);
813 template <
typename TCompare>
822 int number_of_merges;
837 number_of_merges = 0;
839 while (i_left !=
end())
846 for (
int i = 0; i < list_size; ++i)
851 if (i_right ==
end())
858 right_size = list_size;
861 while (left_size > 0 || (right_size > 0 && i_right !=
end()))
870 else if (right_size == 0 || i_right ==
end())
876 else if (!
compare(*i_right, *i_left))
893 etl::link<link_type>(i_head.p_value, i_node.p_value);
899 etl::link<link_type>(i_tail.p_value, i_node.p_value);
903 etl::link<link_type>(i_tail.p_value, this->terminal_link);
911 if (number_of_merges <= 1)
924 void remove(const_reference value)
928 while (i_item !=
end())
930 if (*i_item == value)
932 i_item =
erase(i_item);
944 template <
typename TPredicate>
949 while (i_item !=
end())
951 if (predicate(*i_item))
953 i_item =
erase(i_item);
972 link_type& first = *other.
get_head();
973 link_type& last = *other.
get_tail();
980 link_type& after = *position.p_value;
981 link_type& before = *after.etl_previous;
983 etl::link<link_type>(before, first);
984 etl::link<link_type>(last, after);
996 link_type& before = *position.p_value->link_type::etl_previous;
998 etl::unlink<link_type>(*isource.p_value);
999 etl::link_splice<link_type>(before, *isource.p_value);
1017 size_t n = etl::distance(begin_, end_);
1022 link_type& first = *begin_.p_value;
1023 link_type& last = *end_.p_value->link_type::etl_previous;
1026 etl::unlink(first, last);
1029 link_type& before = *position.p_value->link_type::etl_previous;
1031 etl::link_splice<link_type>(before, first, last);
1046 template <
typename TCompare>
1049 if ((
this != &other) && !other.
empty())
1051 #if defined(ETL_DEBUG)
1056 value_type* other_begin =
static_cast<value_type*
>(other.
get_head());
1057 value_type* other_end =
static_cast<value_type*
>(&other.
terminal_link);
1059 value_type* this_begin =
static_cast<value_type*
>(this->
get_head());
1060 value_type* this_end =
static_cast<value_type*
>(&this->
terminal_link);
1062 while ((this_begin != this_end) && (other_begin != other_end))
1065 while ((this_begin != this_end) && !(
compare(*other_begin, *this_begin)))
1067 this_begin =
static_cast<value_type*
>(this_begin->link_type::etl_next);
1071 if (this_begin != this_end)
1073 while ((other_begin != other_end) && (
compare(*other_begin, *this_begin)))
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);
1083 if ((this_begin == this_end) && (other_begin != other_end))
1085 etl::link_splice<link_type>(*this->
get_tail(), *other_begin, *other_end->link_type::etl_previous);
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
iterator
Definition: iterator.h:422
Definition: functional.h:112