Updated intrusive links

Refactored intrusive_forward_list so that links report status consistantly
This commit is contained in:
John Wellbelove 2023-06-26 08:07:40 +01:00
parent ed589c91c6
commit 3510fd61a9
24 changed files with 1213 additions and 336 deletions

1
.gitignore vendored
View File

@ -380,3 +380,4 @@ test/vs2022/Debug MSVC C++17
test/vs2022/Debug MSVC C++17 - No STL
test/vs2022/Release MSVC C++20 - No STL - Optimised -O2
test/vs2022/Release MSVC C++20 - Optimised O2
test/vs2022/Debug MSVC C++ 20 - No Tests

View File

@ -727,7 +727,7 @@ namespace etl
#if defined(ETL_CHECK_PUSH_POP)
ETL_ASSERT(!full(), ETL_ERROR(forward_list_full));
#endif
data_node_t* p_data_node = create_data_node();
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);
@ -743,7 +743,7 @@ namespace etl
#if defined(ETL_CHECK_PUSH_POP)
ETL_ASSERT(!full(), ETL_ERROR(forward_list_full));
#endif
data_node_t* p_data_node = create_data_node();
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);
@ -759,7 +759,7 @@ namespace etl
#if defined(ETL_CHECK_PUSH_POP)
ETL_ASSERT(!full(), ETL_ERROR(forward_list_full));
#endif
data_node_t* p_data_node = create_data_node();
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);
@ -775,7 +775,7 @@ namespace etl
#if defined(ETL_CHECK_PUSH_POP)
ETL_ASSERT(!full(), ETL_ERROR(forward_list_full));
#endif
data_node_t* p_data_node = create_data_node();
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);
@ -791,7 +791,7 @@ namespace etl
#if defined(ETL_CHECK_PUSH_POP)
ETL_ASSERT(!full(), ETL_ERROR(forward_list_full));
#endif
data_node_t* p_data_node = create_data_node();
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);
@ -888,7 +888,7 @@ namespace etl
{
ETL_ASSERT(!full(), ETL_ERROR(forward_list_full));
data_node_t* p_data_node = create_data_node();
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);
@ -904,7 +904,7 @@ namespace etl
{
ETL_ASSERT(!full(), ETL_ERROR(forward_list_full));
data_node_t* p_data_node = create_data_node();
data_node_t* p_data_node = allocate_data_node();
::new (&(p_data_node->value)) T(value1);
ETL_INCREMENT_DEBUG_COUNT
insert_node_after(*position.p_node, *p_data_node);
@ -920,7 +920,7 @@ namespace etl
{
ETL_ASSERT(!full(), ETL_ERROR(forward_list_full));
data_node_t* p_data_node = create_data_node();
data_node_t* p_data_node = allocate_data_node();
::new (&(p_data_node->value)) T(value1, value2);
ETL_INCREMENT_DEBUG_COUNT
insert_node_after(*position.p_node, *p_data_node);
@ -936,7 +936,7 @@ namespace etl
{
ETL_ASSERT(!full(), ETL_ERROR(forward_list_full));
data_node_t* p_data_node = create_data_node();
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(*position.p_node, *p_data_node);
@ -952,7 +952,7 @@ namespace etl
{
ETL_ASSERT(!full(), ETL_ERROR(forward_list_full));
data_node_t* p_data_node = create_data_node();
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(*position.p_node, *p_data_node);
@ -1457,7 +1457,7 @@ namespace etl
//*************************************************************************
data_node_t& allocate_data_node(const_reference value)
{
data_node_t* p_node = create_data_node();
data_node_t* p_node = allocate_data_node();
::new (&(p_node->value)) T(value);
ETL_INCREMENT_DEBUG_COUNT
@ -1470,7 +1470,7 @@ namespace etl
//*************************************************************************
data_node_t& allocate_data_node(rvalue_reference value)
{
data_node_t* p_node = create_data_node();
data_node_t* p_node = allocate_data_node();
::new (&(p_node->value)) T(etl::move(value));
ETL_INCREMENT_DEBUG_COUNT
@ -1582,7 +1582,7 @@ namespace etl
//*************************************************************************
/// Create a node.
//*************************************************************************
data_node_t* create_data_node()
data_node_t* allocate_data_node()
{
data_node_t* (etl::ipool::*func)() = &etl::ipool::allocate<data_node_t>;
return (p_node_pool->*func)();

View File

@ -117,6 +117,20 @@ namespace etl
}
};
//***************************************************************************
/// intrusive_stack_value_is_already_linked exception.
///\ingroup intrusive_stack
//***************************************************************************
class intrusive_forward_list_value_is_already_linked : public intrusive_forward_list_exception
{
public:
intrusive_forward_list_value_is_already_linked(string_type file_name_, numeric_type line_number_)
: intrusive_forward_list_exception(ETL_ERROR_TEXT("intrusive_forward_list:value is already linked", ETL_INTRUSIVE_FORWARD_LIST_FILE_ID"E"), file_name_, line_number_)
{
}
};
//***************************************************************************
/// Base for intrusive forward list.
///\ingroup intrusive_forward_list
@ -134,6 +148,16 @@ namespace etl
//*************************************************************************
void clear()
{
// Unlink all of the items.
link_type* p_unlink = start.etl_next;
while (p_unlink != &terminator)
{
link_type* p_next = p_unlink->etl_next;
p_unlink->clear();
p_unlink = p_next;
}
initialise();
}
@ -146,19 +170,27 @@ namespace etl
{
#if ETL_IS_DEBUG_BUILD
intmax_t d = etl::distance(first, last);
ETL_ASSERT(d >= 0, ETL_ERROR(intrusive_forward_list_iterator_exception));
ETL_ASSERT_OR_RETURN(d >= 0, ETL_ERROR(intrusive_forward_list_iterator_exception));
#endif
initialise();
clear();
link_type* p_last_link = &start_link;
link_type* p_last = &start;
int count = 0;
// Add all of the elements.
while (first != last)
{
link_type& link = *first++;
etl::link_splice<link_type>(p_last_link, link);
p_last_link = &link;
++count;
link_type& value = *first++;
ETL_ASSERT_OR_RETURN(!value.is_linked(), ETL_ERROR(intrusive_forward_list_value_is_already_linked));
value.etl_next = p_last->etl_next;
p_last->etl_next = &value;
p_last = &value;
++current_size;
}
}
@ -168,7 +200,9 @@ namespace etl
//*************************************************************************
void push_front(link_type& value)
{
insert_link_after(start_link, value);
ETL_ASSERT_OR_RETURN(!value.is_linked(), ETL_ERROR(intrusive_forward_list_value_is_already_linked));
insert_link_after(start, value);
}
//*************************************************************************
@ -177,9 +211,9 @@ namespace etl
void pop_front()
{
#if defined(ETL_CHECK_PUSH_POP)
ETL_ASSERT(!empty(), ETL_ERROR(intrusive_forward_list_empty));
ETL_ASSERT_OR_RETURN(!empty(), ETL_ERROR(intrusive_forward_list_empty));
#endif
remove_link_after(start_link);
remove_link_after(start);
}
//*************************************************************************
@ -192,19 +226,19 @@ namespace etl
return;
}
link_type* first = ETL_NULLPTR; // To keep first link
link_type* second = start_link.etl_next; // To keep second link
link_type* track = start_link.etl_next; // Track the list
while (track != NULL)
link_type* previous = &terminator; // Point to the terminator of the linked list.
link_type* current = start.etl_next; // Point to the first item in the linked list (could be the terminator).
link_type* next = start.etl_next; // Point to the first item in the linked list (could be the terminator).
while (next != &terminator)
{
track = track->etl_next; // Track point to next link;
second->etl_next = first; // Second link point to first
first = second; // Move first link to next
second = track; // Move second link to next
next = next->etl_next; // Point to next link.
current->etl_next = previous; // Reverse the current link.
previous = current; // Previous points to current.
current = next; // Current points to next.
}
etl::link<link_type>(start_link, first);
etl::link<link_type>(start, previous);
}
//*************************************************************************
@ -212,7 +246,7 @@ namespace etl
//*************************************************************************
bool empty() const
{
return start_link.etl_next == ETL_NULLPTR;
return (current_size == 0);
}
//*************************************************************************
@ -225,15 +259,25 @@ namespace etl
protected:
link_type start_link; ///< The link that acts as the intrusive_forward_list start.
link_type start; ///< The link pointer that acts as the intrusive_forward_list start.
static link_type terminator; ///< The link that acts as the intrusive_forward_list terminator.
size_t current_size; ///< Counts the number of elements in the list.
//*************************************************************************
/// Constructor
//*************************************************************************
intrusive_forward_list_base()
{
initialise();
}
//*************************************************************************
/// Destructor
//*************************************************************************
~intrusive_forward_list_base()
{
clear();
}
//*************************************************************************
@ -241,7 +285,7 @@ namespace etl
//*************************************************************************
bool is_trivial_list() const
{
return (start_link.link_type::etl_next == ETL_NULLPTR) || (start_link.link_type::etl_next->etl_next == ETL_NULLPTR);
return (size() <= 1U);
}
//*************************************************************************
@ -263,7 +307,8 @@ namespace etl
if (p_next != ETL_NULLPTR)
{
etl::unlink_after<link_type>(link);
link_type* p_unlinked = etl::unlink_after<link_type>(link);
p_unlinked->clear();
--current_size;
}
}
@ -273,7 +318,7 @@ namespace etl
//*************************************************************************
link_type* get_head()
{
return start_link.etl_next;
return start.etl_next;
}
//*************************************************************************
@ -281,7 +326,7 @@ namespace etl
//*************************************************************************
const link_type* get_head() const
{
return start_link.etl_next;
return start.etl_next;
}
//*************************************************************************
@ -289,17 +334,20 @@ namespace etl
//*************************************************************************
void initialise()
{
start_link.etl_next = ETL_NULLPTR;
start.etl_next = &terminator;
current_size = 0;
}
};
template <typename TLink>
TLink etl::intrusive_forward_list_base<TLink>::terminator;
//***************************************************************************
/// An intrusive forward list.
///\ingroup intrusive_forward_list
///\note TLink must be a base of TValue.
//***************************************************************************
template <typename TValue, typename TLink = etl::forward_link<0> >
template <typename TValue, typename TLink>
class intrusive_forward_list : public etl::intrusive_forward_list_base<TLink>
{
public:
@ -480,7 +528,6 @@ namespace etl
//*************************************************************************
intrusive_forward_list()
{
this->initialise();
}
//*************************************************************************
@ -488,7 +535,6 @@ namespace etl
//*************************************************************************
~intrusive_forward_list()
{
this->clear();
}
//*************************************************************************
@ -521,7 +567,7 @@ namespace etl
//*************************************************************************
iterator before_begin()
{
return iterator(&this->start_link);
return iterator(&this->start);
}
//*************************************************************************
@ -529,7 +575,7 @@ namespace etl
//*************************************************************************
const_iterator before_begin() const
{
return const_iterator(&this->start_link);
return const_iterator(&this->start);
}
//*************************************************************************
@ -545,7 +591,7 @@ namespace etl
//*************************************************************************
iterator end()
{
return iterator();
return iterator(&this->terminator);
}
//*************************************************************************
@ -553,7 +599,7 @@ namespace etl
//*************************************************************************
const_iterator end() const
{
return const_iterator();
return const_iterator(&this->terminator);
}
//*************************************************************************
@ -561,7 +607,7 @@ namespace etl
//*************************************************************************
const_iterator cend() const
{
return const_iterator();
return const_iterator(&this->terminator);
}
//*************************************************************************
@ -585,6 +631,8 @@ namespace etl
//*************************************************************************
iterator insert_after(iterator position, value_type& value)
{
ETL_ASSERT_OR_RETURN_VALUE(!value.link_type::is_linked(), ETL_ERROR(intrusive_forward_list_value_is_already_linked), iterator(&value));
this->insert_link_after(*position.p_value, value);
return iterator(&value);
}
@ -598,6 +646,8 @@ namespace etl
while (first != last)
{
// Set up the next free link.
ETL_ASSERT_OR_RETURN(!(*first).link_type::is_linked(), ETL_ERROR(intrusive_forward_list_value_is_already_linked));
this->insert_link_after(*position.p_value, *first);
++first;
++position;
@ -633,13 +683,23 @@ namespace etl
this->current_size -= etl::distance(first, last) - 1;
link_type* p_first = first.p_value;
link_type* p_last = last.p_value;
link_type* p_next = p_first->etl_next;
link_type* p_last = last.p_value;
link_type* p_after = p_first->etl_next;
// Join the ends.
etl::link<link_type>(p_first, p_last);
if (p_next == ETL_NULLPTR)
// Unlink the erased range.
link_type* p_unlink = p_after;
while (p_unlink != p_last)
{
link_type* p_next = p_unlink->etl_next;
p_unlink->clear();
p_unlink = p_next;
}
if (p_after == &this->terminator)
{
return end();
}
@ -813,7 +873,7 @@ namespace etl
i_tail = i_link;
}
i_tail.p_value->etl_next = ETL_NULLPTR;
i_tail.p_value->etl_next = &this->terminator;
}
// Now left has stepped `list_size' places along, and right has too.
@ -899,7 +959,7 @@ namespace etl
etl::link<link_type>(before, first);
link_type* last = &before;
while (last->etl_next != ETL_NULLPTR)
while (last->etl_next != &other.terminator)
{
last = last->etl_next;
}
@ -983,11 +1043,11 @@ namespace etl
#endif
link_type* other_begin = other.get_head();
link_type* other_terminal = ETL_NULLPTR;
link_type* other_terminal = &other.terminator;
link_type* before = &this->start_link;
link_type* before = &this->start;
link_type* before_next = get_next(before);
link_type* terminal = ETL_NULLPTR;
link_type* terminal = &this->terminator;;
while ((before->etl_next != terminal) && (other_begin != other_terminal))
{

View File

@ -97,6 +97,12 @@ namespace etl
{
}
//***********************************
forward_link(forward_link* p_next)
: etl_next(p_next)
{
}
//***********************************
forward_link(const forward_link& other)
: etl_next(other.etl_next)
@ -298,14 +304,18 @@ namespace etl
//***************************************************************************
// Reference
template <typename TLink>
typename etl::enable_if<etl::is_forward_link<TLink>::value, void>::type
typename etl::enable_if<etl::is_forward_link<TLink>::value, TLink*>::type
unlink_after(TLink& node)
{
if (node.etl_next != ETL_NULLPTR)
{
TLink* unlinked_node = node.etl_next;
node.etl_next = unlinked_node->etl_next;
unlinked_node->clear();
return unlinked_node;
}
return node.etl_next;
}
//***********************************
@ -319,13 +329,53 @@ namespace etl
if (&before != &last)
{
before.etl_next = last.etl_next;
last.clear();
}
return first;
}
// Reference
template <typename TLink>
typename etl::enable_if<etl::is_forward_link<TLink>::value, bool>::type
is_linked(TLink& node)
{
return node.is_linked();
}
// Pointer
template <typename TLink>
typename etl::enable_if<etl::is_forward_link<TLink>::value, bool>::type
is_linked(TLink* node)
{
return node->is_linked();
}
//***************************************************************************
// link_clear_range
// link_clear
//***************************************************************************
// Reference
template <typename TLink>
typename etl::enable_if<etl::is_forward_link<TLink>::value, void>::type
link_clear(TLink& start)
{
start.etl_next = ETL_NULLPTR;
}
//***********************************
// Pointer
template <typename TLink>
typename etl::enable_if<etl::is_forward_link<TLink>::value, void>::type
link_clear(TLink* start)
{
if (start != ETL_NULLPTR)
{
etl::link_clear(*start);
}
}
//***************************************************************************
// link_clear
//***************************************************************************
// Reference
template <typename TLink>
@ -348,7 +398,10 @@ namespace etl
typename etl::enable_if<etl::is_forward_link<TLink>::value, void>::type
link_clear_range(TLink* start)
{
etl::link_clear_range(*start);
if (start != ETL_NULLPTR)
{
etl::link_clear_range(*start);
}
}
//***************************************************************************
@ -369,6 +422,13 @@ namespace etl
{
}
//***********************************
bidirectional_link(bidirectional_link* p_previous, bidirectional_link* p_next)
: etl_previous(p_previous)
, etl_next(p_next)
{
}
//***********************************
bidirectional_link(const bidirectional_link& other)
: etl_previous(other.etl_previous)
@ -716,6 +776,7 @@ namespace etl
if (first.etl_previous != ETL_NULLPTR)
{
first.etl_previous->etl_next = last.etl_next;
last.clear();
}
first.etl_previous = ETL_NULLPTR;
@ -725,6 +786,22 @@ namespace etl
return first;
}
// Reference
template <typename TLink>
typename etl::enable_if<etl::is_same<TLink, etl::bidirectional_link<TLink::ID> >::value, bool>::type
is_linked(TLink& node)
{
return node.is_linked();
}
// Pointer
template <typename TLink>
typename etl::enable_if<etl::is_same<TLink, etl::bidirectional_link<TLink::ID> >::value, bool>::type
is_linked(TLink* node)
{
return node->is_linked();
}
//***************************************************************************
// link_clear_range
//***************************************************************************
@ -771,6 +848,14 @@ namespace etl
{
}
//***********************************
tree_link(tree_link* p_parent, tree_link* p_left, tree_link* p_right)
: etl_parent(p_parent)
, etl_left(p_left)
, etl_right(p_right)
{
}
//***********************************
tree_link(const tree_link& other)
: etl_parent(other.etl_parent)
@ -1223,7 +1308,7 @@ namespace etl
// Reference
template <typename TLink>
typename etl::enable_if<etl::is_same<TLink, etl::tree_link<TLink::ID> >::value, bool>::type
link_is_linked(TLink& node)
is_linked(TLink& node)
{
return node.is_linked();
}
@ -1231,9 +1316,9 @@ namespace etl
// Pointer
template <typename TLink>
typename etl::enable_if<etl::is_same<TLink, etl::tree_link<TLink::ID> >::value, bool>::type
link_is_linked(TLink* node)
is_linked(TLink* node)
{
return node.is_linked();
return node->is_linked();
}
}

