Loading...
Searching...
No Matches
forward_list.h
Go to the documentation of this file.
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2014 John Wellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#ifndef ETL_FORWARD_LIST_INCLUDED
#define ETL_FORWARD_LIST_INCLUDED
#include "platform.h"
#include "algorithm.h"
#include "debug_count.h"
#include "error_handler.h"
#include "exception.h"
#include "functional.h"
#include "initializer_list.h"
#include "iterator.h"
#include "memory.h"
#include "nullptr.h"
#include "placement_new.h"
#include "pool.h"
#include "static_assert.h"
#include "type_traits.h"
#include "utility.h"
#include <stddef.h>
#include "private/minmax_push.h"
//*****************************************************************************
//*****************************************************************************
namespace etl
{
//***************************************************************************
//***************************************************************************
class forward_list_exception : public etl::exception
{
public:
forward_list_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
: exception(reason_, file_name_, line_number_)
{
}
};
//***************************************************************************
//***************************************************************************
class forward_list_full : public etl::forward_list_exception
{
public:
forward_list_full(string_type file_name_, numeric_type line_number_)
: etl::forward_list_exception(ETL_ERROR_TEXT("forward_list:full", ETL_FORWARD_LIST_FILE_ID"A"), file_name_, line_number_)
{
}
};
//***************************************************************************
//***************************************************************************
class forward_list_empty : public etl::forward_list_exception
{
public:
forward_list_empty(string_type file_name_, numeric_type line_number_)
: etl::forward_list_exception(ETL_ERROR_TEXT("forward_list:empty", ETL_FORWARD_LIST_FILE_ID"B"), file_name_, line_number_)
{
}
};
//***************************************************************************
//***************************************************************************
class forward_list_iterator : public etl::forward_list_exception
{
public:
forward_list_iterator(string_type file_name_, numeric_type line_number_)
: etl::forward_list_exception(ETL_ERROR_TEXT("forward_list:iterator", ETL_FORWARD_LIST_FILE_ID"C"), file_name_, line_number_)
{
}
};
//***************************************************************************
//***************************************************************************
class forward_list_no_pool : public forward_list_exception
{
public:
forward_list_no_pool(string_type file_name_, numeric_type line_number_)
: forward_list_exception(ETL_ERROR_TEXT("forward_list:no pool", ETL_FORWARD_LIST_FILE_ID"D"), file_name_, line_number_)
{
}
};
//***************************************************************************
//***************************************************************************
class forward_list_base
{
protected:
//*************************************************************************
//*************************************************************************
struct node_t
{
node_t()
: next(ETL_NULLPTR)
{
}
node_t* next;
};
public:
typedef size_t size_type;
//*************************************************************************
//*************************************************************************
bool has_shared_pool() const
{
return pool_is_shared;
}
//*************************************************************************
//*************************************************************************
size_type max_size() const
{
return MAX_SIZE;
}
//*************************************************************************
//*************************************************************************
size_type capacity() const
{
return MAX_SIZE;
}
//*************************************************************************
//*************************************************************************
size_type size() const
{
if (has_shared_pool())
{
// We have to count what we actually own.
size_type count = 0;
node_t* p_node = start_node.next;
while (p_node != ETL_NULLPTR)
{
++count;
p_node = p_node->next;
}
return count;
}
else
{
return p_node_pool->size();
}
}
//*************************************************************************
//*************************************************************************
bool empty() const
{
return (start_node.next == ETL_NULLPTR);
}
//*************************************************************************
//*************************************************************************
bool full() const
{
ETL_ASSERT(p_node_pool != ETL_NULLPTR, ETL_ERROR(forward_list_no_pool));
return p_node_pool->full();
}
//*************************************************************************
//*************************************************************************
size_t available() const
{
ETL_ASSERT(p_node_pool != ETL_NULLPTR, ETL_ERROR(forward_list_no_pool));
return p_node_pool->available();
}
//*************************************************************************
//*************************************************************************
void reverse()
{
if (is_trivial_list())
{
return;
}
node_t* p_last = &start_node;
node_t* p_current = p_last->next;
node_t* p_next = p_current->next;
p_current->next = ETL_NULLPTR;
while (p_next != ETL_NULLPTR)
{
p_last = p_current;
p_current = p_next;
p_next = p_current->next;
p_current->next = p_last;
}
join(&start_node, p_current);
}
protected:
//*************************************************************************
//*************************************************************************
forward_list_base(bool pool_is_shared_)
: p_node_pool(ETL_NULLPTR)
, MAX_SIZE(0)
, pool_is_shared(pool_is_shared_)
{
}
//*************************************************************************
//*************************************************************************
forward_list_base(etl::ipool& node_pool_, size_type max_size_, bool pool_is_shared_)
: p_node_pool(&node_pool_)
, MAX_SIZE(max_size_)
, pool_is_shared(pool_is_shared_)
{
}
//*************************************************************************
//*************************************************************************
~forward_list_base() {}
//*************************************************************************
//*************************************************************************
node_t* get_head()
{
return start_node.next;
}
//*************************************************************************
//*************************************************************************
const node_t* get_head() const
{
return start_node.next;
}
//*************************************************************************
//*************************************************************************
inline void insert_node_after(node_t& position, node_t& node)
{
// Connect to the forward_list.
join(&node, position.next);
join(&position, &node);
}
//*************************************************************************
//*************************************************************************
bool is_trivial_list() const
{
return (size() < 2);
}
//*************************************************************************
//*************************************************************************
void join(node_t* left, node_t* right)
{
left->next = right;
}
//*************************************************************************
//*************************************************************************
void set_node_pool(etl::ipool& node_pool_)
{
p_node_pool = &node_pool_;
MAX_SIZE = p_node_pool->max_size();
}
//*************************************************************************
//*************************************************************************
etl::ipool* get_node_pool()
{
return p_node_pool;
}
node_t start_node;
etl::ipool* p_node_pool;
size_type MAX_SIZE;
bool pool_is_shared;
ETL_DECLARE_DEBUG_COUNT;
};
//***************************************************************************
//***************************************************************************
template <typename T>
class iforward_list : public etl::forward_list_base
{
public:
typedef T value_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef size_t size_type;
#if ETL_USING_CPP11
typedef T&& rvalue_reference;
#endif
protected:
//*************************************************************************
//*************************************************************************
struct data_node_t : public node_t
{
explicit data_node_t(const T& value_)
: value(value_)
{
}
T value;
};
public:
//*************************************************************************
//*************************************************************************
class iterator : public etl::iterator<ETL_OR_STD::forward_iterator_tag, T>
{
public:
friend class iforward_list;
friend class const_iterator;
iterator()
: p_node(ETL_NULLPTR)
{
}
iterator(node_t* node)
: p_node(node)
{
}
iterator(const iterator& other)
: p_node(other.p_node)
{
}
iterator& operator++()
{
p_node = p_node->next;
return *this;
}
iterator operator++(int)
{
iterator temp(*this);
p_node = p_node->next;
return temp;
}
iterator operator=(const iterator& other)
{
p_node = other.p_node;
return *this;
}
reference operator*() const
{
return iforward_list::data_cast(p_node)->value;
}
pointer operator&() const
{
return &(iforward_list::data_cast(p_node)->value);
}
pointer operator->() const
{
return &(iforward_list::data_cast(p_node)->value);
}
friend bool operator==(const iterator& lhs, const iterator& rhs)
{
return lhs.p_node == rhs.p_node;
}
friend bool operator!=(const iterator& lhs, const iterator& rhs)
{
return !(lhs == rhs);
}
private:
node_t* p_node;
};
//*************************************************************************
//*************************************************************************
class const_iterator : public etl::iterator<ETL_OR_STD::forward_iterator_tag, const T>
{
public:
friend class iforward_list;
const_iterator()
: p_node(ETL_NULLPTR)
{
}
const_iterator(node_t* node)
: p_node(node)
{
}
const_iterator(const node_t* node)
: p_node(node)
{
}
const_iterator(const typename iforward_list::iterator& other)
: p_node(other.p_node)
{
}
const_iterator(const const_iterator& other)
: p_node(other.p_node)
{
}
const_iterator& operator++()
{
p_node = p_node->next;
return *this;
}
const_iterator operator++(int)
{
const_iterator temp(*this);
p_node = p_node->next;
return temp;
}
const_iterator& operator=(const const_iterator& other)
{
p_node = other.p_node;
return *this;
}
const_reference operator*() const
{
return iforward_list::data_cast(p_node)->value;
}
const_pointer operator&() const
{
return &(iforward_list::data_cast(p_node)->value);
}
const_pointer operator->() const
{
return &(iforward_list::data_cast(p_node)->value);
}
friend bool operator==(const const_iterator& lhs, const const_iterator& rhs)
{
return lhs.p_node == rhs.p_node;
}
friend bool operator!=(const const_iterator& lhs, const const_iterator& rhs)
{
return !(lhs == rhs);
}
private:
const node_t* p_node;
};
typedef typename etl::iterator_traits<iterator>::difference_type difference_type;
//*************************************************************************
//*************************************************************************
iterator begin()
{
return iterator(get_head());
}
//*************************************************************************
//*************************************************************************
const_iterator begin() const
{
return const_iterator(get_head());
}
//*************************************************************************
//*************************************************************************
iterator before_begin()
{
return iterator(&start_node);
}
//*************************************************************************
//*************************************************************************
const_iterator before_begin() const
{
return const_iterator(&start_node);
}
//*************************************************************************
//*************************************************************************
const_iterator cbegin() const
{
return const_iterator(get_head());
}
//*************************************************************************
//*************************************************************************
iterator end()
{
return iterator();
}
//*************************************************************************
//*************************************************************************
const_iterator end() const
{
return const_iterator();
}
//*************************************************************************
//*************************************************************************
const_iterator cend() const
{
return const_iterator();
}
//*************************************************************************
//*************************************************************************
void clear()
{
initialise();
}
//*************************************************************************
//*************************************************************************
reference front()
{
ETL_ASSERT_CHECK_EXTRA(!empty(), ETL_ERROR(forward_list_empty));
return data_cast(*get_head()).value;
}
//*************************************************************************
//*************************************************************************
const_reference front() const
{
ETL_ASSERT_CHECK_EXTRA(!empty(), ETL_ERROR(forward_list_empty));
return data_cast(*get_head()).value;
}
//*************************************************************************
//*************************************************************************
template <typename TIterator>
void assign(TIterator first, TIterator last, typename etl::enable_if<!etl::is_integral<TIterator>::value, int>::type = 0)
{
#if ETL_IS_DEBUG_BUILD
difference_type d = etl::distance(first, last);
ETL_ASSERT(d >= 0, ETL_ERROR(forward_list_iterator));
#endif
initialise();
node_t* p_last_node = &start_node;
// Add all of the elements.
while (first != last)
{
ETL_ASSERT(!full(), ETL_ERROR(forward_list_full));
data_node_t& data_node = allocate_data_node(*first);
++first;
join(p_last_node, &data_node);
data_node.next = ETL_NULLPTR;
p_last_node = &data_node;
}
}
//*************************************************************************
//*************************************************************************
void assign(size_t n, const T& value)
{
ETL_ASSERT(n <= MAX_SIZE, ETL_ERROR(forward_list_full));
initialise();
node_t* p_last_node = &start_node;
// Add all of the elements.
while (size() < n)
{
data_node_t& data_node = allocate_data_node(value);
join(p_last_node, &data_node);
data_node.next = ETL_NULLPTR;
p_last_node = &data_node;
}
}
//*************************************************************************
//*************************************************************************
void push_front(const T& value)
{
ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(!full(), ETL_ERROR(forward_list_full));
data_node_t& data_node = allocate_data_node(value);
insert_node_after(start_node, data_node);
}
#if ETL_USING_CPP11
//*************************************************************************
//*************************************************************************
void push_front(rvalue_reference value)
{
ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(!full(), ETL_ERROR(forward_list_full));
data_node_t& data_node = allocate_data_node(etl::move(value));
insert_node_after(start_node, data_node);
}
#endif
#if ETL_USING_CPP11 && ETL_NOT_USING_STLPORT && !defined(ETL_FORWARD_LIST_FORCE_CPP03_IMPLEMENTATION)
//*************************************************************************
//*************************************************************************
template <typename... Args>
reference emplace_front(Args&&... args)
{
ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(forward_list_full));
data_node_t* p_data_node = allocate_data_node();
::new (&(p_data_node->value)) T(etl::forward<Args>(args)...);
ETL_INCREMENT_DEBUG_COUNT;
insert_node_after(start_node, *p_data_node);
return front();
}
#else
//*************************************************************************
//*************************************************************************
reference emplace_front()
{
ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(forward_list_full));
data_node_t* p_data_node = allocate_data_node();
::new (&(p_data_node->value)) T();
ETL_INCREMENT_DEBUG_COUNT;
insert_node_after(start_node, *p_data_node);
return front();
}
//*************************************************************************
//*************************************************************************
template <typename T1>
reference emplace_front(const T1& value1)
{
ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(forward_list_full));
data_node_t* p_data_node = allocate_data_node();
::new (&(p_data_node->value)) T(value1);
ETL_INCREMENT_DEBUG_COUNT;
insert_node_after(start_node, *p_data_node);
return front();
}
//*************************************************************************
//*************************************************************************
template <typename T1, typename T2>
reference emplace_front(const T1& value1, const T2& value2)
{
ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(forward_list_full));
data_node_t* p_data_node = allocate_data_node();
::new (&(p_data_node->value)) T(value1, value2);
ETL_INCREMENT_DEBUG_COUNT;
insert_node_after(start_node, *p_data_node);
return front();
}
//*************************************************************************
//*************************************************************************
template <typename T1, typename T2, typename T3>
reference emplace_front(const T1& value1, const T2& value2, const T3& value3)
{
ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(forward_list_full));
data_node_t* p_data_node = allocate_data_node();
::new (&(p_data_node->value)) T(value1, value2, value3);
ETL_INCREMENT_DEBUG_COUNT;
insert_node_after(start_node, *p_data_node);
return front();
}
//*************************************************************************
//*************************************************************************
template <typename T1, typename T2, typename T3, typename T4>
reference emplace_front(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
{
ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(forward_list_full));
data_node_t* p_data_node = allocate_data_node();
::new (&(p_data_node->value)) T(value1, value2, value3, value4);
ETL_INCREMENT_DEBUG_COUNT;
insert_node_after(start_node, *p_data_node);
return front();
}
#endif // ETL_USING_CPP11 && ETL_NOT_USING_STLPORT
//*************************************************************************
//*************************************************************************
void pop_front()
{
ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(!empty(), ETL_ERROR(forward_list_empty));
remove_node_after(start_node);
}
//*************************************************************************
//*************************************************************************
void resize(size_t n)
{
resize(n, T());
}
//*************************************************************************
//*************************************************************************
void resize(size_t n, T value)
{
ETL_ASSERT(n <= MAX_SIZE, ETL_ERROR(forward_list_full));
if (n == 0U)
{
clear();
}
else if (empty())
{
assign(n, value);
}
else
{
size_t i = 0UL;
iterator i_node = begin();
iterator i_last_node;
// Find where we're currently at.
while ((i < n) && (i_node != end()))
{
++i;
i_last_node = i_node;
++i_node;
}
if (i_node != end())
{
// Reduce.
erase_after(i_last_node, end());
}
else if (i_node == end())
{
// Increase.
while (i < n)
{
i_last_node = insert_after(i_last_node, value);
++i;
}
}
}
}
//*************************************************************************
//*************************************************************************
iterator insert_after(const_iterator position, const T& value)
{
ETL_ASSERT(!full(), ETL_ERROR(forward_list_full));
data_node_t& data_node = allocate_data_node(value);
insert_node_after(*to_iterator(position).p_node, data_node);
return iterator(&data_node);
}
#if ETL_USING_CPP11 && ETL_NOT_USING_STLPORT && !defined(ETL_FORWARD_LIST_FORCE_CPP03_IMPLEMENTATION)
//*************************************************************************
//*************************************************************************
template <typename... Args>
iterator emplace_after(const_iterator position, Args&&... args)
{
ETL_ASSERT(!full(), ETL_ERROR(forward_list_full));
data_node_t* p_data_node = allocate_data_node();
::new (&(p_data_node->value)) T(etl::forward<Args>(args)...);
ETL_INCREMENT_DEBUG_COUNT;
insert_node_after(*to_iterator(position).p_node, *p_data_node);
return iterator(p_data_node);
}
#else
//*************************************************************************
//*************************************************************************
iterator emplace_after(const_iterator position)
{
ETL_ASSERT(!full(), ETL_ERROR(forward_list_full));
data_node_t* p_data_node = allocate_data_node();
::new (&(p_data_node->value)) T();
ETL_INCREMENT_DEBUG_COUNT;
insert_node_after(*to_iterator(position).p_node, *p_data_node);
return iterator(p_data_node);
}
//*************************************************************************
//*************************************************************************
template <typename T1>
iterator emplace_after(const_iterator position, const T1& value1)
{
ETL_ASSERT(!full(), ETL_ERROR(forward_list_full));
data_node_t* p_data_node = allocate_data_node();
::new (&(p_data_node->value)) T(value1);
ETL_INCREMENT_DEBUG_COUNT;
insert_node_after(*to_iterator(position).p_node, *p_data_node);
return iterator(p_data_node);
}
//*************************************************************************
//*************************************************************************
template <typename T1, typename T2>
iterator emplace_after(const_iterator position, const T1& value1, const T2& value2)
{
ETL_ASSERT(!full(), ETL_ERROR(forward_list_full));
data_node_t* p_data_node = allocate_data_node();
::new (&(p_data_node->value)) T(value1, value2);
ETL_INCREMENT_DEBUG_COUNT;
insert_node_after(*to_iterator(position).p_node, *p_data_node);
return iterator(p_data_node);
}
//*************************************************************************
//*************************************************************************
template <typename T1, typename T2, typename T3>
iterator emplace_after(const_iterator position, const T1& value1, const T2& value2, const T3& value3)
{
ETL_ASSERT(!full(), ETL_ERROR(forward_list_full));
data_node_t* p_data_node = allocate_data_node();
::new (&(p_data_node->value)) T(value1, value2, value3);
ETL_INCREMENT_DEBUG_COUNT;
insert_node_after(*to_iterator(position).p_node, *p_data_node);
return iterator(p_data_node);
}
//*************************************************************************
//*************************************************************************
template <typename T1, typename T2, typename T3, typename T4>
iterator emplace_after(const_iterator position, const T1& value1, const T2& value2, const T3& value3, const T4& value4)
{
ETL_ASSERT(!full(), ETL_ERROR(forward_list_full));
data_node_t* p_data_node = allocate_data_node();
::new (&(p_data_node->value)) T(value1, value2, value3, value4);
ETL_INCREMENT_DEBUG_COUNT;
insert_node_after(*to_iterator(position).p_node, *p_data_node);
return iterator(p_data_node);
}
#endif // ETL_USING_CPP11 && ETL_NOT_USING_STLPORT
//*************************************************************************
//*************************************************************************
iterator insert_after(const_iterator position, size_t n, const T& value)
{
ETL_ASSERT(!full(), ETL_ERROR(forward_list_full));
for (size_t i = 0UL; !full() && (i < n); ++i)
{
// Set up the next free node.
data_node_t& data_node = allocate_data_node(value);
insert_node_after(*to_iterator(position).p_node, data_node);
}
if (n > 0U)
{
++position;
}
return to_iterator(position);
}
//*************************************************************************
//*************************************************************************
template <typename TIterator>
iterator insert_after(const_iterator position, TIterator first, TIterator last,
typename etl::enable_if<!etl::is_integral<TIterator>::value, int>::type = 0)
{
#if ETL_IS_DEBUG_BUILD
difference_type d = etl::distance(first, last);
ETL_ASSERT((static_cast<size_type>(d) + size()) <= MAX_SIZE, ETL_ERROR(forward_list_full));
#endif
while (first != last)
{
// Set up the next free node.
data_node_t& data_node = allocate_data_node(*first);
++first;
insert_node_after(*to_iterator(position).p_node, data_node);
++position;
}
return to_iterator(position);
}
//*************************************************************************
//*************************************************************************
iterator erase_after(iterator position)
{
iterator next(position);
if (next != end())
{
++next;
if (next != end())
{
++next;
remove_node_after(*position.p_node);
}
}
return next;
}
//*************************************************************************
//*************************************************************************
iterator erase_after(const_iterator position)
{
iterator next(position);
if (next != end())
{
++next;
if (next != end())
{
++next;
remove_node_after(*position.p_node);
}
}
return next;
}
//*************************************************************************
//*************************************************************************
iterator erase_after(const_iterator first, const_iterator last)
{
if (first != end() && (first != last))
{
node_t* p_first = to_iterator(first).p_node;
node_t* p_last = to_iterator(last).p_node;
node_t* p_next = p_first->next;
// Join the ends.
join(p_first, p_last);
p_first = p_next;
// Erase the ones in between.
while (p_first != p_last)
{
p_next = p_first->next; // Remember the next node.
destroy_data_node(static_cast<data_node_t&>(*p_first)); // Destroy the pool object.
p_first = p_next; // Move to the next node.
}
if (p_next == ETL_NULLPTR)
{
return end();
}
else
{
return iterator(p_last);
}
}
else
{
return end();
}
}
//*************************************************************************
//*************************************************************************
void move_after(const_iterator from_before, const_iterator to_before)
{
if (from_before == to_before) // Can't move to after yourself!
{
return;
}
node_t* p_from_before = const_cast<node_t*>(from_before.p_node); // We're not changing the value, just it's position.
node_t* p_to_before = const_cast<node_t*>(to_before.p_node); // We're not changing the value, just it's position.
node_t* p_from = p_from_before->next;
// Disconnect from the list.
join(p_from_before, p_from->next);
// Attach it to the new position.
join(p_from, p_to_before->next);
join(p_to_before, p_from);
}
//*************************************************************************
//*************************************************************************
void move_after(const_iterator first_before, const_iterator last, const_iterator to_before)
{
if ((first_before == to_before) || (last == to_before))
{
return; // Can't more to before yourself!
}
// #if ETL_IS_DEBUG_BUILD
// Check that we are not doing an illegal move!
for (const_iterator item = first_before; item != last; ++item)
{
ETL_ASSERT(item != to_before, ETL_ERROR(forward_list_iterator));
}
// #endif
node_t* p_first_before = const_cast<node_t*>(first_before.p_node); // We're not changing the value, just it's position.
node_t* p_last = const_cast<node_t*>(last.p_node); // We're not changing the value, just it's position.
node_t* p_to_before = const_cast<node_t*>(to_before.p_node); // We're not changing the value, just it's position.
node_t* p_first = p_first_before->next;
node_t* p_final = p_first_before;
// Find the last node that will be moved.
while (p_final->next != p_last)
{
p_final = p_final->next;
}
// Disconnect from the list.
join(p_first_before, p_final->next);
// Attach it to the new position.
join(p_final, p_to_before->next);
join(p_to_before, p_first);
}
//*************************************************************************
//*************************************************************************
void unique()
{
unique(etl::equal_to<T>());
}
//*************************************************************************
//*************************************************************************
template <typename TIsEqual>
void unique(TIsEqual isEqual)
{
if (empty())
{
return;
}
node_t* last = get_head();
node_t* current = last->next;
while (current != ETL_NULLPTR)
{
// Is this value the same as the last?
if (isEqual(data_cast(current)->value, data_cast(last)->value))
{
remove_node_after(*last);
}
else
{
// Move on one.
last = current;
}
current = last->next;
}
}
//*************************************************************************
//*************************************************************************
void sort()
{
sort(etl::less<T>());
}
//*************************************************************************
//*************************************************************************
template <typename TCompare>
void sort(TCompare compare)
{
iterator p_left;
iterator p_right;
iterator p_node;
iterator p_head;
iterator p_tail;
int list_size = 1;
int number_of_merges;
int left_size;
int right_size;
if (is_trivial_list())
{
return;
}
while (true)
{
p_left = begin();
p_head = before_begin();
p_tail = before_begin();
number_of_merges = 0; // Count the number of merges we do in this pass.
while (p_left != end())
{
++number_of_merges; // There exists a merge to be done.
p_right = p_left;
left_size = 0;
// Step 'list_size' places along from left
for (int i = 0; i < list_size; ++i)
{
++left_size;
++p_right;
if (p_right == end())
{
break;
}
}
// If right hasn't fallen off end, we have two lists to merge.
right_size = list_size;
// Now we have two lists. Merge them.
while (left_size > 0 || (right_size > 0 && p_right != end()))
{
// Decide whether the next node of merge comes from left or right.
if (left_size == 0)
{
// Left is empty. The node must come from right.
p_node = p_right;
++p_right;
--right_size;
}
else if (right_size == 0 || p_right == end())
{
// Right is empty. The node must come from left.
p_node = p_left;
++p_left;
--left_size;
}
else if (!compare(*p_right, *p_left))
{
// First node of left is lower or same. The node must come from
// left.
p_node = p_left;
++p_left;
--left_size;
}
else
{
// First node of right is lower. The node must come from right.
p_node = p_right;
++p_right;
--right_size;
}
// Add the next node to the merged head.
if (p_head == before_begin())
{
join(p_head.p_node, p_node.p_node);
p_head = p_node;
p_tail = p_node;
}
else
{
join(p_tail.p_node, p_node.p_node);
p_tail = p_node;
}
p_tail.p_node->next = ETL_NULLPTR;
}
// Now left has stepped `list_size' places along, and right has too.
p_left = p_right;
}
// If we have done only one merge, we're finished.
if (number_of_merges <= 1) // Allow for number_of_merges == 0, the empty head case
{
return;
}
// Otherwise repeat, merging lists twice the size
list_size *= 2;
}
}
//*************************************************************************
// Removes the values specified.
//*************************************************************************
void remove(const T& value)
{
iterator i_item = begin();
iterator i_last_item = before_begin();
while (i_item != end())
{
if (*i_item == value)
{
i_item = erase_after(i_last_item);
}
else
{
++i_item;
++i_last_item;
}
}
}
//*************************************************************************
//*************************************************************************
template <typename TPredicate>
void remove_if(TPredicate predicate)
{
iterator i_item = begin();
iterator i_last_item = before_begin();
while (i_item != end())
{
if (predicate(*i_item))
{
i_item = erase_after(i_last_item);
}
else
{
++i_item;
++i_last_item;
}
}
}
//*************************************************************************
//*************************************************************************
iforward_list& operator=(const iforward_list& rhs)
{
if (&rhs != this)
{
assign(rhs.cbegin(), rhs.cend());
}
return *this;
}
#if ETL_USING_CPP11
//*************************************************************************
//*************************************************************************
iforward_list& operator=(iforward_list&& rhs)
{
move_container(etl::move(rhs));
return *this;
}
#endif
protected:
//*************************************************************************
//*************************************************************************
iforward_list(bool pool_is_shared_)
: forward_list_base(pool_is_shared_)
{
}
//*************************************************************************
//*************************************************************************
iforward_list(etl::ipool& node_pool, size_t max_size_, bool pool_is_shared_)
: forward_list_base(node_pool, max_size_, pool_is_shared_)
{
}
//*************************************************************************
//*************************************************************************
void initialise()
{
if (!empty())
{
if (etl::is_trivially_destructible<T>::value && !has_shared_pool())
{
ETL_ASSERT(p_node_pool != ETL_NULLPTR, ETL_ERROR(forward_list_no_pool));
p_node_pool->release_all();
ETL_RESET_DEBUG_COUNT;
}
else
{
node_t* p_first = start_node.next;
node_t* p_next;
// Erase the ones in between.
while (p_first != ETL_NULLPTR)
{
p_next = p_first->next; // Remember the next node.
destroy_data_node(static_cast<data_node_t&>(*p_first)); // Destroy the pool object.
p_first = p_next; // Move to the next node.
}
}
}
start_node.next = ETL_NULLPTR;
}
//*************************************************************************
//*************************************************************************
data_node_t& allocate_data_node(const_reference value)
{
data_node_t* p_node = allocate_data_node();
::new (&(p_node->value)) T(value);
ETL_INCREMENT_DEBUG_COUNT;
return *p_node;
}
#if ETL_USING_CPP11
//*************************************************************************
//*************************************************************************
data_node_t& allocate_data_node(rvalue_reference value)
{
data_node_t* p_node = allocate_data_node();
::new (&(p_node->value)) T(etl::move(value));
ETL_INCREMENT_DEBUG_COUNT;
return *p_node;
}
#endif
#if ETL_USING_CPP11
//*************************************************************************
//*************************************************************************
void move_container(iforward_list&& rhs)
{
if (&rhs != this)
{
this->initialise();
if (!rhs.empty())
{
// Are we using the same pool?
if (this->get_node_pool() == rhs.get_node_pool())
{
// Just link the nodes to this list.
this->start_node.next = rhs.start_node.next;
ETL_SET_DEBUG_COUNT(ETL_OBJECT_GET_DEBUG_COUNT(rhs));
ETL_OBJECT_RESET_DEBUG_COUNT(rhs);
rhs.start_node.next = ETL_NULLPTR;
}
else
{
node_t* p_last_node = &this->start_node;
// Add all of the elements.
etl::iforward_list<T>::iterator first = rhs.begin();
etl::iforward_list<T>::iterator last = rhs.end();
while (first != last)
{
ETL_ASSERT(!full(), ETL_ERROR(forward_list_full));
data_node_t& data_node = this->allocate_data_node(etl::move(*first));
++first;
join(p_last_node, &data_node);
data_node.next = ETL_NULLPTR;
p_last_node = &data_node;
}
rhs.initialise();
}
}
}
}
#endif
private:
//*************************************************************************
//*************************************************************************
static data_node_t* data_cast(node_t* p_node)
{
return static_cast<data_node_t*>(p_node);
}
//*************************************************************************
//*************************************************************************
static data_node_t& data_cast(node_t& node)
{
return static_cast<data_node_t&>(node);
}
//*************************************************************************
//*************************************************************************
static const data_node_t* data_cast(const node_t* p_node)
{
return static_cast<const data_node_t*>(p_node);
}
//*************************************************************************
//*************************************************************************
static const data_node_t& data_cast(const node_t& node)
{
return static_cast<const data_node_t&>(node);
}
//*************************************************************************
//*************************************************************************
void remove_node_after(node_t& node)
{
// The node to erase.
node_t* p_node = node.next;
if (p_node != ETL_NULLPTR)
{
// Disconnect the node from the forward_list.
join(&node, p_node->next);
// Destroy the pool object.
destroy_data_node(static_cast<data_node_t&>(*p_node));
}
}
//*************************************************************************
//*************************************************************************
data_node_t* allocate_data_node()
{
data_node_t* (etl::ipool::*func)() = &etl::ipool::allocate<data_node_t>;
return (p_node_pool->*func)();
}
//*************************************************************************
//*************************************************************************
void destroy_data_node(data_node_t& node)
{
node.value.~T();
p_node_pool->release(&node);
ETL_DECREMENT_DEBUG_COUNT;
}
// Disable copy construction.
iforward_list(const iforward_list&);
//*************************************************************************
//*************************************************************************
#if defined(ETL_POLYMORPHIC_FORWARD_LIST) || defined(ETL_POLYMORPHIC_CONTAINERS)
public:
virtual ~iforward_list() {}
#else
protected:
~iforward_list() {}
#endif
private:
//*************************************************************************
//*************************************************************************
iterator to_iterator(const_iterator itr) const
{
return iterator(const_cast<node_t*>(itr.p_node));
}
};
//*************************************************************************
//*************************************************************************
template <typename T, const size_t MAX_SIZE_>
class forward_list : public etl::iforward_list<T>
{
public:
ETL_STATIC_ASSERT((MAX_SIZE_ > 0U), "Zero capacity etl::forward_list is not valid");
static ETL_CONSTANT size_t MAX_SIZE = MAX_SIZE_;
public:
typedef T value_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef size_t size_type;
//*************************************************************************
//*************************************************************************
forward_list()
: etl::iforward_list<T>(node_pool, MAX_SIZE, false)
{
this->initialise();
}
//*************************************************************************
//*************************************************************************
explicit forward_list(size_t initial_size, const T& value = T())
: etl::iforward_list<T>(node_pool, MAX_SIZE, false)
{
this->assign(initial_size, value);
}
//*************************************************************************
//*************************************************************************
forward_list(const forward_list& other)
: etl::iforward_list<T>(node_pool, MAX_SIZE, false)
{
this->assign(other.cbegin(), other.cend());
}
#if ETL_USING_CPP11
//*************************************************************************
//*************************************************************************
forward_list(forward_list&& other)
: etl::iforward_list<T>(node_pool, MAX_SIZE, false)
{
this->move_container(etl::move(other));
}
#endif
//*************************************************************************
//*************************************************************************
template <typename TIterator>
forward_list(TIterator first, TIterator last, typename etl::enable_if<!etl::is_integral<TIterator>::value, int>::type = 0)
: etl::iforward_list<T>(node_pool, MAX_SIZE, false)
{
this->assign(first, last);
}
#if ETL_HAS_INITIALIZER_LIST
//*************************************************************************
//*************************************************************************
forward_list(std::initializer_list<T> init)
: etl::iforward_list<T>(node_pool, MAX_SIZE, false)
{
this->assign(init.begin(), init.end());
}
#endif
//*************************************************************************
//*************************************************************************
~forward_list()
{
this->initialise();
}
//*************************************************************************
//*************************************************************************
forward_list& operator=(const forward_list& rhs)
{
if (&rhs != this)
{
this->assign(rhs.cbegin(), rhs.cend());
}
return *this;
}
#if ETL_USING_CPP11
//*************************************************************************
//*************************************************************************
forward_list& operator=(forward_list&& rhs)
{
this->move_container(etl::move(rhs));
return *this;
}
#endif
private:
etl::pool<typename etl::iforward_list<T>::data_node_t, MAX_SIZE> node_pool;
};
template <typename T, const size_t MAX_SIZE_>
ETL_CONSTANT size_t forward_list<T, MAX_SIZE_>::MAX_SIZE;
//*************************************************************************
//*************************************************************************
#if ETL_USING_CPP17 && ETL_HAS_INITIALIZER_LIST
template <typename... T>
forward_list(T...) -> forward_list<typename etl::common_type_t<T...>, sizeof...(T)>;
#endif
//*************************************************************************
//*************************************************************************
#if ETL_USING_CPP11 && ETL_HAS_INITIALIZER_LIST
template <typename... T>
constexpr auto make_forward_list(T&&... t) -> etl::forward_list<typename etl::common_type_t<T...>, sizeof...(T)>
{
return {etl::forward<T>(t)...};
}
#endif
//*************************************************************************
//*************************************************************************
template <typename T>
class forward_list_ext : public etl::iforward_list<T>
{
public:
typedef T value_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef size_t size_type;
typedef typename etl::iforward_list<T>::data_node_t pool_type;
//*************************************************************************
//*************************************************************************
forward_list_ext()
: etl::iforward_list<T>(true)
{
}
//*************************************************************************
//*************************************************************************
explicit forward_list_ext(etl::ipool& node_pool)
: etl::iforward_list<T>(node_pool, node_pool.max_size(), true)
{
this->initialise();
}
//*************************************************************************
//*************************************************************************
explicit forward_list_ext(size_t initial_size, etl::ipool& node_pool)
: etl::iforward_list<T>(node_pool, node_pool.max_size(), true)
{
this->assign(initial_size, T());
}
//*************************************************************************
//*************************************************************************
explicit forward_list_ext(size_t initial_size, const T& value, etl::ipool& node_pool)
: etl::iforward_list<T>(node_pool, node_pool.max_size(), true)
{
this->assign(initial_size, value);
}
//*************************************************************************
//*************************************************************************
forward_list_ext(const forward_list_ext& other)
: etl::iforward_list<T>(*other.p_node_pool, other.p_node_pool->max_size(), true)
{
this->assign(other.cbegin(), other.cend());
}
//*************************************************************************
//*************************************************************************
forward_list_ext(const forward_list_ext& other, etl::ipool& node_pool)
: etl::iforward_list<T>(node_pool, node_pool.max_size(), true)
{
this->assign(other.cbegin(), other.cend());
}
#if ETL_USING_CPP11
//*************************************************************************
//*************************************************************************
forward_list_ext(forward_list_ext&& other)
: etl::iforward_list<T>(*other.p_node_pool, other.p_node_pool->max_size(), true)
{
this->move_container(etl::move(other));
}
//*************************************************************************
//*************************************************************************
forward_list_ext(forward_list_ext&& other, etl::ipool& node_pool)
: etl::iforward_list<T>(node_pool, node_pool.max_size(), true)
{
this->move_container(etl::move(other));
}
#endif
//*************************************************************************
//*************************************************************************
template <typename TIterator>
forward_list_ext(TIterator first, TIterator last, etl::ipool& node_pool,
typename etl::enable_if<!etl::is_integral<TIterator>::value, int>::type = 0)
: etl::iforward_list<T>(node_pool, node_pool.max_size(), true)
{
this->assign(first, last);
}
#if ETL_HAS_INITIALIZER_LIST
//*************************************************************************
//*************************************************************************
forward_list_ext(std::initializer_list<T> init, etl::ipool& node_pool)
: etl::iforward_list<T>(node_pool, node_pool.max_size(), true)
{
this->assign(init.begin(), init.end());
}
#endif
//*************************************************************************
//*************************************************************************
~forward_list_ext()
{
this->initialise();
}
//*************************************************************************
//*************************************************************************
forward_list_ext& operator=(const forward_list_ext& rhs)
{
if (&rhs != this)
{
this->assign(rhs.cbegin(), rhs.cend());
}
return *this;
}
#if ETL_USING_CPP11
//*************************************************************************
//*************************************************************************
forward_list_ext& operator=(forward_list_ext&& rhs)
{
this->move_container(etl::move(rhs));
return *this;
}
#endif
//*************************************************************************
//*************************************************************************
void set_pool(etl::ipool& pool)
{
// Clear the list of any current elements.
if (this->get_node_pool() != ETL_NULLPTR)
{
this->clear();
}
this->set_node_pool(pool);
}
//*************************************************************************
//*************************************************************************
etl::ipool& get_pool() const
{
return *this->p_node_pool;
}
};
//*************************************************************************
//*************************************************************************
template <typename T>
bool operator==(const etl::iforward_list<T>& lhs, const etl::iforward_list<T>& rhs)
{
return (lhs.size() == rhs.size()) && etl::equal(lhs.begin(), lhs.end(), rhs.begin());
}
//*************************************************************************
//*************************************************************************
template <typename T>
bool operator!=(const etl::iforward_list<T>& lhs, const etl::iforward_list<T>& rhs)
{
return !(lhs == rhs);
}
//*************************************************************************
//*************************************************************************
template <typename T>
bool operator<(const etl::iforward_list<T>& lhs, const etl::iforward_list<T>& rhs)
{
return etl::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
}
//*************************************************************************
//*************************************************************************
template <typename T>
bool operator>(const etl::iforward_list<T>& lhs, const etl::iforward_list<T>& rhs)
{
return (rhs < lhs);
}
//*************************************************************************
//*************************************************************************
template <typename T>
bool operator<=(const etl::iforward_list<T>& lhs, const etl::iforward_list<T>& rhs)
{
return !(lhs > rhs);
}
//*************************************************************************
//*************************************************************************
template <typename T>
bool operator>=(const etl::iforward_list<T>& lhs, const etl::iforward_list<T>& rhs)
{
return !(lhs < rhs);
}
} // namespace etl
#include "private/minmax_pop.h"
#endif
algorithm.h
etl::forward_list_ext
Template deduction guides.
Definition forward_list.h:1809
etl::forward_list_ext::set_pool
void set_pool(etl::ipool &pool)
Set the pool instance.
Definition forward_list.h:1952
etl::forward_list_ext::get_pool
etl::ipool & get_pool() const
Get the pool instance.
Definition forward_list.h:1966
etl::forward_list_ext::forward_list_ext
forward_list_ext()
Default constructor.
Definition forward_list.h:1824
etl::forward_list_ext::forward_list_ext
forward_list_ext(etl::ipool &node_pool)
Default constructor.
Definition forward_list.h:1832
etl::forward_list_ext::forward_list_ext
forward_list_ext(size_t initial_size, const T &value, etl::ipool &node_pool)
Construct from size and value.
Definition forward_list.h:1850
etl::forward_list_ext::forward_list_ext
forward_list_ext(TIterator first, TIterator last, etl::ipool &node_pool, typename etl::enable_if<!etl::is_integral< TIterator >::value, int >::type=0)
Construct from range.
Definition forward_list.h:1898
etl::forward_list_ext::operator=
forward_list_ext & operator=(const forward_list_ext &rhs)
Assignment operator.
Definition forward_list.h:1927
etl::forward_list_ext::forward_list_ext
forward_list_ext(const forward_list_ext &other)
Copy constructor. Implicit pool.
Definition forward_list.h:1859
etl::forward_list_ext::forward_list_ext
forward_list_ext(size_t initial_size, etl::ipool &node_pool)
Construct from size.
Definition forward_list.h:1841
etl::forward_list_ext::forward_list_ext
forward_list_ext(const forward_list_ext &other, etl::ipool &node_pool)
Copy constructor. Explicit pool.
Definition forward_list.h:1868
etl::forward_list_ext::~forward_list_ext
~forward_list_ext()
Destructor.
Definition forward_list.h:1919
etl::forward_list
Definition forward_list.h:1667
etl::forward_list::~forward_list
~forward_list()
Destructor.
Definition forward_list.h:1745
etl::forward_list::forward_list
forward_list(size_t initial_size, const T &value=T())
Construct from size and value.
Definition forward_list.h:1695
etl::forward_list::forward_list
forward_list(const forward_list &other)
Copy constructor.
Definition forward_list.h:1704
etl::forward_list::operator=
forward_list & operator=(const forward_list &rhs)
Assignment operator.
Definition forward_list.h:1753
etl::forward_list::forward_list
forward_list()
Default constructor.
Definition forward_list.h:1686
etl::forward_list::forward_list
forward_list(TIterator first, TIterator last, typename etl::enable_if<!etl::is_integral< TIterator >::value, int >::type=0)
Construct from range.
Definition forward_list.h:1725
etl::iforward_list::iterator
iterator.
Definition forward_list.h:396
debug_count.h
error_handler.h
exception.h
functional.h
etl::remove
ETL_CONSTEXPR14 TIterator remove(TIterator first, TIterator last, const T &value)
Definition algorithm.h:2381
etl::const_iterator
ETL_ASSERT
#define ETL_ASSERT(b, e)
Definition error_handler.h:511
etl::exception::exception
ETL_EXCEPTION_CONSTEXPR exception(string_type reason_, string_type, numeric_type)
Constructor.
Definition exception.h:81
etl::exception
Definition exception.h:59
etl::data_node_t
etl::iforward_list::end
iterator end()
Gets the end of the forward_list.
Definition forward_list.h:594
etl::iforward_list::resize
void resize(size_t n)
Resizes the forward_list.
Definition forward_list.h:826
etl::iforward_list::emplace_front
reference emplace_front(const T1 &value1)
Emplaces a value to the front of the list..
Definition forward_list.h:756
etl::forward_list_base::MAX_SIZE
size_type MAX_SIZE
The maximum size of the forward_list.
Definition forward_list.h:350
etl::iforward_list::unique
void unique(TIsEqual isEqual)
Definition forward_list.h:1193
etl::iforward_list::assign
void assign(TIterator first, TIterator last, typename etl::enable_if<!etl::is_integral< TIterator >::value, int >::type=0)
Definition forward_list.h:653
etl::iforward_list::operator=
iforward_list & operator=(const iforward_list &rhs)
Assignment operator.
Definition forward_list.h:1415
etl::iforward_list::emplace_after
iterator emplace_after(const_iterator position, const T1 &value1)
Emplaces a value to the forward_list after the specified position.
Definition forward_list.h:928
etl::forward_list_base::forward_list_base
forward_list_base(bool pool_is_shared_)
The constructor that is called from derived classes.
Definition forward_list.h:267
etl::iforward_list::emplace_front
reference emplace_front(const T1 &value1, const T2 &value2, const T3 &value3)
Emplaces a value to the front of the list..
Definition forward_list.h:786
etl::iforward_list::cbegin
const_iterator cbegin() const
Gets the beginning of the forward_list.
Definition forward_list.h:586
etl::iforward_list::before_begin
iterator before_begin()
Gets before the beginning of the forward_list.
Definition forward_list.h:570
etl::iforward_list::erase_after
iterator erase_after(iterator position)
Erases the value at the specified position.
Definition forward_list.h:1040
etl::forward_list_base::insert_node_after
void insert_node_after(node_t &position, node_t &node)
Insert a node.
Definition forward_list.h:308
etl::iforward_list::erase_after
iterator erase_after(const_iterator position)
Erases the value at the specified position.
Definition forward_list.h:1059
etl::iforward_list::emplace_after
iterator emplace_after(const_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:976
etl::iforward_list::unique
void unique()
Definition forward_list.h:1183
etl::forward_list_base::start_node
node_t start_node
The node that acts as the forward_list start.
Definition forward_list.h:348
etl::iforward_list::insert_after
iterator insert_after(const_iterator position, size_t n, const T &value)
Definition forward_list.h:993
etl::forward_list_base::max_size
size_type max_size() const
Gets the maximum possible size of the forward_list.
Definition forward_list.h:168
etl::forward_list_base::forward_list_base
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:277
etl::iforward_list::emplace_front
reference 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:801
etl::iforward_list::resize
void resize(size_t n, T value)
Definition forward_list.h:836
etl::iforward_list::iforward_list
iforward_list(etl::ipool &node_pool, size_t max_size_, bool pool_is_shared_)
Constructor.
Definition forward_list.h:1450
etl::forward_list_base::available
size_t available() const
Definition forward_list.h:228
etl::forward_list_base::ETL_DECLARE_DEBUG_COUNT
ETL_DECLARE_DEBUG_COUNT
Internal debugging.
Definition forward_list.h:352
etl::forward_list_base::capacity
size_type capacity() const
Gets the maximum possible size of the forward_list.
Definition forward_list.h:176
etl::iforward_list::clear
void clear()
Clears the forward_list.
Definition forward_list.h:618
etl::iforward_list::emplace_after
iterator emplace_after(const_iterator position)
Emplaces a value to the forward_list after the specified position.
Definition forward_list.h:912
etl::iforward_list::emplace_after
iterator emplace_after(const_iterator position, const T1 &value1, const T2 &value2)
Emplaces a value to the forward_list after the specified position.
Definition forward_list.h:944
etl::forward_list_base::get_head
node_t * get_head()
Get the head node.
Definition forward_list.h:292
etl::iforward_list::before_begin
const_iterator before_begin() const
Gets before the beginning of the forward_list.
Definition forward_list.h:578
etl::forward_list_base::get_node_pool
etl::ipool * get_node_pool()
Get the node pool instance.
Definition forward_list.h:343
etl::forward_list_base::reverse
void reverse()
Reverses the forward_list.
Definition forward_list.h:237
etl::iforward_list::cend
const_iterator cend() const
Gets the end of the forward_list.
Definition forward_list.h:610
etl::iforward_list::begin
const_iterator begin() const
Gets the beginning of the forward_list.
Definition forward_list.h:562
etl::forward_list_base::join
void join(node_t *left, node_t *right)
Join two nodes.
Definition forward_list.h:326
etl::forward_list_base::size_type
size_t size_type
The type used for determining the size of forward_list.
Definition forward_list.h:155
etl::iforward_list::front
reference front()
Definition forward_list.h:628
etl::iforward_list::move_after
void move_after(const_iterator first_before, const_iterator last, const_iterator to_before)
Definition forward_list.h:1144
etl::forward_list_base::pool_is_shared
bool pool_is_shared
If true then the pool is shared between lists.
Definition forward_list.h:351
etl::iforward_list::push_front
void push_front(const T &value)
Pushes a value to the front of the forward_list.
Definition forward_list.h:701
etl::iforward_list::insert_after
iterator insert_after(const_iterator position, const T &value)
Inserts a value to the forward_list after the specified position.
Definition forward_list.h:882
etl::iforward_list::emplace_front
reference emplace_front(const T1 &value1, const T2 &value2)
Emplaces a value to the front of the list..
Definition forward_list.h:771
etl::iforward_list::emplace_after
iterator emplace_after(const_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:960
etl::iforward_list::sort
void sort()
Definition forward_list.h:1224
etl::iforward_list::sort
void sort(TCompare compare)
Definition forward_list.h:1255
etl::iforward_list::initialise
void initialise()
Initialise the forward_list.
Definition forward_list.h:1458
etl::forward_list_base::p_node_pool
etl::ipool * p_node_pool
The pool of data nodes used in the list.
Definition forward_list.h:349
etl::iforward_list::front
const_reference front() const
Definition forward_list.h:639
etl::iforward_list::remove_if
void remove_if(TPredicate predicate)
Removes according to a predicate.
Definition forward_list.h:1393
etl::forward_list_base::has_shared_pool
bool has_shared_pool() const
true if the list has a shared pool.
Definition forward_list.h:160
etl::forward_list_base::full
bool full() const
Checks to see if the forward_list is full.
Definition forward_list.h:218
etl::iforward_list::pop_front
void pop_front()
Removes a value from the front of the forward_list.
Definition forward_list.h:816
etl::iforward_list::insert_after
iterator insert_after(const_iterator position, TIterator first, TIterator last, typename etl::enable_if<!etl::is_integral< TIterator >::value, int >::type=0)
Definition forward_list.h:1017
etl::forward_list_base::~forward_list_base
~forward_list_base()
Destructor.
Definition forward_list.h:287
etl::iforward_list::erase_after
iterator erase_after(const_iterator first, const_iterator last)
Erases a range of elements.
Definition forward_list.h:1078
etl::forward_list_base::empty
bool empty() const
Checks to see if the forward_list is empty.
Definition forward_list.h:210
etl::iforward_list::assign
void assign(size_t n, const T &value)
Assigns 'n' copies of a value to the forward_list.
Definition forward_list.h:680
etl::forward_list_base::set_node_pool
void set_node_pool(etl::ipool &node_pool_)
Set the node pool instance.
Definition forward_list.h:334
etl::iforward_list::move_after
void move_after(const_iterator from_before, const_iterator to_before)
Definition forward_list.h:1119
etl::iforward_list::~iforward_list
~iforward_list()
Destructor.
Definition forward_list.h:1647
etl::iforward_list::emplace_front
reference emplace_front()
Emplaces a value to the front of the list..
Definition forward_list.h:741
etl::forward_list_base::size
size_type size() const
Gets the size of the forward_list.
Definition forward_list.h:184
etl::iforward_list::allocate_data_node
data_node_t & allocate_data_node(const_reference value)
Allocate a data_node_t.
Definition forward_list.h:1489
etl::iforward_list::end
const_iterator end() const
Gets the end of the forward_list.
Definition forward_list.h:602
etl::iforward_list::begin
iterator begin()
Gets the beginning of the forward_list.
Definition forward_list.h:554
etl::iforward_list::iforward_list
iforward_list(bool pool_is_shared_)
Constructor.
Definition forward_list.h:1442
etl::forward_list_base::get_head
const node_t * get_head() const
Get the head node.
Definition forward_list.h:300
etl::forward_list_base::is_trivial_list
bool is_trivial_list() const
Is the forward_list a trivial length?
Definition forward_list.h:318
etl::forward_list_base
Definition forward_list.h:137
etl::forward_list_empty
Definition forward_list.h:95
etl::forward_list_exception
Definition forward_list.h:67
etl::forward_list_full
Definition forward_list.h:81
etl::forward_list_iterator
Definition forward_list.h:109
etl::forward_list_no_pool
Definition forward_list.h:123
etl::iforward_list
Definition forward_list.h:361
etl::ipool::allocate
T * allocate()
Definition ipool.h:334
etl::ipool
Definition ipool.h:110
etl::pool
Definition pool.h:54
initializer_list.h
iterator.h
memory.h
minmax_pop.h
minmax_push.h
etl
Definition absolute.h:40
etl::operator==
ETL_CONSTEXPR14 bool operator==(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1078
etl::operator>
bool operator>(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1130
etl::operator>=
bool operator>=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1144
etl::operator!=
ETL_CONSTEXPR14 bool operator!=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1090
etl::operator<
bool operator<(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1103
etl::operator<=
bool operator<=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1117
nullptr.h
placement_new.h
platform.h
pool.h
etl::compare
Definition compare.h:51
etl::equal_to
Definition functional.h:305
etl::forward_list_base::node_t
The node element in the forward_list.
Definition forward_list.h:144
etl::iforward_list::data_node_t
The data node element in the forward_list.
Definition forward_list.h:381
etl::iterator
iterator
Definition iterator.h:482
etl::less
Definition functional.h:201
etl::type
operator==
ETL_CONSTEXPR14 bool operator==(const etl::to_arithmetic_result< T > &lhs, const etl::to_arithmetic_result< T > &rhs)
Equality test for etl::to_arithmetic_result.
Definition to_arithmetic.h:903
operator!=
ETL_CONSTEXPR14 bool operator!=(const etl::to_arithmetic_result< T > &lhs, const etl::to_arithmetic_result< T > &rhs)
Inequality test for etl::to_arithmetic_result.
Definition to_arithmetic.h:937
type_traits.h
utility.h