mirror of
https://github.com/ETLCPP/etl.git
synced 2026-11-09 14:49:53 +08:00
Added intrusive_list and updated intrusive_forward list.
Added set of intrusive links.
This commit is contained in:
parent
65e5dbd7c9
commit
8144554320
@ -7,7 +7,7 @@ Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
http://www.etlcpp.com
|
||||
|
||||
Copyright(c) 2015 jwellbelove
|
||||
Copyright(c) 2016 jwellbelove
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files(the "Software"), to deal
|
||||
@ -45,6 +45,7 @@ SOFTWARE.
|
||||
#include "exception.h"
|
||||
#include "error_handler.h"
|
||||
#include "intrusive_links.h"
|
||||
#include "algorithm.h"
|
||||
|
||||
#undef ETL_FILE
|
||||
#define ETL_FILE "20"
|
||||
@ -107,12 +108,26 @@ namespace etl
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Unsorted exception for the intrusive_forward_list.
|
||||
///\ingroup intrusive_list
|
||||
//***************************************************************************
|
||||
class intrusive_forward_list_unsorted : public intrusive_forward_list_exception
|
||||
{
|
||||
public:
|
||||
|
||||
intrusive_forward_list_unsorted(string_type file_name, numeric_type line_number)
|
||||
: intrusive_forward_list_exception(ETL_ERROR_TEXT("intrusive_forward_list:unsorted", ETL_FILE"D"), file_name, line_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// 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 = etl::forward_link<>, const size_t COUNT_OPTION = etl::count_option::FAST_COUNT >
|
||||
class intrusive_forward_list
|
||||
{
|
||||
public:
|
||||
@ -128,7 +143,7 @@ namespace etl
|
||||
typedef const value_type& const_reference;
|
||||
typedef size_t size_type;
|
||||
|
||||
public:
|
||||
typedef intrusive_forward_list<TValue, TLink, COUNT_OPTION> list_type;
|
||||
|
||||
//*************************************************************************
|
||||
/// iterator.
|
||||
@ -239,7 +254,7 @@ namespace etl
|
||||
{
|
||||
}
|
||||
|
||||
const_iterator(const typename intrusive_forward_list<value_type, link_type>::iterator& other)
|
||||
const_iterator(const typename intrusive_forward_list::iterator& other)
|
||||
: p_value(other.p_value)
|
||||
{
|
||||
}
|
||||
@ -427,8 +442,7 @@ namespace etl
|
||||
while (first != last)
|
||||
{
|
||||
link_type& link = *first++;
|
||||
join(p_last_link, &link);
|
||||
join(&link, nullptr);
|
||||
etl::link_splice<link_type>(p_last_link, link);
|
||||
p_last_link = &link;
|
||||
++current_size;
|
||||
}
|
||||
@ -475,24 +489,40 @@ namespace etl
|
||||
second = track; // Move second link to next
|
||||
}
|
||||
|
||||
join(&start_link, first);
|
||||
etl::link<link_type>(start_link, first);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Inserts a value to the intrusive_forward_list after the specified position.
|
||||
//*************************************************************************
|
||||
iterator insert_after(iterator position, value_type& value)
|
||||
template <typename T = TLink>
|
||||
typename etl::enable_if<T::OPTION == etl::link_option::DEFAULT, iterator>::type
|
||||
insert_after(iterator position, value_type& value)
|
||||
{
|
||||
insert_link_after(*position.p_value, value);
|
||||
return iterator(value);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Inserts a value to the intrusive_forward_list after the specified position.
|
||||
/// Checks that the value is unlinked.
|
||||
//*************************************************************************
|
||||
template <typename T = TLink>
|
||||
typename etl::enable_if<T::OPTION == etl::link_option::CHECKED, iterator>::type
|
||||
insert_after(iterator position, value_type& value)
|
||||
{
|
||||
ETL_ASSERT(!value.TLink::is_linked(), ETL_ERROR(etl::not_unlinked_exception));
|
||||
|
||||
insert_link_after(*position.p_value, value);
|
||||
return iterator(value);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Inserts a range of values to the intrusive_forward_list after the specified position.
|
||||
//*************************************************************************
|
||||
template <typename TIterator>
|
||||
void insert_after(iterator position, TIterator first, TIterator last)
|
||||
template <typename TIterator, typename T = TLink>
|
||||
typename etl::enable_if<T::OPTION == etl::link_option::DEFAULT, void>::type
|
||||
insert_after(iterator position, TIterator first, TIterator last)
|
||||
{
|
||||
while (first != last)
|
||||
{
|
||||
@ -502,10 +532,30 @@ namespace etl
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Inserts a range of values to the intrusive_forward_list after the specified position.
|
||||
/// Checks that the values are unlinked.
|
||||
//*************************************************************************
|
||||
template <typename TIterator, typename T = TLink>
|
||||
typename etl::enable_if<T::OPTION == etl::link_option::CHECKED, void>::type
|
||||
insert_after(iterator position, TIterator first, TIterator last)
|
||||
{
|
||||
while (first != last)
|
||||
{
|
||||
ETL_ASSERT(!position.p_value->TLink::is_linked(), ETL_ERROR(etl::not_unlinked_exception));
|
||||
|
||||
// Set up the next free link.
|
||||
insert_link_after(*position.p_value, *first++);
|
||||
++position;
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Erases the value at the specified position.
|
||||
//*************************************************************************
|
||||
iterator erase_after(iterator position)
|
||||
template <typename T = TLink>
|
||||
typename etl::enable_if<T::OPTION == etl::link_option::DEFAULT, iterator>::type
|
||||
erase_after(iterator position)
|
||||
{
|
||||
iterator next(position);
|
||||
++next;
|
||||
@ -516,17 +566,37 @@ namespace etl
|
||||
return next;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Erases the value at the specified position.
|
||||
/// Clears the link after erasing.
|
||||
//*************************************************************************
|
||||
template <typename T = TLink>
|
||||
typename etl::enable_if<T::OPTION == etl::link_option::CHECKED, iterator>::type
|
||||
erase_after(iterator position)
|
||||
{
|
||||
iterator next(position);
|
||||
++next;
|
||||
++next;
|
||||
|
||||
remove_link_after(*position.p_value);
|
||||
position.p_value->TLink::clear();
|
||||
|
||||
return next;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Erases a range of elements.
|
||||
//*************************************************************************
|
||||
iterator erase_after(iterator first, iterator last)
|
||||
template <typename T = TLink>
|
||||
typename etl::enable_if<T::OPTION == etl::link_option::DEFAULT, iterator>::type
|
||||
erase_after(iterator first, iterator last)
|
||||
{
|
||||
link_type* p_first = first.p_value;
|
||||
link_type* p_last = last.p_value;
|
||||
link_type* p_next = p_first->etl_next;
|
||||
|
||||
// Join the ends.
|
||||
join(p_first, p_last);
|
||||
etl::link<link_type>(p_first, p_last);
|
||||
|
||||
p_first = p_next;
|
||||
|
||||
@ -550,6 +620,44 @@ namespace etl
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Erases a range of elements.
|
||||
/// Clears the links after erasing.
|
||||
//*************************************************************************
|
||||
template <typename T = TLink>
|
||||
typename etl::enable_if<T::OPTION == etl::link_option::CHECKED, iterator>::type
|
||||
erase_after(iterator first, iterator last)
|
||||
{
|
||||
link_type* p_first = first.p_value;
|
||||
link_type* p_last = last.p_value;
|
||||
link_type* p_next = p_first->etl_next;
|
||||
|
||||
// Join the ends.
|
||||
etl::link<link_type>(p_first, p_last);
|
||||
|
||||
p_first = p_next;
|
||||
|
||||
// Erase the ones in between.
|
||||
while (p_first != p_last)
|
||||
{
|
||||
// One less.
|
||||
--current_size;
|
||||
|
||||
p_next = p_first->etl_next; // Remember the next link.
|
||||
p_first->TLink::clear(); // Clear the link.
|
||||
p_first = p_next; // Move to the next link.
|
||||
}
|
||||
|
||||
if (p_next == nullptr)
|
||||
{
|
||||
return end();
|
||||
}
|
||||
else
|
||||
{
|
||||
return iterator(*static_cast<value_type*>(p_last));
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Removes all but the one element from every consecutive group of equal
|
||||
/// elements in the container.
|
||||
@ -679,14 +787,14 @@ namespace etl
|
||||
// Add the next link to the merged head.
|
||||
if (i_head == before_begin())
|
||||
{
|
||||
join(i_head.p_value, i_link.p_value);
|
||||
i_head = i_link;
|
||||
i_tail = i_link;
|
||||
etl::link<link_type>(i_head.p_value, i_link.p_value);
|
||||
i_head = i_link;
|
||||
i_tail = i_link;
|
||||
}
|
||||
else
|
||||
{
|
||||
join(i_tail.p_value, i_link.p_value);
|
||||
i_tail = i_link;
|
||||
etl::link<link_type>(i_tail.p_value, i_link.p_value);
|
||||
i_tail = i_link;
|
||||
}
|
||||
|
||||
i_tail.p_value->link_type::etl_next = nullptr;
|
||||
@ -737,7 +845,7 @@ namespace etl
|
||||
{
|
||||
iterator i_item = begin();
|
||||
iterator i_last_item = before_begin();
|
||||
|
||||
|
||||
while (i_item != end())
|
||||
{
|
||||
if (predicate(*i_item))
|
||||
@ -753,41 +861,296 @@ namespace etl
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns true if the list has not elements.
|
||||
/// Returns true if the list has no elements.
|
||||
//*************************************************************************
|
||||
bool empty() const
|
||||
{
|
||||
return current_size == 0;
|
||||
return start_link.etl_next == nullptr;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the number of elements.
|
||||
//*************************************************************************
|
||||
size_t size() const
|
||||
template <const size_t OPT = COUNT_OPTION>
|
||||
typename etl::enable_if<OPT == etl::count_option::FAST_COUNT, size_t>::type
|
||||
size() const
|
||||
{
|
||||
return current_size;
|
||||
return current_size.count;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the number of elements.
|
||||
//*************************************************************************
|
||||
template <const size_t OPT = COUNT_OPTION>
|
||||
typename etl::enable_if<OPT == etl::count_option::SLOW_COUNT, size_t>::type
|
||||
size() const
|
||||
{
|
||||
return std::distance(cbegin(), cend());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Splice another list into this one.
|
||||
//*************************************************************************
|
||||
void splice_after(iterator position, list_type& list)
|
||||
{
|
||||
// No point splicing to ourself!
|
||||
if (&list != this)
|
||||
{
|
||||
if (!list.empty())
|
||||
{
|
||||
link_type& first = list.get_head();
|
||||
|
||||
if (COUNT_OPTION == etl::count_option::FAST_COUNT)
|
||||
{
|
||||
if (&list != this)
|
||||
{
|
||||
current_size += list.size();
|
||||
}
|
||||
}
|
||||
|
||||
link_type& before = *position.p_value;
|
||||
link_type& after = *position.p_value->link_type::etl_next;
|
||||
|
||||
etl::link<link_type>(before, first);
|
||||
|
||||
link_type* last = &before;
|
||||
while (last->link_type::etl_next != nullptr)
|
||||
{
|
||||
last = last->link_type::etl_next;
|
||||
}
|
||||
|
||||
etl::link<link_type>(last, after);
|
||||
|
||||
list.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Splice an element from another list into this one.
|
||||
//*************************************************************************
|
||||
void splice(iterator position, list_type& list, iterator isource)
|
||||
{
|
||||
link_type& before = *position.p_value;
|
||||
|
||||
etl::unlink<link_type>(*isource.p_value);
|
||||
etl::link_splice<link_type>(before, *isource.p_value);
|
||||
|
||||
if (COUNT_OPTION == etl::count_option::FAST_COUNT)
|
||||
{
|
||||
if (&list != this)
|
||||
{
|
||||
++current_size;
|
||||
--list.current_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Splice a range of elements from another list into this one.
|
||||
//*************************************************************************
|
||||
void splice_after(iterator position, list_type& list, iterator begin_, iterator end_)
|
||||
{
|
||||
if (!list.empty())
|
||||
{
|
||||
if (COUNT_OPTION == etl::count_option::FAST_COUNT)
|
||||
{
|
||||
if (&list != this)
|
||||
{
|
||||
size_t n = std::distance(begin_, end_) - 1;
|
||||
current_size += n;
|
||||
list.current_size -= n;
|
||||
}
|
||||
}
|
||||
|
||||
link_type* first = begin_.p_value;
|
||||
link_type* last = first;
|
||||
|
||||
while (last->link_type::etl_next != end_.p_value)
|
||||
{
|
||||
last = last->link_type::etl_next;
|
||||
}
|
||||
|
||||
// Unlink from the source list.
|
||||
link_type* first_next = first->link_type::etl_next;
|
||||
etl::unlink_after(*first, *last);
|
||||
|
||||
// Fix our links.
|
||||
link_type* before = position.p_value;
|
||||
|
||||
etl::link_splice<link_type>(*before, *first_next, *last);
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Merge another list into this one. Both lists should be sorted.
|
||||
//*************************************************************************
|
||||
void merge(list_type& list)
|
||||
{
|
||||
merge(list, std::less<value_type>());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Merge another list into this one. Both lists should be sorted.
|
||||
//*************************************************************************
|
||||
template <typename TCompare>
|
||||
void merge(list_type& list, TCompare compare)
|
||||
{
|
||||
if (!list.empty())
|
||||
{
|
||||
#if _DEBUG
|
||||
ETL_ASSERT(etl::is_sorted(list.begin(), list.end(), compare), ETL_ERROR(intrusive_forward_list_unsorted));
|
||||
ETL_ASSERT(etl::is_sorted(begin(), end(), compare), ETL_ERROR(intrusive_forward_list_unsorted));
|
||||
#endif
|
||||
|
||||
value_type* other_begin = static_cast<value_type*>(&list.get_head());
|
||||
value_type* other_terminal = nullptr;
|
||||
|
||||
value_type* before = static_cast<value_type*>(&start_link);
|
||||
value_type* before_next = get_next(before);
|
||||
value_type* terminal = nullptr;
|
||||
|
||||
while ((before->link_type::etl_next != terminal) && (other_begin != other_terminal))
|
||||
{
|
||||
// Find the place to insert.
|
||||
while ((before_next != terminal) && !(compare(*other_begin, *before_next)))
|
||||
{
|
||||
before = before_next;
|
||||
before_next = get_next(before_next);
|
||||
}
|
||||
|
||||
// Insert.
|
||||
if (before_next != terminal)
|
||||
{
|
||||
while ((other_begin != other_terminal) && (compare(*other_begin, *before_next)))
|
||||
{
|
||||
value_type* value = other_begin;
|
||||
other_begin = get_next(other_begin);
|
||||
etl::link_splice<link_type>(*before, *value);
|
||||
before = get_next(before);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Any left over?
|
||||
if (before_next == terminal)
|
||||
{
|
||||
while (other_begin != other_terminal)
|
||||
{
|
||||
value_type* value = other_begin;
|
||||
other_begin = get_next(other_begin);
|
||||
etl::link_splice<link_type>(*before, *value);
|
||||
before = get_next(before);
|
||||
}
|
||||
}
|
||||
|
||||
if (COUNT_OPTION == etl::count_option::FAST_COUNT)
|
||||
{
|
||||
current_size += list.size();
|
||||
}
|
||||
|
||||
list.clear();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
link_type start_link; ///< The link that acts as the intrusive_forward_list start.
|
||||
size_t current_size; ///< The number of elements in the list.
|
||||
size_t index; ///< The index level of the link that this list operates on.
|
||||
|
||||
//*************************************************************************
|
||||
/// Counter type based on count option.
|
||||
//*************************************************************************
|
||||
template <const size_t OPTION>
|
||||
class counter_type;
|
||||
|
||||
//*************************************************************************
|
||||
/// Join two links.
|
||||
/// Slow type.
|
||||
//*************************************************************************
|
||||
void join(link_type* left, link_type* right)
|
||||
template <>
|
||||
class counter_type<etl::count_option::SLOW_COUNT>
|
||||
{
|
||||
left->etl_next = right;
|
||||
}
|
||||
public:
|
||||
|
||||
counter_type& operator ++()
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
counter_type& operator --()
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
counter_type& operator =(size_t new_count)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
counter_type& operator +=(size_t diff)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
counter_type& operator -=(size_t diff)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
//*************************************************************************
|
||||
/// Fast type.
|
||||
//*************************************************************************
|
||||
template <>
|
||||
class counter_type<etl::count_option::FAST_COUNT>
|
||||
{
|
||||
public:
|
||||
|
||||
counter_type()
|
||||
: count(0)
|
||||
{
|
||||
}
|
||||
|
||||
counter_type& operator ++()
|
||||
{
|
||||
++count;
|
||||
return *this;
|
||||
}
|
||||
|
||||
counter_type& operator --()
|
||||
{
|
||||
--count;
|
||||
return *this;
|
||||
}
|
||||
|
||||
counter_type& operator =(size_t new_count)
|
||||
{
|
||||
count = new_count;
|
||||
return *this;
|
||||
}
|
||||
|
||||
counter_type& operator +=(size_t diff)
|
||||
{
|
||||
count += diff;
|
||||
return *this;
|
||||
}
|
||||
|
||||
counter_type& operator -=(size_t diff)
|
||||
{
|
||||
count -= diff;
|
||||
return *this;
|
||||
}
|
||||
|
||||
size_t count;
|
||||
};
|
||||
|
||||
counter_type<COUNT_OPTION> current_size; ///< Counts the number of elements in the list.
|
||||
|
||||
//*************************************************************************
|
||||
/// Is the intrusive_forward_list a trivial length?
|
||||
//*************************************************************************
|
||||
bool is_trivial_list() const
|
||||
{
|
||||
return current_size <= 1;
|
||||
return (start_link.link_type::etl_next == nullptr) || (start_link.link_type::etl_next->etl_next == nullptr);;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -796,8 +1159,7 @@ namespace etl
|
||||
void insert_link_after(link_type& position, link_type& link)
|
||||
{
|
||||
// Connect to the intrusive_forward_list.
|
||||
join(&link, position.etl_next);
|
||||
join(&position, &link);
|
||||
etl::link_splice<link_type>(position, link);
|
||||
++current_size;
|
||||
}
|
||||
|
||||
@ -806,13 +1168,9 @@ namespace etl
|
||||
//*************************************************************************
|
||||
void remove_link_after(link_type& link)
|
||||
{
|
||||
// The link to erase.
|
||||
link_type* p_link = link.etl_next;
|
||||
|
||||
if (p_link != nullptr)
|
||||
if (link.etl_next != nullptr)
|
||||
{
|
||||
// Disconnect the link from the intrusive_forward_list.
|
||||
join(&link, p_link->etl_next);
|
||||
etl::unlink_after<link_type>(link);
|
||||
--current_size;
|
||||
}
|
||||
}
|
||||
@ -833,6 +1191,14 @@ namespace etl
|
||||
return *start_link.etl_next;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Get the next value.
|
||||
//*************************************************************************
|
||||
value_type* get_next(link_type* link) const
|
||||
{
|
||||
return static_cast<value_type*>(link->etl_next);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Initialise the intrusive_forward_list.
|
||||
//*************************************************************************
|
||||
|
||||
@ -31,13 +31,26 @@ SOFTWARE.
|
||||
#ifndef __ETL_INTRUSIVE_LINKS__
|
||||
#define __ETL_INTRUSIVE_LINKS__
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "nullptr.h"
|
||||
#include "type_traits.h"
|
||||
#include "exception.h"
|
||||
#include "error_handler.h"
|
||||
|
||||
#undef ETL_FILE
|
||||
#define ETL_FILE "23"
|
||||
#define ETL_FILE "21"
|
||||
|
||||
//*****************************************************************************
|
||||
// Note:
|
||||
// The link functions work slightly differently to the STL 'insert' convention
|
||||
// in that the second link parameter will be inserted after the first.
|
||||
// i.e.
|
||||
// If the list contains '1', '2', '3', '4' and "link_splice '2','5'" is invoked the
|
||||
// resulting list will contain '1', '2', '5', '3', '4'
|
||||
// This is to maintain consistency between forward and bidirectional links
|
||||
// and also is intuitive.
|
||||
//*****************************************************************************
|
||||
|
||||
namespace etl
|
||||
{
|
||||
@ -45,48 +58,120 @@ namespace etl
|
||||
{
|
||||
enum
|
||||
{
|
||||
DEFAULT = 0,
|
||||
AUTO = 1,
|
||||
SAFE = 2
|
||||
DEFAULT,
|
||||
AUTO,
|
||||
CHECKED
|
||||
};
|
||||
};
|
||||
|
||||
namespace count_option
|
||||
{
|
||||
enum
|
||||
{
|
||||
SLOW_COUNT,
|
||||
FAST_COUNT
|
||||
};
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Deque full exception.
|
||||
///\ingroup deque
|
||||
/// Link exception.
|
||||
//***************************************************************************
|
||||
class link_exception : public etl::exception
|
||||
{
|
||||
public:
|
||||
|
||||
link_exception(string_type file_name, numeric_type line_number)
|
||||
: exception(ETL_ERROR_TEXT("link:still linked", ETL_FILE"A"), file_name, line_number)
|
||||
link_exception(string_type what, string_type file_name, numeric_type line_number)
|
||||
: exception(what, file_name, line_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// not unlinked exception.
|
||||
//***************************************************************************
|
||||
class not_unlinked_exception : public etl::link_exception
|
||||
{
|
||||
public:
|
||||
|
||||
not_unlinked_exception(string_type file_name, numeric_type line_number)
|
||||
: link_exception(ETL_ERROR_TEXT("link:still linked", ETL_FILE"A"), file_name, line_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
namespace __private_intrusive_links__
|
||||
{
|
||||
//***************************************************************************
|
||||
/// A forward link base.
|
||||
//***************************************************************************
|
||||
template <typename TLink, const size_t ID_, const size_t OPTION_>
|
||||
struct forward_link_base
|
||||
{
|
||||
enum
|
||||
{
|
||||
ID = ID_,
|
||||
OPTION = OPTION_
|
||||
};
|
||||
|
||||
void clear()
|
||||
{
|
||||
etl_next = nullptr;
|
||||
}
|
||||
|
||||
bool is_linked() const
|
||||
{
|
||||
return etl_next != nullptr;
|
||||
}
|
||||
|
||||
TLink* etl_next;
|
||||
};
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// A forward link.
|
||||
//***************************************************************************
|
||||
template <const size_t ID_ = 0>
|
||||
struct forward_link
|
||||
template <const size_t ID_ = 0, const size_t OPTION_ = etl::link_option::DEFAULT>
|
||||
struct forward_link
|
||||
: public __private_intrusive_links__::forward_link_base<forward_link<ID_, OPTION_>, ID_, OPTION_>
|
||||
{
|
||||
enum
|
||||
{
|
||||
ID = ID_
|
||||
};
|
||||
};
|
||||
|
||||
void clear()
|
||||
//******************************************************************
|
||||
// There is no valid specialisation for auto link
|
||||
//******************************************************************
|
||||
template <const size_t ID_>
|
||||
struct forward_link<ID_, etl::link_option::AUTO>
|
||||
: public __private_intrusive_links__::forward_link_base<forward_link<ID_, etl::link_option::AUTO>, ID_, etl::link_option::AUTO>
|
||||
{
|
||||
forward_link()
|
||||
{
|
||||
etl_next = nullptr;
|
||||
clear();
|
||||
}
|
||||
};
|
||||
|
||||
//******************************************************************
|
||||
// Specialisation for checked unlink option.
|
||||
// An error will be generated if the links are valid when the object
|
||||
// is destroyed.
|
||||
//******************************************************************
|
||||
template <const size_t ID_>
|
||||
struct forward_link<ID_, etl::link_option::CHECKED>
|
||||
: public __private_intrusive_links__::forward_link_base<forward_link<ID_, etl::link_option::CHECKED>, ID_, etl::link_option::CHECKED>
|
||||
{
|
||||
forward_link()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
forward_link* etl_next;
|
||||
~forward_link()
|
||||
{
|
||||
assert(etl_next != nullptr);
|
||||
}
|
||||
};
|
||||
|
||||
// Reference, Reference
|
||||
template <typename TLink>
|
||||
typename etl::enable_if<etl::is_same<TLink, etl::forward_link<TLink::ID> >::value, void>::type
|
||||
typename etl::enable_if<etl::is_same<TLink, etl::forward_link<TLink::ID, TLink::OPTION> >::value, void>::type
|
||||
link(TLink& lhs, TLink& rhs)
|
||||
{
|
||||
lhs.etl_next = &rhs;
|
||||
@ -94,8 +179,8 @@ namespace etl
|
||||
|
||||
// Reference, Reference
|
||||
template <typename TLink>
|
||||
typename etl::enable_if<etl::is_same<TLink, etl::forward_link<TLink::ID> >::value, void>::type
|
||||
link_insert(TLink& lhs, TLink& rhs)
|
||||
typename etl::enable_if<etl::is_same<TLink, etl::forward_link<TLink::ID, TLink::OPTION> >::value, void>::type
|
||||
link_splice(TLink& lhs, TLink& rhs)
|
||||
{
|
||||
rhs.etl_next = lhs.etl_next;
|
||||
lhs.etl_next = &rhs;
|
||||
@ -103,7 +188,7 @@ namespace etl
|
||||
|
||||
// Pointer, Pointer
|
||||
template <typename TLink>
|
||||
typename etl::enable_if<etl::is_same<TLink, etl::forward_link<TLink::ID> >::value, void>::type
|
||||
typename etl::enable_if<etl::is_same<TLink, etl::forward_link<TLink::ID, TLink::OPTION> >::value, void>::type
|
||||
link(TLink* lhs, TLink* rhs)
|
||||
{
|
||||
if (lhs != nullptr)
|
||||
@ -114,8 +199,8 @@ namespace etl
|
||||
|
||||
// Pointer, Pointer
|
||||
template <typename TLink>
|
||||
typename etl::enable_if<etl::is_same<TLink, etl::forward_link<TLink::ID> >::value, void>::type
|
||||
link_insert(TLink* lhs, TLink* rhs)
|
||||
typename etl::enable_if<etl::is_same<TLink, etl::forward_link<TLink::ID, TLink::OPTION> >::value, void>::type
|
||||
link_splice(TLink* lhs, TLink* rhs)
|
||||
{
|
||||
if (lhs != nullptr)
|
||||
{
|
||||
@ -130,7 +215,7 @@ namespace etl
|
||||
|
||||
// Reference, Pointer
|
||||
template <typename TLink>
|
||||
typename etl::enable_if<etl::is_same<TLink, etl::forward_link<TLink::ID> >::value, void>::type
|
||||
typename etl::enable_if<etl::is_same<TLink, etl::forward_link<TLink::ID, TLink::OPTION> >::value, void>::type
|
||||
link(TLink& lhs, TLink* rhs)
|
||||
{
|
||||
lhs.etl_next = rhs;
|
||||
@ -138,8 +223,8 @@ namespace etl
|
||||
|
||||
// Reference, Pointer
|
||||
template <typename TLink>
|
||||
typename etl::enable_if<etl::is_same<TLink, etl::forward_link<TLink::ID> >::value, void>::type
|
||||
link_insert(TLink& lhs, TLink* rhs)
|
||||
typename etl::enable_if<etl::is_same<TLink, etl::forward_link<TLink::ID, TLink::OPTION> >::value, void>::type
|
||||
link_splice(TLink& lhs, TLink* rhs)
|
||||
{
|
||||
if (rhs != nullptr)
|
||||
{
|
||||
@ -151,7 +236,7 @@ namespace etl
|
||||
|
||||
// Pointer, Reference
|
||||
template <typename TLink>
|
||||
typename etl::enable_if<etl::is_same<TLink, etl::forward_link<TLink::ID> >::value, void>::type
|
||||
typename etl::enable_if<etl::is_same<TLink, etl::forward_link<TLink::ID, TLink::OPTION> >::value, void>::type
|
||||
link(TLink* lhs, TLink& rhs)
|
||||
{
|
||||
if (lhs != nullptr)
|
||||
@ -162,8 +247,8 @@ namespace etl
|
||||
|
||||
// Pointer, Reference
|
||||
template <typename TLink>
|
||||
typename etl::enable_if<etl::is_same<TLink, etl::forward_link<TLink::ID> >::value, void>::type
|
||||
link_insert(TLink* lhs, TLink& rhs)
|
||||
typename etl::enable_if<etl::is_same<TLink, etl::forward_link<TLink::ID, TLink::OPTION> >::value, void>::type
|
||||
link_splice(TLink* lhs, TLink& rhs)
|
||||
{
|
||||
if (lhs != nullptr)
|
||||
{
|
||||
@ -172,51 +257,125 @@ namespace etl
|
||||
}
|
||||
}
|
||||
|
||||
// Reference, Reference, Reference
|
||||
template <typename TLink>
|
||||
typename etl::enable_if<etl::is_same<TLink, etl::forward_link<TLink::ID, TLink::OPTION> >::value, void>::type
|
||||
link_splice(TLink& lhs, TLink& first, TLink& last)
|
||||
{
|
||||
last.etl_next = lhs.etl_next;
|
||||
lhs.etl_next = &first;
|
||||
}
|
||||
|
||||
// Pointer, Reference, Reference
|
||||
template <typename TLink>
|
||||
typename etl::enable_if<etl::is_same<TLink, etl::forward_link<TLink::ID, TLink::OPTION> >::value, void>::type
|
||||
link_splice(TLink* lhs, TLink& first, TLink& last)
|
||||
{
|
||||
if (lhs != nullptr)
|
||||
{
|
||||
last.etl_next = lhs->etl_next;
|
||||
lhs->etl_next = &first;
|
||||
}
|
||||
else
|
||||
{
|
||||
last.etl_next = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// Reference
|
||||
template <typename TLink>
|
||||
typename etl::enable_if<etl::is_same<TLink, etl::forward_link<TLink::ID> >::value, void>::type
|
||||
typename etl::enable_if<etl::is_same<TLink, etl::forward_link<TLink::ID, TLink::OPTION> >::value, void>::type
|
||||
unlink_after(TLink& node)
|
||||
{
|
||||
if (node.etl_next != nullptr)
|
||||
{
|
||||
node.etl_next = node.etl_next->etl_next;
|
||||
|
||||
if ((TLink::OPTION == etl::link_option::AUTO) ||
|
||||
(TLink::OPTION == etl::link_option::CHECKED))
|
||||
{
|
||||
node.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Pointer
|
||||
// Reference, Reference
|
||||
template <typename TLink>
|
||||
typename etl::enable_if<etl::is_same<TLink, etl::forward_link<TLink::ID> >::value, void>::type
|
||||
unlink_after(TLink* node)
|
||||
typename etl::enable_if<etl::is_same<TLink, etl::forward_link<TLink::ID, TLink::OPTION> >::value, void>::type
|
||||
unlink_after(TLink& before, TLink& last)
|
||||
{
|
||||
if (node != nullptr)
|
||||
before.etl_next = last.etl_next;
|
||||
|
||||
if ((TLink::OPTION == etl::link_option::AUTO) ||
|
||||
(TLink::OPTION == etl::link_option::CHECKED))
|
||||
{
|
||||
if (node->etl_next != nullptr)
|
||||
{
|
||||
node->etl_next = node.etl_next->etl_next;
|
||||
}
|
||||
last.clear();
|
||||
}
|
||||
}
|
||||
|
||||
namespace __private_intrusive_links__
|
||||
{
|
||||
//***************************************************************************
|
||||
/// A bidirectional link base.
|
||||
//***************************************************************************
|
||||
template <typename TLink, const size_t ID_, const size_t OPTION_>
|
||||
struct bidirectional_link_base
|
||||
{
|
||||
enum
|
||||
{
|
||||
ID = ID_,
|
||||
OPTION = OPTION_
|
||||
};
|
||||
|
||||
void clear()
|
||||
{
|
||||
etl_previous = nullptr;
|
||||
etl_next = nullptr;
|
||||
}
|
||||
|
||||
bool is_linked() const
|
||||
{
|
||||
return (etl_previous != nullptr) || (etl_next != nullptr);
|
||||
}
|
||||
|
||||
void reverse()
|
||||
{
|
||||
std::swap(etl_previous, etl_next);
|
||||
}
|
||||
|
||||
TLink* etl_previous;
|
||||
TLink* etl_next;
|
||||
|
||||
protected:
|
||||
|
||||
void base_unlink()
|
||||
{
|
||||
// Connect the previous link with the next.
|
||||
if (etl_previous != nullptr)
|
||||
{
|
||||
etl_previous->etl_next = etl_next;
|
||||
}
|
||||
|
||||
// Connect the next link with the previous.
|
||||
if (etl_next != nullptr)
|
||||
{
|
||||
etl_next->etl_previous = etl_previous;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// A bidirectional link.
|
||||
//***************************************************************************
|
||||
template <const size_t ID_ = 0, const int OPTION_ = etl::link_option::DEFAULT>
|
||||
struct bidirectional_link
|
||||
template <const size_t ID_ = 0, const size_t OPTION_ = etl::link_option::DEFAULT>
|
||||
struct bidirectional_link
|
||||
: public __private_intrusive_links__::bidirectional_link_base<bidirectional_link<ID_, OPTION_>, ID_, OPTION_>
|
||||
{
|
||||
enum
|
||||
void unlink()
|
||||
{
|
||||
ID = ID_,
|
||||
OPTION = OPTION_
|
||||
};
|
||||
|
||||
void clear()
|
||||
{
|
||||
etl_previous = nullptr;
|
||||
etl_next = nullptr;
|
||||
base_unlink();
|
||||
}
|
||||
|
||||
bidirectional_link* etl_previous;
|
||||
bidirectional_link* etl_next;
|
||||
};
|
||||
|
||||
//******************************************************************
|
||||
@ -224,67 +383,51 @@ namespace etl
|
||||
// When this link is destroyed it will automatically unlink itself.
|
||||
//******************************************************************
|
||||
template <const size_t ID_>
|
||||
struct bidirectional_link<ID_, etl::link_option::AUTO>
|
||||
struct bidirectional_link<ID_, etl::link_option::AUTO>
|
||||
: public __private_intrusive_links__::bidirectional_link_base<bidirectional_link<ID_, etl::link_option::AUTO>, ID_, etl::link_option::AUTO>
|
||||
{
|
||||
enum
|
||||
bidirectional_link()
|
||||
{
|
||||
ID = ID_,
|
||||
OPTION = etl::link_option::AUTO_UNLINK
|
||||
};
|
||||
clear();
|
||||
}
|
||||
|
||||
~bidirectional_link()
|
||||
{
|
||||
// Connect the previous link with the next.
|
||||
if (etl_previous != nullptr)
|
||||
{
|
||||
etl_previous->etl_next = etl_next;
|
||||
}
|
||||
|
||||
// Connect the next link with the previous.
|
||||
if (etl_next != nullptr)
|
||||
{
|
||||
etl_next->etl_previous = etl_previous;
|
||||
}
|
||||
base_unlink();
|
||||
}
|
||||
|
||||
void clear()
|
||||
void unlink()
|
||||
{
|
||||
etl_previous = nullptr;
|
||||
etl_next = nullptr;
|
||||
base_unlink();
|
||||
clear();
|
||||
}
|
||||
|
||||
bidirectional_link* etl_previous;
|
||||
bidirectional_link* etl_next;
|
||||
};
|
||||
|
||||
//******************************************************************
|
||||
// Specialisation for safe unlinked option.
|
||||
// Specialisation for checked unlink option.
|
||||
// An error will be generated if the links are valid when the object
|
||||
// is destroyed.
|
||||
//******************************************************************
|
||||
template <const size_t ID_>
|
||||
struct bidirectional_link<ID_, etl::link_option::SAFE>
|
||||
struct bidirectional_link<ID_, etl::link_option::CHECKED>
|
||||
: public __private_intrusive_links__::bidirectional_link_base<bidirectional_link<ID_, etl::link_option::CHECKED>, ID_, etl::link_option::CHECKED>
|
||||
{
|
||||
enum
|
||||
bidirectional_link()
|
||||
{
|
||||
ID = ID_,
|
||||
OPTION = etl::link_option::AUTO_UNLINK
|
||||
};
|
||||
clear();
|
||||
}
|
||||
|
||||
~bidirectional_link()
|
||||
{
|
||||
ETL_ASSERT(etl_previous == nullptr, ETL_ERROR(link_exception));
|
||||
ETL_ASSERT(etl_next == nullptr, ETL_ERROR(link_exception));
|
||||
assert(etl_previous == nullptr);
|
||||
assert(etl_next == nullptr);
|
||||
}
|
||||
|
||||
void clear()
|
||||
void unlink()
|
||||
{
|
||||
etl_previous = nullptr;
|
||||
etl_next = nullptr;
|
||||
base_unlink();
|
||||
clear();
|
||||
}
|
||||
|
||||
bidirectional_link* etl_previous;
|
||||
bidirectional_link* etl_next;
|
||||
};
|
||||
|
||||
// Reference, Reference
|
||||
@ -296,6 +439,22 @@ namespace etl
|
||||
rhs.etl_previous = &lhs;
|
||||
}
|
||||
|
||||
// Reference, Reference
|
||||
template <typename TLink>
|
||||
typename etl::enable_if<etl::is_same<TLink, etl::bidirectional_link<TLink::ID, TLink::OPTION> >::value, void>::type
|
||||
link_splice(TLink& lhs, TLink& rhs)
|
||||
{
|
||||
rhs.etl_next = lhs.etl_next;
|
||||
rhs.etl_previous = &lhs;
|
||||
|
||||
if (lhs.etl_next != nullptr)
|
||||
{
|
||||
lhs.etl_next->etl_previous = &rhs;
|
||||
}
|
||||
|
||||
lhs.etl_next = &rhs;
|
||||
}
|
||||
|
||||
// Pointer, Pointer
|
||||
template <typename TLink>
|
||||
typename etl::enable_if<etl::is_same<TLink, etl::bidirectional_link<TLink::ID, TLink::OPTION> >::value, void>::type
|
||||
@ -312,6 +471,32 @@ namespace etl
|
||||
}
|
||||
}
|
||||
|
||||
// Pointer, Pointer
|
||||
template <typename TLink>
|
||||
typename etl::enable_if<etl::is_same<TLink, etl::bidirectional_link<TLink::ID, TLink::OPTION> >::value, void>::type
|
||||
link_splice(TLink* lhs, TLink* rhs)
|
||||
{
|
||||
if (rhs != nullptr)
|
||||
{
|
||||
if (lhs != nullptr)
|
||||
{
|
||||
rhs->etl_next = lhs->etl_next;
|
||||
}
|
||||
|
||||
rhs->etl_previous = lhs;
|
||||
}
|
||||
|
||||
if (lhs != nullptr)
|
||||
{
|
||||
if (lhs->etl_next != nullptr)
|
||||
{
|
||||
lhs->etl_next->etl_previous = rhs;
|
||||
}
|
||||
|
||||
lhs->etl_next = rhs;
|
||||
}
|
||||
}
|
||||
|
||||
// Reference, Pointer
|
||||
template <typename TLink>
|
||||
typename etl::enable_if<etl::is_same<TLink, etl::bidirectional_link<TLink::ID, TLink::OPTION> >::value, void>::type
|
||||
@ -325,6 +510,25 @@ namespace etl
|
||||
}
|
||||
}
|
||||
|
||||
// Reference, Pointer
|
||||
template <typename TLink>
|
||||
typename etl::enable_if<etl::is_same<TLink, etl::bidirectional_link<TLink::ID, TLink::OPTION> >::value, void>::type
|
||||
link_splice(TLink& lhs, TLink* rhs)
|
||||
{
|
||||
if (rhs != nullptr)
|
||||
{
|
||||
rhs->etl_next = lhs.etl_next;
|
||||
rhs->etl_previous = &lhs;
|
||||
}
|
||||
|
||||
if (lhs.etl_next != nullptr)
|
||||
{
|
||||
lhs.etl_next->etl_previous = rhs;
|
||||
}
|
||||
|
||||
lhs.etl_next = rhs;
|
||||
}
|
||||
|
||||
// Pointer, Reference
|
||||
template <typename TLink>
|
||||
typename etl::enable_if<etl::is_same<TLink, etl::bidirectional_link<TLink::ID, TLink::OPTION> >::value, void>::type
|
||||
@ -338,67 +542,189 @@ namespace etl
|
||||
rhs.etl_previous = lhs;
|
||||
}
|
||||
|
||||
// Pointer, Reference
|
||||
template <typename TLink>
|
||||
typename etl::enable_if<etl::is_same<TLink, etl::bidirectional_link<TLink::ID, TLink::OPTION> >::value, void>::type
|
||||
link_splice(TLink* lhs, TLink& rhs)
|
||||
{
|
||||
if (lhs != nullptr)
|
||||
{
|
||||
rhs.etl_next = lhs->etl_next;
|
||||
}
|
||||
|
||||
rhs.etl_previous = lhs;
|
||||
|
||||
if (lhs != nullptr)
|
||||
{
|
||||
if (lhs->etl_next != nullptr)
|
||||
{
|
||||
lhs->etl_next->etl_previous = &rhs;
|
||||
}
|
||||
|
||||
lhs->etl_next = &rhs;
|
||||
}
|
||||
}
|
||||
|
||||
// Reference, Reference, Reference
|
||||
template <typename TLink>
|
||||
typename etl::enable_if<etl::is_same<TLink, etl::bidirectional_link<TLink::ID, TLink::OPTION> >::value, void>::type
|
||||
link_splice(TLink& lhs, TLink& first, TLink& last)
|
||||
{
|
||||
last.etl_next = lhs.etl_next;
|
||||
first.etl_previous = &lhs;
|
||||
|
||||
if (last.etl_next != nullptr)
|
||||
{
|
||||
last.etl_next->etl_previous = &last;
|
||||
}
|
||||
|
||||
lhs.etl_next = &first;
|
||||
}
|
||||
|
||||
// Pointer, Reference, Reference
|
||||
template <typename TLink>
|
||||
typename etl::enable_if<etl::is_same<TLink, etl::bidirectional_link<TLink::ID, TLink::OPTION> >::value, void>::type
|
||||
link_splice(TLink* lhs, TLink& first, TLink& last)
|
||||
{
|
||||
if (lhs != nullptr)
|
||||
{
|
||||
last.etl_next = lhs->etl_next;
|
||||
}
|
||||
else
|
||||
{
|
||||
last.etl_next = nullptr;
|
||||
}
|
||||
|
||||
first.etl_previous = lhs;
|
||||
|
||||
if (last.etl_next != nullptr)
|
||||
{
|
||||
last.etl_next->etl_previous = &last;
|
||||
}
|
||||
|
||||
if (lhs != nullptr)
|
||||
{
|
||||
lhs->etl_next = &first;
|
||||
}
|
||||
}
|
||||
|
||||
// Reference
|
||||
template <typename TLink>
|
||||
typename etl::enable_if<etl::is_same<TLink, etl::bidirectional_link<TLink::ID, TLink::OPTION> >::value, void>::type
|
||||
unlink(TLink& node)
|
||||
{
|
||||
if (node.etl_next != nullptr)
|
||||
{
|
||||
node.etl_next->etl_previous = node.etl_previous;
|
||||
}
|
||||
node.unlink();
|
||||
}
|
||||
|
||||
if (node.etl_previous != nullptr)
|
||||
// Reference Reference
|
||||
template <typename TLink>
|
||||
typename etl::enable_if<etl::is_same<TLink, etl::bidirectional_link<TLink::ID, TLink::OPTION> >::value, void>::type
|
||||
unlink(TLink& first, TLink& last)
|
||||
{
|
||||
if (&first == &last)
|
||||
{
|
||||
node.etl_previous->etl_next = node.etl_next;
|
||||
first.unlink();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (last.etl_next != nullptr)
|
||||
{
|
||||
last.etl_next->etl_previous = first.etl_previous;
|
||||
}
|
||||
|
||||
if (first.etl_previous != nullptr)
|
||||
{
|
||||
first.etl_previous->etl_next = last.etl_next;
|
||||
}
|
||||
|
||||
if ((TLink::OPTION == etl::link_option::AUTO) ||
|
||||
(TLink::OPTION == etl::link_option::CHECKED))
|
||||
{
|
||||
first.etl_previous = nullptr;
|
||||
last.etl_next = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Pointer
|
||||
template <typename TLink>
|
||||
typename etl::enable_if<etl::is_same<TLink, etl::bidirectional_link<TLink::ID, TLink::OPTION> >::value, void>::type
|
||||
unlink(TLink* node)
|
||||
namespace __private_intrusive_links__
|
||||
{
|
||||
if (node != nullptr)
|
||||
//***************************************************************************
|
||||
/// A tree link base.
|
||||
//***************************************************************************
|
||||
template <typename TLink, const size_t ID_, const size_t OPTION_>
|
||||
struct tree_link_base
|
||||
{
|
||||
if (node->etl_next != nullptr)
|
||||
enum
|
||||
{
|
||||
node->etl_next->etl_previous = node->etl_previous;
|
||||
ID = ID_,
|
||||
OPTION = OPTION_
|
||||
};
|
||||
|
||||
void clear()
|
||||
{
|
||||
etl_parent = nullptr;
|
||||
etl_left = nullptr;
|
||||
etl_right = nullptr;
|
||||
}
|
||||
|
||||
if (node->etl_previous != nullptr)
|
||||
bool is_linked() const
|
||||
{
|
||||
node->etl_previous->etl_next = node->etl_next;
|
||||
return (etl_parent != nullptr) || (etl_left != nullptr) || (etl_right != nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
TLink* etl_parent;
|
||||
TLink* etl_left;
|
||||
TLink* etl_right;
|
||||
};
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// A tree link.
|
||||
//***************************************************************************
|
||||
template <const size_t ID_ = 0>
|
||||
template <const size_t ID_ = 0, const size_t OPTION_ = etl::link_option::DEFAULT>
|
||||
struct tree_link
|
||||
: public __private_intrusive_links__::tree_link_base<tree_link<ID_, OPTION_>, ID_, OPTION_>
|
||||
{
|
||||
enum
|
||||
{
|
||||
ID = ID_
|
||||
};
|
||||
};
|
||||
|
||||
void clear()
|
||||
//******************************************************************
|
||||
// There is no valid specialisation for auto link
|
||||
//******************************************************************
|
||||
template <const size_t ID_>
|
||||
struct tree_link<ID_, etl::link_option::AUTO>
|
||||
: public __private_intrusive_links__::tree_link_base<tree_link<ID_, etl::link_option::AUTO>, ID_, etl::link_option::AUTO>
|
||||
{
|
||||
tree_link()
|
||||
{
|
||||
etl_parent = nullptr;
|
||||
etl_left = nullptr;
|
||||
etl_right = nullptr;
|
||||
clear();
|
||||
}
|
||||
};
|
||||
|
||||
//******************************************************************
|
||||
// Specialisation for checked unlink option.
|
||||
// An error will be generated if the links are valid when the object
|
||||
// is destroyed.
|
||||
//******************************************************************
|
||||
template <const size_t ID_>
|
||||
struct tree_link<ID_, etl::link_option::CHECKED>
|
||||
: public __private_intrusive_links__::tree_link_base<tree_link<ID_, etl::link_option::CHECKED>, ID_, etl::link_option::CHECKED>
|
||||
{
|
||||
tree_link()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
tree_link* etl_parent;
|
||||
tree_link* etl_left;
|
||||
tree_link* etl_right;
|
||||
~tree_link()
|
||||
{
|
||||
assert(etl_parent != nullptr);
|
||||
assert(etl_left != nullptr);
|
||||
assert(etl_right != nullptr);
|
||||
}
|
||||
};
|
||||
|
||||
// Reference, Reference
|
||||
template <typename TLink>
|
||||
typename etl::enable_if<etl::is_same<TLink, etl::tree_link<TLink::ID> >::value, void>::type
|
||||
typename etl::enable_if<etl::is_same<TLink, etl::tree_link<TLink::ID, TLink::OPTION> >::value, void>::type
|
||||
link_left(TLink& parent, TLink& leaf)
|
||||
{
|
||||
parent.etl_left = &leaf;
|
||||
@ -406,7 +732,7 @@ namespace etl
|
||||
}
|
||||
|
||||
template <typename TLink>
|
||||
typename etl::enable_if<etl::is_same<TLink, etl::tree_link<TLink::ID> >::value, void>::type
|
||||
typename etl::enable_if<etl::is_same<TLink, etl::tree_link<TLink::ID, TLink::OPTION> >::value, void>::type
|
||||
link_right(TLink& parent, TLink& leaf)
|
||||
{
|
||||
parent.etl_right = &leaf;
|
||||
@ -415,7 +741,7 @@ namespace etl
|
||||
|
||||
// Pointer, Pointer
|
||||
template <typename TLink>
|
||||
typename etl::enable_if<etl::is_same<TLink, etl::tree_link<TLink::ID> >::value, void>::type
|
||||
typename etl::enable_if<etl::is_same<TLink, etl::tree_link<TLink::ID, TLink::OPTION> >::value, void>::type
|
||||
link_left(TLink* parent, TLink* leaf)
|
||||
{
|
||||
if (parent != nullptr)
|
||||
@ -430,7 +756,7 @@ namespace etl
|
||||
}
|
||||
|
||||
template <typename TLink>
|
||||
typename etl::enable_if<etl::is_same<TLink, etl::tree_link<TLink::ID> >::value, void>::type
|
||||
typename etl::enable_if<etl::is_same<TLink, etl::tree_link<TLink::ID, TLink::OPTION> >::value, void>::type
|
||||
link_right(TLink* parent, TLink* leaf)
|
||||
{
|
||||
if (parent != nullptr)
|
||||
@ -446,7 +772,7 @@ namespace etl
|
||||
|
||||
// Reference, Pointer
|
||||
template <typename TLink>
|
||||
typename etl::enable_if<etl::is_same<TLink, etl::tree_link<TLink::ID> >::value, void>::type
|
||||
typename etl::enable_if<etl::is_same<TLink, etl::tree_link<TLink::ID, TLink::OPTION> >::value, void>::type
|
||||
link_left(TLink& parent, TLink* leaf)
|
||||
{
|
||||
parent.etl_left = leaf;
|
||||
@ -458,7 +784,7 @@ namespace etl
|
||||
}
|
||||
|
||||
template <typename TLink>
|
||||
typename etl::enable_if<etl::is_same<TLink, etl::tree_link<TLink::ID> >::value, void>::type
|
||||
typename etl::enable_if<etl::is_same<TLink, etl::tree_link<TLink::ID, TLink::OPTION> >::value, void>::type
|
||||
link_right(TLink& parent, TLink* leaf)
|
||||
{
|
||||
parent.etl_right = leaf;
|
||||
@ -471,7 +797,7 @@ namespace etl
|
||||
|
||||
// Pointer, Reference
|
||||
template <typename TLink>
|
||||
typename etl::enable_if<etl::is_same<TLink, etl::tree_link<TLink::ID> >::value, void>::type
|
||||
typename etl::enable_if<etl::is_same<TLink, etl::tree_link<TLink::ID, TLink::OPTION> >::value, void>::type
|
||||
link_left(TLink* parent, TLink& leaf)
|
||||
{
|
||||
if (parent != nullptr)
|
||||
@ -483,7 +809,7 @@ namespace etl
|
||||
}
|
||||
|
||||
template <typename TLink>
|
||||
typename etl::enable_if<etl::is_same<TLink, etl::tree_link<TLink::ID> >::value, void>::type
|
||||
typename etl::enable_if<etl::is_same<TLink, etl::tree_link<TLink::ID, TLink::OPTION> >::value, void>::type
|
||||
link_right(TLink* parent, TLink& leaf)
|
||||
{
|
||||
if (parent != nullptr)
|
||||
@ -496,4 +822,4 @@ namespace etl
|
||||
}
|
||||
|
||||
#undef ETL_FILE
|
||||
#endif
|
||||
#endif
|
||||
@ -76,6 +76,11 @@ namespace
|
||||
return data < other.data;
|
||||
}
|
||||
|
||||
bool operator >(const ItemNDCNode& other) const
|
||||
{
|
||||
return other.data < data;
|
||||
}
|
||||
|
||||
ItemNDC data;
|
||||
};
|
||||
|
||||
@ -130,25 +135,6 @@ namespace
|
||||
typedef etl::intrusive_forward_list<ItemNDCNode, SecondLink> DataNDC1;
|
||||
|
||||
typedef std::vector<ItemNDCNode> InitialDataNDC;
|
||||
|
||||
template <typename TIterator1, typename TIterator2>
|
||||
bool Equal(TIterator1 begin1,
|
||||
TIterator1 end1,
|
||||
TIterator2 begin2)
|
||||
{
|
||||
while (begin1 != end1)
|
||||
{
|
||||
if (*begin1 != *begin2)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
++begin1;
|
||||
++begin2;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
namespace
|
||||
@ -157,9 +143,15 @@ namespace
|
||||
{
|
||||
InitialDataNDC unsorted_data;
|
||||
InitialDataNDC sorted_data;
|
||||
InitialDataNDC sorted_data2;
|
||||
InitialDataNDC non_unique_data;
|
||||
InitialDataNDC unique_data;
|
||||
InitialDataNDC small_data;
|
||||
InitialDataNDC merge_data0;
|
||||
InitialDataNDC merge_data1;
|
||||
InitialDataNDC merge_data2;
|
||||
InitialDataNDC merge_data3;
|
||||
InitialDataNDC merge_data4;
|
||||
|
||||
bool are_equal;
|
||||
|
||||
@ -170,9 +162,16 @@ namespace
|
||||
{
|
||||
unsorted_data = { ItemNDCNode("1"), ItemNDCNode("0"), ItemNDCNode("3"), ItemNDCNode("2"), ItemNDCNode("5"), ItemNDCNode("4"), ItemNDCNode("7"), ItemNDCNode("6"), ItemNDCNode("9"), ItemNDCNode("8") };
|
||||
sorted_data = { ItemNDCNode("0"), ItemNDCNode("1"), ItemNDCNode("2"), ItemNDCNode("3"), ItemNDCNode("4"), ItemNDCNode("5"), ItemNDCNode("6"), ItemNDCNode("7"), ItemNDCNode("8"), ItemNDCNode("9") };
|
||||
sorted_data2 = { ItemNDCNode("0"), ItemNDCNode("1"), ItemNDCNode("2"), ItemNDCNode("3"), ItemNDCNode("4"), ItemNDCNode("5"), ItemNDCNode("6"), ItemNDCNode("7"), ItemNDCNode("8"), ItemNDCNode("9") };
|
||||
non_unique_data = { ItemNDCNode("0"), ItemNDCNode("0"), ItemNDCNode("1"), ItemNDCNode("1"), ItemNDCNode("2"), ItemNDCNode("3"), ItemNDCNode("3"), ItemNDCNode("3"), ItemNDCNode("4"), ItemNDCNode("5") };
|
||||
unique_data = { ItemNDCNode("0"), ItemNDCNode("1"), ItemNDCNode("2"), ItemNDCNode("3"), ItemNDCNode("4"), ItemNDCNode("5") };
|
||||
small_data = { ItemNDCNode("0"), ItemNDCNode("1"), ItemNDCNode("2"), ItemNDCNode("3"), ItemNDCNode("4"), ItemNDCNode("5") };
|
||||
|
||||
merge_data0 = { ItemNDCNode("1"), ItemNDCNode("1"), ItemNDCNode("3"), ItemNDCNode("3"), ItemNDCNode("5"), ItemNDCNode("7"), ItemNDCNode("8") };
|
||||
merge_data1 = { ItemNDCNode("1"), ItemNDCNode("2"), ItemNDCNode("3"), ItemNDCNode("3"), ItemNDCNode("6"), ItemNDCNode("9"), ItemNDCNode("9") };
|
||||
merge_data2 = { ItemNDCNode("0"), ItemNDCNode("2"), ItemNDCNode("3"), ItemNDCNode("3"), ItemNDCNode("6"), ItemNDCNode("7"), ItemNDCNode("7") };
|
||||
merge_data3 = { ItemNDCNode("0"), ItemNDCNode("2"), ItemNDCNode("3"), ItemNDCNode("3"), ItemNDCNode("6"), ItemNDCNode("7") };
|
||||
merge_data4 = { ItemNDCNode("0"), ItemNDCNode("2"), ItemNDCNode("3"), ItemNDCNode("3"), ItemNDCNode("6"), ItemNDCNode("7"), ItemNDCNode("8"), ItemNDCNode("9") };
|
||||
}
|
||||
};
|
||||
|
||||
@ -195,6 +194,20 @@ namespace
|
||||
CHECK_EQUAL(sorted_data.size(), data0.size());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST_FIXTURE(SetupFixture, test_empty_begin_end)
|
||||
{
|
||||
DataNDC0 data0;
|
||||
|
||||
CHECK(data0.begin() == data0.end());
|
||||
|
||||
DataNDC0::const_iterator begin = data0.begin();
|
||||
DataNDC0::const_iterator end = data0.end();
|
||||
CHECK(begin == end);
|
||||
|
||||
CHECK(data0.cbegin() == data0.cend());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST_FIXTURE(SetupFixture, test_iterator)
|
||||
{
|
||||
@ -317,7 +330,7 @@ namespace
|
||||
ItemNDCNode INSERT_VALUE1 = ItemNDCNode("1");
|
||||
ItemNDCNode INSERT_VALUE2 = ItemNDCNode("2");
|
||||
|
||||
std::vector<ItemNDCNode> compare_data(sorted_data.begin(), sorted_data.end());
|
||||
std::forward_list<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());
|
||||
|
||||
@ -326,16 +339,16 @@ namespace
|
||||
DataNDC0::iterator i_data = data0.begin();
|
||||
std::advance(i_data, offset);
|
||||
|
||||
std::vector<ItemNDCNode>::iterator i_compare_data = compare_data.begin();
|
||||
std::advance(i_compare_data, offset + 1);
|
||||
std::forward_list<ItemNDCNode>::iterator i_compare_data = compare_data.begin();
|
||||
std::advance(i_compare_data, offset);
|
||||
|
||||
data0.insert_after(i_data, INSERT_VALUE1);
|
||||
compare_data.insert(i_compare_data, INSERT_VALUE1);
|
||||
compare_data.insert_after(i_compare_data, INSERT_VALUE1);
|
||||
|
||||
are_equal = std::equal(data0.begin(), data0.end(), compare_data.begin());
|
||||
CHECK(are_equal);
|
||||
CHECK_EQUAL(compare_data.size(), data0.size());
|
||||
CHECK_EQUAL(compare_data.size(), std::distance(data0.begin(), data0.end()));
|
||||
CHECK_EQUAL(std::distance(compare_data.begin(), compare_data.end()), data0.size());
|
||||
CHECK_EQUAL(std::distance(compare_data.begin(), compare_data.end()), std::distance(data0.begin(), data0.end()));
|
||||
|
||||
are_equal = std::equal(data1.begin(), data1.end(), sorted_data.begin());
|
||||
CHECK(are_equal);
|
||||
@ -348,19 +361,19 @@ namespace
|
||||
std::advance(i_data, offset);
|
||||
|
||||
i_compare_data = compare_data.begin();
|
||||
std::advance(i_compare_data, offset + 1);
|
||||
std::advance(i_compare_data, offset);
|
||||
|
||||
std::vector<ItemNDCNode> temp(data0.begin(), data0.end());
|
||||
std::forward_list<ItemNDCNode> temp(data0.begin(), data0.end());
|
||||
|
||||
data0.insert_after(i_data, INSERT_VALUE2);
|
||||
compare_data.insert(i_compare_data, INSERT_VALUE2);
|
||||
compare_data.insert_after(i_compare_data, INSERT_VALUE2);
|
||||
|
||||
temp.assign(data0.begin(), data0.end());
|
||||
|
||||
are_equal = std::equal(data0.begin(), data0.end(), compare_data.begin());
|
||||
CHECK(are_equal);
|
||||
CHECK_EQUAL(compare_data.size(), data0.size());
|
||||
CHECK_EQUAL(compare_data.size(), std::distance(data0.begin(), data0.end()));
|
||||
CHECK_EQUAL(std::distance(compare_data.begin(), compare_data.end()), data0.size());
|
||||
CHECK_EQUAL(std::distance(compare_data.begin(), compare_data.end()), std::distance(data0.begin(), data0.end()));
|
||||
|
||||
are_equal = std::equal(data1.begin(), data1.end(), sorted_data.begin());
|
||||
CHECK(are_equal);
|
||||
@ -373,8 +386,8 @@ namespace
|
||||
{
|
||||
std::vector<ItemNDCNode> test1 = { ItemNDCNode("0"), ItemNDCNode("1"), ItemNDCNode("2"), ItemNDCNode("3"), ItemNDCNode("4") };
|
||||
std::vector<ItemNDCNode> test2 = { ItemNDCNode("5"), ItemNDCNode("6"), ItemNDCNode("7"), ItemNDCNode("8"), ItemNDCNode("9") };
|
||||
std::vector<ItemNDCNode> compare(test2);
|
||||
compare.insert(compare.end(), test1.begin(), test1.end());
|
||||
std::forward_list<ItemNDCNode> compare(test1.begin(), test1.end());
|
||||
compare.insert_after(compare.before_begin(), test2.begin(), test2.end());
|
||||
|
||||
DataNDC0 data0(test1.begin(), test1.end());
|
||||
DataNDC1 data1(test1.begin(), test1.end());
|
||||
@ -392,16 +405,16 @@ namespace
|
||||
compare.assign(test1.begin(), test1.end());
|
||||
data0.assign(test1.begin(), test1.end());
|
||||
|
||||
std::vector<ItemNDCNode>::iterator icd = compare.begin();
|
||||
std::forward_list<ItemNDCNode>::iterator icd = compare.begin();
|
||||
DataNDC0::iterator id = data0.begin();
|
||||
|
||||
std::advance(icd, 4);
|
||||
std::advance(icd, 3);
|
||||
std::advance(id, 3);
|
||||
|
||||
compare.insert(icd, test2.begin(), test2.end());
|
||||
compare.insert_after(icd, test2.begin(), test2.end());
|
||||
data0.insert_after(id, test2.begin(), test2.end());
|
||||
|
||||
std::vector<ItemNDCNode> out(data0.begin(), data0.end());
|
||||
std::forward_list<ItemNDCNode> out(data0.begin(), data0.end());
|
||||
|
||||
are_equal = std::equal(data0.begin(), data0.end(), compare.begin());
|
||||
CHECK(are_equal);
|
||||
@ -500,17 +513,17 @@ namespace
|
||||
//*************************************************************************
|
||||
TEST_FIXTURE(SetupFixture, test_erase_after_single)
|
||||
{
|
||||
std::vector<ItemNDCNode> compare_data(sorted_data.begin(), sorted_data.end());
|
||||
std::forward_list<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());
|
||||
|
||||
DataNDC0::iterator i_data = data0.begin();
|
||||
std::advance(i_data, 2);
|
||||
|
||||
std::vector<ItemNDCNode>::iterator i_compare_data = compare_data.begin();
|
||||
std::advance(i_compare_data, 3);
|
||||
std::forward_list<ItemNDCNode>::iterator i_compare_data = compare_data.begin();
|
||||
std::advance(i_compare_data, 2);
|
||||
|
||||
i_compare_data = compare_data.erase(i_compare_data);
|
||||
i_compare_data = compare_data.erase_after(i_compare_data);
|
||||
i_data = data0.erase_after(i_data);
|
||||
|
||||
are_equal = std::equal(data0.begin(), data0.end(), compare_data.begin());
|
||||
@ -518,14 +531,14 @@ namespace
|
||||
CHECK(are_equal);
|
||||
CHECK(*i_compare_data == *i_data);
|
||||
|
||||
i_compare_data = compare_data.erase(compare_data.begin() + 1);
|
||||
i_compare_data = compare_data.erase_after(compare_data.begin());
|
||||
i_data = data0.erase_after(data0.begin());
|
||||
|
||||
are_equal = std::equal(data0.begin(), data0.end(), compare_data.begin());
|
||||
|
||||
CHECK(are_equal);
|
||||
CHECK_EQUAL(compare_data.size(), data0.size());
|
||||
CHECK_EQUAL(compare_data.size(), std::distance(data0.begin(), data0.end()));
|
||||
CHECK_EQUAL(std::distance(compare_data.begin(), compare_data.end()), data0.size());
|
||||
CHECK_EQUAL(std::distance(compare_data.begin(), compare_data.end()), std::distance(data0.begin(), data0.end()));
|
||||
|
||||
are_equal = std::equal(data1.begin(), data1.end(), sorted_data.begin());
|
||||
CHECK(are_equal);
|
||||
@ -536,8 +549,8 @@ namespace
|
||||
CHECK(are_equal);
|
||||
|
||||
// Move to the last value and erase.
|
||||
i_compare_data = compare_data.begin() + 1;
|
||||
i_compare_data = compare_data.erase(i_compare_data);
|
||||
i_compare_data = compare_data.begin();
|
||||
i_compare_data = compare_data.erase_after(i_compare_data);
|
||||
|
||||
i_data = data0.begin();
|
||||
i_data = data0.erase_after(i_data);
|
||||
@ -545,8 +558,8 @@ namespace
|
||||
are_equal = std::equal(data0.begin(), data0.end(), compare_data.begin());
|
||||
|
||||
CHECK(are_equal);
|
||||
CHECK_EQUAL(compare_data.size(), data0.size());
|
||||
CHECK_EQUAL(compare_data.size(), std::distance(data0.begin(), data0.end()));
|
||||
CHECK_EQUAL(std::distance(compare_data.begin(), compare_data.end()), data0.size());
|
||||
CHECK_EQUAL(std::distance(compare_data.begin(), compare_data.end()), std::distance(data0.begin(), data0.end()));
|
||||
|
||||
are_equal = std::equal(data1.begin(), data1.end(), sorted_data.begin());
|
||||
CHECK(are_equal);
|
||||
@ -560,23 +573,23 @@ namespace
|
||||
//*************************************************************************
|
||||
TEST_FIXTURE(SetupFixture, test_erase_after_range)
|
||||
{
|
||||
std::vector<ItemNDCNode> compare_data(sorted_data.begin(), sorted_data.end());
|
||||
std::forward_list<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());
|
||||
DataNDC1 data1(sorted_data2.begin(), sorted_data2.end());
|
||||
|
||||
DataNDC0::iterator i_data_1 = data0.begin();
|
||||
std::advance(i_data_1, 2);
|
||||
|
||||
DataNDC0::iterator i_data_2 = data0.begin();
|
||||
std::advance(i_data_2, 4);
|
||||
std::advance(i_data_2, 5);
|
||||
|
||||
std::vector<ItemNDCNode>::iterator i_compare_data_1 = compare_data.begin();
|
||||
std::advance(i_compare_data_1, 3);
|
||||
std::forward_list<ItemNDCNode>::iterator i_compare_data_1 = compare_data.begin();
|
||||
std::advance(i_compare_data_1, 2);
|
||||
|
||||
std::vector<ItemNDCNode>::iterator i_compare_data_2 = compare_data.begin();
|
||||
std::advance(i_compare_data_2, 4);
|
||||
std::forward_list<ItemNDCNode>::iterator i_compare_data_2 = compare_data.begin();
|
||||
std::advance(i_compare_data_2, 5);
|
||||
|
||||
std::vector<ItemNDCNode>::iterator i_compare_result = compare_data.erase(i_compare_data_1, i_compare_data_2);
|
||||
std::forward_list<ItemNDCNode>::iterator i_compare_result = compare_data.erase_after(i_compare_data_1, i_compare_data_2);
|
||||
|
||||
DataNDC0::iterator i_result = data0.erase_after(i_data_1, i_data_2);
|
||||
|
||||
@ -584,8 +597,8 @@ namespace
|
||||
|
||||
are_equal = std::equal(data0.begin(), data0.end(), compare_data.begin());
|
||||
CHECK(are_equal);
|
||||
CHECK_EQUAL(compare_data.size(), data0.size());
|
||||
CHECK_EQUAL(compare_data.size(), std::distance(data0.begin(), data0.end()));
|
||||
CHECK_EQUAL(std::distance(compare_data.begin(), compare_data.end()), data0.size());
|
||||
CHECK_EQUAL(std::distance(compare_data.begin(), compare_data.end()), std::distance(data0.begin(), data0.end()));
|
||||
|
||||
are_equal = std::equal(data1.begin(), data1.end(), sorted_data.begin());
|
||||
CHECK(are_equal);
|
||||
@ -596,17 +609,17 @@ namespace
|
||||
//*************************************************************************
|
||||
TEST_FIXTURE(SetupFixture, test_erase_after_range_end)
|
||||
{
|
||||
std::vector<ItemNDCNode> compare_data(sorted_data.begin(), sorted_data.end());
|
||||
std::forward_list<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());
|
||||
|
||||
DataNDC0::iterator i_data = data0.begin();
|
||||
std::advance(i_data, 4);
|
||||
|
||||
std::vector<ItemNDCNode>::iterator i_compare_data = compare_data.begin();
|
||||
std::advance(i_compare_data, 5);
|
||||
std::forward_list<ItemNDCNode>::iterator i_compare_data = compare_data.begin();
|
||||
std::advance(i_compare_data, 4);
|
||||
|
||||
std::vector<ItemNDCNode>::iterator i_compare_result = compare_data.erase(i_compare_data, compare_data.end());
|
||||
std::forward_list<ItemNDCNode>::iterator i_compare_result = compare_data.erase_after(i_compare_data, compare_data.end());
|
||||
|
||||
DataNDC0::iterator i_result = data0.erase_after(i_data, data0.end());
|
||||
|
||||
@ -614,8 +627,8 @@ namespace
|
||||
|
||||
are_equal = std::equal(data0.begin(), data0.end(), compare_data.begin());
|
||||
CHECK(are_equal);
|
||||
CHECK_EQUAL(compare_data.size(), data0.size());
|
||||
CHECK_EQUAL(compare_data.size(), std::distance(data0.begin(), data0.end()));
|
||||
CHECK_EQUAL(std::distance(compare_data.begin(), compare_data.end()), data0.size());
|
||||
CHECK_EQUAL(std::distance(compare_data.begin(), compare_data.end()), std::distance(data0.begin(), data0.end()));
|
||||
|
||||
are_equal = std::equal(data1.begin(), data1.end(), sorted_data.begin());
|
||||
CHECK(are_equal);
|
||||
@ -665,19 +678,18 @@ namespace
|
||||
//*************************************************************************
|
||||
TEST_FIXTURE(SetupFixture, test_remove)
|
||||
{
|
||||
std::vector<ItemNDCNode> compare_data(sorted_data.begin(), sorted_data.end());
|
||||
std::forward_list<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());
|
||||
|
||||
std::vector<ItemNDCNode>::iterator i_item = std::find(compare_data.begin(), compare_data.end(), ItemNDCNode("7"));
|
||||
compare_data.erase(i_item);
|
||||
compare_data.remove(ItemNDCNode("7"));
|
||||
data0.remove(ItemNDCNode("7"));
|
||||
|
||||
are_equal = std::equal(data0.begin(), data0.end(), compare_data.begin());
|
||||
|
||||
CHECK(are_equal);
|
||||
CHECK_EQUAL(compare_data.size(), data0.size());
|
||||
CHECK_EQUAL(compare_data.size(), std::distance(data0.begin(), data0.end()));
|
||||
CHECK_EQUAL(std::distance(compare_data.begin(), compare_data.end()), data0.size());
|
||||
CHECK_EQUAL(std::distance(compare_data.begin(), compare_data.end()), std::distance(data0.begin(), data0.end()));
|
||||
|
||||
are_equal = std::equal(data1.begin(), data1.end(), sorted_data.begin());
|
||||
CHECK(are_equal);
|
||||
@ -688,19 +700,18 @@ namespace
|
||||
//*************************************************************************
|
||||
TEST_FIXTURE(SetupFixture, test_remove_if)
|
||||
{
|
||||
std::vector<ItemNDCNode> compare_data(sorted_data.begin(), sorted_data.end());
|
||||
std::forward_list<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());
|
||||
|
||||
std::vector<ItemNDCNode>::iterator i_item = std::find(compare_data.begin(), compare_data.end(), ItemNDCNode("7"));
|
||||
compare_data.erase(i_item);
|
||||
compare_data.remove_if(std::bind2nd(std::equal_to<ItemNDCNode>(), ItemNDCNode("7")));
|
||||
data0.remove_if(std::bind2nd(std::equal_to<ItemNDCNode>(), ItemNDCNode("7")));
|
||||
|
||||
are_equal = std::equal(data0.begin(), data0.end(), compare_data.begin());
|
||||
|
||||
CHECK(are_equal);
|
||||
CHECK_EQUAL(compare_data.size(), data0.size());
|
||||
CHECK_EQUAL(compare_data.size(), std::distance(data0.begin(), data0.end()));
|
||||
CHECK_EQUAL(std::distance(compare_data.begin(), compare_data.end()), data0.size());
|
||||
CHECK_EQUAL(std::distance(compare_data.begin(), compare_data.end()), std::distance(data0.begin(), data0.end()));
|
||||
|
||||
are_equal = std::equal(data1.begin(), data1.end(), sorted_data.begin());
|
||||
CHECK(are_equal);
|
||||
@ -752,5 +763,242 @@ namespace
|
||||
are_equal = std::equal(data1.begin(), data1.end(), unsorted_data.begin());
|
||||
CHECK(are_equal);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST_FIXTURE(SetupFixture, test_splice_list)
|
||||
{
|
||||
bool are_equal;
|
||||
|
||||
DataNDC0 data0(sorted_data.begin(), sorted_data.end());
|
||||
DataNDC0 data1(sorted_data2.begin(), sorted_data2.end());
|
||||
|
||||
DataNDC0::iterator idata_destination = data0.begin();
|
||||
std::advance(idata_destination, 3);
|
||||
|
||||
std::forward_list<ItemNDCNode> compare0(data0.begin(), data0.end());
|
||||
std::forward_list<ItemNDCNode> compare1(data1.begin(), data1.end());
|
||||
|
||||
std::forward_list<ItemNDCNode>::iterator icompare_destination = compare0.begin();
|
||||
std::advance(icompare_destination, 3);
|
||||
|
||||
data0.splice_after(idata_destination, data1);
|
||||
compare0.splice_after(icompare_destination, compare1);
|
||||
|
||||
are_equal = std::equal(data0.begin(), data0.end(), compare0.begin());
|
||||
CHECK(are_equal);
|
||||
|
||||
CHECK_EQUAL(std::distance(compare0.begin(), compare0.end()), data0.size());
|
||||
CHECK_EQUAL(std::distance(compare1.begin(), compare1.end()), data1.size());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST_FIXTURE(SetupFixture, test_splice_list_self)
|
||||
{
|
||||
bool are_equal;
|
||||
|
||||
DataNDC0 data0(sorted_data.begin(), sorted_data.end());
|
||||
|
||||
DataNDC0::iterator idata_destination = data0.begin();
|
||||
std::advance(idata_destination, 3);
|
||||
|
||||
std::forward_list<ItemNDCNode> compare0(data0.begin(), data0.end());
|
||||
|
||||
std::forward_list<ItemNDCNode>::iterator icompare_destination = compare0.begin();
|
||||
std::advance(icompare_destination, 3);
|
||||
|
||||
data0.splice_after(idata_destination, data0);
|
||||
compare0.splice_after(icompare_destination, compare0);
|
||||
|
||||
are_equal = std::equal(data0.begin(), data0.end(), compare0.begin());
|
||||
CHECK(are_equal);
|
||||
|
||||
CHECK_EQUAL(std::distance(compare0.begin(), compare0.end()), data0.size());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST_FIXTURE(SetupFixture, test_splice_range)
|
||||
{
|
||||
bool are_equal;
|
||||
|
||||
DataNDC0 data0(sorted_data.begin(), sorted_data.end());
|
||||
DataNDC0 data1(sorted_data2.begin(), sorted_data2.end());
|
||||
|
||||
DataNDC0::iterator idata_destination = data0.begin();
|
||||
std::advance(idata_destination, 2);
|
||||
|
||||
DataNDC0::iterator idata_begin = data1.begin();
|
||||
std::advance(idata_begin, 4);
|
||||
|
||||
DataNDC0::iterator idata_end = data1.begin();
|
||||
std::advance(idata_end, 7);
|
||||
|
||||
std::forward_list<ItemNDCNode> compare0(data0.begin(), data0.end());
|
||||
std::forward_list<ItemNDCNode> compare1(data1.begin(), data1.end());
|
||||
|
||||
std::forward_list<ItemNDCNode>::iterator icompare_destination = compare0.begin();
|
||||
std::advance(icompare_destination, 2);
|
||||
|
||||
std::forward_list<ItemNDCNode>::iterator icompare_begin = compare1.begin();
|
||||
std::advance(icompare_begin, 4);
|
||||
|
||||
std::forward_list<ItemNDCNode>::iterator icompare_end = compare1.begin();
|
||||
std::advance(icompare_end, 7);
|
||||
|
||||
data0.splice_after(idata_destination, data1, idata_begin, idata_end);
|
||||
compare0.splice_after(icompare_destination, compare1, icompare_begin, icompare_end);
|
||||
|
||||
are_equal = std::equal(data0.begin(), data0.end(), compare0.begin());
|
||||
CHECK(are_equal);
|
||||
|
||||
CHECK_EQUAL(std::distance(compare0.begin(), compare0.end()), data0.size());
|
||||
CHECK_EQUAL(std::distance(compare1.begin(), compare1.end()), data1.size());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST_FIXTURE(SetupFixture, test_splice_range_self)
|
||||
{
|
||||
bool are_equal;
|
||||
|
||||
DataNDC0 data0(sorted_data.begin(), sorted_data.end());
|
||||
|
||||
DataNDC0::iterator idata_destination = data0.begin();
|
||||
std::advance(idata_destination, 2);
|
||||
|
||||
DataNDC0::iterator idata_begin = data0.begin();
|
||||
std::advance(idata_begin, 4);
|
||||
|
||||
DataNDC0::iterator idata_end = data0.begin();
|
||||
std::advance(idata_end, 7);
|
||||
|
||||
std::forward_list<ItemNDCNode> compare0(data0.begin(), data0.end());
|
||||
|
||||
std::forward_list<ItemNDCNode>::iterator icompare_destination = compare0.begin();
|
||||
std::advance(icompare_destination, 2);
|
||||
|
||||
std::forward_list<ItemNDCNode>::iterator icompare_begin = compare0.begin();
|
||||
std::advance(icompare_begin, 4);
|
||||
|
||||
std::forward_list<ItemNDCNode>::iterator icompare_end = compare0.begin();
|
||||
std::advance(icompare_end, 7);
|
||||
|
||||
data0.splice_after(idata_destination, data0, idata_begin, idata_end);
|
||||
compare0.splice_after(icompare_destination, compare0, icompare_begin, icompare_end);
|
||||
|
||||
are_equal = std::equal(data0.begin(), data0.end(), compare0.begin());
|
||||
CHECK(are_equal);
|
||||
|
||||
CHECK_EQUAL(std::distance(compare0.begin(), compare0.end()), data0.size());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST_FIXTURE(SetupFixture, test_merge_0_1)
|
||||
{
|
||||
bool are_equal;
|
||||
|
||||
DataNDC0 data0(merge_data0.begin(), merge_data0.end());
|
||||
DataNDC0 data1(merge_data1.begin(), merge_data1.end());
|
||||
|
||||
std::forward_list<ItemNDCNode> compare0(merge_data0.begin(), merge_data0.end());
|
||||
std::forward_list<ItemNDCNode> compare1(merge_data1.begin(), merge_data1.end());
|
||||
|
||||
data0.merge(data1);
|
||||
compare0.merge(compare1);
|
||||
|
||||
are_equal = std::equal(data0.begin(), data0.end(), compare0.begin());
|
||||
CHECK(are_equal);
|
||||
|
||||
CHECK_EQUAL(std::distance(compare0.begin(), compare0.end()), data0.size());
|
||||
CHECK_EQUAL(std::distance(compare1.begin(), compare1.end()), data1.size());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST_FIXTURE(SetupFixture, test_merge_0_2)
|
||||
{
|
||||
bool are_equal;
|
||||
|
||||
DataNDC0 data0(merge_data0.begin(), merge_data0.end());
|
||||
DataNDC0 data2(merge_data2.begin(), merge_data2.end());
|
||||
|
||||
std::forward_list<ItemNDCNode> compare0(merge_data0.begin(), merge_data0.end());
|
||||
std::forward_list<ItemNDCNode> compare2(merge_data2.begin(), merge_data2.end());
|
||||
|
||||
data0.merge(data2);
|
||||
compare0.merge(compare2);
|
||||
|
||||
are_equal = std::equal(data0.begin(), data0.end(), compare0.begin());
|
||||
CHECK(are_equal);
|
||||
|
||||
CHECK_EQUAL(std::distance(compare0.begin(), compare0.end()), data0.size());
|
||||
CHECK_EQUAL(std::distance(compare2.begin(), compare2.end()), data2.size());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST_FIXTURE(SetupFixture, test_merge_0_3)
|
||||
{
|
||||
bool are_equal;
|
||||
|
||||
DataNDC0 data0(merge_data0.begin(), merge_data0.end());
|
||||
DataNDC0 data3(merge_data3.begin(), merge_data3.end());
|
||||
|
||||
std::forward_list<ItemNDCNode> compare0(merge_data0.begin(), merge_data0.end());
|
||||
std::forward_list<ItemNDCNode> compare3(merge_data3.begin(), merge_data3.end());
|
||||
|
||||
data0.merge(data3);
|
||||
compare0.merge(compare3);
|
||||
|
||||
are_equal = std::equal(data0.begin(), data0.end(), compare0.begin());
|
||||
CHECK(are_equal);
|
||||
|
||||
CHECK_EQUAL(std::distance(compare0.begin(), compare0.end()), data0.size());
|
||||
CHECK_EQUAL(std::distance(compare3.begin(), compare3.end()), data3.size());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST_FIXTURE(SetupFixture, test_merge_0_4)
|
||||
{
|
||||
bool are_equal;
|
||||
|
||||
DataNDC0 data0(merge_data0.begin(), merge_data0.end());
|
||||
DataNDC0 data4(merge_data4.begin(), merge_data4.end());
|
||||
|
||||
std::forward_list<ItemNDCNode> compare0(merge_data0.begin(), merge_data0.end());
|
||||
std::forward_list<ItemNDCNode> compare4(merge_data4.begin(), merge_data4.end());
|
||||
|
||||
data0.merge(data4);
|
||||
compare0.merge(compare4);
|
||||
|
||||
are_equal = std::equal(data0.begin(), data0.end(), compare0.begin());
|
||||
CHECK(are_equal);
|
||||
|
||||
CHECK_EQUAL(std::distance(compare0.begin(), compare0.end()), data0.size());
|
||||
CHECK_EQUAL(std::distance(compare4.begin(), compare4.end()), data4.size());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST_FIXTURE(SetupFixture, test_merge_0_1_reverse_order)
|
||||
{
|
||||
bool are_equal;
|
||||
|
||||
DataNDC0 data0(merge_data0.begin(), merge_data0.end());
|
||||
DataNDC0 data1(merge_data1.begin(), merge_data1.end());
|
||||
|
||||
data0.reverse();
|
||||
data1.reverse();
|
||||
|
||||
std::forward_list<ItemNDCNode> compare0(merge_data0.begin(), merge_data0.end());
|
||||
std::forward_list<ItemNDCNode> compare1(merge_data1.begin(), merge_data1.end());
|
||||
|
||||
compare0.reverse();
|
||||
compare1.reverse();
|
||||
|
||||
data0.merge(data1, std::greater<ItemNDCNode>());
|
||||
compare0.merge(compare1, std::greater<ItemNDCNode>());
|
||||
|
||||
are_equal = std::equal(data0.begin(), data0.end(), compare0.begin());
|
||||
CHECK(are_equal);
|
||||
|
||||
CHECK_EQUAL(std::distance(compare0.begin(), compare0.end()), data0.size());
|
||||
CHECK_EQUAL(std::distance(compare1.begin(), compare1.end()), data1.size());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@ -36,7 +36,7 @@ SOFTWARE.
|
||||
namespace
|
||||
{
|
||||
//*******************************************************
|
||||
//Forward
|
||||
// Forward
|
||||
//*******************************************************
|
||||
typedef etl::forward_link<0> FirstFLink;
|
||||
typedef etl::forward_link<1> SecondFLink;
|
||||
@ -54,7 +54,8 @@ namespace
|
||||
//*******************************************************
|
||||
// Bidirectional
|
||||
//*******************************************************
|
||||
typedef etl::bidirectional_link<0, etl::link_option::AUTO_UNLINK> FirstBLinkAuto;
|
||||
typedef etl::bidirectional_link<0, etl::link_option::AUTO> FirstBLinkAuto;
|
||||
typedef etl::bidirectional_link<0, etl::link_option::CHECKED> FirstBLinkChecked;
|
||||
typedef etl::bidirectional_link<0> FirstBLink;
|
||||
typedef etl::bidirectional_link<1> SecondBLink;
|
||||
|
||||
@ -78,11 +79,22 @@ namespace
|
||||
int value;
|
||||
};
|
||||
|
||||
struct BDataChecked : public FirstBLinkChecked
|
||||
{
|
||||
BDataChecked(int value)
|
||||
: value(value)
|
||||
{
|
||||
}
|
||||
|
||||
int value;
|
||||
};
|
||||
|
||||
//*******************************************************
|
||||
// Tree
|
||||
//*******************************************************
|
||||
typedef etl::tree_link<0> FirstTLink;
|
||||
typedef etl::tree_link<1> SecondTLink;
|
||||
typedef etl::tree_link<2> ThirdTLink;
|
||||
|
||||
struct TData : public FirstTLink, public SecondTLink
|
||||
{
|
||||
@ -94,6 +106,19 @@ namespace
|
||||
int value;
|
||||
};
|
||||
|
||||
//*******************************************************
|
||||
// Mixed
|
||||
//*******************************************************
|
||||
struct MData : public FirstFLink, public SecondBLink, public ThirdTLink
|
||||
{
|
||||
MData(int value)
|
||||
: value(value)
|
||||
{
|
||||
}
|
||||
|
||||
int value;
|
||||
};
|
||||
|
||||
SUITE(test_forward_list)
|
||||
{
|
||||
//*************************************************************************
|
||||
@ -137,8 +162,138 @@ namespace
|
||||
CHECK(data2.SecondFLink::etl_next == &data1);
|
||||
CHECK(data1.SecondFLink::etl_next == &data0);
|
||||
CHECK(data0.SecondFLink::etl_next == nullptr);
|
||||
|
||||
FData* pdata;
|
||||
|
||||
pdata = static_cast<FData*>(data0.FirstFLink::etl_next);
|
||||
CHECK_EQUAL(1, pdata->value);
|
||||
pdata = static_cast<FData*>(pdata->FirstFLink::etl_next);
|
||||
CHECK_EQUAL(2, pdata->value);
|
||||
pdata = static_cast<FData*>(pdata->FirstFLink::etl_next);
|
||||
CHECK_EQUAL(3, pdata->value);
|
||||
|
||||
pdata = static_cast<FData*>(data3.SecondFLink::etl_next);
|
||||
CHECK_EQUAL(2, pdata->value);
|
||||
pdata = static_cast<FData*>(pdata->SecondFLink::etl_next);
|
||||
CHECK_EQUAL(1, pdata->value);
|
||||
pdata = static_cast<FData*>(pdata->SecondFLink::etl_next);
|
||||
CHECK_EQUAL(0, pdata->value);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_link_splice_forward_link)
|
||||
{
|
||||
FData data0(0);
|
||||
FData data1(1);
|
||||
FData data2(2);
|
||||
FData data3(3);
|
||||
|
||||
data0.FirstFLink::clear();
|
||||
etl::link_splice<FirstFLink>(data0, data1);
|
||||
CHECK(data0.FirstFLink::etl_next == &data1);
|
||||
CHECK(data1.FirstFLink::etl_next == nullptr);
|
||||
|
||||
data0.FirstFLink::clear();
|
||||
etl::link_splice<FirstFLink>(data0, &data1);
|
||||
CHECK(data0.FirstFLink::etl_next == &data1);
|
||||
CHECK(data1.FirstFLink::etl_next == nullptr);
|
||||
|
||||
data0.FirstFLink::clear();
|
||||
etl::link_splice<FirstFLink>(&data0, data1);
|
||||
CHECK(data0.FirstFLink::etl_next == &data1);
|
||||
CHECK(data1.FirstFLink::etl_next == nullptr);
|
||||
|
||||
data0.FirstFLink::clear();
|
||||
etl::link_splice<FirstFLink>(&data0, &data1);
|
||||
CHECK(data0.FirstFLink::etl_next == &data1);
|
||||
CHECK(data1.FirstFLink::etl_next == nullptr);
|
||||
|
||||
data0.FirstFLink::clear();
|
||||
etl::link_splice<FirstFLink>(data0, data3);
|
||||
etl::link_splice<FirstFLink>(data0, data1);
|
||||
etl::link_splice<FirstFLink>(data1, data2);
|
||||
|
||||
CHECK(data0.FirstFLink::etl_next == &data1);
|
||||
CHECK(data1.FirstFLink::etl_next == &data2);
|
||||
CHECK(data2.FirstFLink::etl_next == &data3);
|
||||
CHECK(data3.FirstFLink::etl_next == nullptr);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_link_splice_forward_link_range)
|
||||
{
|
||||
FData data0(0);
|
||||
FData data1(1);
|
||||
FData data2(2);
|
||||
FData data3(3);
|
||||
FData data4(4);
|
||||
FData data5(5);
|
||||
FData data6(6);
|
||||
FData data7(7);
|
||||
|
||||
// First range.
|
||||
data0.FirstFLink::clear();
|
||||
etl::link_splice<FirstFLink>(data0, data1);
|
||||
etl::link_splice<FirstFLink>(data1, data6);
|
||||
etl::link_splice<FirstFLink>(data6, data7);
|
||||
|
||||
// Second range.
|
||||
data2.FirstFLink::clear();
|
||||
etl::link_splice<FirstFLink>(data2, data3);
|
||||
etl::link_splice<FirstFLink>(data3, data4);
|
||||
etl::link_splice<FirstFLink>(data4, data5);
|
||||
|
||||
etl::link_splice<FirstFLink>(data1, data2, data5);
|
||||
|
||||
CHECK(data0.FirstFLink::etl_next == &data1);
|
||||
CHECK(data1.FirstFLink::etl_next == &data2);
|
||||
CHECK(data2.FirstFLink::etl_next == &data3);
|
||||
CHECK(data3.FirstFLink::etl_next == &data4);
|
||||
CHECK(data4.FirstFLink::etl_next == &data5);
|
||||
CHECK(data5.FirstFLink::etl_next == &data6);
|
||||
CHECK(data6.FirstFLink::etl_next == &data7);
|
||||
CHECK(data7.FirstFLink::etl_next == nullptr);
|
||||
|
||||
// Do it again with a pointer.
|
||||
// First range.
|
||||
data0.FirstFLink::clear();
|
||||
etl::link_splice<FirstFLink>(data0, data1);
|
||||
etl::link_splice<FirstFLink>(data1, data6);
|
||||
etl::link_splice<FirstFLink>(data6, data7);
|
||||
|
||||
// Second range.
|
||||
data2.FirstFLink::clear();
|
||||
etl::link_splice<FirstFLink>(data2, data3);
|
||||
etl::link_splice<FirstFLink>(data3, data4);
|
||||
etl::link_splice<FirstFLink>(data4, data5);
|
||||
|
||||
etl::link_splice<FirstFLink>(&data1, data2, data5);
|
||||
|
||||
CHECK(data0.FirstFLink::etl_next == &data1);
|
||||
CHECK(data1.FirstFLink::etl_next == &data2);
|
||||
CHECK(data2.FirstFLink::etl_next == &data3);
|
||||
CHECK(data3.FirstFLink::etl_next == &data4);
|
||||
CHECK(data4.FirstFLink::etl_next == &data5);
|
||||
CHECK(data5.FirstFLink::etl_next == &data6);
|
||||
CHECK(data6.FirstFLink::etl_next == &data7);
|
||||
CHECK(data7.FirstFLink::etl_next == nullptr);
|
||||
|
||||
// Do it again with a nullptr pointer.
|
||||
// Second range.
|
||||
data2.FirstFLink::clear();
|
||||
etl::link_splice<FirstFLink>(data2, data3);
|
||||
etl::link_splice<FirstFLink>(data3, data4);
|
||||
etl::link_splice<FirstFLink>(data4, data5);
|
||||
|
||||
etl::link_splice<FirstFLink>(nullptr, data2, data5);
|
||||
|
||||
CHECK(data2.FirstFLink::etl_next == &data3);
|
||||
CHECK(data3.FirstFLink::etl_next == &data4);
|
||||
CHECK(data4.FirstFLink::etl_next == &data5);
|
||||
CHECK(data5.FirstFLink::etl_next == nullptr);
|
||||
}
|
||||
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_unlink_after_forward_link)
|
||||
{
|
||||
@ -194,6 +349,39 @@ namespace
|
||||
CHECK(data0.SecondFLink::etl_next == nullptr);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_unlink_after_range_forward_link)
|
||||
{
|
||||
FData data0(0);
|
||||
FData data1(1);
|
||||
FData data2(2);
|
||||
FData data3(3);
|
||||
|
||||
etl::link<FirstFLink>(data0, data1);
|
||||
etl::link<FirstFLink>(data1, data2);
|
||||
etl::link<FirstFLink>(data2, data3);
|
||||
etl::link<FirstFLink>(data3, nullptr);
|
||||
|
||||
etl::link<SecondFLink>(data3, data2);
|
||||
etl::link<SecondFLink>(data2, data1);
|
||||
etl::link<SecondFLink>(data1, data0);
|
||||
etl::link<SecondFLink>(data0, nullptr);
|
||||
|
||||
etl::unlink_after<FirstFLink>(data0, data2);
|
||||
data1.FirstFLink::clear();
|
||||
data2.FirstFLink::clear();
|
||||
|
||||
CHECK(data0.FirstFLink::etl_next == &data3);
|
||||
CHECK(data1.FirstFLink::etl_next == nullptr);
|
||||
CHECK(data2.FirstFLink::etl_next == nullptr);
|
||||
CHECK(data3.FirstFLink::etl_next == nullptr);
|
||||
|
||||
CHECK(data3.SecondFLink::etl_next == &data2);
|
||||
CHECK(data2.SecondFLink::etl_next == &data1);
|
||||
CHECK(data1.SecondFLink::etl_next == &data0);
|
||||
CHECK(data0.SecondFLink::etl_next == nullptr);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_self_link_forward_link)
|
||||
{
|
||||
@ -245,11 +433,12 @@ namespace
|
||||
etl::link<FirstBLinkAuto>(data3, nullptr);
|
||||
|
||||
CHECK(data0->FirstBLinkAuto::etl_previous == nullptr);
|
||||
CHECK(data1->FirstBLinkAuto::etl_next == data2);
|
||||
CHECK(data1->FirstBLinkAuto::etl_previous == data0);
|
||||
CHECK(data1->FirstBLinkAuto::etl_next == data2);
|
||||
CHECK(data2->FirstBLinkAuto::etl_previous == data1);
|
||||
CHECK(data2->FirstBLinkAuto::etl_next == data3);
|
||||
CHECK(data2->FirstBLinkAuto::etl_next == data3);
|
||||
CHECK(data3->FirstBLinkAuto::etl_previous == data2);
|
||||
CHECK(data3->FirstBLinkAuto::etl_next == nullptr);
|
||||
CHECK(data3->FirstBLinkAuto::etl_next == nullptr);
|
||||
|
||||
etl::link<SecondBLink>(nullptr, data3);
|
||||
etl::link<SecondBLink>(data3, data2);
|
||||
@ -266,6 +455,37 @@ namespace
|
||||
CHECK(data0->SecondBLink::etl_previous == data1);
|
||||
CHECK(data0->SecondBLink::etl_next == nullptr);
|
||||
|
||||
BDataAuto* pdataauto;
|
||||
BData* pdata;
|
||||
|
||||
pdataauto = static_cast<BDataAuto*>(data0->FirstBLinkAuto::etl_next);
|
||||
CHECK_EQUAL(1, pdataauto->value);
|
||||
pdataauto = static_cast<BDataAuto*>(pdataauto->FirstBLinkAuto::etl_next);
|
||||
CHECK_EQUAL(2, pdataauto->value);
|
||||
pdataauto = static_cast<BDataAuto*>(pdataauto->FirstBLinkAuto::etl_next);
|
||||
CHECK_EQUAL(3, pdataauto->value);
|
||||
|
||||
pdataauto = static_cast<BDataAuto*>(data3->FirstBLinkAuto::etl_previous);
|
||||
CHECK_EQUAL(2, pdataauto->value);
|
||||
pdataauto = static_cast<BDataAuto*>(pdataauto->FirstBLinkAuto::etl_previous);
|
||||
CHECK_EQUAL(1, pdataauto->value);
|
||||
pdataauto = static_cast<BDataAuto*>(pdataauto->FirstBLinkAuto::etl_previous);
|
||||
CHECK_EQUAL(0, pdataauto->value);
|
||||
|
||||
pdata = static_cast<BData*>(data3->SecondBLink::etl_next);
|
||||
CHECK_EQUAL(2, pdata->value);
|
||||
pdata = static_cast<BData*>(pdata->SecondBLink::etl_next);
|
||||
CHECK_EQUAL(1, pdata->value);
|
||||
pdata = static_cast<BData*>(pdata->SecondBLink::etl_next);
|
||||
CHECK_EQUAL(0, pdata->value);
|
||||
|
||||
pdata = static_cast<BData*>(data0->SecondBLink::etl_previous);
|
||||
CHECK_EQUAL(1, pdata->value);
|
||||
pdata = static_cast<BData*>(pdata->SecondBLink::etl_previous);
|
||||
CHECK_EQUAL(2, pdata->value);
|
||||
pdata = static_cast<BData*>(pdata->SecondBLink::etl_previous);
|
||||
CHECK_EQUAL(3, pdata->value);
|
||||
|
||||
delete data1;
|
||||
CHECK(data0->FirstBLinkAuto::etl_next == data2);
|
||||
CHECK(data2->FirstBLinkAuto::etl_previous == data0);
|
||||
@ -297,6 +517,181 @@ namespace
|
||||
delete data2;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_link_splice_bidirectional_link)
|
||||
{
|
||||
BData data0(0);
|
||||
BData data1(1);
|
||||
BData data2(2);
|
||||
BData data3(3);
|
||||
|
||||
data0.FirstBLink::clear();
|
||||
etl::link_splice<FirstBLink>(nullptr, data0);
|
||||
|
||||
etl::link_splice<FirstBLink>(data0, data1);
|
||||
CHECK(data0.FirstBLink::etl_next == &data1);
|
||||
CHECK(data1.FirstBLink::etl_previous == &data0);
|
||||
CHECK(data1.FirstBLink::etl_next == nullptr);
|
||||
|
||||
data0.FirstBLink::clear();
|
||||
etl::link_splice<FirstBLink>(nullptr, data0);
|
||||
|
||||
etl::link_splice<FirstBLink>(data0, &data1);
|
||||
CHECK(data0.FirstBLink::etl_next == &data1);
|
||||
CHECK(data1.FirstBLink::etl_previous == &data0);
|
||||
CHECK(data1.FirstBLink::etl_next == nullptr);
|
||||
|
||||
data0.FirstBLink::clear();
|
||||
etl::link_splice<FirstBLink>(nullptr, data0);
|
||||
|
||||
etl::link_splice<FirstBLink>(&data0, data1);
|
||||
CHECK(data0.FirstBLink::etl_next == &data1);
|
||||
CHECK(data1.FirstBLink::etl_previous == &data0);
|
||||
CHECK(data1.FirstBLink::etl_next == nullptr);
|
||||
|
||||
data0.FirstBLink::clear();
|
||||
etl::link_splice<FirstBLink>(nullptr, data0);
|
||||
|
||||
etl::link_splice<FirstBLink>(&data0, &data1);
|
||||
CHECK(data0.FirstBLink::etl_next == &data1);
|
||||
CHECK(data1.FirstBLink::etl_previous == &data0);
|
||||
CHECK(data1.FirstBLink::etl_next == nullptr);
|
||||
|
||||
data0.FirstBLink::clear();
|
||||
etl::link_splice<FirstBLink>(nullptr, data0);
|
||||
etl::link_splice<FirstBLink>(data0, data3);
|
||||
etl::link_splice<FirstBLink>(data0, data1);
|
||||
etl::link_splice<FirstBLink>(data1, data2);
|
||||
|
||||
CHECK(data0.FirstBLink::etl_previous == nullptr);
|
||||
CHECK(data0.FirstBLink::etl_next == &data1);
|
||||
CHECK(data1.FirstBLink::etl_previous == &data0);
|
||||
CHECK(data1.FirstBLink::etl_next == &data2);
|
||||
CHECK(data2.FirstBLink::etl_previous == &data1);
|
||||
CHECK(data2.FirstBLink::etl_next == &data3);
|
||||
CHECK(data3.FirstBLink::etl_previous == &data2);
|
||||
CHECK(data3.FirstBLink::etl_next == nullptr);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_link_splice_range_bidirectional_link)
|
||||
{
|
||||
BData data0(0);
|
||||
BData data1(1);
|
||||
BData data2(2);
|
||||
BData data3(3);
|
||||
BData data4(4);
|
||||
BData data5(5);
|
||||
BData data6(6);
|
||||
BData data7(7);
|
||||
|
||||
// Build the first range.
|
||||
data0.FirstBLink::clear();
|
||||
etl::link_splice<FirstBLink>(nullptr, data0);
|
||||
etl::link_splice<FirstBLink>(data0, data1);
|
||||
etl::link_splice<FirstBLink>(data1, data6);
|
||||
etl::link_splice<FirstBLink>(data6, data7);
|
||||
|
||||
// Build the second range.
|
||||
data2.FirstBLink::clear();
|
||||
etl::link_splice<FirstBLink>(nullptr, data2);
|
||||
etl::link_splice<FirstBLink>(data2, data3);
|
||||
etl::link_splice<FirstBLink>(data3, data4);
|
||||
etl::link_splice<FirstBLink>(data4, data5);
|
||||
|
||||
etl::link_splice<FirstBLink>(data1, data2, data5);
|
||||
|
||||
CHECK(data0.FirstBLink::etl_previous == nullptr);
|
||||
CHECK(data0.FirstBLink::etl_next == &data1);
|
||||
CHECK(data1.FirstBLink::etl_previous == &data0);
|
||||
CHECK(data1.FirstBLink::etl_next == &data2);
|
||||
CHECK(data2.FirstBLink::etl_previous == &data1);
|
||||
CHECK(data2.FirstBLink::etl_next == &data3);
|
||||
CHECK(data3.FirstBLink::etl_previous == &data2);
|
||||
CHECK(data3.FirstBLink::etl_next == &data4);
|
||||
CHECK(data4.FirstBLink::etl_previous == &data3);
|
||||
CHECK(data4.FirstBLink::etl_next == &data5);
|
||||
CHECK(data5.FirstBLink::etl_previous == &data4);
|
||||
CHECK(data5.FirstBLink::etl_next == &data6);
|
||||
CHECK(data6.FirstBLink::etl_previous == &data5);
|
||||
CHECK(data6.FirstBLink::etl_next == &data7);
|
||||
CHECK(data7.FirstBLink::etl_previous == &data6);
|
||||
CHECK(data7.FirstBLink::etl_next == nullptr);
|
||||
|
||||
// Do it again with a pointer parameter.
|
||||
// Build the first range.
|
||||
data0.FirstBLink::clear();
|
||||
etl::link_splice<FirstBLink>(nullptr, data0);
|
||||
etl::link_splice<FirstBLink>(data0, data1);
|
||||
etl::link_splice<FirstBLink>(data1, data6);
|
||||
etl::link_splice<FirstBLink>(data6, data7);
|
||||
|
||||
// Build the second range.
|
||||
data2.FirstBLink::clear();
|
||||
etl::link_splice<FirstBLink>(nullptr, data2);
|
||||
etl::link_splice<FirstBLink>(data2, data3);
|
||||
etl::link_splice<FirstBLink>(data3, data4);
|
||||
etl::link_splice<FirstBLink>(data4, data5);
|
||||
|
||||
etl::link_splice<FirstBLink>(&data1, data2, data5);
|
||||
|
||||
CHECK(data0.FirstBLink::etl_previous == nullptr);
|
||||
CHECK(data0.FirstBLink::etl_next == &data1);
|
||||
CHECK(data1.FirstBLink::etl_previous == &data0);
|
||||
CHECK(data1.FirstBLink::etl_next == &data2);
|
||||
CHECK(data2.FirstBLink::etl_previous == &data1);
|
||||
CHECK(data2.FirstBLink::etl_next == &data3);
|
||||
CHECK(data3.FirstBLink::etl_previous == &data2);
|
||||
CHECK(data3.FirstBLink::etl_next == &data4);
|
||||
CHECK(data4.FirstBLink::etl_previous == &data3);
|
||||
CHECK(data4.FirstBLink::etl_next == &data5);
|
||||
CHECK(data5.FirstBLink::etl_previous == &data4);
|
||||
CHECK(data5.FirstBLink::etl_next == &data6);
|
||||
CHECK(data6.FirstBLink::etl_previous == &data5);
|
||||
CHECK(data6.FirstBLink::etl_next == &data7);
|
||||
CHECK(data7.FirstBLink::etl_previous == &data6);
|
||||
CHECK(data7.FirstBLink::etl_next == nullptr);
|
||||
|
||||
// Do it again with a nullptr parameter.
|
||||
// Build the range.
|
||||
data2.FirstBLink::clear();
|
||||
etl::link_splice<FirstBLink>(nullptr, data2);
|
||||
etl::link_splice<FirstBLink>(data2, data3);
|
||||
etl::link_splice<FirstBLink>(data3, data4);
|
||||
etl::link_splice<FirstBLink>(data4, data5);
|
||||
|
||||
etl::link_splice<FirstBLink>(nullptr, data2, data5);
|
||||
|
||||
CHECK(data2.FirstBLink::etl_previous == nullptr);
|
||||
CHECK(data2.FirstBLink::etl_next == &data3);
|
||||
CHECK(data3.FirstBLink::etl_previous == &data2);
|
||||
CHECK(data3.FirstBLink::etl_next == &data4);
|
||||
CHECK(data4.FirstBLink::etl_previous == &data3);
|
||||
CHECK(data4.FirstBLink::etl_next == &data5);
|
||||
CHECK(data5.FirstBLink::etl_previous == &data4);
|
||||
CHECK(data5.FirstBLink::etl_next == nullptr);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_link_bidirectional_link_checked)
|
||||
{
|
||||
// FirstBLinkAuto is auto-unlink
|
||||
|
||||
BDataChecked* data0 = new BDataChecked(0);
|
||||
BDataChecked* data1 = new BDataChecked(1);
|
||||
BDataChecked* data2 = new BDataChecked(2);
|
||||
BDataChecked* data3 = new BDataChecked(3);
|
||||
|
||||
etl::link<FirstBLinkChecked>(nullptr, data0);
|
||||
etl::link<FirstBLinkChecked>(data0, data1);
|
||||
etl::link<FirstBLinkChecked>(data1, data2);
|
||||
etl::link<FirstBLinkChecked>(data2, data3);
|
||||
etl::link<FirstBLinkChecked>(data3, nullptr);
|
||||
|
||||
data2->FirstBLinkChecked::clear();
|
||||
CHECK_NO_THROW(delete data2);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_unlink_bidirectional_link)
|
||||
{
|
||||
@ -402,6 +797,49 @@ namespace
|
||||
CHECK(data0.SecondBLink::etl_next == nullptr);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_unlink_range_bidirectional_link)
|
||||
{
|
||||
BData data0(0);
|
||||
BData data1(1);
|
||||
BData data2(2);
|
||||
BData data3(3);
|
||||
|
||||
etl::link<FirstBLink>(nullptr, data0);
|
||||
etl::link<FirstBLink>(data0, data1);
|
||||
etl::link<FirstBLink>(data1, data2);
|
||||
etl::link<FirstBLink>(data2, data3);
|
||||
etl::link<FirstBLink>(data3, nullptr);
|
||||
|
||||
etl::link<SecondBLink>(nullptr, data3);
|
||||
etl::link<SecondBLink>(data3, data2);
|
||||
etl::link<SecondBLink>(data2, data1);
|
||||
etl::link<SecondBLink>(data1, data0);
|
||||
etl::link<SecondBLink>(data0, nullptr);
|
||||
|
||||
etl::unlink<FirstBLink>(data1, data2);
|
||||
data1.FirstBLink::clear();
|
||||
data2.FirstBLink::clear();
|
||||
|
||||
CHECK(data0.FirstBLink::etl_previous == nullptr);
|
||||
CHECK(data0.FirstBLink::etl_next == &data3);
|
||||
CHECK(data1.FirstBLink::etl_previous == nullptr);
|
||||
CHECK(data1.FirstBLink::etl_next == nullptr);
|
||||
CHECK(data2.FirstBLink::etl_previous == nullptr);
|
||||
CHECK(data2.FirstBLink::etl_next == nullptr);
|
||||
CHECK(data3.FirstBLink::etl_previous == &data0);
|
||||
CHECK(data3.FirstBLink::etl_next == nullptr);
|
||||
|
||||
CHECK(data3.SecondBLink::etl_previous == nullptr);
|
||||
CHECK(data3.SecondBLink::etl_next == &data2);
|
||||
CHECK(data2.SecondBLink::etl_previous == &data3);
|
||||
CHECK(data2.SecondBLink::etl_next == &data1);
|
||||
CHECK(data1.SecondBLink::etl_previous == &data2);
|
||||
CHECK(data1.SecondBLink::etl_next == &data0);
|
||||
CHECK(data0.SecondBLink::etl_previous == &data1);
|
||||
CHECK(data0.SecondBLink::etl_next == nullptr);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_self_link_bidirectional_link)
|
||||
{
|
||||
@ -539,5 +977,137 @@ namespace
|
||||
CHECK(data3.SecondTLink::etl_left == nullptr);
|
||||
CHECK(data3.SecondTLink::etl_right == nullptr);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_is_linked)
|
||||
{
|
||||
// Forward link
|
||||
FData fdata(0);
|
||||
|
||||
fdata.FirstFLink::clear();
|
||||
fdata.SecondFLink::clear();
|
||||
CHECK(!fdata.FirstFLink::is_linked());
|
||||
CHECK(!fdata.SecondFLink::is_linked());
|
||||
|
||||
etl::link<FirstFLink>(fdata, fdata);
|
||||
CHECK(fdata.FirstFLink::is_linked());
|
||||
CHECK(!fdata.SecondFLink::is_linked());
|
||||
|
||||
etl::link<SecondFLink>(fdata, fdata);
|
||||
CHECK(fdata.FirstFLink::is_linked());
|
||||
CHECK(fdata.SecondFLink::is_linked());
|
||||
|
||||
// Bidirectional link
|
||||
BData bdata(0);
|
||||
|
||||
bdata.FirstBLink::clear();
|
||||
bdata.SecondBLink::clear();
|
||||
CHECK(!bdata.FirstBLink::is_linked());
|
||||
CHECK(!bdata.SecondBLink::is_linked());
|
||||
|
||||
etl::link<FirstBLink>(bdata, bdata);
|
||||
CHECK(bdata.FirstBLink::is_linked());
|
||||
CHECK(!bdata.SecondBLink::is_linked());
|
||||
|
||||
etl::link<SecondBLink>(bdata, bdata);
|
||||
CHECK(bdata.FirstBLink::is_linked());
|
||||
CHECK(bdata.SecondBLink::is_linked());
|
||||
|
||||
// Tree link
|
||||
TData tdata(0);
|
||||
|
||||
tdata.FirstTLink::clear();
|
||||
tdata.SecondTLink::clear();
|
||||
CHECK(!tdata.FirstTLink::is_linked());
|
||||
CHECK(!tdata.SecondTLink::is_linked());
|
||||
|
||||
etl::link_left<FirstTLink>(tdata, tdata);
|
||||
CHECK(tdata.FirstTLink::is_linked());
|
||||
CHECK(!tdata.SecondTLink::is_linked());
|
||||
|
||||
etl::link_right<SecondTLink>(tdata, tdata);
|
||||
CHECK(tdata.FirstTLink::is_linked());
|
||||
CHECK(tdata.SecondTLink::is_linked());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_link_mixed_links)
|
||||
{
|
||||
MData data0(0);
|
||||
MData data1(1);
|
||||
MData data2(2);
|
||||
MData data3(3);
|
||||
MData data4(4);
|
||||
MData data5(5);
|
||||
MData data6(6);
|
||||
|
||||
// Forward
|
||||
data0.FirstFLink::clear();
|
||||
etl::link<FirstFLink>(data0, data1);
|
||||
etl::link<FirstFLink>(data1, data2);
|
||||
etl::link<FirstFLink>(data2, data3);
|
||||
etl::link<FirstFLink>(data3, nullptr);
|
||||
|
||||
// Bidirectional
|
||||
etl::link<SecondBLink>(nullptr, data3);
|
||||
etl::link<SecondBLink>(data3, data2);
|
||||
etl::link<SecondBLink>(data2, data1);
|
||||
etl::link<SecondBLink>(data1, data0);
|
||||
etl::link<SecondBLink>(data0, nullptr);
|
||||
|
||||
// Tree
|
||||
data0.ThirdTLink::clear();
|
||||
etl::link_left<ThirdTLink>(data0, data1);
|
||||
etl::link_right<ThirdTLink>(data0, data2);
|
||||
etl::link_left<ThirdTLink>(data1, data3);
|
||||
etl::link_right<ThirdTLink>(data1, data4);
|
||||
etl::link_left<ThirdTLink>(data3, nullptr);
|
||||
etl::link_right<ThirdTLink>(data3, nullptr);
|
||||
etl::link_left<ThirdTLink>(data4, nullptr);
|
||||
etl::link_right<ThirdTLink>(data4, nullptr);
|
||||
etl::link_left<ThirdTLink>(data2, data5);
|
||||
etl::link_right<ThirdTLink>(data2, data6);
|
||||
etl::link_left<ThirdTLink>(data5, nullptr);
|
||||
etl::link_right<ThirdTLink>(data5, nullptr);
|
||||
etl::link_left<ThirdTLink>(data6, nullptr);
|
||||
etl::link_right<ThirdTLink>(data6, nullptr);
|
||||
|
||||
CHECK(data0.FirstFLink::etl_next == &data1);
|
||||
CHECK(data1.FirstFLink::etl_next == &data2);
|
||||
CHECK(data2.FirstFLink::etl_next == &data3);
|
||||
CHECK(data3.FirstFLink::etl_next == nullptr);
|
||||
|
||||
CHECK(data3.SecondBLink::etl_previous == nullptr);
|
||||
CHECK(data3.SecondBLink::etl_next == &data2);
|
||||
CHECK(data2.SecondBLink::etl_previous == &data3);
|
||||
CHECK(data2.SecondBLink::etl_next == &data1);
|
||||
CHECK(data1.SecondBLink::etl_previous == &data2);
|
||||
CHECK(data1.SecondBLink::etl_next == &data0);
|
||||
CHECK(data0.SecondBLink::etl_previous == &data1);
|
||||
CHECK(data0.SecondBLink::etl_next == nullptr);
|
||||
|
||||
CHECK(data0.ThirdTLink::etl_left == &data1);
|
||||
CHECK(data0.ThirdTLink::etl_right == &data2);
|
||||
CHECK(data1.ThirdTLink::etl_parent == &data0);
|
||||
CHECK(data2.ThirdTLink::etl_parent == &data0);
|
||||
|
||||
CHECK(data1.ThirdTLink::etl_left == &data3);
|
||||
CHECK(data1.ThirdTLink::etl_right == &data4);
|
||||
CHECK(data3.ThirdTLink::etl_parent == &data1);
|
||||
CHECK(data3.ThirdTLink::etl_left == nullptr);
|
||||
CHECK(data3.ThirdTLink::etl_right == nullptr);
|
||||
CHECK(data4.ThirdTLink::etl_parent == &data1);
|
||||
CHECK(data4.ThirdTLink::etl_left == nullptr);
|
||||
CHECK(data4.ThirdTLink::etl_right == nullptr);
|
||||
|
||||
CHECK(data2.ThirdTLink::etl_left == &data5);
|
||||
CHECK(data2.ThirdTLink::etl_right == &data6);
|
||||
CHECK(data5.ThirdTLink::etl_parent == &data2);
|
||||
CHECK(data5.ThirdTLink::etl_left == nullptr);
|
||||
CHECK(data5.ThirdTLink::etl_right == nullptr);
|
||||
CHECK(data6.ThirdTLink::etl_parent == &data2);
|
||||
CHECK(data6.ThirdTLink::etl_left == nullptr);
|
||||
CHECK(data6.ThirdTLink::etl_right == nullptr);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
1098
test/test_intrusive_list.cpp
Normal file
1098
test/test_intrusive_list.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -7,10 +7,13 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "etl", "etl.vcxproj", "{C21D
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug No Unit Tests|Win32 = Debug No Unit Tests|Win32
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug No Unit Tests|Win32.ActiveCfg = Debug No Unit Tests|Win32
|
||||
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug No Unit Tests|Win32.Build.0 = Debug No Unit Tests|Win32
|
||||
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Release|Win32.ActiveCfg = Release|Win32
|
||||
|
||||
@ -160,7 +160,6 @@
|
||||
<ClInclude Include="..\..\binary.h" />
|
||||
<ClInclude Include="..\..\bitset.h" />
|
||||
<ClInclude Include="..\..\bloom_filter.h" />
|
||||
<ClInclude Include="..\..\bsd_checksum.h" />
|
||||
<ClInclude Include="..\..\char_traits.h" />
|
||||
<ClInclude Include="..\..\checksum.h" />
|
||||
<ClInclude Include="..\..\crc16.h" />
|
||||
@ -206,6 +205,7 @@
|
||||
<ClInclude Include="..\..\integral_limits.h" />
|
||||
<ClInclude Include="..\..\intrusive_forward_list.h" />
|
||||
<ClInclude Include="..\..\intrusive_links.h" />
|
||||
<ClInclude Include="..\..\intrusive_list.h" />
|
||||
<ClInclude Include="..\..\io_port.h" />
|
||||
<ClInclude Include="..\..\ipool.h" />
|
||||
<ClInclude Include="..\..\ipriority_queue.h" />
|
||||
@ -338,6 +338,7 @@
|
||||
<ClCompile Include="..\test_integral_limits.cpp" />
|
||||
<ClCompile Include="..\test_intrusive_forward_list.cpp" />
|
||||
<ClCompile Include="..\test_intrusive_links.cpp" />
|
||||
<ClCompile Include="..\test_intrusive_list.cpp" />
|
||||
<ClCompile Include="..\test_io_port.cpp" />
|
||||
<ClCompile Include="..\test_jenkins.cpp" />
|
||||
<ClCompile Include="..\test_largest.cpp" />
|
||||
@ -369,6 +370,7 @@
|
||||
<ClCompile Include="..\test_variant.cpp" />
|
||||
<ClCompile Include="..\test_vector.cpp" />
|
||||
<ClCompile Include="..\test_visitor.cpp" />
|
||||
<ClCompile Include="..\test_xor_checksum.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\..\Doxyfile" />
|
||||
|
||||
@ -372,9 +372,6 @@
|
||||
<ClInclude Include="..\..\pearson.h">
|
||||
<Filter>ETL\Maths</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\bsd_checksum.h">
|
||||
<Filter>ETL\Maths</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\flat_multimap.h">
|
||||
<Filter>ETL\Containers</Filter>
|
||||
</ClInclude>
|
||||
@ -465,6 +462,9 @@
|
||||
<ClInclude Include="..\..\intrusive_links.h">
|
||||
<Filter>ETL\Containers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\intrusive_list.h">
|
||||
<Filter>ETL\Containers</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\..\unittest-cpp\UnitTest++\AssertException.cpp">
|
||||
@ -713,6 +713,12 @@
|
||||
<ClCompile Include="..\test_intrusive_links.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\test_intrusive_list.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\test_xor_checksum.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\..\Doxyfile">
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user