View File

@ -186,6 +186,16 @@ namespace etl
//*************************************************************************
void clear()
{
// Unlink all of the items.
link_type* p_unlink = terminal_link.etl_next;
while (p_unlink != &terminal_link)
{
link_type* p_next = p_unlink->etl_next;
p_unlink->clear();
p_unlink = p_next;
}
initialise();
}
@ -354,7 +364,7 @@ namespace etl
///\ingroup intrusive_list
///\note TLink must be a base of TValue.
//***************************************************************************
template <typename TValue, typename TLink = etl::bidirectional_link<0> >
template <typename TValue, typename TLink>
class intrusive_list : public etl::intrusive_list_base<TLink>
{
public:
@ -726,10 +736,17 @@ namespace etl
link_type* p_first = const_cast<link_type*>(cp_first);
link_type* p_last = const_cast<link_type*>(cp_last);
this->current_size -= etl::distance(first, last);
// Join the ends.
etl::link<link_type>(p_first->etl_previous, p_last);
this->current_size -= etl::distance(first, last);
while (p_first != p_last)
{
link_type* p_next = p_first->etl_next;
p_first->clear();
p_first = p_next;
}
if (p_last == &this->terminal_link)
{

View File

@ -68,9 +68,23 @@ namespace etl
}
};
//***************************************************************************
/// intrusive_queue_value_is_already_linked exception.
///\ingroup intrusive_queue
//***************************************************************************
class intrusive_queue_value_is_already_linked : public intrusive_queue_exception
{
public:
intrusive_queue_value_is_already_linked(string_type file_name_, numeric_type line_number_)
: intrusive_queue_exception(ETL_ERROR_TEXT("intrusive_queue:value is already linked", ETL_INTRUSIVE_QUEUE_FILE_ID"B"), file_name_, line_number_)
{
}
};
//***************************************************************************
///\ingroup queue
/// Base for intrusive queue. Stores elements derived any type that supports an 'etl_next' pointer member.
/// Base for intrusive queue. Stores elements derived any ETL type that supports an 'etl_next' pointer member.
/// \tparam TLink The link type that the value is derived from.
//***************************************************************************
template <typename TLink>
@ -87,21 +101,19 @@ namespace etl
//*************************************************************************
void push(link_type& value)
{
//if (value.is_linked())
//{
// return;
//}
ETL_ASSERT_OR_RETURN(!value.is_linked(), ETL_ERROR(intrusive_queue_value_is_already_linked));
if (p_back != ETL_NULLPTR)
if (empty())
{
etl::link(p_back, value);
terminator.etl_next = &value;
}
else
{
p_front = &value;
p_back->etl_next = &value;
}
p_back = &value;
value.etl_next = &terminator;
++current_size;
}
@ -113,16 +125,19 @@ namespace etl
void pop()
{
#if defined(ETL_CHECK_PUSH_POP)
ETL_ASSERT(!empty(), ETL_ERROR(intrusive_queue_empty));
ETL_ASSERT_OR_RETURN(!empty(), ETL_ERROR(intrusive_queue_empty));
#endif
link_type* p_next = p_front->etl_next;
p_front->clear();
p_front = p_next;
// Now empty?
if (p_front == ETL_NULLPTR)
link_type* p_front = terminator.etl_next;
link_type* p_next = p_front->etl_next;
terminator.etl_next = p_next;
p_front->clear();
if (empty())
{
p_back = ETL_NULLPTR;
p_back = &terminator;
}
--current_size;
@ -136,7 +151,7 @@ namespace etl
template <typename TContainer>
void pop_into(TContainer& destination)
{
link_type* p_link = p_front;
link_type* p_link = terminator.etl_next;
pop();
destination.push(*p_link);
}
@ -176,10 +191,10 @@ namespace etl
/// Constructor
//*************************************************************************
intrusive_queue_base()
: p_front(ETL_NULLPTR),
p_back(ETL_NULLPTR),
current_size(0)
: p_back (&terminator)
, current_size(0)
{
terminator.etl_next = &terminator;
}
//*************************************************************************
@ -189,8 +204,8 @@ namespace etl
{
}
link_type* p_front; ///< The current front of the queue.
link_type* p_back; ///< The current back of the queue.
link_type* p_back; ///< Pointer to the current back of the queue.
link_type terminator; ///< This link terminates the queue and points to the front of the queue.
size_t current_size; ///< Counts the number of elements in the list.
};
@ -233,7 +248,7 @@ namespace etl
//*************************************************************************
reference front()
{
return *static_cast<TValue*>(this->p_front);
return *static_cast<TValue*>(this->terminator.etl_next);
}
//*************************************************************************
@ -253,7 +268,7 @@ namespace etl
//*************************************************************************
const_reference front() const
{
return *static_cast<const TValue*>(this->p_front);
return *static_cast<const TValue*>(this->terminator.etl_next);
}
//*************************************************************************

