31 #ifndef ETL_FORWARD_LIST_INCLUDED
32 #define ETL_FORWARD_LIST_INCLUDED
50 #include "static_assert.h"
53 #if ETL_CPP11_SUPPORTED && ETL_NOT_USING_STLPORT && ETL_USING_STL
54 #include <initializer_list>
79 :
exception(reason_, file_name_, line_number_)
201 while (p_node != ETL_NULLPTR)
204 p_node = p_node->next;
253 node_t* p_current = p_last->next;
254 node_t* p_next = p_current->next;
256 p_current->next = ETL_NULLPTR;
258 while (p_next != ETL_NULLPTR)
262 p_next = p_current->next;
264 p_current->next = p_last;
321 join(&node, position.next);
322 join(&position, &node);
362 ETL_DECLARE_DEBUG_COUNT
369 template <
typename T>
374 typedef T value_type;
376 typedef const T* const_pointer;
377 typedef T& reference;
378 typedef const T& const_reference;
381 #if ETL_CPP11_SUPPORTED
382 typedef T&& rvalue_reference;
412 : p_node(ETL_NULLPTR)
422 : p_node(other.p_node)
428 p_node = p_node->next;
435 p_node = p_node->next;
441 p_node = other.p_node;
445 reference operator *()
447 return iforward_list::data_cast(p_node)->value;
450 const_reference operator *()
const
452 return iforward_list::data_cast(p_node)->value;
457 return &(iforward_list::data_cast(p_node)->value);
462 return &(iforward_list::data_cast(p_node)->value);
465 pointer operator ->()
467 return &(iforward_list::data_cast(p_node)->value);
470 const_pointer operator ->()
const
472 return &(iforward_list::data_cast(p_node)->value);
477 return lhs.p_node == rhs.p_node;
482 return !(lhs == rhs);
500 : p_node(ETL_NULLPTR)
515 : p_node(other.p_node)
520 : p_node(other.p_node)
526 p_node = p_node->next;
533 p_node = p_node->next;
539 p_node = other.p_node;
543 const_reference operator *()
const
545 return iforward_list::data_cast(p_node)->value;
550 return &(iforward_list::data_cast(p_node)->value);
553 const_pointer operator ->()
const
555 return &(iforward_list::data_cast(p_node)->value);
560 return lhs.p_node == rhs.p_node;
565 return !(lhs == rhs);
573 typedef typename etl::iterator_traits<iterator>::difference_type difference_type;
652 return data_cast(*
get_head()).value;
660 return data_cast(*
get_head()).value;
668 template <
typename TIterator>
669 void assign(TIterator first, TIterator last)
671 #if defined(ETL_DEBUG)
672 difference_type d = etl::distance(first, last);
681 while (first != last)
686 join(p_last_node, &data_node);
687 data_node.next = ETL_NULLPTR;
688 p_last_node = &data_node;
707 join(p_last_node, &data_node);
708 data_node.next = ETL_NULLPTR;
709 p_last_node = &data_node;
718 #if defined(ETL_CHECK_PUSH_POP)
726 #if ETL_CPP11_SUPPORTED
732 #if defined(ETL_CHECK_PUSH_POP)
741 #if ETL_CPP11_SUPPORTED && ETL_NOT_USING_STLPORT
745 template <
typename ... Args>
748 #if defined(ETL_CHECK_PUSH_POP)
751 data_node_t* p_data_node = create_data_node();
752 ::new (&(p_data_node->value)) T(
etl::forward<Args>(args)...);
753 ETL_INCREMENT_DEBUG_COUNT
760 template <
typename T1>
763 #if defined(ETL_CHECK_PUSH_POP)
767 ::new (&(p_data_node->value)) T(value1);
768 ETL_INCREMENT_DEBUG_COUNT
775 template <
typename T1,
typename T2>
778 #if defined(ETL_CHECK_PUSH_POP)
782 ::new (&(p_data_node->value)) T(value1, value2);
783 ETL_INCREMENT_DEBUG_COUNT
790 template <
typename T1,
typename T2,
typename T3>
793 #if defined(ETL_CHECK_PUSH_POP)
797 ::new (&(p_data_node->value)) T(value1, value2, value3);
798 ETL_INCREMENT_DEBUG_COUNT
805 template <
typename T1,
typename T2,
typename T3,
typename T4>
806 void emplace_front(
const T1& value1,
const T2& value2,
const T3& value3,
const T4& value4)
808 #if defined(ETL_CHECK_PUSH_POP)
812 ::new (&(p_data_node->value)) T(value1, value2, value3, value4);
813 ETL_INCREMENT_DEBUG_COUNT
823 #if defined(ETL_CHECK_PUSH_POP)
861 while ((i < n) && (i_node !=
end()))
864 i_last_node = i_node;
873 else if (i_node ==
end())
898 #if ETL_CPP11_SUPPORTED && ETL_NOT_USING_STLPORT
902 template <
typename ... Args>
907 data_node_t* p_data_node = create_data_node();
908 ::new (&(p_data_node->value)) T(
etl::forward<Args>(args)...);
909 ETL_INCREMENT_DEBUG_COUNT
918 template <
typename T1>
924 ::new (&(p_data_node->value)) T(value1);
925 ETL_INCREMENT_DEBUG_COUNT
934 template <
typename T1,
typename T2>
940 ::new (&(p_data_node->value)) T(value1, value2);
941 ETL_INCREMENT_DEBUG_COUNT
950 template <
typename T1,
typename T2,
typename T3>
956 ::new (&(p_data_node->value)) T(value1, value2, value3);
957 ETL_INCREMENT_DEBUG_COUNT
966 template <
typename T1,
typename T2,
typename T3,
typename T4>
972 ::new (&(p_data_node->value)) T(value1, value2, value3, value4);
973 ETL_INCREMENT_DEBUG_COUNT
987 for (
size_t i = 0; !
full() && (i < n); ++i)
998 template <
typename TIterator>
1001 #if defined(ETL_DEBUG)
1002 difference_type d = etl::distance(first, last);
1006 while (first != last)
1027 remove_node_after(*position.p_node);
1039 if (first !=
end() && (first != last))
1041 node_t* p_first = first.p_node;
1042 node_t* p_last = last.p_node;
1043 node_t* p_next = p_first->next;
1046 join(p_first, p_last);
1051 while (p_first != p_last)
1053 p_next = p_first->next;
1054 destroy_data_node(
static_cast<data_node_t&
>(*p_first));
1058 if (p_next == ETL_NULLPTR)
1079 if (from_before == to_before)
1084 node_t* p_from_before =
const_cast<node_t*
>(from_before.p_node);
1085 node_t* p_to_before =
const_cast<node_t*
>(to_before.p_node);
1087 node_t* p_from = p_from_before->next;
1090 join(p_from_before, p_from->next);
1093 join(p_from, p_to_before->next);
1094 join(p_to_before, p_from);
1103 if ((first_before == to_before) || (last == to_before))
1108 #if defined(ETL_DEBUG)
1116 node_t* p_first_before =
const_cast<node_t*
>(first_before.p_node);
1118 node_t* p_to_before =
const_cast<node_t*
>(to_before.p_node);
1119 node_t* p_first = p_first_before->next;
1120 node_t* p_final = p_first_before;
1123 while (p_final->next != p_last)
1125 p_final = p_final->next;
1129 join(p_first_before, p_final->next);
1132 join(p_final, p_to_before->next);
1133 join(p_to_before, p_first);
1149 template <
typename TIsEqual>
1158 node_t* current = last->next;
1160 while (current != ETL_NULLPTR)
1163 if (isEqual(data_cast(current)->value, data_cast(last)->value))
1165 remove_node_after(*last);
1173 current = last->next;
1211 template <
typename TCompare>
1220 int number_of_merges;
1235 number_of_merges = 0;
1237 while (p_left !=
end())
1244 for (
int i = 0; i < list_size; ++i)
1250 if (p_right ==
end())
1257 right_size = list_size;
1260 while (left_size > 0 || (right_size > 0 && p_right !=
end()))
1270 else if (right_size == 0 || p_right ==
end())
1277 else if (!
compare(*p_right, *p_left))
1295 join(p_head.p_node, p_node.p_node);
1301 join(p_tail.p_node, p_node.p_node);
1305 p_tail.p_node->next = ETL_NULLPTR;
1313 if (number_of_merges <= 1)
1326 void remove(
const T& value)
1331 while (i_item !=
end())
1333 if (*i_item == value)
1348 template <
typename TPredicate>
1354 while (i_item !=
end())
1356 if (predicate(*i_item))
1381 #if ETL_CPP11_SUPPORTED
1387 move_container(etl::move(rhs));
1422 ETL_RESET_DEBUG_COUNT
1430 while (p_first != ETL_NULLPTR)
1432 p_next = p_first->next;
1433 destroy_data_node(
static_cast<data_node_t&
>(*p_first));
1448 ::new (&(p_node->value)) T(value);
1449 ETL_INCREMENT_DEBUG_COUNT
1454 #if ETL_CPP11_SUPPORTED
1460 data_node_t* p_node = create_data_node();
1461 ::new (&(p_node->value)) T(
etl::move(value));
1462 ETL_INCREMENT_DEBUG_COUNT
1468 #if ETL_CPP11_SUPPORTED
1481 node_t* p_rhs_node = rhs.start_node.next;
1489 node_t* p_node = p_rhs_node;
1490 p_rhs_node = p_rhs_node->next;
1494 p_last_node = p_node;
1496 ETL_INCREMENT_DEBUG_COUNT;
1498 }
while (p_rhs_node != ETL_NULLPTR);
1500 ETL_OBJECT_RESET_DEBUG_COUNT(rhs);
1501 rhs.start_node.next = ETL_NULLPTR;
1509 while (first != last)
1514 join(p_last_node, &data_node);
1515 data_node.next = ETL_NULLPTR;
1516 p_last_node = &data_node;
1531 static data_node_t* data_cast(node_t* p_node)
1533 return static_cast<data_node_t*
>(p_node);
1539 static data_node_t& data_cast(node_t& node)
1541 return static_cast<data_node_t&
>(node);
1547 static const data_node_t* data_cast(
const node_t* p_node)
1549 return static_cast<const data_node_t*
>(p_node);
1555 static const data_node_t& data_cast(
const node_t& node)
1557 return static_cast<const data_node_t&
>(node);
1563 void remove_node_after(node_t& node)
1566 node_t* p_node = node.next;
1568 if (p_node != ETL_NULLPTR)
1571 join(&node, p_node->next);
1574 destroy_data_node(
static_cast<data_node_t&
>(*p_node));
1581 data_node_t* create_data_node()
1583 data_node_t* (
etl::ipool::*func)() = &etl::ipool::allocate<data_node_t>;
1590 void destroy_data_node(data_node_t& node)
1594 ETL_DECREMENT_DEBUG_COUNT
1603 #if defined(ETL_POLYMORPHIC_FORWARD_LIST) || defined(ETL_POLYMORPHIC_CONTAINERS)
1620 template <
typename T, const
size_t MAX_SIZE_>
1625 ETL_STATIC_ASSERT((MAX_SIZE_ > 0U),
"Zero capacity etl::forward_list is not valid");
1627 static const size_t MAX_SIZE = MAX_SIZE_;
1631 typedef T value_type;
1633 typedef const T* const_pointer;
1634 typedef T& reference;
1635 typedef const T& const_reference;
1653 this->
assign(initial_size, value);
1665 #if ETL_CPP11_SUPPORTED
1672 this->move_container(etl::move(other));
1679 template <
typename TIterator>
1683 this->
assign(first, last);
1686 #if ETL_CPP11_SUPPORTED && ETL_NOT_USING_STLPORT && ETL_USING_STL
1693 this->
assign(init.begin(), init.end());
1718 #if ETL_CPP11_SUPPORTED
1725 this->move_container(etl::move(rhs));
1740 #if ETL_CPP17_SUPPORTED && ETL_NOT_USING_STLPORT && ETL_USING_STL
1741 template <
typename T,
typename... Ts>
1742 forward_list(T, Ts...)
1743 ->forward_list<etl::enable_if_t<(etl::is_same_v<T, Ts> && ...), T>, 1U +
sizeof...(Ts)>;
1750 template <
typename T>
1755 typedef T value_type;
1757 typedef const T* const_pointer;
1758 typedef T& reference;
1759 typedef const T& const_reference;
1787 this->
assign(initial_size, T());
1796 this->
assign(initial_size, value);
1817 #if ETL_CPP11_SUPPORTED
1824 this->move_container(etl::move(other));
1830 forward_list_ext(forward_list_ext&& other,
etl::ipool& node_pool)
1833 this->move_container(etl::move(other));
1840 template <
typename TIterator>
1844 this->
assign(first, last);
1847 #if ETL_CPP11_SUPPORTED && ETL_NOT_USING_STLPORT && ETL_USING_STL
1854 this->
assign(init.begin(), init.end());
1879 #if ETL_CPP11_SUPPORTED
1885 this->move_container(etl::move(rhs));
1920 template <
typename T>
1923 return (lhs.
size() == rhs.
size()) &&
1933 template <
typename T>
1936 return !(lhs == rhs);
1946 template <
typename T>
1949 return etl::lexicographical_compare(lhs.
begin(), lhs.
end(), rhs.
begin(), rhs.
end());
1959 template <
typename T>
1972 template <
typename T>
1975 return !(lhs > rhs);
1985 template <
typename T>
1988 return !(lhs < rhs);
Template deduction guides.
Definition: forward_list.h:1752
void set_pool(etl::ipool &pool)
Set the pool instance.
Definition: forward_list.h:1894
forward_list_ext()
Default constructor.
Definition: forward_list.h:1767
forward_list_ext(etl::ipool &node_pool)
Default constructor.
Definition: forward_list.h:1775
etl::ipool & get_pool() const
Get the pool instance.
Definition: forward_list.h:1908
forward_list_ext(size_t initial_size, const T &value, etl::ipool &node_pool)
Construct from size and value.
Definition: forward_list.h:1793
forward_list_ext(TIterator first, TIterator last, etl::ipool &node_pool)
Construct from range.
Definition: forward_list.h:1841
forward_list_ext(const forward_list_ext &other)
Copy constructor. Implicit pool.
Definition: forward_list.h:1802
forward_list_ext(size_t initial_size, etl::ipool &node_pool)
Construct from size.
Definition: forward_list.h:1784
forward_list_ext(const forward_list_ext &other, etl::ipool &node_pool)
Copy constructor. Explicit pool.
Definition: forward_list.h:1811
~forward_list_ext()
Destructor.
Definition: forward_list.h:1861
Definition: forward_list.h:1622
~forward_list()
Destructor.
Definition: forward_list.h:1700
forward_list(size_t initial_size, const T &value=T())
Construct from size and value.
Definition: forward_list.h:1650
forward_list(const forward_list &other)
Copy constructor.
Definition: forward_list.h:1659
forward_list()
Default constructor.
Definition: forward_list.h:1641
forward_list(TIterator first, TIterator last)
Construct from range.
Definition: forward_list.h:1680
const_iterator
Definition: forward_list.h:494
iterator.
Definition: forward_list.h:405
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
iterator end()
Gets the end of the forward_list.
Definition: forward_list.h:618
void resize(size_t n)
Resizes the forward_list.
Definition: forward_list.h:832
void assign(TIterator first, TIterator last)
Definition: forward_list.h:669
size_type MAX_SIZE
The maximum size of the forward_list.
Definition: forward_list.h:360
void unique(TIsEqual isEqual)
Definition: forward_list.h:1150
forward_list_base(bool pool_is_shared_)
The constructor that is called from derived classes.
Definition: forward_list.h:275
const_iterator cbegin() const
Gets the beginning of the forward_list.
Definition: forward_list.h:610
iterator before_begin()
Gets before the beginning of the forward_list.
Definition: forward_list.h:594
iterator erase_after(iterator position)
Erases the value at the specified position.
Definition: forward_list.h:1018
void insert_node_after(node_t &position, node_t &node)
Insert a node.
Definition: forward_list.h:318
etl::ipool * get_node_pool()
Get the node pool instance.
Definition: forward_list.h:353
void unique()
Definition: forward_list.h:1140
node_t start_node
The node that acts as the forward_list start.
Definition: forward_list.h:358
void emplace_front(const T1 &value1, const T2 &value2, const T3 &value3)
Emplaces a value to the front of the list..
Definition: forward_list.h:791
void emplace_front(const T1 &value1, const T2 &value2)
Emplaces a value to the front of the list..
Definition: forward_list.h:776
void insert_after(iterator position, size_t n, const T &value)
Inserts 'n' copies of a value to the forward_list after the specified position.
Definition: forward_list.h:983
size_type max_size() const
Gets the maximum possible size of the forward_list.
Definition: forward_list.h:176
forward_list_base(etl::ipool &node_pool_, size_type max_size_, bool pool_is_shared_)
The constructor that is called from derived classes.
Definition: forward_list.h:285
void resize(size_t n, T value)
Definition: forward_list.h:842
iforward_list(etl::ipool &node_pool, size_t max_size_, bool pool_is_shared_)
Constructor.
Definition: forward_list.h:1406
size_t available() const
Definition: forward_list.h:236
size_type capacity() const
Gets the maximum possible size of the forward_list.
Definition: forward_list.h:184
void clear()
Clears the forward_list.
Definition: forward_list.h:642
iterator erase_after(iterator first, iterator last)
Erases a range of elements.
Definition: forward_list.h:1037
const_iterator before_begin() const
Gets before the beginning of the forward_list.
Definition: forward_list.h:602
void reverse()
Reverses the forward_list.
Definition: forward_list.h:245
const_iterator cend() const
Gets the end of the forward_list.
Definition: forward_list.h:634
const_iterator begin() const
Gets the beginning of the forward_list.
Definition: forward_list.h:586
void emplace_front(const T1 &value1)
Emplaces a value to the front of the list..
Definition: forward_list.h:761
iterator insert_after(iterator position, const T &value)
Inserts a value to the forward_list after the specified position.
Definition: forward_list.h:888
void join(node_t *left, node_t *right)
Join two nodes.
Definition: forward_list.h:336
size_t size_type
The type used for determining the size of forward_list.
Definition: forward_list.h:163
void insert_after(iterator position, TIterator first, TIterator last)
Inserts a range of values to the forward_list after the specified position.
Definition: forward_list.h:999
reference front()
Gets a reference to the first element.
Definition: forward_list.h:650
void move_after(const_iterator first_before, const_iterator last, const_iterator to_before)
Definition: forward_list.h:1101
iterator emplace_after(iterator position, const T1 &value1, const T2 &value2, const T3 &value3)
Emplaces a value to the forward_list after the specified position.
Definition: forward_list.h:951
bool pool_is_shared
If true then the pool is shared between lists.
Definition: forward_list.h:361
void push_front(const T &value)
Pushes a value to the front of the forward_list.
Definition: forward_list.h:716
void emplace_front(const T1 &value1, const T2 &value2, const T3 &value3, const T4 &value4)
Emplaces a value to the front of the list..
Definition: forward_list.h:806
void sort()
Definition: forward_list.h:1181
void sort(TCompare compare)
Definition: forward_list.h:1212
void initialise()
Initialise the forward_list.
Definition: forward_list.h:1414
etl::ipool * p_node_pool
The pool of data nodes used in the list.
Definition: forward_list.h:359
iforward_list & operator=(const iforward_list &rhs)
Assignment operator.
Definition: forward_list.h:1371
const_reference front() const
Gets a const reference to the first element.
Definition: forward_list.h:658
iterator emplace_after(iterator position, const T1 &value1)
Emplaces a value to the forward_list after the specified position.
Definition: forward_list.h:919
void remove_if(TPredicate predicate)
Removes according to a predicate.
Definition: forward_list.h:1349
bool has_shared_pool() const
true if the list has a shared pool.
Definition: forward_list.h:168
iterator emplace_after(iterator position, const T1 &value1, const T2 &value2)
Emplaces a value to the forward_list after the specified position.
Definition: forward_list.h:935
bool full() const
Checks to see if the forward_list is full.
Definition: forward_list.h:226
const node_t * get_head() const
Get the head node.
Definition: forward_list.h:310
void pop_front()
Removes a value from the front of the forward_list.
Definition: forward_list.h:821
node_t * get_head()
Get the head node.
Definition: forward_list.h:302
~forward_list_base()
Destructor.
Definition: forward_list.h:295
bool empty() const
Checks to see if the forward_list is empty.
Definition: forward_list.h:218
void assign(size_t n, const T &value)
Assigns 'n' copies of a value to the forward_list.
Definition: forward_list.h:695
void set_node_pool(etl::ipool &node_pool_)
Set the node pool instance.
Definition: forward_list.h:344
data_node_t & allocate_data_node(const_reference value)
Allocate a data_node_t.
Definition: forward_list.h:1445
void move_after(const_iterator from_before, const_iterator to_before)
Definition: forward_list.h:1077
~iforward_list()
Destructor.
Definition: forward_list.h:1610
iterator emplace_after(iterator position, const T1 &value1, const T2 &value2, const T3 &value3, const T4 &value4)
Emplaces a value to the forward_list after the specified position.
Definition: forward_list.h:967
size_type size() const
Gets the size of the forward_list.
Definition: forward_list.h:192
const_iterator end() const
Gets the end of the forward_list.
Definition: forward_list.h:626
iterator begin()
Gets the beginning of the forward_list.
Definition: forward_list.h:578
iforward_list(bool pool_is_shared_)
Constructor.
Definition: forward_list.h:1398
bool is_trivial_list() const
Is the forward_list a trivial length?
Definition: forward_list.h:328
Definition: forward_list.h:145
Definition: forward_list.h:103
Definition: forward_list.h:75
Definition: forward_list.h:89
Definition: forward_list.h:117
Definition: forward_list.h:371
Definition: forward_list.h:131
size_t size() const
Returns the number of allocated items in the pool.
Definition: pool.h:309
void release_all()
Release all objects in the pool.
Definition: pool.h:264
bool full() const
Definition: pool.h:327
size_t max_size() const
Returns the maximum number of items in the pool.
Definition: pool.h:285
void release(const void *const p_object)
Definition: pool.h:255
size_t available() const
Returns the number of free items in the pool.
Definition: pool.h:301
is_trivially_destructible
Definition: type_traits_generator.h:1171
Definition: absolute.h:37
bool operator>(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:633
bool operator>=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:645
bool operator!=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:594
bool operator!=(const etl::iforward_list< T > &lhs, const etl::iforward_list< T > &rhs)
Definition: forward_list.h:1934
bool operator==(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:582
bool operator==(const etl::iforward_list< T > &lhs, const etl::iforward_list< T > &rhs)
Definition: forward_list.h:1921
bool operator<(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:606
bool operator<=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:621
Definition: functional.h:136
The node element in the forward_list.
Definition: forward_list.h:152
The data node element in the forward_list.
Definition: forward_list.h:391
iterator
Definition: iterator.h:422