View File

@ -68,6 +68,20 @@ namespace etl
}
};
//***************************************************************************
/// intrusive_stack_value_is_already_linked exception.
///\ingroup intrusive_stack
//***************************************************************************
class intrusive_stack_value_is_already_linked : public intrusive_stack_exception
{
public:
intrusive_stack_value_is_already_linked(string_type file_name_, numeric_type line_number_)
: intrusive_stack_exception(ETL_ERROR_TEXT("intrusive_stack:value is already linked", ETL_INTRUSIVE_STACK_FILE_ID"B"), file_name_, line_number_)
{
}
};
//***************************************************************************
///\ingroup stack
/// Base for intrusive stack. Stores elements derived any type that supports an 'etl_next' pointer member.
@ -87,20 +101,11 @@ namespace etl
//*************************************************************************
void push(link_type& value)
{
//if (value.is_linked())
//{
// return;
//}
value.clear();
if (p_top != ETL_NULLPTR)
{
etl::link(value, p_top);
}
ETL_ASSERT_OR_RETURN(!value.is_linked(), ETL_ERROR(intrusive_stack_value_is_already_linked));
value.etl_next = p_top;
p_top = &value;
++current_size;
}
@ -111,9 +116,10 @@ namespace etl
void pop()
{
#if defined(ETL_CHECK_PUSH_POP)
ETL_ASSERT(!empty(), ETL_ERROR(intrusive_stack_empty));
ETL_ASSERT_OR_RETURN(!empty(), ETL_ERROR(intrusive_stack_empty));
#endif
link_type* p_next = p_top->etl_next;
p_top->clear();
p_top = p_next;
--current_size;
}
@ -136,11 +142,11 @@ namespace etl
//*************************************************************************
void reverse()
{
link_type* previous = ETL_NULLPTR;
link_type* previous = &terminator;
link_type* current = p_top;
link_type* next;
while (current != ETL_NULLPTR)
while (current != &terminator)
{
next = current->etl_next;
current->etl_next = previous;
@ -186,9 +192,9 @@ namespace etl
/// Constructor
//*************************************************************************
intrusive_stack_base()
: p_top(ETL_NULLPTR),
current_size(0)
{
: p_top(&terminator)
, current_size(0)
{
}
//*************************************************************************
@ -198,7 +204,8 @@ namespace etl
{
}
link_type* p_top; ///< The current top of the stack.
link_type* p_top; ///< The current top of the stack.
link_type terminator; ///< Terminator link of the queue.
size_t current_size; ///< Counts the number of elements in the list.
};

View File

@ -869,7 +869,7 @@ namespace etl
#endif
ETL_ASSERT(p_node_pool != ETL_NULLPTR, ETL_ERROR(list_no_pool));
data_node_t* p_data_node = create_data_node();
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(get_head(), *p_data_node);
@ -887,7 +887,7 @@ namespace etl
#endif
ETL_ASSERT(p_node_pool != ETL_NULLPTR, ETL_ERROR(list_no_pool));
data_node_t* p_data_node = create_data_node();
data_node_t* p_data_node = allocate_data_node();
::new (&(p_data_node->value)) T(value1);
ETL_INCREMENT_DEBUG_COUNT
insert_node(get_head(), *p_data_node);
@ -905,7 +905,7 @@ namespace etl
#endif
ETL_ASSERT(p_node_pool != ETL_NULLPTR, ETL_ERROR(list_no_pool));
data_node_t* p_data_node = create_data_node();
data_node_t* p_data_node = allocate_data_node();
::new (&(p_data_node->value)) T(value1, value2);
ETL_INCREMENT_DEBUG_COUNT
insert_node(get_head(), *p_data_node);
@ -923,7 +923,7 @@ namespace etl
#endif
ETL_ASSERT(p_node_pool != ETL_NULLPTR, ETL_ERROR(list_no_pool));
data_node_t* p_data_node = create_data_node();
data_node_t* p_data_node = allocate_data_node();
::new (&(p_data_node->value)) T(value1, value2, value3);
ETL_INCREMENT_DEBUG_COUNT
insert_node(get_head(), *p_data_node);
@ -941,7 +941,7 @@ namespace etl
#endif
ETL_ASSERT(p_node_pool != ETL_NULLPTR, ETL_ERROR(list_no_pool));
data_node_t* p_data_node = create_data_node();
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(get_head(), *p_data_node);
@ -997,7 +997,7 @@ namespace etl
#endif
ETL_ASSERT(p_node_pool != ETL_NULLPTR, ETL_ERROR(list_no_pool));
data_node_t* p_data_node = create_data_node();
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(terminal_node, *p_data_node);
@ -1012,7 +1012,7 @@ namespace etl
#endif
ETL_ASSERT(p_node_pool != ETL_NULLPTR, ETL_ERROR(list_no_pool));
data_node_t* p_data_node = create_data_node();
data_node_t* p_data_node = allocate_data_node();
::new (&(p_data_node->value)) T(value1);
ETL_INCREMENT_DEBUG_COUNT
insert_node(terminal_node, *p_data_node);
@ -1027,7 +1027,7 @@ namespace etl
#endif
ETL_ASSERT(p_node_pool != ETL_NULLPTR, ETL_ERROR(list_no_pool));
data_node_t* p_data_node = create_data_node();
data_node_t* p_data_node = allocate_data_node();
::new (&(p_data_node->value)) T(value1, value2);
ETL_INCREMENT_DEBUG_COUNT
insert_node(terminal_node, *p_data_node);
@ -1042,7 +1042,7 @@ namespace etl
#endif
ETL_ASSERT(p_node_pool != ETL_NULLPTR, ETL_ERROR(list_no_pool));
data_node_t* p_data_node = create_data_node();
data_node_t* p_data_node = allocate_data_node();
::new (&(p_data_node->value)) T(value1, value2, value3);
ETL_INCREMENT_DEBUG_COUNT
insert_node(terminal_node, *p_data_node);
@ -1057,7 +1057,7 @@ namespace etl
#endif
ETL_ASSERT(p_node_pool != ETL_NULLPTR, ETL_ERROR(list_no_pool));
data_node_t* p_data_node = create_data_node();
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(terminal_node, *p_data_node);
@ -1115,7 +1115,7 @@ namespace etl
ETL_ASSERT(!full(), ETL_ERROR(list_full));
ETL_ASSERT(p_node_pool != ETL_NULLPTR, ETL_ERROR(list_no_pool));
data_node_t* p_data_node = create_data_node();
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(*to_iterator(position).p_node, *p_data_node);
@ -1129,7 +1129,7 @@ namespace etl
ETL_ASSERT(!full(), ETL_ERROR(list_full));
ETL_ASSERT(p_node_pool != ETL_NULLPTR, ETL_ERROR(list_no_pool));
data_node_t* p_data_node = create_data_node();
data_node_t* p_data_node = allocate_data_node();
::new (&(p_data_node->value)) T(value1);
ETL_INCREMENT_DEBUG_COUNT
insert_node(*position.p_node, *p_data_node);
@ -1143,7 +1143,7 @@ namespace etl
ETL_ASSERT(!full(), ETL_ERROR(list_full));
ETL_ASSERT(p_node_pool != ETL_NULLPTR, ETL_ERROR(list_no_pool));
data_node_t* p_data_node = create_data_node();
data_node_t* p_data_node = allocate_data_node();
::new (&(p_data_node->value)) T(value1, value2);
ETL_INCREMENT_DEBUG_COUNT
insert_node(*position.p_node, *p_data_node);
@ -1157,7 +1157,7 @@ namespace etl
ETL_ASSERT(!full(), ETL_ERROR(list_full));
ETL_ASSERT(p_node_pool != ETL_NULLPTR, ETL_ERROR(list_no_pool));
data_node_t* p_data_node = create_data_node();
data_node_t* p_data_node = allocate_data_node();
::new (&(p_data_node->value)) T(value1, value2, value3);
ETL_INCREMENT_DEBUG_COUNT
insert_node(*position.p_node, *p_data_node);
@ -1171,7 +1171,7 @@ namespace etl
ETL_ASSERT(!full(), ETL_ERROR(list_full));
ETL_ASSERT(p_node_pool != ETL_NULLPTR, ETL_ERROR(list_no_pool));
data_node_t* p_data_node = create_data_node();
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(*position.p_node, *p_data_node);
@ -1953,7 +1953,7 @@ namespace etl
{
ETL_ASSERT(p_node_pool != ETL_NULLPTR, ETL_ERROR(list_no_pool));
data_node_t* p_data_node = create_data_node();
data_node_t* p_data_node = allocate_data_node();
::new (&(p_data_node->value)) T(value);
ETL_INCREMENT_DEBUG_COUNT
@ -1968,7 +1968,7 @@ namespace etl
{
ETL_ASSERT(p_node_pool != ETL_NULLPTR, ETL_ERROR(list_no_pool));
data_node_t* p_data_node = create_data_node();
data_node_t* p_data_node = allocate_data_node();
::new (&(p_data_node->value)) T(etl::move(value));
ETL_INCREMENT_DEBUG_COUNT
@ -1979,7 +1979,7 @@ namespace etl
//*************************************************************************
/// Create a data_node_t.
//*************************************************************************
data_node_t* create_data_node()
data_node_t* allocate_data_node()
{
data_node_t* (etl::ipool::*func)() = &etl::ipool::allocate<data_node_t>;
return (p_node_pool->*func)();

View File

@ -1496,7 +1496,7 @@ namespace etl
//*************************************************************************
Data_Node& allocate_data_node(const_reference value)
{
Data_Node& node = create_data_node();
Data_Node& node = allocate_data_node();
::new (&node.value) value_type(value);
ETL_INCREMENT_DEBUG_COUNT
return node;
@ -1507,7 +1507,7 @@ namespace etl
//*************************************************************************
Data_Node& allocate_data_node_with_key(const_key_reference key)
{
Data_Node& node = create_data_node();
Data_Node& node = allocate_data_node();
::new ((void*)etl::addressof(node.value.first)) key_type(key);
::new ((void*)etl::addressof(node.value.second)) mapped_type();
@ -1521,7 +1521,7 @@ namespace etl
//*************************************************************************
Data_Node& allocate_data_node(rvalue_reference value)
{
Data_Node& node = create_data_node();
Data_Node& node = allocate_data_node();
::new (&node.value) value_type(etl::move(value));
ETL_INCREMENT_DEBUG_COUNT
return node;
@ -1532,7 +1532,7 @@ namespace etl
//*************************************************************************
Data_Node& allocate_data_node_with_key(rvalue_key_reference key)
{
Data_Node& node = create_data_node();
Data_Node& node = allocate_data_node();
::new ((void*)etl::addressof(node.value.first)) key_type(etl::move(key));
::new ((void*)etl::addressof(node.value.second)) mapped_type();
@ -1545,7 +1545,7 @@ namespace etl
//*************************************************************************
/// Create a Data_Node.
//*************************************************************************
Data_Node& create_data_node()
Data_Node& allocate_data_node()
{
Data_Node* (etl::ipool::*func)() = &etl::ipool::allocate<Data_Node>;
return *(p_node_pool->*func)();

View File

@ -1542,7 +1542,7 @@ namespace etl
//*************************************************************************
Data_Node& allocate_data_node(const_reference value)
{
Data_Node& node = create_data_node();
Data_Node& node = allocate_data_node();
::new (&node.value) const value_type(value);
ETL_INCREMENT_DEBUG_COUNT
return node;
@ -1554,7 +1554,7 @@ namespace etl
//*************************************************************************
Data_Node& allocate_data_node(rvalue_reference value)
{
Data_Node& node = create_data_node();
Data_Node& node = allocate_data_node();
::new (&node.value) const value_type(etl::move(value));
ETL_INCREMENT_DEBUG_COUNT
return node;
@ -1564,7 +1564,7 @@ namespace etl
//*************************************************************************
/// Create a Data_Node.
//*************************************************************************
Data_Node& create_data_node()
Data_Node& allocate_data_node()
{
Data_Node* (etl::ipool::*func)() = &etl::ipool::allocate<Data_Node>;
return *(p_node_pool->*func)();

View File

@ -1528,7 +1528,7 @@ namespace etl
//*************************************************************************
Data_Node& allocate_data_node(const_reference value)
{
Data_Node& node = create_data_node();
Data_Node& node = allocate_data_node();
::new ((void*)&node.value) value_type(value);
ETL_INCREMENT_DEBUG_COUNT
return node;
@ -1540,7 +1540,7 @@ namespace etl
//*************************************************************************
Data_Node& allocate_data_node(rvalue_reference value)
{
Data_Node& node = create_data_node();
Data_Node& node = allocate_data_node();
::new ((void*)&node.value) value_type(etl::move(value));
ETL_INCREMENT_DEBUG_COUNT
return node;
@ -1550,7 +1550,7 @@ namespace etl
//*************************************************************************
/// Create a Data_Node.
//*************************************************************************
Data_Node& create_data_node()
Data_Node& allocate_data_node()
{
Data_Node* (etl::ipool::*func)() = &etl::ipool::allocate<Data_Node>;
return *(p_node_pool->*func)();

View File

@ -1361,7 +1361,7 @@ namespace etl
//*************************************************************************
Data_Node& allocate_data_node(const_reference value)
{
Data_Node& node = create_data_node();
Data_Node& node = allocate_data_node();
::new ((void*)&node.value) value_type(value);
ETL_INCREMENT_DEBUG_COUNT
return node;
@ -1373,7 +1373,7 @@ namespace etl
//*************************************************************************
Data_Node& allocate_data_node(rvalue_reference value)
{
Data_Node& node = create_data_node();
Data_Node& node = allocate_data_node();
::new ((void*)&node.value) value_type(etl::move(value));
ETL_INCREMENT_DEBUG_COUNT
return node;
@ -1383,7 +1383,7 @@ namespace etl
//*************************************************************************
/// Create a Data_Node.
//*************************************************************************
Data_Node& create_data_node()
Data_Node& allocate_data_node()
{
Data_Node* (etl::ipool::*func)() = &etl::ipool::allocate<Data_Node>;
return *(p_node_pool->*func)();

View File

@ -659,7 +659,8 @@ namespace etl
// Doesn't exist, so add a new one.
// Get a new node.
node_t& node = create_data_node();
node_t& node = allocate_data_node();
node.clear();
::new ((void*)etl::addressof(node.key_value_pair.first)) key_type(etl::move(key));
::new ((void*)etl::addressof(node.key_value_pair.second)) mapped_type();
ETL_INCREMENT_DEBUG_COUNT
@ -702,7 +703,8 @@ namespace etl
// Doesn't exist, so add a new one.
// Get a new node.
node_t& node = create_data_node();
node_t& node = allocate_data_node();
node.clear();
::new ((void*)etl::addressof(node.key_value_pair.first)) key_type(key);
::new ((void*)etl::addressof(node.key_value_pair.second)) mapped_type();
ETL_INCREMENT_DEBUG_COUNT
@ -833,7 +835,8 @@ namespace etl
if (bucket.empty())
{
// Get a new node.
node_t& node = create_data_node();
node_t& node = allocate_data_node();
node.clear();
::new ((void*)etl::addressof(node.key_value_pair)) value_type(key_value_pair);
ETL_INCREMENT_DEBUG_COUNT
@ -867,7 +870,8 @@ namespace etl
if (inode == bucket.end())
{
// Get a new node.
node_t& node = create_data_node();
node_t& node = allocate_data_node();
node.clear();
::new ((void*)etl::addressof(node.key_value_pair)) value_type(key_value_pair);
ETL_INCREMENT_DEBUG_COUNT
@ -909,7 +913,8 @@ namespace etl
if (bucket.empty())
{
// Get a new node.
node_t& node = create_data_node();
node_t& node = allocate_data_node();
node.clear();
::new ((void*)etl::addressof(node.key_value_pair)) value_type(etl::move(key_value_pair));
ETL_INCREMENT_DEBUG_COUNT
@ -943,7 +948,8 @@ namespace etl
if (inode == bucket.end())
{
// Get a new node.
node_t& node = create_data_node();
node_t& node = allocate_data_node();
node.clear();
::new ((void*)etl::addressof(node.key_value_pair)) value_type(etl::move(key_value_pair));
ETL_INCREMENT_DEBUG_COUNT
@ -1027,12 +1033,8 @@ namespace etl
// Did we find it?
if (icurrent != bucket.end())
{
bucket.erase_after(iprevious); // Unlink from the bucket.
icurrent->key_value_pair.~value_type(); // Destroy the value.
pnodepool->release(&*icurrent); // Release it back to the pool.
adjust_first_last_markers_after_erase(&bucket);
delete_data_node(iprevious, icurrent, bucket);
n = 1;
ETL_DECREMENT_DEBUG_COUNT
}
return n;
@ -1058,11 +1060,7 @@ namespace etl
++iprevious;
}
bucket.erase_after(iprevious); // Unlink from the bucket.
icurrent->key_value_pair.~value_type(); // Destroy the value.
pnodepool->release(&*icurrent); // Release it back to the pool.
adjust_first_last_markers_after_erase(&bucket);
ETL_DECREMENT_DEBUG_COUNT
delete_data_node(iprevious, icurrent, bucket);
return inext;
}
@ -1096,16 +1094,13 @@ namespace etl
++iprevious;
}
// Remember the item before the first erased one.
iterator ibefore_erased = iterator((pbuckets + number_of_buckets), pbucket, iprevious);
// Until we reach the end.
while ((icurrent != iend) || (pbucket != pend_bucket))
{
local_iterator inext = pbucket->erase_after(iprevious); // Unlink from the bucket.
icurrent->key_value_pair.~value_type(); // Destroy the value.
pnodepool->release(&*icurrent); // Release it back to the pool.
adjust_first_last_markers_after_erase(pbucket);
ETL_DECREMENT_DEBUG_COUNT
icurrent = inext;
{
icurrent = delete_data_node(iprevious, icurrent, *pbucket);
// Have we not reached the end?
if ((icurrent != iend) || (pbucket != pend_bucket))
@ -1125,7 +1120,7 @@ namespace etl
}
}
return iterator((pbuckets + number_of_buckets), last_.get_bucket_list_iterator(), last_.get_local_iterator());
return ++ibefore_erased;
}
//*************************************************************************
@ -1442,7 +1437,7 @@ namespace etl
//*************************************************************************
/// Create a node.
//*************************************************************************
node_t& create_data_node()
node_t& allocate_data_node()
{
node_t* (etl::ipool::*func)() = &etl::ipool::allocate<node_t>;
return *(pnodepool->*func)();
@ -1512,6 +1507,20 @@ namespace etl
}
}
//*********************************************************************
/// Delete a data noe at the specified location.
//*********************************************************************
local_iterator delete_data_node(local_iterator iprevious, local_iterator icurrent, bucket_t& bucket)
{
local_iterator inext = bucket.erase_after(iprevious); // Unlink from the bucket.
icurrent->key_value_pair.~value_type(); // Destroy the value.
pnodepool->release(&*icurrent); // Release it back to the pool.
adjust_first_last_markers_after_erase(&bucket);
ETL_DECREMENT_DEBUG_COUNT
return inext;
}
// Disable copy construction.
iunordered_map(const iunordered_map&);

View File

@ -675,7 +675,8 @@ namespace etl
if (bucket.empty())
{
// Get a new node.
node_t& node = create_data_node();
node_t& node = allocate_data_node();
node.clear();
::new (&node.key_value_pair) value_type(key_value_pair);
ETL_INCREMENT_DEBUG_COUNT
@ -704,7 +705,8 @@ namespace etl
}
// Get a new node.
node_t& node = create_data_node();
node_t& node = allocate_data_node();
node.clear();
::new (&node.key_value_pair) value_type(key_value_pair);
ETL_INCREMENT_DEBUG_COUNT
@ -744,7 +746,8 @@ namespace etl
if (bucket.empty())
{
// Get a new node.
node_t& node = create_data_node();
node_t& node = allocate_data_node();
node.clear();
::new (&node.key_value_pair) value_type(etl::move(key_value_pair));
ETL_INCREMENT_DEBUG_COUNT
@ -773,7 +776,8 @@ namespace etl
}
// Get a new node.
node_t& node = create_data_node();
node_t& node = allocate_data_node();
node.clear();
::new (&node.key_value_pair) value_type(etl::move(key_value_pair));
ETL_INCREMENT_DEBUG_COUNT
@ -849,13 +853,9 @@ namespace etl
{
if (key_equal_function(icurrent->key_value_pair.first, key))
{
bucket.erase_after(iprevious); // Unlink from the bucket.
icurrent->key_value_pair.~value_type(); // Destroy the value.
pnodepool->release(&*icurrent); // Release it back to the pool.
adjust_first_last_markers_after_erase(&bucket);
delete_data_node(iprevious, icurrent, bucket);
++n;
icurrent = iprevious;
ETL_DECREMENT_DEBUG_COUNT
}
else
{
@ -888,11 +888,7 @@ namespace etl
++iprevious;
}
bucket.erase_after(iprevious); // Unlink from the bucket.
icurrent->key_value_pair.~value_type(); // Destroy the value.
pnodepool->release(&*icurrent); // Release it back to the pool.
adjust_first_last_markers_after_erase(&bucket);
ETL_DECREMENT_DEBUG_COUNT
delete_data_node(iprevious, icurrent, bucket);
return inext;
}
@ -913,9 +909,6 @@ namespace etl
return end();
}
// Make a note of the last.
iterator result((pbuckets + number_of_buckets), last_.get_bucket_list_iterator(), last_.get_local_iterator());
// Get the starting point.
bucket_t* pbucket = first_.get_bucket_list_iterator();
bucket_t* pend_bucket = last_.get_bucket_list_iterator();
@ -929,17 +922,13 @@ namespace etl
++iprevious;
}
// Remember the item before the first erased one.
iterator ibefore_erased = iterator((pbuckets + number_of_buckets), pbucket, iprevious);
// Until we reach the end.
while ((icurrent != iend) || (pbucket != pend_bucket))
{
local_iterator inext = pbucket->erase_after(iprevious); // Unlink from the bucket.
icurrent->key_value_pair.~value_type(); // Destroy the value.
pnodepool->release(&*icurrent); // Release it back to the pool.
adjust_first_last_markers_after_erase(pbucket);
ETL_DECREMENT_DEBUG_COUNT
icurrent = inext;
icurrent = delete_data_node(iprevious, icurrent, *pbucket);
// Have we not reached the end?
if ((icurrent != iend) || (pbucket != pend_bucket))
@ -959,7 +948,7 @@ namespace etl
}
}
return result;
return ++ibefore_erased;
}
//*************************************************************************
@ -1302,7 +1291,7 @@ namespace etl
//*************************************************************************
/// Create a node.
//*************************************************************************
node_t& create_data_node()
node_t& allocate_data_node()
{
node_t* (etl::ipool::*func)() = &etl::ipool::allocate<node_t>;
return *(pnodepool->*func)();
@ -1372,6 +1361,20 @@ namespace etl
}
}
//*********************************************************************
/// Delete a data noe at the specified location.
//*********************************************************************
local_iterator delete_data_node(local_iterator iprevious, local_iterator icurrent, bucket_t& bucket)
{
local_iterator inext = bucket.erase_after(iprevious); // Unlink from the bucket.
icurrent->key_value_pair.~value_type(); // Destroy the value.
pnodepool->release(&*icurrent); // Release it back to the pool.
adjust_first_last_markers_after_erase(&bucket);
ETL_DECREMENT_DEBUG_COUNT
return inext;
}
// Disable copy construction.
iunordered_multimap(const iunordered_multimap&);

View File

@ -664,7 +664,8 @@ namespace etl
if (bucket.empty())
{
// Get a new node.
node_t& node = create_data_node();
node_t& node = allocate_data_node();
node.clear();
::new (&node.key) value_type(key);
ETL_INCREMENT_DEBUG_COUNT
@ -694,7 +695,8 @@ namespace etl
}
// Get a new node.
node_t& node = create_data_node();
node_t& node = allocate_data_node();
node.clear();
::new (&node.key) value_type(key);
ETL_INCREMENT_DEBUG_COUNT
@ -733,7 +735,8 @@ namespace etl
if (bucket.empty())
{
// Get a new node.
node_t& node = create_data_node();
node_t& node = allocate_data_node();
node.clear();
::new (&node.key) value_type(etl::move(key));
ETL_INCREMENT_DEBUG_COUNT
@ -763,7 +766,8 @@ namespace etl
}
// Get a new node.
node_t& node = create_data_node();
node_t& node = allocate_data_node();
node.clear();
::new (&node.key) value_type(etl::move(key));
ETL_INCREMENT_DEBUG_COUNT
@ -827,13 +831,9 @@ namespace etl
{
if (key_equal_function(icurrent->key, key))
{
bucket.erase_after(iprevious); // Unlink from the bucket.
icurrent->key.~value_type(); // Destroy the value.
pnodepool->release(&*icurrent); // Release it back to the pool.
adjust_first_last_markers_after_erase(&bucket);
delete_data_node(iprevious, icurrent, bucket);
++n;
icurrent = iprevious;
ETL_DECREMENT_DEBUG_COUNT
}
else
{
@ -866,11 +866,7 @@ namespace etl
++iprevious;
}
bucket.erase_after(iprevious); // Unlink from the bucket.
icurrent->key.~value_type(); // Destroy the value.
pnodepool->release(&*icurrent); // Release it back to the pool.
adjust_first_last_markers_after_erase(&bucket);
ETL_DECREMENT_DEBUG_COUNT
delete_data_node(iprevious, icurrent, bucket);
return inext;
}
@ -891,9 +887,6 @@ namespace etl
return end();
}
// Make a note of the last.
iterator result((pbuckets + number_of_buckets), last_.get_bucket_list_iterator(), last_.get_local_iterator());
// Get the starting point.
bucket_t* pbucket = first_.get_bucket_list_iterator();
bucket_t* pend_bucket = last_.get_bucket_list_iterator();
@ -907,17 +900,13 @@ namespace etl
++iprevious;
}
// Remember the item before the first erased one.
iterator ibefore_erased = iterator((pbuckets + number_of_buckets), pbucket, iprevious);
// Until we reach the end.
while ((icurrent != iend) || (pbucket != pend_bucket))
{
local_iterator inext = pbucket->erase_after(iprevious); // Unlink from the bucket.
icurrent->key.~value_type(); // Destroy the value.
pnodepool->release(&*icurrent); // Release it back to the pool.
adjust_first_last_markers_after_erase(pbucket);
ETL_DECREMENT_DEBUG_COUNT
icurrent = inext;
icurrent = delete_data_node(iprevious, icurrent, *pbucket);
// Have we not reached the end?
if ((icurrent != iend) || (pbucket != pend_bucket))
@ -937,7 +926,7 @@ namespace etl
}
}
return result;
return ++ibefore_erased;
}
//*************************************************************************
@ -1280,7 +1269,7 @@ namespace etl
//*************************************************************************
/// Create a node.
//*************************************************************************
node_t& create_data_node()
node_t& allocate_data_node()
{
node_t* (etl::ipool::*func)() = &etl::ipool::allocate<node_t>;
return *(pnodepool->*func)();
@ -1350,6 +1339,20 @@ namespace etl
}
}
//*********************************************************************
/// Delete a data noe at the specified location.
//*********************************************************************
local_iterator delete_data_node(local_iterator iprevious, local_iterator icurrent, bucket_t& bucket)
{
local_iterator inext = bucket.erase_after(iprevious); // Unlink from the bucket.
icurrent->key.~value_type(); // Destroy the value.
pnodepool->release(&*icurrent); // Release it back to the pool.
adjust_first_last_markers_after_erase(&bucket);
ETL_DECREMENT_DEBUG_COUNT
return inext;
}
// Disable copy construction.
iunordered_multiset(const iunordered_multiset&);

View File

@ -665,7 +665,8 @@ namespace etl
if (bucket.empty())
{
// Get a new node.
node_t& node = create_data_node();
node_t& node = allocate_data_node();
node.clear();
::new (&node.key) value_type(key);
ETL_INCREMENT_DEBUG_COUNT
@ -698,7 +699,8 @@ namespace etl
if (inode == bucket.end())
{
// Get a new node.
node_t& node = create_data_node();
node_t& node = allocate_data_node();
node.clear();
::new (&node.key) value_type(key);
ETL_INCREMENT_DEBUG_COUNT
@ -738,7 +740,8 @@ namespace etl
if (bucket.empty())
{
// Get a new node.
node_t& node = create_data_node();
node_t& node = allocate_data_node();
node.clear();
::new (&node.key) value_type(etl::move(key));
ETL_INCREMENT_DEBUG_COUNT
@ -771,7 +774,8 @@ namespace etl
if (inode == bucket.end())
{
// Get a new node.
node_t& node = create_data_node();
node_t& node = allocate_data_node();
node.clear();
::new (&node.key) value_type(etl::move(key));
ETL_INCREMENT_DEBUG_COUNT
@ -855,12 +859,8 @@ namespace etl
// Did we find it?
if (icurrent != bucket.end())
{
bucket.erase_after(iprevious); // Unlink from the bucket.
icurrent->key.~value_type(); // Destroy the value.
pnodepool->release(&*icurrent); // Release it back to the pool.
adjust_first_last_markers_after_erase(&bucket);
delete_data_node(iprevious, icurrent, bucket);
n = 1;
ETL_DECREMENT_DEBUG_COUNT
}
return n;
@ -886,11 +886,7 @@ namespace etl
++iprevious;
}
bucket.erase_after(iprevious); // Unlink from the bucket.
icurrent->key.~value_type(); // Destroy the value.
pnodepool->release(&*icurrent); // Release it back to the pool.
adjust_first_last_markers_after_erase(&bucket);
ETL_DECREMENT_DEBUG_COUNT
delete_data_node(iprevious, icurrent, bucket);
return inext;
}
@ -911,9 +907,6 @@ namespace etl
return end();
}
// Make a note of the last.
iterator result((pbuckets + number_of_buckets), last_.get_bucket_list_iterator(), last_.get_local_iterator());
// Get the starting point.
bucket_t* pbucket = first_.get_bucket_list_iterator();
bucket_t* pend_bucket = last_.get_bucket_list_iterator();
@ -927,17 +920,13 @@ namespace etl
++iprevious;
}
// Remember the item before the first erased one.
iterator ibefore_erased = iterator((pbuckets + number_of_buckets), pbucket, iprevious);
// Until we reach the end.
while ((icurrent != iend) || (pbucket != pend_bucket))
{
local_iterator inext = pbucket->erase_after(iprevious); // Unlink from the bucket.
icurrent->key.~value_type(); // Destroy the value.
pnodepool->release(&*icurrent); // Release it back to the pool.
adjust_first_last_markers_after_erase(pbucket);
ETL_DECREMENT_DEBUG_COUNT
icurrent = inext;
icurrent = delete_data_node(iprevious, icurrent, *pbucket);
// Have we not reached the end?
if ((icurrent != iend) || (pbucket != pend_bucket))
@ -957,7 +946,7 @@ namespace etl
}
}
return result;
return ++ibefore_erased;
}
//*************************************************************************
@ -1280,7 +1269,7 @@ namespace etl
//*************************************************************************
/// Create a node.
//*************************************************************************
node_t& create_data_node()
node_t& allocate_data_node()
{
node_t* (etl::ipool::*func)() = &etl::ipool::allocate<node_t>;
return *(pnodepool->*func)();
@ -1314,40 +1303,54 @@ namespace etl
//*********************************************************************
void adjust_first_last_markers_after_erase(bucket_t* pcurrent)
{
if (empty())
{
first = pbuckets;
last = pbuckets;
}
else
{
if (pcurrent == first)
{
// We erased the first so, we need to search again from where we erased.
while (first->empty())
{
++first;
}
}
else if (pcurrent == last)
{
// We erased the last, so we need to search again. Start from the first, go no further than the current last.
bucket_t* pcurrent = first;
bucket_t* pend = last;
last = first;
while (pcurrent != pend)
{
if (!pcurrent->empty())
if (empty())
{
last = pcurrent;
first = pbuckets;
last = pbuckets;
}
else
{
if (pcurrent == first)
{
// We erased the first so, we need to search again from where we erased.
while (first->empty())
{
++first;
}
}
else if (pcurrent == last)
{
// We erased the last, so we need to search again. Start from the first, go no further than the current last.
bucket_t* pcurrent = first;
bucket_t* pend = last;
++pcurrent;
last = first;
while (pcurrent != pend)
{
if (!pcurrent->empty())
{
last = pcurrent;
}
++pcurrent;
}
}
}
}
}
}
//*********************************************************************
/// Delete a data noe at the specified location.
//*********************************************************************
local_iterator delete_data_node(local_iterator iprevious, local_iterator icurrent, bucket_t& bucket)
{
local_iterator inext = bucket.erase_after(iprevious); // Unlink from the bucket.
icurrent->key.~value_type(); // Destroy the value.
pnodepool->release(&*icurrent); // Release it back to the pool.
adjust_first_last_markers_after_erase(&bucket);
ETL_DECREMENT_DEBUG_COUNT
return inext;
}
// Disable copy construction.

View File

@ -8,6 +8,7 @@
#712 Unable to use etl::optional with non-default-constructible POD objects.
Modified etl::visitor to allow direct specification of the argument type.
Added etl::is_visitor trait.
Removed default link type for etl::intrusive_list and etl::intrusive_forward_list
===============================================================================
20.36.2

View File

@ -253,8 +253,19 @@ namespace
TEST_FIXTURE(SetupFixture, test_clear)
{
DataNDC0 data0(sorted_data.begin(), sorted_data.end());
for (auto& item : sorted_data)
{
CHECK_TRUE(etl::is_linked<FirstLink>(item));
}
data0.clear();
for (auto& item : sorted_data)
{
CHECK_FALSE(etl::is_linked<FirstLink>(item));
}
CHECK(data0.empty());
}
@ -263,11 +274,13 @@ namespace
{
DataNDC0 data0;
static InitialDataNDC sorted_data = { ItemNDCNode("0"), ItemNDCNode("1"), ItemNDCNode("2"), ItemNDCNode("3"), ItemNDCNode("4"), ItemNDCNode("5"), ItemNDCNode("6"), ItemNDCNode("7"), ItemNDCNode("8"), ItemNDCNode("9") };
// Do it twice. We should only get one copy.
data0.assign(sorted_data.begin(), sorted_data.end());
data0.assign(sorted_data.begin(), sorted_data.end());
are_equal = std::equal(data0.begin(), data0.end(), sorted_data.begin());
bool are_equal = std::equal(data0.begin(), data0.end(), sorted_data.begin());
CHECK(are_equal);
}
@ -276,7 +289,7 @@ namespace
TEST_FIXTURE(SetupFixture, test_assign_range_two_lists_same)
{
DataNDC0 data0;
DataNDC0 data1;
DataNDC1 data1;
data0.assign(sorted_data.begin(), sorted_data.end());
data1.assign(sorted_data.begin(), sorted_data.end());
@ -596,6 +609,17 @@ namespace
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_erase_after_range)
{
FirstLink& fl0 = sorted_data[0];
FirstLink& fl1 = sorted_data[1];
FirstLink& fl2 = sorted_data[2];
FirstLink& fl3 = sorted_data[3];
FirstLink& fl4 = sorted_data[4];
FirstLink& fl5 = sorted_data[5];
FirstLink& fl6 = sorted_data[6];
FirstLink& fl7 = sorted_data[7];
FirstLink& fl8 = sorted_data[8];
FirstLink& fl9 = sorted_data[9];
std::forward_list<ItemNDCNode> compare_data(sorted_data.begin(), sorted_data.end());
DataNDC0 data0(sorted_data.begin(), sorted_data.end());
DataNDC1 data1(sorted_data2.begin(), sorted_data2.end());
@ -614,8 +638,30 @@ namespace
std::forward_list<ItemNDCNode>::iterator i_compare_result = compare_data.erase_after(i_compare_data_1, i_compare_data_2);
CHECK_TRUE(fl0.is_linked());
CHECK_TRUE(fl1.is_linked());
CHECK_TRUE(fl2.is_linked());
CHECK_TRUE(fl3.is_linked());
CHECK_TRUE(fl4.is_linked());
CHECK_TRUE(fl5.is_linked());
CHECK_TRUE(fl6.is_linked());
CHECK_TRUE(fl7.is_linked());
CHECK_TRUE(fl8.is_linked());
CHECK_TRUE(fl9.is_linked());
DataNDC0::iterator i_result = data0.erase_after(i_data_1, i_data_2);
CHECK_TRUE(fl0.is_linked());
CHECK_TRUE(fl1.is_linked());
CHECK_TRUE(fl2.is_linked());
CHECK_FALSE(fl3.is_linked());
CHECK_FALSE(fl4.is_linked());
CHECK_TRUE(fl5.is_linked());
CHECK_TRUE(fl6.is_linked());
CHECK_TRUE(fl7.is_linked());
CHECK_TRUE(fl8.is_linked());
CHECK_TRUE(fl9.is_linked());
CHECK_EQUAL(*i_compare_result, *i_result);
are_equal = std::equal(data0.begin(), data0.end(), compare_data.begin());
@ -748,11 +794,46 @@ namespace
DataNDC0 data0(sorted_data.begin(), sorted_data.end());
DataNDC1 data1(sorted_data.begin(), sorted_data.end());
FirstLink& fl0 = sorted_data[0];
FirstLink& fl1 = sorted_data[1];
FirstLink& fl2 = sorted_data[2];
FirstLink& fl3 = sorted_data[3];
FirstLink& fl4 = sorted_data[4];
FirstLink& fl5 = sorted_data[5];
FirstLink& fl6 = sorted_data[6];
FirstLink& fl7 = sorted_data[7];
FirstLink& fl8 = sorted_data[8];
FirstLink& fl9 = sorted_data[9];
CHECK_TRUE(fl0.etl_next == &fl1);
CHECK_TRUE(fl1.etl_next == &fl2);
CHECK_TRUE(fl2.etl_next == &fl3);
CHECK_TRUE(fl3.etl_next == &fl4);
CHECK_TRUE(fl4.etl_next == &fl5);
CHECK_TRUE(fl5.etl_next == &fl6);
CHECK_TRUE(fl6.etl_next == &fl7);
CHECK_TRUE(fl7.etl_next == &fl8);
CHECK_TRUE(fl8.etl_next == &fl9);
CHECK_TRUE(fl9.etl_next == &(*data0.end()));
data0.reverse(); // Just reverse one of them.
CHECK_TRUE(fl9.etl_next == &fl8);
CHECK_TRUE(fl8.etl_next == &fl7);
CHECK_TRUE(fl7.etl_next == &fl6);
CHECK_TRUE(fl6.etl_next == &fl5);
CHECK_TRUE(fl5.etl_next == &fl4);
CHECK_TRUE(fl4.etl_next == &fl3);
CHECK_TRUE(fl3.etl_next == &fl2);
CHECK_TRUE(fl2.etl_next == &fl1);
CHECK_TRUE(fl1.etl_next == &fl0);
CHECK_TRUE(fl0.etl_next == &(*data0.end()));
CHECK_EQUAL(data1.size(), data0.size());
CHECK_EQUAL(data0.size(), size_t(std::distance(data0.begin(), data0.end())));
bool are_equal = false;
are_equal = std::equal(data0.begin(), data0.end(), sorted_data.rbegin());
CHECK(are_equal);
@ -811,7 +892,7 @@ namespace
CHECK(are_equal);
}
//*************************************************************************
////*************************************************************************
TEST_FIXTURE(SetupFixture, test_splice_list)
{
DataNDC0 data0(sorted_data.begin(), sorted_data.end());

View File

@ -106,19 +106,19 @@ namespace
FData data2(2);
FData data3(3);
data0.FLink0::clear();
etl::link_clear<FLink0>(data0);
etl::link<FLink0>(data0, data1);
CHECK(data0.FLink0::etl_next == &data1);
data0.FLink0::clear();
etl::link_clear<FLink0>(data0);
etl::link<FLink0>(&data0, data1);
CHECK(data0.FLink0::etl_next == &data1);
data0.FLink0::clear();
etl::link_clear<FLink0>(data0);
etl::link<FLink0>(data0, &data1);
CHECK(data0.FLink0::etl_next == &data1);
data0.FLink0::clear();
etl::link_clear<FLink0>(data0);
etl::link<FLink0>(&data0, &data1);
CHECK(data0.FLink0::etl_next == &data1);
@ -390,7 +390,7 @@ namespace
FLink0* start = etl::unlink_after<FLink0>(data0, data2);
CHECK(data0.FLink0::etl_next == &data3);
CHECK(data1.FLink0::etl_next == &data2);
CHECK(data2.FLink0::etl_next == &data3);
CHECK(data2.FLink0::etl_next == nullptr);
CHECK(data3.FLink0::etl_next == nullptr);
etl::link_clear_range(*start);
@ -416,7 +416,7 @@ namespace
etl::unlink_after<FLink0>(data0);
CHECK(data0.FLink0::etl_next == &data0);
CHECK(data0.FLink0::etl_next == nullptr);
}
//*************************************************************************

View File

@ -267,10 +267,123 @@ namespace
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_clear)
{
FirstLink& fl0 = sorted_data[0];
FirstLink& fl1 = sorted_data[1];
FirstLink& fl2 = sorted_data[2];
FirstLink& fl3 = sorted_data[3];
FirstLink& fl4 = sorted_data[4];
FirstLink& fl5 = sorted_data[5];
FirstLink& fl6 = sorted_data[6];
FirstLink& fl7 = sorted_data[7];
FirstLink& fl8 = sorted_data[8];
FirstLink& fl9 = sorted_data[9];
SecondLink& sl0 = sorted_data[0];
SecondLink& sl1 = sorted_data[1];
SecondLink& sl2 = sorted_data[2];
SecondLink& sl3 = sorted_data[3];
SecondLink& sl4 = sorted_data[4];
SecondLink& sl5 = sorted_data[5];
SecondLink& sl6 = sorted_data[6];
SecondLink& sl7 = sorted_data[7];
SecondLink& sl8 = sorted_data[8];
SecondLink& sl9 = sorted_data[9];
DataNDC0 data0(sorted_data.begin(), sorted_data.end());
CHECK_TRUE(fl0.is_linked());
CHECK_TRUE(fl1.is_linked());
CHECK_TRUE(fl2.is_linked());
CHECK_TRUE(fl3.is_linked());
CHECK_TRUE(fl4.is_linked());
CHECK_TRUE(fl5.is_linked());
CHECK_TRUE(fl6.is_linked());
CHECK_TRUE(fl7.is_linked());
CHECK_TRUE(fl8.is_linked());
CHECK_TRUE(fl9.is_linked());
CHECK_FALSE(sl0.is_linked());
CHECK_FALSE(sl1.is_linked());
CHECK_FALSE(sl2.is_linked());
CHECK_FALSE(sl3.is_linked());
CHECK_FALSE(sl4.is_linked());
CHECK_FALSE(sl5.is_linked());
CHECK_FALSE(sl6.is_linked());
CHECK_FALSE(sl7.is_linked());
CHECK_FALSE(sl8.is_linked());
CHECK_FALSE(sl9.is_linked());
DataNDC1 data1(sorted_data.begin(), sorted_data.end());
CHECK_TRUE(fl0.is_linked());
CHECK_TRUE(fl1.is_linked());
CHECK_TRUE(fl2.is_linked());
CHECK_TRUE(fl3.is_linked());
CHECK_TRUE(fl4.is_linked());
CHECK_TRUE(fl5.is_linked());
CHECK_TRUE(fl6.is_linked());
CHECK_TRUE(fl7.is_linked());
CHECK_TRUE(fl8.is_linked());
CHECK_TRUE(fl9.is_linked());
CHECK_TRUE(sl0.is_linked());
CHECK_TRUE(sl1.is_linked());
CHECK_TRUE(sl2.is_linked());
CHECK_TRUE(sl3.is_linked());
CHECK_TRUE(sl4.is_linked());
CHECK_TRUE(sl5.is_linked());
CHECK_TRUE(sl6.is_linked());
CHECK_TRUE(sl7.is_linked());
CHECK_TRUE(sl8.is_linked());
CHECK_TRUE(sl9.is_linked());
data0.clear();
CHECK(data0.empty());
CHECK_FALSE(fl0.is_linked());
CHECK_FALSE(fl1.is_linked());
CHECK_FALSE(fl2.is_linked());
CHECK_FALSE(fl3.is_linked());
CHECK_FALSE(fl4.is_linked());
CHECK_FALSE(fl5.is_linked());
CHECK_FALSE(fl6.is_linked());
CHECK_FALSE(fl7.is_linked());
CHECK_FALSE(fl8.is_linked());
CHECK_FALSE(fl9.is_linked());
CHECK_TRUE(sl0.is_linked());
CHECK_TRUE(sl1.is_linked());
CHECK_TRUE(sl2.is_linked());
CHECK_TRUE(sl3.is_linked());
CHECK_TRUE(sl4.is_linked());
CHECK_TRUE(sl5.is_linked());
CHECK_TRUE(sl6.is_linked());
CHECK_TRUE(sl7.is_linked());
CHECK_TRUE(sl8.is_linked());
CHECK_TRUE(sl9.is_linked());
data1.clear();
CHECK_FALSE(fl0.is_linked());
CHECK_FALSE(fl1.is_linked());
CHECK_FALSE(fl2.is_linked());
CHECK_FALSE(fl3.is_linked());
CHECK_FALSE(fl4.is_linked());
CHECK_FALSE(fl5.is_linked());
CHECK_FALSE(fl6.is_linked());
CHECK_FALSE(fl7.is_linked());
CHECK_FALSE(fl8.is_linked());
CHECK_FALSE(fl9.is_linked());
CHECK_FALSE(sl0.is_linked());
CHECK_FALSE(sl1.is_linked());
CHECK_FALSE(sl2.is_linked());
CHECK_FALSE(sl3.is_linked());
CHECK_FALSE(sl4.is_linked());
CHECK_FALSE(sl5.is_linked());
CHECK_FALSE(sl6.is_linked());
CHECK_FALSE(sl7.is_linked());
CHECK_FALSE(sl8.is_linked());
CHECK_FALSE(sl9.is_linked());
}
//*************************************************************************
@ -626,6 +739,28 @@ namespace
{
bool are_equal;
FirstLink& fl0 = sorted_data[0];
FirstLink& fl1 = sorted_data[1];
FirstLink& fl2 = sorted_data[2];
FirstLink& fl3 = sorted_data[3];
FirstLink& fl4 = sorted_data[4];
FirstLink& fl5 = sorted_data[5];
FirstLink& fl6 = sorted_data[6];
FirstLink& fl7 = sorted_data[7];
FirstLink& fl8 = sorted_data[8];
FirstLink& fl9 = sorted_data[9];
SecondLink& sl0 = sorted_data[0];
SecondLink& sl1 = sorted_data[1];
SecondLink& sl2 = sorted_data[2];
SecondLink& sl3 = sorted_data[3];
SecondLink& sl4 = sorted_data[4];
SecondLink& sl5 = sorted_data[5];
SecondLink& sl6 = sorted_data[6];
SecondLink& sl7 = sorted_data[7];
SecondLink& sl8 = sorted_data[8];
SecondLink& sl9 = sorted_data[9];
std::vector<ItemNDCNode> compare_data(sorted_data.begin(), sorted_data.end());
DataNDC0 data0(sorted_data.begin(), sorted_data.end());
DataNDC1 data1(sorted_data.begin(), sorted_data.end());
@ -634,18 +769,40 @@ namespace
std::advance(i_data_1, 3);
DataNDC0::iterator i_data_2 = data0.begin();
std::advance(i_data_2, 4);
std::advance(i_data_2, 7);
std::vector<ItemNDCNode>::iterator i_compare_data_1 = compare_data.begin();
std::advance(i_compare_data_1, 3);
std::vector<ItemNDCNode>::iterator i_compare_data_2 = compare_data.begin();
std::advance(i_compare_data_2, 4);
std::advance(i_compare_data_2, 7);
std::vector<ItemNDCNode>::iterator i_compare_result = compare_data.erase(i_compare_data_1, i_compare_data_2);
DataNDC0::iterator i_result = data0.erase(i_data_1, i_data_2);
CHECK_TRUE(fl0.is_linked());
CHECK_TRUE(fl1.is_linked());
CHECK_TRUE(fl2.is_linked());
CHECK_FALSE(fl3.is_linked());
CHECK_FALSE(fl4.is_linked());
CHECK_FALSE(fl5.is_linked());
CHECK_FALSE(fl6.is_linked());
CHECK_TRUE(fl7.is_linked());
CHECK_TRUE(fl8.is_linked());
CHECK_TRUE(fl9.is_linked());
CHECK_TRUE(sl0.is_linked());
CHECK_TRUE(sl1.is_linked());
CHECK_TRUE(sl2.is_linked());
CHECK_TRUE(sl3.is_linked());
CHECK_TRUE(sl4.is_linked());
CHECK_TRUE(sl5.is_linked());
CHECK_TRUE(sl6.is_linked());
CHECK_TRUE(sl7.is_linked());
CHECK_TRUE(sl8.is_linked());
CHECK_TRUE(sl9.is_linked());
CHECK_EQUAL(*i_compare_result, *i_result);
are_equal = std::equal(data0.begin(), data0.end(), compare_data.begin());

View File

@ -138,10 +138,30 @@ namespace
queueC.push(data2);
queueD.clear();
CHECK_TRUE(queueD.empty());
CHECK_FALSE(queueC.empty());
CHECK_FALSE(etl::is_linked<link_fwd>(data1));
CHECK_FALSE(etl::is_linked<link_fwd>(data2));
CHECK_FALSE(etl::is_linked<link_fwd>(data3));
CHECK_TRUE(etl::is_linked<link_bdir>(data1));
CHECK_TRUE(etl::is_linked<link_bdir>(data2));
CHECK_FALSE(etl::is_linked<link_bdir>(data3));
queueC.clear();
CHECK(queueD.empty());
CHECK(queueC.empty());
CHECK_FALSE(etl::is_linked<link_fwd>(data1));
CHECK_FALSE(etl::is_linked<link_fwd>(data2));
CHECK_FALSE(etl::is_linked<link_fwd>(data3));
CHECK_FALSE(etl::is_linked<link_bdir>(data1));
CHECK_FALSE(etl::is_linked<link_bdir>(data2));
CHECK_FALSE(etl::is_linked<link_bdir>(data3));
CHECK_TRUE(queueD.empty());
CHECK_TRUE(queueC.empty());
}
//*************************************************************************
@ -186,34 +206,34 @@ namespace
etl::intrusive_queue<Data, link_fwd> queue;
queue.push(data1);
CHECK(data1.link_fwd::etl_next == ETL_NULLPTR);
CHECK(data2.link_fwd::etl_next == ETL_NULLPTR);
CHECK(data3.link_fwd::etl_next == ETL_NULLPTR);
CHECK(data4.link_fwd::etl_next == ETL_NULLPTR);
CHECK_TRUE(data1.link_fwd::is_linked());
CHECK_FALSE(data2.link_fwd::is_linked());
CHECK_FALSE(data3.link_fwd::is_linked());
CHECK_FALSE(data4.link_fwd::is_linked());
queue.push(data2);
CHECK(data1.link_fwd::etl_next == &data2);
CHECK(data2.link_fwd::etl_next == ETL_NULLPTR);
CHECK(data3.link_fwd::etl_next == ETL_NULLPTR);
CHECK(data4.link_fwd::etl_next == ETL_NULLPTR);
CHECK_TRUE(data1.link_fwd::is_linked());
CHECK_TRUE(data2.link_fwd::is_linked());
CHECK_FALSE(data3.link_fwd::is_linked());
CHECK_FALSE(data4.link_fwd::is_linked());
queue.push(data3);
CHECK(data1.link_fwd::etl_next == &data2);
CHECK(data2.link_fwd::etl_next == &data3);
CHECK(data3.link_fwd::etl_next == ETL_NULLPTR);
CHECK(data4.link_fwd::etl_next == ETL_NULLPTR);
CHECK_TRUE(data1.link_fwd::is_linked());
CHECK_TRUE(data2.link_fwd::is_linked());
CHECK_TRUE(data3.link_fwd::is_linked());
CHECK_FALSE(data4.link_fwd::is_linked());
queue.push(data2);
CHECK(data1.link_fwd::etl_next == &data2);
CHECK(data2.link_fwd::etl_next == &data3);
CHECK(data3.link_fwd::etl_next == ETL_NULLPTR);
CHECK(data4.link_fwd::etl_next == ETL_NULLPTR);
CHECK_THROW(queue.push(data2), etl::intrusive_queue_value_is_already_linked);
CHECK_TRUE(data1.link_fwd::is_linked());
CHECK_TRUE(data2.link_fwd::is_linked());
CHECK_TRUE(data3.link_fwd::is_linked());
CHECK_FALSE(data4.link_fwd::is_linked());
queue.push(data4);
CHECK(data1.link_fwd::etl_next == &data2);
CHECK(data2.link_fwd::etl_next == &data3);
CHECK(data3.link_fwd::etl_next == &data4);
CHECK(data4.link_fwd::etl_next == ETL_NULLPTR);
CHECK_TRUE(data1.link_fwd::is_linked());
CHECK_TRUE(data2.link_fwd::is_linked());
CHECK_TRUE(data3.link_fwd::is_linked());
CHECK_TRUE(data4.link_fwd::is_linked());
CHECK_EQUAL(4, queue.size());
}
@ -238,20 +258,25 @@ namespace
CHECK_EQUAL(queueD.front(), data1);
CHECK_EQUAL(queueD.back(), data3);
queueD.pop();
CHECK_FALSE(data1.link_fwd::is_linked());
CHECK_EQUAL(queueD.front(), data2);
CHECK_EQUAL(queueD.back(), data3);
queueD.pop();
CHECK_FALSE(data2.link_fwd::is_linked());
CHECK_EQUAL(queueD.front(), data3);
CHECK_EQUAL(queueD.back(), data3);
queueD.pop();
CHECK_FALSE(data3.link_fwd::is_linked());
CHECK(queueD.empty());
CHECK_EQUAL(queueC.front(), data1);
CHECK_EQUAL(queueC.back(), data2);
queueC.pop();
CHECK_FALSE(data1.link_bdir::is_linked());
CHECK_EQUAL(queueC.front(), data2);
CHECK_EQUAL(queueC.back(), data2);
queueC.pop();
CHECK_FALSE(data2.link_bdir::is_linked());
CHECK(queueC.empty());
}
@ -266,10 +291,22 @@ namespace
etl::intrusive_queue<Data, link_fwd> queue2;
queue1.push(data1);
CHECK_TRUE(data1.link_fwd::is_linked());
CHECK_FALSE(data2.link_fwd::is_linked());
CHECK_FALSE(data3.link_fwd::is_linked());
queue1.push(data2);
CHECK_TRUE(data1.link_fwd::is_linked());
CHECK_TRUE(data2.link_fwd::is_linked());
CHECK_FALSE(data3.link_fwd::is_linked());
queue1.push(data3);
CHECK_TRUE(data1.link_fwd::is_linked());
CHECK_TRUE(data2.link_fwd::is_linked());
CHECK_TRUE(data3.link_fwd::is_linked());
queue1.pop_into(queue2);
CHECK_TRUE(data1.link_fwd::is_linked());
CHECK_EQUAL(2U, queue1.size());
CHECK_EQUAL(data2, queue1.front());
@ -278,6 +315,7 @@ namespace
CHECK_EQUAL(data1, queue2.back());
queue1.pop_into(queue2);
CHECK_TRUE(data2.link_fwd::is_linked());
CHECK_EQUAL(1U, queue1.size());
CHECK_EQUAL(data3, queue1.front());
@ -286,6 +324,7 @@ namespace
CHECK_EQUAL(data2, queue2.back());
queue1.pop_into(queue2);
CHECK_TRUE(data3.link_fwd::is_linked());
CHECK_EQUAL(0U, queue1.size());
CHECK_EQUAL(3U, queue2.size());
@ -305,24 +344,24 @@ namespace
queue.push(data1);
queue.push(data2);
queue.push(data3);
CHECK_TRUE(data1.link_fwd::etl_next != ETL_NULLPTR);
CHECK_TRUE(data2.link_fwd::etl_next != ETL_NULLPTR);
CHECK_TRUE(data3.link_fwd::etl_next == ETL_NULLPTR);
CHECK_TRUE(data1.link_fwd::is_linked());
CHECK_TRUE(data2.link_fwd::is_linked());
CHECK_TRUE(data3.link_fwd::is_linked());
queue.pop();
CHECK_TRUE(data1.link_fwd::etl_next == ETL_NULLPTR);
CHECK_TRUE(data2.link_fwd::etl_next != ETL_NULLPTR);
CHECK_TRUE(data3.link_fwd::etl_next == ETL_NULLPTR);
CHECK_FALSE(data1.link_fwd::is_linked());
CHECK_TRUE(data2.link_fwd::is_linked());
CHECK_TRUE(data3.link_fwd::is_linked());
queue.pop();
CHECK_TRUE(data1.link_fwd::etl_next == ETL_NULLPTR);
CHECK_TRUE(data2.link_fwd::etl_next == ETL_NULLPTR);
CHECK_TRUE(data3.link_fwd::etl_next == ETL_NULLPTR);
CHECK_FALSE(data1.link_fwd::is_linked());
CHECK_FALSE(data2.link_fwd::is_linked());
CHECK_TRUE(data3.link_fwd::is_linked());
queue.pop();
CHECK_TRUE(data1.link_fwd::etl_next == ETL_NULLPTR);
CHECK_TRUE(data2.link_fwd::etl_next == ETL_NULLPTR);
CHECK_TRUE(data3.link_fwd::etl_next == ETL_NULLPTR);
CHECK_FALSE(data1.link_fwd::is_linked());
CHECK_FALSE(data2.link_fwd::is_linked());
CHECK_FALSE(data3.link_fwd::is_linked());
}
//*************************************************************************
@ -337,24 +376,24 @@ namespace
queue.push(data1);
queue.push(data2);
queue.push(data3);
CHECK_TRUE(data1.link_bdir::etl_next != ETL_NULLPTR);
CHECK_TRUE(data2.link_bdir::etl_next != ETL_NULLPTR);
CHECK_TRUE(data3.link_bdir::etl_next == ETL_NULLPTR);
CHECK_TRUE(data1.link_bdir::is_linked());
CHECK_TRUE(data2.link_bdir::is_linked());
CHECK_TRUE(data3.link_bdir::is_linked());
queue.pop();
CHECK_TRUE(data1.link_bdir::etl_next == ETL_NULLPTR);
CHECK_TRUE(data2.link_bdir::etl_next != ETL_NULLPTR);
CHECK_TRUE(data3.link_bdir::etl_next == ETL_NULLPTR);
CHECK_FALSE(data1.link_bdir::is_linked());
CHECK_TRUE(data2.link_bdir::is_linked());
CHECK_TRUE(data3.link_bdir::is_linked());
queue.pop();
CHECK_TRUE(data1.link_bdir::etl_next == ETL_NULLPTR);
CHECK_TRUE(data2.link_bdir::etl_next == ETL_NULLPTR);
CHECK_TRUE(data3.link_bdir::etl_next == ETL_NULLPTR);
CHECK_FALSE(data1.link_bdir::is_linked());
CHECK_FALSE(data2.link_bdir::is_linked());
CHECK_TRUE(data3.link_bdir::is_linked());
queue.pop();
CHECK_TRUE(data1.link_bdir::etl_next == ETL_NULLPTR);
CHECK_TRUE(data2.link_bdir::etl_next == ETL_NULLPTR);
CHECK_TRUE(data3.link_bdir::etl_next == ETL_NULLPTR);
CHECK_FALSE(data1.link_bdir::is_linked());
CHECK_FALSE(data2.link_bdir::is_linked());
CHECK_FALSE(data3.link_bdir::is_linked());
}
//*************************************************************************

View File

@ -138,10 +138,30 @@ namespace
stackC.push(data2);
stackD.clear();
CHECK_TRUE(stackD.empty());
CHECK_FALSE(stackC.empty());
CHECK_FALSE(etl::is_linked<link0>(data1));
CHECK_FALSE(etl::is_linked<link0>(data2));
CHECK_FALSE(etl::is_linked<link0>(data3));
CHECK_TRUE(etl::is_linked<link1>(data1));
CHECK_TRUE(etl::is_linked<link1>(data2));
CHECK_FALSE(etl::is_linked<link1>(data3));
stackC.clear();
CHECK(stackD.empty());
CHECK(stackC.empty());
CHECK_FALSE(etl::is_linked<link0>(data1));
CHECK_FALSE(etl::is_linked<link0>(data2));
CHECK_FALSE(etl::is_linked<link0>(data3));
CHECK_FALSE(etl::is_linked<link1>(data1));
CHECK_FALSE(etl::is_linked<link1>(data2));
CHECK_FALSE(etl::is_linked<link1>(data3));
CHECK_TRUE(stackD.empty());
CHECK_TRUE(stackC.empty());
}
//*************************************************************************

View File

@ -7,6 +7,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "etl", "etl.vcxproj", "{C21D
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug MSVC C++ 20 - No Tests|Win32 = Debug MSVC C++ 20 - No Tests|Win32
Debug MSVC C++ 20 - No Tests|x64 = Debug MSVC C++ 20 - No Tests|x64
Debug MSVC C++14 - No STL|Win32 = Debug MSVC C++14 - No STL|Win32
Debug MSVC C++14 - No STL|x64 = Debug MSVC C++14 - No STL|x64
Debug MSVC C++14|Win32 = Debug MSVC C++14|Win32
@ -25,6 +27,10 @@ Global
Release MSVC C++20 - Optimised O2|x64 = Release MSVC C++20 - Optimised O2|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug MSVC C++ 20 - No Tests|Win32.ActiveCfg = Debug MSVC C++ 20 - No Tests|Win32
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug MSVC C++ 20 - No Tests|Win32.Build.0 = Debug MSVC C++ 20 - No Tests|Win32
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug MSVC C++ 20 - No Tests|x64.ActiveCfg = Debug MSVC C++ 20 - No Tests|x64
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug MSVC C++ 20 - No Tests|x64.Build.0 = Debug MSVC C++ 20 - No Tests|x64
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug MSVC C++14 - No STL|Win32.ActiveCfg = Debug MSVC C++14 - No STL|Win32
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug MSVC C++14 - No STL|Win32.Build.0 = Debug MSVC C++14 - No STL|Win32
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug MSVC C++14 - No STL|x64.ActiveCfg = Debug MSVC C++14 - No STL|x64

File diff suppressed because it is too large Load Diff