mirror of
https://github.com/ETLCPP/etl.git
synced 2026-06-26 20:38:45 +08:00
Merge branch 'development'
This commit is contained in:
commit
e1e3e8505f
@ -33,6 +33,7 @@ SOFTWARE.
|
||||
|
||||
#include <algorithm>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "exception.h"
|
||||
#include "integral_limits.h"
|
||||
|
||||
2
ideque.h
2
ideque.h
@ -890,7 +890,6 @@ namespace etl
|
||||
// Are we closer to the front?
|
||||
if (distance(_begin, insert_position) < difference_type(current_size / 2))
|
||||
{
|
||||
size_t insert_index = std::distance(begin(), position);
|
||||
size_t n_insert = n;
|
||||
size_t n_move = std::distance(begin(), position);
|
||||
size_t n_create_copy = std::min(n_insert, n_move);
|
||||
@ -922,7 +921,6 @@ namespace etl
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t insert_index = std::distance(begin(), position);
|
||||
size_t n_insert = n;
|
||||
size_t n_move = std::distance(position, end());
|
||||
size_t n_create_copy = std::min(n_insert, n_move);
|
||||
|
||||
@ -573,6 +573,68 @@ namespace etl
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Erases the value at the specified position.
|
||||
//*************************************************************************
|
||||
void move_after(const_iterator from_before, const_iterator to_before)
|
||||
{
|
||||
if (from_before == to_before) // Can't more to after yourself!
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Node* p_from_before = const_cast<Node*>(from_before.p_node); // We're not changing the value, just it's position.
|
||||
Node* p_to_before = const_cast<Node*>(to_before.p_node); // We're not changing the value, just it's position.
|
||||
|
||||
Node* p_from = p_from_before->next;
|
||||
|
||||
// Disconnect from the list.
|
||||
join(p_from_before, p_from->next);
|
||||
|
||||
// Attach it to the new position.
|
||||
join(p_from, p_to_before->next);
|
||||
join(p_to_before, p_from);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Moves a range from one position to another within the list.
|
||||
/// Moves a range at position 'first_before'/'last' to the position before 'to_before'.
|
||||
//*************************************************************************
|
||||
void move_after(const_iterator first_before, const_iterator last, const_iterator to_before)
|
||||
{
|
||||
if ((first_before == to_before) || (last == to_before))
|
||||
{
|
||||
return; // Can't more to before yourself!
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
// Check that we are not doing an illegal move!
|
||||
for (const_iterator item = first_before; item != last; ++item)
|
||||
{
|
||||
ETL_ASSERT(item != to_before, ETL_ERROR(forward_list_iterator));
|
||||
}
|
||||
#endif
|
||||
|
||||
Node* p_first_before = const_cast<Node*>(first_before.p_node); // We're not changing the value, just it's position.
|
||||
Node* p_last = const_cast<Node*>(last.p_node); // We're not changing the value, just it's position.
|
||||
Node* p_to_before = const_cast<Node*>(to_before.p_node); // We're not changing the value, just it's position.
|
||||
Node* p_first = p_first_before->next;
|
||||
Node* p_final = p_first_before;
|
||||
|
||||
// Find the last node that will be moved.
|
||||
while (p_final->next != p_last)
|
||||
{
|
||||
p_final = p_final->next;
|
||||
}
|
||||
|
||||
// Disconnect from the list.
|
||||
join(p_first_before, p_final->next);
|
||||
|
||||
// Attach it to the new position.
|
||||
join(p_final, p_to_before->next);
|
||||
join(p_to_before, p_first);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Removes all but the first element from every consecutive group of equal
|
||||
/// elements in the container.
|
||||
|
||||
54
ilist.h
54
ilist.h
@ -762,6 +762,60 @@ namespace etl
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Moves an element from one position to another within the list.
|
||||
/// Moves the element at position 'from' to the position before 'to'.
|
||||
//*************************************************************************
|
||||
void move(const_iterator from, const_iterator to)
|
||||
{
|
||||
if (from == to)
|
||||
{
|
||||
return; // Can't more to before yourself!
|
||||
}
|
||||
|
||||
Node& from_node = const_cast<Node&>(*from.p_node); // We're not changing the value, just it's position.
|
||||
Node& to_node = const_cast<Node&>(*to.p_node); // We're not changing the value, just it's position.
|
||||
|
||||
// Disconnect the node from the list.
|
||||
join(*from_node.previous, *from_node.next);
|
||||
|
||||
// Attach it to the new position.
|
||||
join(*to_node.previous, from_node);
|
||||
join(from_node, to_node);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Moves a range from one position to another within the list.
|
||||
/// Moves a range at position 'first'/'last' to the position before 'to'.
|
||||
//*************************************************************************
|
||||
void move(const_iterator first, const_iterator last, const_iterator to)
|
||||
{
|
||||
if ((first == to) || (last == to))
|
||||
{
|
||||
return; // Can't more to before yourself!
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
// Check that we are not doing an illegal move!
|
||||
for (const_iterator item = first; item != last; ++item)
|
||||
{
|
||||
ETL_ASSERT(item != to, ETL_ERROR(list_iterator));
|
||||
}
|
||||
#endif
|
||||
|
||||
Node& first_node = const_cast<Node&>(*first.p_node); // We're not changing the value, just it's position.
|
||||
Node& last_node = const_cast<Node&>(*last.p_node); // We're not changing the value, just it's position.
|
||||
Node& to_node = const_cast<Node&>(*to.p_node); // We're not changing the value, just it's position.
|
||||
Node& final_node = *last_node.previous;
|
||||
|
||||
// Disconnect the range from the list.
|
||||
join(*first_node.previous, last_node);
|
||||
|
||||
// Attach it to the new position.
|
||||
join(*to_node.previous, first_node);
|
||||
join(final_node, to_node);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Sort using in-place merge sort algorithm.
|
||||
/// Uses 'less-than operator as the predicate.
|
||||
|
||||
@ -42,7 +42,7 @@ SOFTWARE.
|
||||
|
||||
#include "nullptr.h"
|
||||
#include "type_traits.h"
|
||||
#include "intrusive_forward_list_node.h"
|
||||
#include "intrusive_forward_list_link.h"
|
||||
|
||||
namespace etl
|
||||
{
|
||||
@ -105,22 +105,23 @@ namespace etl
|
||||
//***************************************************************************
|
||||
/// An intrusive forward list.
|
||||
///\ingroup intrusive_forward_list
|
||||
///\note TLink must be a base of TValue.
|
||||
//***************************************************************************
|
||||
template <typename TValue>
|
||||
template <typename TValue, typename TLink = etl::intrusive_forward_list_link<0> >
|
||||
class intrusive_forward_list
|
||||
{
|
||||
public:
|
||||
|
||||
// Node typedef.
|
||||
typedef __private_intrusive_forward_list__::intrusive_forward_list_node_base node_t;
|
||||
typedef TLink link_type;
|
||||
|
||||
// STL style typedefs.
|
||||
typedef TValue value_type;
|
||||
typedef TValue* pointer;
|
||||
typedef const TValue* const_pointer;
|
||||
typedef TValue& reference;
|
||||
typedef const TValue& const_reference;
|
||||
typedef size_t size_type;
|
||||
typedef TValue value_type;
|
||||
typedef value_type* pointer;
|
||||
typedef const value_type* const_pointer;
|
||||
typedef value_type& reference;
|
||||
typedef const value_type& const_reference;
|
||||
typedef size_t size_type;
|
||||
|
||||
public:
|
||||
|
||||
@ -134,75 +135,74 @@ namespace etl
|
||||
friend class intrusive_forward_list;
|
||||
|
||||
iterator()
|
||||
: p_node(nullptr),
|
||||
index(0)
|
||||
: p_value(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
iterator(node_t& node, size_t index)
|
||||
: p_node(&node),
|
||||
index(index)
|
||||
iterator(value_type& value)
|
||||
: p_value(&value)
|
||||
{
|
||||
}
|
||||
|
||||
iterator(const iterator& other)
|
||||
: p_node(other.p_node),
|
||||
index(other.index)
|
||||
: p_value(other.p_value)
|
||||
{
|
||||
}
|
||||
|
||||
iterator& operator ++()
|
||||
{
|
||||
p_node = p_node->get_next(index);
|
||||
// Read the appropriate 'ifll_next'.
|
||||
p_value = static_cast<value_type*>(p_value->link_type::ifll_next);
|
||||
return *this;
|
||||
}
|
||||
|
||||
iterator operator ++(int)
|
||||
{
|
||||
iterator temp(*this);
|
||||
p_node = p_node->get_next(index);
|
||||
// Read the appropriate 'ifll_next'.
|
||||
p_value = static_cast<value_type*>(p_value->link_type::ifll_next);
|
||||
return temp;
|
||||
}
|
||||
|
||||
iterator operator =(const iterator& other)
|
||||
{
|
||||
p_node = other.p_node;
|
||||
p_value = other.p_value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
reference operator *()
|
||||
{
|
||||
return static_cast<reference>(*p_node);
|
||||
return *p_value;
|
||||
}
|
||||
|
||||
const_reference operator *() const
|
||||
{
|
||||
return static_cast<const_reference>(*p_node);
|
||||
return *p_value;
|
||||
}
|
||||
|
||||
pointer operator &()
|
||||
{
|
||||
return static_cast<pointer>(p_node);
|
||||
return p_value;
|
||||
}
|
||||
|
||||
const_pointer operator &() const
|
||||
{
|
||||
return static_cast<const_pointer>(p_node);
|
||||
return p_value;
|
||||
}
|
||||
|
||||
pointer operator ->()
|
||||
{
|
||||
return static_cast<pointer>(p_node);
|
||||
return p_value;
|
||||
}
|
||||
|
||||
const_pointer operator ->() const
|
||||
{
|
||||
return static_cast<const_pointer>(p_node);
|
||||
return p_value;
|
||||
}
|
||||
|
||||
friend bool operator == (const iterator& lhs, const iterator& rhs)
|
||||
{
|
||||
return lhs.p_node == rhs.p_node;
|
||||
return lhs.p_value == rhs.p_value;
|
||||
}
|
||||
|
||||
friend bool operator != (const iterator& lhs, const iterator& rhs)
|
||||
@ -212,8 +212,7 @@ namespace etl
|
||||
|
||||
private:
|
||||
|
||||
node_t* p_node;
|
||||
size_t index;
|
||||
value_type* p_value;
|
||||
};
|
||||
|
||||
//*************************************************************************
|
||||
@ -226,72 +225,64 @@ namespace etl
|
||||
friend class intrusive_forward_list;
|
||||
|
||||
const_iterator()
|
||||
: p_node(nullptr),
|
||||
index(0)
|
||||
: p_value(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
const_iterator(node_t& node, size_t index)
|
||||
: p_node(&node),
|
||||
index(index)
|
||||
const_iterator(const value_type& value)
|
||||
: p_value(&value)
|
||||
{
|
||||
}
|
||||
|
||||
const_iterator(const node_t& node, size_t index)
|
||||
: p_node(&node),
|
||||
index(index)
|
||||
{
|
||||
}
|
||||
|
||||
const_iterator(const typename intrusive_forward_list<TValue>::iterator& other)
|
||||
: p_node(other.p_node),
|
||||
index(other.index)
|
||||
const_iterator(const typename intrusive_forward_list<value_type, link_type>::iterator& other)
|
||||
: p_value(other.p_value)
|
||||
{
|
||||
}
|
||||
|
||||
const_iterator(const const_iterator& other)
|
||||
: p_node(other.p_node),
|
||||
index(other.index)
|
||||
: p_value(other.p_value)
|
||||
{
|
||||
}
|
||||
|
||||
const_iterator& operator ++()
|
||||
{
|
||||
p_node = p_node->get_next(index);
|
||||
// Read the appropriate 'ifll_next'.
|
||||
p_value = static_cast<value_type*>(p_value->link_type::ifll_next);
|
||||
return *this;
|
||||
}
|
||||
|
||||
const_iterator operator ++(int)
|
||||
{
|
||||
const_iterator temp(*this);
|
||||
p_node = p_node->get_next(index);
|
||||
// Read the appropriate 'ifll_next'.
|
||||
p_value = static_cast<value_type*>(p_value->link_type::ifll_next);
|
||||
return temp;
|
||||
}
|
||||
|
||||
const_iterator operator =(const const_iterator& other)
|
||||
{
|
||||
p_node = other.p_node;
|
||||
p_value = other.p_value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const_reference operator *() const
|
||||
{
|
||||
return static_cast<const_reference>(*p_node);
|
||||
return *p_value;
|
||||
}
|
||||
|
||||
const_pointer operator &() const
|
||||
{
|
||||
return static_cast<const_pointer>(p_node);
|
||||
return p_value;
|
||||
}
|
||||
|
||||
const_pointer operator ->() const
|
||||
{
|
||||
return static_cast<const_pointer>(p_node);
|
||||
return p_value;
|
||||
}
|
||||
|
||||
friend bool operator == (const const_iterator& lhs, const const_iterator& rhs)
|
||||
{
|
||||
return lhs.p_node == rhs.p_node;
|
||||
return lhs.p_value == rhs.p_value;
|
||||
}
|
||||
|
||||
friend bool operator != (const const_iterator& lhs, const const_iterator& rhs)
|
||||
@ -301,8 +292,7 @@ namespace etl
|
||||
|
||||
private:
|
||||
|
||||
const node_t* p_node;
|
||||
size_t index;
|
||||
const value_type* p_value;
|
||||
};
|
||||
|
||||
typedef typename std::iterator_traits<iterator>::difference_type difference_type;
|
||||
@ -310,8 +300,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
/// Constructor.
|
||||
//*************************************************************************
|
||||
intrusive_forward_list(size_t index)
|
||||
: index(index)
|
||||
intrusive_forward_list()
|
||||
{
|
||||
initialise();
|
||||
}
|
||||
@ -320,8 +309,7 @@ namespace etl
|
||||
/// Constructor from range
|
||||
//*************************************************************************
|
||||
template <typename TIterator>
|
||||
intrusive_forward_list(size_t index, TIterator first, TIterator last)
|
||||
: index(index)
|
||||
intrusive_forward_list(TIterator first, TIterator last)
|
||||
{
|
||||
assign(first, last);
|
||||
}
|
||||
@ -331,7 +319,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
iterator begin()
|
||||
{
|
||||
return iterator(get_head(), index);
|
||||
return iterator(static_cast<value_type&>(get_head()));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -339,7 +327,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
const_iterator begin() const
|
||||
{
|
||||
return const_iterator(get_head(), index);
|
||||
return const_iterator(static_cast<const value_type&>(get_head()));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -347,7 +335,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
iterator before_begin()
|
||||
{
|
||||
return iterator(start_node, index);
|
||||
return iterator(static_cast<value_type&>(start_link));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -355,7 +343,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
const_iterator before_begin() const
|
||||
{
|
||||
return const_iterator(start_node, index);
|
||||
return const_iterator(static_cast<const value_type&>(start_link));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -363,7 +351,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
const_iterator cbegin() const
|
||||
{
|
||||
return const_iterator(get_head(), index);
|
||||
return const_iterator(static_cast<const value_type&>(get_head()));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -403,7 +391,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
reference front()
|
||||
{
|
||||
return static_cast<reference>(get_head());
|
||||
return static_cast<value_type&>(get_head());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -411,7 +399,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
const_reference front() const
|
||||
{
|
||||
return get_head();
|
||||
return static_cast<const value_type&>(get_head());;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -428,15 +416,15 @@ namespace etl
|
||||
|
||||
initialise();
|
||||
|
||||
node_t* p_last_node = &start_node;
|
||||
link_type* p_last_link = &start_link;
|
||||
|
||||
// Add all of the elements.
|
||||
while (first != last)
|
||||
{
|
||||
node_t& node = *first++;
|
||||
join(p_last_node, &node);
|
||||
join(&node, nullptr);
|
||||
p_last_node = &node;
|
||||
link_type& link = *first++;
|
||||
join(p_last_link, &link);
|
||||
join(&link, nullptr);
|
||||
p_last_link = &link;
|
||||
++current_size;
|
||||
}
|
||||
}
|
||||
@ -444,9 +432,9 @@ namespace etl
|
||||
//*************************************************************************
|
||||
/// Pushes a value to the front of the intrusive_forward_list.
|
||||
//*************************************************************************
|
||||
void push_front(node_t& value)
|
||||
void push_front(link_type& value)
|
||||
{
|
||||
insert_node_after(start_node, value);
|
||||
insert_link_after(start_link, value);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -457,7 +445,7 @@ namespace etl
|
||||
#if defined(ETL_CHECK_PUSH_POP)
|
||||
ETL_ASSERT(!empty(), ETL_ERROR(intrusive_forward_list_empty));
|
||||
#endif
|
||||
remove_node_after(start_node);
|
||||
remove_link_after(start_link);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -470,29 +458,29 @@ namespace etl
|
||||
return;
|
||||
}
|
||||
|
||||
node_t* first = nullptr; // To keep first node
|
||||
node_t* second = start_node.get_next(index); // To keep second node
|
||||
node_t* track = start_node.get_next(index); // Track the list
|
||||
link_type* first = nullptr; // To keep first link
|
||||
link_type* second = start_link.ifll_next; // To keep second link
|
||||
link_type* track = start_link.ifll_next; // Track the list
|
||||
|
||||
while (track != NULL)
|
||||
{
|
||||
track = track->get_next(index); // Track point to next node;
|
||||
second->set_next(index, first); // Second node point to first
|
||||
first = second; // Move first node to next
|
||||
second = track; // Move second node to next
|
||||
track = track->ifll_next; // Track point to next link;
|
||||
second->ifll_next = first; // Second link point to first
|
||||
first = second; // Move first link to next
|
||||
second = track; // Move second link to next
|
||||
}
|
||||
|
||||
join(&start_node, first);
|
||||
join(&start_link, first);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Inserts a value to the intrusive_forward_list after the specified position.
|
||||
//*************************************************************************
|
||||
iterator insert_after(iterator position, node_t& value)
|
||||
iterator insert_after(iterator position, value_type& value)
|
||||
{
|
||||
insert_node_after(*position.p_node, value);
|
||||
insert_link_after(*position.p_value, value);
|
||||
|
||||
return iterator(value, index);
|
||||
return iterator(value);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -503,8 +491,8 @@ namespace etl
|
||||
{
|
||||
while (first != last)
|
||||
{
|
||||
// Set up the next free node.
|
||||
insert_node_after(*position.p_node, *first++);
|
||||
// Set up the next free link.
|
||||
insert_link_after(*position.p_value, *first++);
|
||||
++position;
|
||||
}
|
||||
}
|
||||
@ -518,7 +506,7 @@ namespace etl
|
||||
++next;
|
||||
++next;
|
||||
|
||||
remove_node_after(*position.p_node);
|
||||
remove_link_after(*position.p_value);
|
||||
|
||||
return next;
|
||||
}
|
||||
@ -528,9 +516,9 @@ namespace etl
|
||||
//*************************************************************************
|
||||
iterator erase_after(iterator first, iterator last)
|
||||
{
|
||||
node_t* p_first = first.p_node;
|
||||
node_t* p_last = last.p_node;
|
||||
node_t* p_next = p_first->get_next(index);
|
||||
link_type* p_first = first.p_value;
|
||||
link_type* p_last = last.p_value;
|
||||
link_type* p_next = p_first->ifll_next;
|
||||
|
||||
// Join the ends.
|
||||
join(p_first, p_last);
|
||||
@ -543,8 +531,8 @@ namespace etl
|
||||
// One less.
|
||||
--current_size;
|
||||
|
||||
p_next = p_first->get_next(index); // Remember the next node.
|
||||
p_first = p_next; // Move to the next node.
|
||||
p_next = p_first->ifll_next; // Remember the next link.
|
||||
p_first = p_next; // Move to the next link.
|
||||
}
|
||||
|
||||
if (p_next == nullptr)
|
||||
@ -553,7 +541,7 @@ namespace etl
|
||||
}
|
||||
else
|
||||
{
|
||||
return iterator(*p_last, index);
|
||||
return iterator(*static_cast<value_type*>(p_last));
|
||||
}
|
||||
}
|
||||
|
||||
@ -569,15 +557,15 @@ namespace etl
|
||||
return;
|
||||
}
|
||||
|
||||
node_t* last = &get_head();
|
||||
node_t* current = last->get_next(index);
|
||||
link_type* last = &get_head();
|
||||
link_type* current = last->ifll_next;
|
||||
|
||||
while (current != nullptr)
|
||||
{
|
||||
// Is this value the same as the last?
|
||||
if (isEqual(static_cast<reference>(*current), static_cast<reference>(*last)))
|
||||
if (isEqual(*static_cast<value_type*>(current), *static_cast<value_type*>(last)))
|
||||
{
|
||||
remove_node_after(*last);
|
||||
remove_link_after(*last);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -585,7 +573,7 @@ namespace etl
|
||||
last = current;
|
||||
}
|
||||
|
||||
current = last->get_next(index);
|
||||
current = last->ifll_next;
|
||||
}
|
||||
}
|
||||
|
||||
@ -594,7 +582,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
void sort()
|
||||
{
|
||||
sort(std::less<TValue>());
|
||||
sort(std::less<value_type>());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -607,7 +595,7 @@ namespace etl
|
||||
{
|
||||
iterator i_left;
|
||||
iterator i_right;
|
||||
iterator i_node;
|
||||
iterator i_link;
|
||||
iterator i_head;
|
||||
iterator i_tail;
|
||||
int list_size = 1;
|
||||
@ -653,50 +641,50 @@ namespace etl
|
||||
// Now we have two lists. Merge them.
|
||||
while (left_size > 0 || (right_size > 0 && i_right != end()))
|
||||
{
|
||||
// Decide whether the next node of merge comes from left or right.
|
||||
// Decide whether the next link of merge comes from left or right.
|
||||
if (left_size == 0)
|
||||
{
|
||||
// Left is empty. The node must come from right.
|
||||
i_node = i_right;
|
||||
// Left is empty. The link must come from right.
|
||||
i_link = i_right;
|
||||
++i_right;
|
||||
--right_size;
|
||||
}
|
||||
else if (right_size == 0 || i_right == end())
|
||||
{
|
||||
// Right is empty. The node must come from left.
|
||||
i_node = i_left;
|
||||
// Right is empty. The link must come from left.
|
||||
i_link = i_left;
|
||||
++i_left;
|
||||
--left_size;
|
||||
}
|
||||
else if (compare(*i_left, *i_right))
|
||||
{
|
||||
// First node of left is lower or same. The node must come from left.
|
||||
i_node = i_left;
|
||||
// First link of left is lower or same. The link must come from left.
|
||||
i_link = i_left;
|
||||
++i_left;
|
||||
--left_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
// First node of right is lower. The node must come from right.
|
||||
i_node = i_right;
|
||||
// First link of right is lower. The link must come from right.
|
||||
i_link = i_right;
|
||||
++i_right;
|
||||
--right_size;
|
||||
}
|
||||
|
||||
// Add the next node to the merged head.
|
||||
// Add the next link to the merged head.
|
||||
if (i_head == before_begin())
|
||||
{
|
||||
join(i_head.p_node, i_node.p_node);
|
||||
i_head = i_node;
|
||||
i_tail = i_node;
|
||||
join(i_head.p_value, i_link.p_value);
|
||||
i_head = i_link;
|
||||
i_tail = i_link;
|
||||
}
|
||||
else
|
||||
{
|
||||
join(i_tail.p_node, i_node.p_node);
|
||||
i_tail = i_node;
|
||||
join(i_tail.p_value, i_link.p_value);
|
||||
i_tail = i_link;
|
||||
}
|
||||
|
||||
i_tail.p_node->set_next(index, nullptr);
|
||||
i_tail.p_value->link_type::ifll_next = nullptr;
|
||||
}
|
||||
|
||||
// Now left has stepped `list_size' places along, and right has too.
|
||||
@ -717,14 +705,14 @@ namespace etl
|
||||
//*************************************************************************
|
||||
// Removes the values specified.
|
||||
//*************************************************************************
|
||||
void remove(node_t& value)
|
||||
void remove(const_reference value)
|
||||
{
|
||||
iterator i_item = begin();
|
||||
iterator i_last_item = before_begin();
|
||||
|
||||
while (i_item != end())
|
||||
{
|
||||
if (static_cast<reference>(*i_item) == static_cast<reference>(value))
|
||||
if (*i_item == value)
|
||||
{
|
||||
i_item = erase_after(i_last_item);
|
||||
}
|
||||
@ -777,16 +765,16 @@ namespace etl
|
||||
|
||||
private:
|
||||
|
||||
node_t start_node; ///< The node 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 node that this list operates on.
|
||||
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.
|
||||
|
||||
//*************************************************************************
|
||||
/// Join two nodes.
|
||||
/// Join two links.
|
||||
//*************************************************************************
|
||||
void join(node_t* left, node_t* right)
|
||||
void join(link_type* left, link_type* right)
|
||||
{
|
||||
left->set_next(index, right);
|
||||
left->ifll_next = right;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -798,46 +786,46 @@ namespace etl
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Insert a node.
|
||||
/// Insert a link.
|
||||
//*************************************************************************
|
||||
void insert_node_after(node_t& position, node_t& node)
|
||||
void insert_link_after(link_type& position, link_type& link)
|
||||
{
|
||||
// Connect to the intrusive_forward_list.
|
||||
join(&node, position.get_next(index));
|
||||
join(&position, &node);
|
||||
join(&link, position.ifll_next);
|
||||
join(&position, &link);
|
||||
++current_size;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Remove a node.
|
||||
/// Remove a link.
|
||||
//*************************************************************************
|
||||
void remove_node_after(node_t& node)
|
||||
void remove_link_after(link_type& link)
|
||||
{
|
||||
// The node to erase.
|
||||
node_t* p_node = node.get_next(index);
|
||||
// The link to erase.
|
||||
link_type* p_link = link.ifll_next;
|
||||
|
||||
if (p_node != nullptr)
|
||||
if (p_link != nullptr)
|
||||
{
|
||||
// Disconnect the node from the intrusive_forward_list.
|
||||
join(&node, p_node->get_next(index));
|
||||
// Disconnect the link from the intrusive_forward_list.
|
||||
join(&link, p_link->ifll_next);
|
||||
--current_size;
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Get the head node.
|
||||
/// Get the head link.
|
||||
//*************************************************************************
|
||||
node_t& get_head()
|
||||
link_type& get_head()
|
||||
{
|
||||
return *start_node.get_next(index);
|
||||
return *start_link.ifll_next;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Get the head node.
|
||||
/// Get the head link.
|
||||
//*************************************************************************
|
||||
const node_t& get_head() const
|
||||
const link_type& get_head() const
|
||||
{
|
||||
return *start_node.get_next(index);
|
||||
return *start_link.ifll_next;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -845,7 +833,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
void initialise()
|
||||
{
|
||||
start_node.set_next(index, nullptr);
|
||||
start_link.ifll_next = nullptr;
|
||||
current_size = 0;
|
||||
}
|
||||
|
||||
|
||||
49
intrusive_forward_list_link.h
Normal file
49
intrusive_forward_list_link.h
Normal file
@ -0,0 +1,49 @@
|
||||
///\file
|
||||
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
http://www.etlcpp.com
|
||||
|
||||
Copyright(c) 2015 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
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions :
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __ETL_INTRUSIVE_FORWARD_LIST_LINK__
|
||||
#define __ETL_INTRUSIVE_FORWARD_LIST_LINK__
|
||||
|
||||
#include "error_handler.h"
|
||||
#include "array.h"
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//***************************************************************************
|
||||
/// The link element in the intrusive_forward_list.
|
||||
//***************************************************************************
|
||||
template <const size_t ID>
|
||||
struct intrusive_forward_list_link
|
||||
{
|
||||
intrusive_forward_list_link<ID>* ifll_next;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -36,58 +36,13 @@ SOFTWARE.
|
||||
|
||||
namespace etl
|
||||
{
|
||||
namespace __private_intrusive_forward_list__
|
||||
{
|
||||
//***************************************************************************
|
||||
/// The node element in the intrusive_forward_list.
|
||||
//***************************************************************************
|
||||
class intrusive_forward_list_node_base
|
||||
{
|
||||
public:
|
||||
|
||||
virtual intrusive_forward_list_node_base* get_next(size_t index) const
|
||||
{
|
||||
return base_next;
|
||||
}
|
||||
|
||||
virtual void set_next(size_t index, intrusive_forward_list_node_base* pnext)
|
||||
{
|
||||
base_next = pnext;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
intrusive_forward_list_node_base* base_next;
|
||||
};
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// The node element in the intrusive_forward_list.
|
||||
//***************************************************************************
|
||||
template <const size_t SIZE>
|
||||
struct intrusive_forward_list_node : public __private_intrusive_forward_list__::intrusive_forward_list_node_base
|
||||
template <const size_t ID>
|
||||
struct intrusive_forward_list_node
|
||||
{
|
||||
public:
|
||||
|
||||
__private_intrusive_forward_list__::intrusive_forward_list_node_base* get_next(size_t index) const
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
ETL_ASSERT(index < SIZE, ETL_ERROR(intrusive_forward_list_index_exception));
|
||||
#endif
|
||||
return next[index];
|
||||
}
|
||||
|
||||
void set_next(size_t index, __private_intrusive_forward_list__::intrusive_forward_list_node_base* pnext)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
ETL_ASSERT(index < SIZE, ETL_ERROR(intrusive_forward_list_index_exception));
|
||||
#endif
|
||||
next[index] = pnext;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
etl::array<__private_intrusive_forward_list__::intrusive_forward_list_node_base*, SIZE> next;
|
||||
intrusive_list_tag<ID>* ifln_next;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -113,7 +113,7 @@ namespace etl
|
||||
/// Can be used as a reference type for all unordered_map containing a specific type.
|
||||
///\ingroup unordered_map
|
||||
//***************************************************************************
|
||||
template <typename TKey, typename T, typename THash = etl::hash<Key>, typename TKeyEqual = std::equal_to<TKey> >
|
||||
template <typename TKey, typename T, typename THash = etl::hash<TKey>, typename TKeyEqual = std::equal_to<TKey> >
|
||||
class iunordered_map
|
||||
{
|
||||
public:
|
||||
@ -130,7 +130,7 @@ namespace etl
|
||||
typedef const value_type* const_pointer;
|
||||
typedef size_t size_type;
|
||||
|
||||
|
||||
|
||||
typedef typename parameter_type<TKey>::type key_value_parameter_t;
|
||||
|
||||
// The nodes that store the elements.
|
||||
@ -151,7 +151,7 @@ namespace etl
|
||||
typedef etl::ivector<bucket_t> bucket_list_t;
|
||||
|
||||
typedef typename bucket_list_t::iterator bucket_list_iterator;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
// Local iterators iterate over one bucket.
|
||||
@ -586,7 +586,7 @@ namespace etl
|
||||
//*********************************************************************
|
||||
size_type bucket(key_value_parameter_t key) const
|
||||
{
|
||||
return hash_function(key) % pbuckets->size();
|
||||
return key_hash_function(key) % pbuckets->size();
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
@ -647,7 +647,9 @@ namespace etl
|
||||
}
|
||||
|
||||
// Doesn't exist, so add a new one.
|
||||
ibucket->insert_after(ibucket->before_begin(), node_t(value_type(key, T())));
|
||||
// Get a new node.
|
||||
node_t& node = *pnodepool->allocate(node_t(value_type(key, T())));
|
||||
ibucket->insert_after(ibucket->before_begin(), node);
|
||||
|
||||
return ibucket->begin().ref_cast<node_t>().key_value_pair.second;
|
||||
}
|
||||
@ -747,9 +749,9 @@ namespace etl
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
// Inserts a value to the unordered_map.
|
||||
// If asserts or exceptions are enabled, emits unordered_map_full if the unordered_map is already full.
|
||||
//\param value The value to insert.
|
||||
/// Inserts a value to the unordered_map.
|
||||
/// If asserts or exceptions are enabled, emits unordered_map_full if the unordered_map is already full.
|
||||
///\param value The value to insert.
|
||||
//*********************************************************************
|
||||
std::pair<iterator, bool> insert(const value_type& key_value_pair)
|
||||
{
|
||||
@ -1084,6 +1086,33 @@ namespace etl
|
||||
return pnodepool->available();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the load factor = size / bucket_count.
|
||||
///\return The load factor = size / bucket_count.
|
||||
//*************************************************************************
|
||||
float load_factor() const
|
||||
{
|
||||
return static_cast<float>(size()) / static_cast<float>(bucket_count());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the function that hashes the keys.
|
||||
///\return The function that hashes the keys..
|
||||
//*************************************************************************
|
||||
hasher hash_function() const
|
||||
{
|
||||
return key_hash_function;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the function that compares the keys.
|
||||
///\return The function that compares the keys..
|
||||
//*************************************************************************
|
||||
key_equal key_eq() const
|
||||
{
|
||||
return key_equal_function;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Assignment operator.
|
||||
//*************************************************************************
|
||||
@ -1146,7 +1175,7 @@ namespace etl
|
||||
last = ibucket;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Disable copy construction.
|
||||
iunordered_map(const iunordered_map&);
|
||||
|
||||
@ -1161,7 +1190,7 @@ namespace etl
|
||||
bucket_list_iterator last;
|
||||
|
||||
/// The function that creates the hashes.
|
||||
hasher hash_function;
|
||||
hasher key_hash_function;
|
||||
|
||||
/// The function that compares the keys for equality.
|
||||
key_equal key_equal_function;
|
||||
|
||||
@ -127,6 +127,8 @@
|
||||
<Unit filename="../../README.md" />
|
||||
<Unit filename="../../alignment.h" />
|
||||
<Unit filename="../../array.h" />
|
||||
<Unit filename="../../basic_intrusive_forward_list.h" />
|
||||
<Unit filename="../../basic_intrusive_forward_list_node.h" />
|
||||
<Unit filename="../../binary.h" />
|
||||
<Unit filename="../../bitset.h" />
|
||||
<Unit filename="../../bloom_filter.h" />
|
||||
@ -162,6 +164,7 @@
|
||||
<Unit filename="../../forward_list_base.h" />
|
||||
<Unit filename="../../function.h" />
|
||||
<Unit filename="../../functional.h" />
|
||||
<Unit filename="../../ibitset.h" />
|
||||
<Unit filename="../../ideque.h" />
|
||||
<Unit filename="../../iflat_map.h" />
|
||||
<Unit filename="../../iflat_set.h" />
|
||||
@ -175,6 +178,7 @@
|
||||
<Unit filename="../../iqueue.h" />
|
||||
<Unit filename="../../iset.h" />
|
||||
<Unit filename="../../istack.h" />
|
||||
<Unit filename="../../iunordered_map.h" />
|
||||
<Unit filename="../../ivector.h" />
|
||||
<Unit filename="../../largest.h" />
|
||||
<Unit filename="../../list.h" />
|
||||
@ -217,6 +221,7 @@
|
||||
<Unit filename="../../stack_base.h" />
|
||||
<Unit filename="../../static_assert.h" />
|
||||
<Unit filename="../../type_traits.h" />
|
||||
<Unit filename="../../unordered_map.h" />
|
||||
<Unit filename="../../variant.h" />
|
||||
<Unit filename="../../vector.h" />
|
||||
<Unit filename="../../vector_base.h" />
|
||||
@ -262,6 +267,7 @@
|
||||
<Unit filename="../test_smallest.cpp" />
|
||||
<Unit filename="../test_stack.cpp" />
|
||||
<Unit filename="../test_type_traits.cpp" />
|
||||
<Unit filename="../test_unordered_map.cpp" />
|
||||
<Unit filename="../test_variant.cpp" />
|
||||
<Unit filename="../test_vector.cpp" />
|
||||
<Unit filename="../test_visitor.cpp" />
|
||||
|
||||
@ -677,8 +677,6 @@ namespace
|
||||
compare_data.insert(compare_data.begin() + offset, insert_size, N14);
|
||||
data.insert(data.begin() + offset, insert_size, N14);
|
||||
|
||||
bool equal = std::equal(compare_data.begin(), compare_data.end(), data.begin());
|
||||
|
||||
CHECK_EQUAL(compare_data.size(), data.size());
|
||||
CHECK(std::equal(compare_data.begin(), compare_data.end(), data.begin()));
|
||||
}
|
||||
@ -1482,7 +1480,7 @@ namespace
|
||||
TEST(test_iterator_comparison_empty)
|
||||
{
|
||||
DataNDC data;
|
||||
|
||||
|
||||
CHECK(data.begin() == data.end());
|
||||
CHECK(data.cbegin() == data.cend());
|
||||
CHECK(data.rbegin() == data.rend());
|
||||
|
||||
@ -61,7 +61,7 @@ void receive_error(const etl::exception& e)
|
||||
std::ostringstream oss;
|
||||
oss << "Error '" << e.what() << "' in " << e.file_name() << " at line " << e.line_number() << "\n";
|
||||
|
||||
#if defined(PLATFORM_WINDOWS)
|
||||
#if defined(PLATFORM_WINDOWS) && defined(COMPILER_MICROSOFT)
|
||||
std::string stext = oss.str();
|
||||
|
||||
WCHAR text[200];
|
||||
@ -86,7 +86,7 @@ public:
|
||||
std::ostringstream oss;
|
||||
oss << "Error '" << e.what() << "' in " << e.file_name() << " at line " << e.line_number() << "\n";
|
||||
|
||||
#if defined(PLATFORM_WINDOWS)
|
||||
#if defined(PLATFORM_WINDOWS) && defined(COMPILER_MICROSOFT)
|
||||
std::string stext = oss.str();
|
||||
|
||||
WCHAR text[200];
|
||||
|
||||
@ -601,5 +601,183 @@ namespace
|
||||
|
||||
CHECK(are_equal);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST_FIXTURE(SetupFixture, test_move)
|
||||
{
|
||||
CompareDataNDC compare_data(sorted_data.begin(), sorted_data.end());
|
||||
DataNDC data(sorted_data.begin(), sorted_data.end());
|
||||
|
||||
DataNDC::const_iterator i_from_before;
|
||||
DataNDC::const_iterator i_to_before;
|
||||
CompareDataNDC::const_iterator i_compare_from_before;
|
||||
CompareDataNDC::const_iterator i_compare_to_before;
|
||||
|
||||
// Move to the beginning.
|
||||
i_from_before = data.begin();
|
||||
std::advance(i_from_before, 5);
|
||||
|
||||
i_to_before = data.before_begin();
|
||||
|
||||
i_compare_from_before = compare_data.begin();
|
||||
std::advance(i_compare_from_before, 5);
|
||||
|
||||
i_compare_to_before = compare_data.before_begin();
|
||||
|
||||
compare_data.splice_after(i_compare_to_before, compare_data, i_compare_from_before);
|
||||
data.move_after(i_from_before, i_to_before);
|
||||
|
||||
are_equal = std::equal(data.begin(), data.end(), compare_data.begin());
|
||||
|
||||
CHECK(are_equal);
|
||||
|
||||
// Move to the end.
|
||||
i_from_before = data.begin();
|
||||
std::advance(i_from_before, 5);
|
||||
|
||||
i_to_before = data.begin();
|
||||
std::advance(i_to_before, 9);
|
||||
|
||||
i_compare_from_before = compare_data.begin();
|
||||
std::advance(i_compare_from_before, 5);
|
||||
|
||||
i_compare_to_before = compare_data.begin();
|
||||
std::advance(i_compare_to_before, 9);
|
||||
|
||||
compare_data.splice_after(i_compare_to_before, compare_data, i_compare_from_before);
|
||||
data.move_after(i_from_before, i_to_before);
|
||||
|
||||
are_equal = std::equal(data.begin(), data.end(), compare_data.begin());
|
||||
|
||||
CHECK(are_equal);
|
||||
|
||||
// Move to nearby.
|
||||
i_from_before = data.begin();
|
||||
std::advance(i_from_before, 3);
|
||||
|
||||
i_to_before = data.begin();
|
||||
std::advance(i_to_before, 7);
|
||||
|
||||
i_compare_from_before = compare_data.begin();
|
||||
std::advance(i_compare_from_before, 3);
|
||||
|
||||
i_compare_to_before = compare_data.begin();
|
||||
std::advance(i_compare_to_before, 7);
|
||||
|
||||
compare_data.splice_after(i_compare_to_before, compare_data, i_compare_from_before);
|
||||
data.move_after(i_from_before, i_to_before);
|
||||
|
||||
are_equal = std::equal(data.begin(), data.end(), compare_data.begin());
|
||||
|
||||
CHECK(are_equal);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST_FIXTURE(SetupFixture, test_move_range)
|
||||
{
|
||||
CompareDataNDC compare_data(sorted_data.begin(), sorted_data.end());
|
||||
DataNDC data(sorted_data.begin(), sorted_data.end());
|
||||
|
||||
DataNDC::const_iterator i_first_before;
|
||||
DataNDC::const_iterator i_last;
|
||||
DataNDC::const_iterator i_to_before;
|
||||
CompareDataNDC::const_iterator i_compare_first_before;
|
||||
CompareDataNDC::const_iterator i_compare_last;
|
||||
CompareDataNDC::const_iterator i_compare_to_before;
|
||||
|
||||
// Move to the beginning.
|
||||
i_first_before = data.begin();
|
||||
std::advance(i_first_before, 4);
|
||||
|
||||
i_last = i_first_before;
|
||||
std::advance(i_last, 4);
|
||||
|
||||
i_to_before = data.before_begin();
|
||||
|
||||
i_compare_first_before = compare_data.begin();
|
||||
std::advance(i_compare_first_before, 4);
|
||||
|
||||
i_compare_last = i_compare_first_before;
|
||||
std::advance(i_compare_last, 4);
|
||||
|
||||
i_compare_to_before = compare_data.before_begin();
|
||||
|
||||
compare_data.splice_after(i_compare_to_before, compare_data, i_compare_first_before, i_compare_last);
|
||||
data.move_after(i_first_before, i_last, i_to_before);
|
||||
|
||||
are_equal = std::equal(data.begin(), data.end(), compare_data.begin());
|
||||
|
||||
CHECK(are_equal);
|
||||
|
||||
// Move to the end.
|
||||
i_first_before = data.begin();
|
||||
std::advance(i_first_before, 4);
|
||||
|
||||
i_last = i_first_before;
|
||||
std::advance(i_last, 4);
|
||||
|
||||
i_to_before = data.begin();
|
||||
std::advance(i_to_before, 9);
|
||||
|
||||
i_compare_first_before = compare_data.begin();
|
||||
std::advance(i_compare_first_before, 4);
|
||||
|
||||
i_compare_last = i_compare_first_before;
|
||||
std::advance(i_compare_last, 4);
|
||||
|
||||
i_compare_to_before = compare_data.begin();
|
||||
std::advance(i_compare_to_before, 9);
|
||||
|
||||
compare_data.splice_after(i_compare_to_before, compare_data, i_compare_first_before, i_compare_last);
|
||||
data.move_after(i_first_before, i_last, i_to_before);
|
||||
|
||||
//DataNDC::const_iterator id = data.begin();
|
||||
//CompareDataNDC::const_iterator ic = compare_data.begin();
|
||||
|
||||
//ItemNDC d;
|
||||
//ItemNDC c;
|
||||
|
||||
//while (ic != compare_data.end())
|
||||
//{
|
||||
// d = *id++;
|
||||
// c = *ic++;
|
||||
//}
|
||||
|
||||
are_equal = std::equal(data.begin(), data.end(), compare_data.begin());
|
||||
|
||||
// Move to nearby.
|
||||
i_first_before = data.begin();
|
||||
std::advance(i_first_before, 4);
|
||||
|
||||
i_last = i_first_before;
|
||||
std::advance(i_last, 4);
|
||||
|
||||
i_to_before = data.begin();
|
||||
std::advance(i_to_before, 2);
|
||||
|
||||
i_compare_first_before = compare_data.begin();
|
||||
std::advance(i_compare_first_before, 4);
|
||||
|
||||
i_compare_last = i_compare_first_before;
|
||||
std::advance(i_compare_last, 4);
|
||||
|
||||
i_compare_to_before = compare_data.begin();
|
||||
std::advance(i_compare_to_before, 2);
|
||||
|
||||
compare_data.splice_after(i_compare_to_before, compare_data, i_compare_first_before, i_compare_last);
|
||||
data.move_after(i_first_before, i_last, i_to_before);
|
||||
|
||||
are_equal = std::equal(data.begin(), data.end(), compare_data.begin());
|
||||
|
||||
// Move to illegal place.
|
||||
i_first_before = data.begin();
|
||||
std::advance(i_first_before, 2);
|
||||
i_last = i_first_before;
|
||||
std::advance(i_last, 3);
|
||||
i_to_before = i_first_before;
|
||||
std::advance(i_to_before, 2);
|
||||
|
||||
CHECK_THROW(data.move_after(i_first_before, i_last, i_to_before), etl::forward_list_iterator);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@ -42,9 +42,14 @@ SOFTWARE.
|
||||
|
||||
typedef TestDataDC<std::string> ItemDC;
|
||||
typedef TestDataNDC<std::string> ItemNDC;
|
||||
|
||||
namespace
|
||||
{
|
||||
class ItemDCNode : public etl::intrusive_forward_list_node<2>
|
||||
typedef etl::intrusive_forward_list_link<0> FirstLink;
|
||||
typedef etl::intrusive_forward_list_link<1> SecondLink;
|
||||
|
||||
//***************************************************************************
|
||||
class ItemDCNode : public FirstLink, public SecondLink
|
||||
{
|
||||
public:
|
||||
|
||||
@ -56,9 +61,8 @@ namespace
|
||||
ItemDC data;
|
||||
};
|
||||
|
||||
const size_t INDEXES = 2;
|
||||
|
||||
class ItemNDCNode : public etl::intrusive_forward_list_node<INDEXES>
|
||||
//***************************************************************************
|
||||
class ItemNDCNode : public FirstLink, public SecondLink
|
||||
{
|
||||
public:
|
||||
|
||||
@ -75,6 +79,7 @@ namespace
|
||||
ItemNDC data;
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
bool operator ==(const ItemDCNode& lhs, const ItemDCNode& rhs)
|
||||
{
|
||||
return lhs.data == rhs.data;
|
||||
@ -85,12 +90,23 @@ namespace
|
||||
return lhs.data == rhs.data;
|
||||
}
|
||||
|
||||
bool operator !=(const ItemDCNode& lhs, const ItemDCNode& rhs)
|
||||
{
|
||||
return lhs.data != rhs.data;
|
||||
}
|
||||
|
||||
bool operator !=(const ItemNDCNode& lhs, const ItemNDCNode& rhs)
|
||||
{
|
||||
return lhs.data != rhs.data;
|
||||
}
|
||||
|
||||
std::ostream& operator << (std::ostream& os, const ItemNDCNode& node)
|
||||
{
|
||||
os << node.data;
|
||||
return os;
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
struct CompareItemNDCNode
|
||||
{
|
||||
bool operator ()(const ItemNDCNode& lhs, const ItemNDCNode& rhs) const
|
||||
@ -106,17 +122,39 @@ namespace
|
||||
return lhs.data == rhs.data;
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
typedef etl::intrusive_forward_list<ItemDCNode, FirstLink> DataDC0;
|
||||
typedef etl::intrusive_forward_list<ItemDCNode, SecondLink> DataDC1;
|
||||
typedef etl::intrusive_forward_list<ItemNDCNode, FirstLink> DataNDC0;
|
||||
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
|
||||
{
|
||||
SUITE(test_forward_list)
|
||||
{
|
||||
typedef etl::intrusive_forward_list<ItemDCNode> DataDC;
|
||||
typedef etl::intrusive_forward_list<ItemNDCNode> DataNDC;
|
||||
|
||||
typedef std::vector<ItemNDCNode> InitialDataNDC;
|
||||
|
||||
InitialDataNDC unsorted_data;
|
||||
InitialDataNDC sorted_data;
|
||||
InitialDataNDC non_unique_data;
|
||||
@ -141,8 +179,8 @@ namespace
|
||||
//*************************************************************************
|
||||
TEST_FIXTURE(SetupFixture, test_default_constructor)
|
||||
{
|
||||
DataNDC data0(0);
|
||||
DataNDC data1(1);
|
||||
DataNDC0 data0;
|
||||
DataNDC1 data1;
|
||||
|
||||
CHECK(data0.empty());
|
||||
CHECK(data1.empty());
|
||||
@ -151,7 +189,7 @@ namespace
|
||||
//*************************************************************************
|
||||
TEST_FIXTURE(SetupFixture, test_constructor_range)
|
||||
{
|
||||
DataNDC data0(0, sorted_data.begin(), sorted_data.end());
|
||||
DataNDC0 data0(sorted_data.begin(), sorted_data.end());
|
||||
|
||||
CHECK(!data0.empty());
|
||||
CHECK_EQUAL(sorted_data.size(), data0.size());
|
||||
@ -160,7 +198,7 @@ namespace
|
||||
//*************************************************************************
|
||||
TEST_FIXTURE(SetupFixture, test_iterator)
|
||||
{
|
||||
DataNDC data0(0, sorted_data.begin(), sorted_data.end());
|
||||
DataNDC0 data0(sorted_data.begin(), sorted_data.end());
|
||||
|
||||
are_equal = std::equal(data0.begin(), data0.end(), sorted_data.begin());
|
||||
|
||||
@ -170,7 +208,7 @@ namespace
|
||||
//*************************************************************************
|
||||
TEST_FIXTURE(SetupFixture, test_const_iterator)
|
||||
{
|
||||
DataNDC data0(0, sorted_data.begin(), sorted_data.end());
|
||||
DataNDC0 data0(sorted_data.begin(), sorted_data.end());
|
||||
|
||||
are_equal = std::equal(data0.cbegin(), data0.cend(), sorted_data.begin());
|
||||
|
||||
@ -180,7 +218,7 @@ namespace
|
||||
//*************************************************************************
|
||||
TEST_FIXTURE(SetupFixture, test_clear)
|
||||
{
|
||||
DataNDC data0(0, sorted_data.begin(), sorted_data.end());
|
||||
DataNDC0 data0(sorted_data.begin(), sorted_data.end());
|
||||
data0.clear();
|
||||
|
||||
CHECK(data0.empty());
|
||||
@ -189,7 +227,7 @@ namespace
|
||||
//*************************************************************************
|
||||
TEST_FIXTURE(SetupFixture, test_assign_range)
|
||||
{
|
||||
DataNDC data0(0);
|
||||
DataNDC0 data0;
|
||||
|
||||
// Do it twice. We should only get one copy.
|
||||
data0.assign(sorted_data.begin(), sorted_data.end());
|
||||
@ -203,8 +241,8 @@ namespace
|
||||
//*************************************************************************
|
||||
TEST_FIXTURE(SetupFixture, test_assign_range_two_lists_same)
|
||||
{
|
||||
DataNDC data0(0);
|
||||
DataNDC data1(1);
|
||||
DataNDC0 data0;
|
||||
DataNDC0 data1;
|
||||
|
||||
data0.assign(sorted_data.begin(), sorted_data.end());
|
||||
data1.assign(sorted_data.begin(), sorted_data.end());
|
||||
@ -216,14 +254,14 @@ namespace
|
||||
CHECK(are_equal);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
////*************************************************************************
|
||||
TEST_FIXTURE(SetupFixture, test_two_lists_different)
|
||||
{
|
||||
std::list<ItemNDCNode> compare0;
|
||||
std::list<ItemNDCNode> compare1;
|
||||
|
||||
DataNDC data0(0);
|
||||
DataNDC data1(1);
|
||||
DataNDC0 data0;
|
||||
DataNDC1 data1;
|
||||
|
||||
ItemNDCNode node0("0");
|
||||
ItemNDCNode node1("1");
|
||||
@ -280,12 +318,12 @@ namespace
|
||||
ItemNDCNode INSERT_VALUE2 = ItemNDCNode("2");
|
||||
|
||||
std::vector<ItemNDCNode> compare_data(sorted_data.begin(), sorted_data.end());
|
||||
DataNDC data0(0, sorted_data.begin(), sorted_data.end());
|
||||
DataNDC data1(1, sorted_data.begin(), sorted_data.end());
|
||||
DataNDC0 data0(sorted_data.begin(), sorted_data.end());
|
||||
DataNDC1 data1(sorted_data.begin(), sorted_data.end());
|
||||
|
||||
size_t offset = 2;
|
||||
|
||||
DataNDC::iterator i_data = data0.begin();
|
||||
DataNDC0::iterator i_data = data0.begin();
|
||||
std::advance(i_data, offset);
|
||||
|
||||
std::vector<ItemNDCNode>::iterator i_compare_data = compare_data.begin();
|
||||
@ -338,8 +376,8 @@ namespace
|
||||
std::vector<ItemNDCNode> compare(test2);
|
||||
compare.insert(compare.end(), test1.begin(), test1.end());
|
||||
|
||||
DataNDC data0(0, test1.begin(), test1.end());
|
||||
DataNDC data1(1, test1.begin(), test1.end());
|
||||
DataNDC0 data0(test1.begin(), test1.end());
|
||||
DataNDC1 data1(test1.begin(), test1.end());
|
||||
|
||||
data0.insert_after(data0.before_begin(), test2.begin(), test2.end());
|
||||
|
||||
@ -355,7 +393,7 @@ namespace
|
||||
data0.assign(test1.begin(), test1.end());
|
||||
|
||||
std::vector<ItemNDCNode>::iterator icd = compare.begin();
|
||||
DataNDC::iterator id = data0.begin();
|
||||
DataNDC0::iterator id = data0.begin();
|
||||
|
||||
std::advance(icd, 4);
|
||||
std::advance(id, 3);
|
||||
@ -378,7 +416,7 @@ namespace
|
||||
TEST_FIXTURE(SetupFixture, test_push_front)
|
||||
{
|
||||
std::list<ItemNDCNode> compare_data;
|
||||
DataNDC data0(0);
|
||||
DataNDC0 data0;
|
||||
|
||||
ItemNDCNode node1("1");
|
||||
ItemNDCNode node2("2");
|
||||
@ -410,8 +448,8 @@ namespace
|
||||
//*************************************************************************
|
||||
TEST_FIXTURE(SetupFixture, test_push_front_pop_front)
|
||||
{
|
||||
DataNDC data0(0);
|
||||
DataNDC data1(1);
|
||||
DataNDC0 data0;
|
||||
DataNDC1 data1;
|
||||
|
||||
ItemNDCNode node1("1");
|
||||
ItemNDCNode node2("2");
|
||||
@ -463,10 +501,10 @@ namespace
|
||||
TEST_FIXTURE(SetupFixture, test_erase_after_single)
|
||||
{
|
||||
std::vector<ItemNDCNode> compare_data(sorted_data.begin(), sorted_data.end());
|
||||
DataNDC data0(0, sorted_data.begin(), sorted_data.end());
|
||||
DataNDC data1(1, sorted_data.begin(), sorted_data.end());
|
||||
DataNDC0 data0(sorted_data.begin(), sorted_data.end());
|
||||
DataNDC1 data1(sorted_data.begin(), sorted_data.end());
|
||||
|
||||
DataNDC::iterator i_data = data0.begin();
|
||||
DataNDC0::iterator i_data = data0.begin();
|
||||
std::advance(i_data, 2);
|
||||
|
||||
std::vector<ItemNDCNode>::iterator i_compare_data = compare_data.begin();
|
||||
@ -523,13 +561,13 @@ namespace
|
||||
TEST_FIXTURE(SetupFixture, test_erase_after_range)
|
||||
{
|
||||
std::vector<ItemNDCNode> compare_data(sorted_data.begin(), sorted_data.end());
|
||||
DataNDC data0(0, sorted_data.begin(), sorted_data.end());
|
||||
DataNDC data1(1, sorted_data.begin(), sorted_data.end());
|
||||
DataNDC0 data0(sorted_data.begin(), sorted_data.end());
|
||||
DataNDC1 data1(sorted_data.begin(), sorted_data.end());
|
||||
|
||||
DataNDC::iterator i_data_1 = data0.begin();
|
||||
DataNDC0::iterator i_data_1 = data0.begin();
|
||||
std::advance(i_data_1, 2);
|
||||
|
||||
DataNDC::iterator i_data_2 = data0.begin();
|
||||
DataNDC0::iterator i_data_2 = data0.begin();
|
||||
std::advance(i_data_2, 4);
|
||||
|
||||
std::vector<ItemNDCNode>::iterator i_compare_data_1 = compare_data.begin();
|
||||
@ -540,7 +578,7 @@ namespace
|
||||
|
||||
std::vector<ItemNDCNode>::iterator i_compare_result = compare_data.erase(i_compare_data_1, i_compare_data_2);
|
||||
|
||||
DataNDC::iterator i_result = data0.erase_after(i_data_1, i_data_2);
|
||||
DataNDC0::iterator i_result = data0.erase_after(i_data_1, i_data_2);
|
||||
|
||||
CHECK_EQUAL(*i_compare_result, *i_result);
|
||||
|
||||
@ -559,10 +597,10 @@ namespace
|
||||
TEST_FIXTURE(SetupFixture, test_erase_after_range_end)
|
||||
{
|
||||
std::vector<ItemNDCNode> compare_data(sorted_data.begin(), sorted_data.end());
|
||||
DataNDC data0(0, sorted_data.begin(), sorted_data.end());
|
||||
DataNDC data1(1, sorted_data.begin(), sorted_data.end());
|
||||
DataNDC0 data0(sorted_data.begin(), sorted_data.end());
|
||||
DataNDC1 data1(sorted_data.begin(), sorted_data.end());
|
||||
|
||||
DataNDC::iterator i_data = data0.begin();
|
||||
DataNDC0::iterator i_data = data0.begin();
|
||||
std::advance(i_data, 4);
|
||||
|
||||
std::vector<ItemNDCNode>::iterator i_compare_data = compare_data.begin();
|
||||
@ -570,7 +608,7 @@ namespace
|
||||
|
||||
std::vector<ItemNDCNode>::iterator i_compare_result = compare_data.erase(i_compare_data, compare_data.end());
|
||||
|
||||
DataNDC::iterator i_result = data0.erase_after(i_data, data0.end());
|
||||
DataNDC0::iterator i_result = data0.erase_after(i_data, data0.end());
|
||||
|
||||
CHECK(i_result == data0.end());
|
||||
|
||||
@ -588,7 +626,7 @@ namespace
|
||||
//*************************************************************************
|
||||
TEST_FIXTURE(SetupFixture, test_erase_after_all)
|
||||
{
|
||||
DataNDC data0(0, sorted_data.begin(), sorted_data.end());
|
||||
DataNDC0 data0(sorted_data.begin(), sorted_data.end());
|
||||
|
||||
data0.erase_after(data0.before_begin(), data0.end());
|
||||
|
||||
@ -598,7 +636,7 @@ namespace
|
||||
//*************************************************************************
|
||||
TEST_FIXTURE(SetupFixture, test_front)
|
||||
{
|
||||
DataNDC data0(0, sorted_data.begin(), sorted_data.end());
|
||||
DataNDC0 data0(sorted_data.begin(), sorted_data.end());
|
||||
|
||||
CHECK_EQUAL(sorted_data.front(), data0.front());
|
||||
}
|
||||
@ -606,8 +644,8 @@ namespace
|
||||
//*************************************************************************
|
||||
TEST_FIXTURE(SetupFixture, test_unique)
|
||||
{
|
||||
DataNDC data0(0, non_unique_data.begin(), non_unique_data.end());
|
||||
DataNDC data1(1, non_unique_data.begin(), non_unique_data.end());
|
||||
DataNDC0 data0(non_unique_data.begin(), non_unique_data.end());
|
||||
DataNDC1 data1(non_unique_data.begin(), non_unique_data.end());
|
||||
|
||||
data0.unique(EqualItemNDCNode());
|
||||
|
||||
@ -628,8 +666,8 @@ namespace
|
||||
TEST_FIXTURE(SetupFixture, test_remove)
|
||||
{
|
||||
std::vector<ItemNDCNode> compare_data(sorted_data.begin(), sorted_data.end());
|
||||
DataNDC data0(0, sorted_data.begin(), sorted_data.end());
|
||||
DataNDC data1(1, 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);
|
||||
@ -651,8 +689,8 @@ namespace
|
||||
TEST_FIXTURE(SetupFixture, test_remove_if)
|
||||
{
|
||||
std::vector<ItemNDCNode> compare_data(sorted_data.begin(), sorted_data.end());
|
||||
DataNDC data0(0, sorted_data.begin(), sorted_data.end());
|
||||
DataNDC data1(1, 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);
|
||||
@ -673,8 +711,8 @@ namespace
|
||||
//*************************************************************************
|
||||
TEST_FIXTURE(SetupFixture, test_reverse)
|
||||
{
|
||||
DataNDC data0(0, sorted_data.begin(), sorted_data.end());
|
||||
DataNDC data1(1, sorted_data.begin(), sorted_data.end());
|
||||
DataNDC0 data0(sorted_data.begin(), sorted_data.end());
|
||||
DataNDC1 data1(sorted_data.begin(), sorted_data.end());
|
||||
|
||||
data0.reverse(); // Just reverse one of them.
|
||||
|
||||
@ -688,8 +726,8 @@ namespace
|
||||
//*************************************************************************
|
||||
TEST_FIXTURE(SetupFixture, test_sort)
|
||||
{
|
||||
DataNDC data0(0, unsorted_data.begin(), unsorted_data.end());
|
||||
DataNDC data1(1, unsorted_data.begin(), unsorted_data.end());
|
||||
DataNDC0 data0(unsorted_data.begin(), unsorted_data.end());
|
||||
DataNDC1 data1(unsorted_data.begin(), unsorted_data.end());
|
||||
|
||||
data0.sort(); // Just sort one of them.
|
||||
|
||||
@ -703,8 +741,8 @@ namespace
|
||||
//*************************************************************************
|
||||
TEST_FIXTURE(SetupFixture, test_sort_compare)
|
||||
{
|
||||
DataNDC data0(0, unsorted_data.begin(), unsorted_data.end());
|
||||
DataNDC data1(1, unsorted_data.begin(), unsorted_data.end());
|
||||
DataNDC0 data0(unsorted_data.begin(), unsorted_data.end());
|
||||
DataNDC1 data1(unsorted_data.begin(), unsorted_data.end());
|
||||
|
||||
data0.sort(CompareItemNDCNode()); // Just sort one of them.
|
||||
|
||||
|
||||
@ -38,8 +38,8 @@ SOFTWARE.
|
||||
#include <list>
|
||||
#include <vector>
|
||||
|
||||
namespace
|
||||
{
|
||||
namespace
|
||||
{
|
||||
SUITE(test_list)
|
||||
{
|
||||
typedef TestDataDC<std::string> ItemDC;
|
||||
@ -136,6 +136,7 @@ namespace
|
||||
TEST_FIXTURE(SetupFixture, test_copy_constructor)
|
||||
{
|
||||
CompareData compare_data(sorted_data.begin(), sorted_data.end());
|
||||
|
||||
DataNDC data(sorted_data.begin(), sorted_data.end());
|
||||
DataNDC other_data(data);
|
||||
|
||||
@ -427,7 +428,7 @@ namespace
|
||||
|
||||
//*************************************************************************
|
||||
TEST_FIXTURE(SetupFixture, test_push_front_excess)
|
||||
{
|
||||
{
|
||||
DataNDC data;
|
||||
|
||||
CHECK_NO_THROW(data.push_front(ItemNDC("1")));
|
||||
@ -454,7 +455,7 @@ namespace
|
||||
CHECK_NO_THROW(data.push_front(ItemNDC("1")));
|
||||
data.pop_front();
|
||||
}
|
||||
|
||||
|
||||
CHECK(data.empty());
|
||||
}
|
||||
|
||||
@ -482,7 +483,7 @@ namespace
|
||||
CHECK_NO_THROW(data.push_front(ItemNDC("1")));
|
||||
data.pop_front();
|
||||
}
|
||||
|
||||
|
||||
CHECK(data.empty());
|
||||
}
|
||||
|
||||
@ -496,7 +497,7 @@ namespace
|
||||
CHECK_NO_THROW(data.push_front(ItemNDC("1")));
|
||||
data.pop_back();
|
||||
}
|
||||
|
||||
|
||||
CHECK(data.empty());
|
||||
}
|
||||
|
||||
@ -524,7 +525,7 @@ namespace
|
||||
|
||||
CHECK(are_equal);
|
||||
}
|
||||
|
||||
|
||||
//*************************************************************************
|
||||
TEST_FIXTURE(SetupFixture, test_push_back_excess)
|
||||
{
|
||||
@ -805,5 +806,159 @@ namespace
|
||||
|
||||
CHECK(are_equal);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST_FIXTURE(SetupFixture, test_move)
|
||||
{
|
||||
CompareData compare_data(unsorted_data.begin(), unsorted_data.end());
|
||||
DataNDC data(unsorted_data.begin(), unsorted_data.end());
|
||||
|
||||
CompareData::iterator compare_from;
|
||||
CompareData::iterator compare_to;
|
||||
|
||||
DataNDC::const_iterator from;
|
||||
DataNDC::const_iterator to;
|
||||
|
||||
// Move to the beginning.
|
||||
compare_from = compare_data.begin();
|
||||
std::advance(compare_from, 4);
|
||||
compare_to = compare_data.begin();
|
||||
compare_data.splice(compare_to, compare_data, compare_from);
|
||||
|
||||
from = data.begin();
|
||||
std::advance(from, 4);
|
||||
to = data.begin();
|
||||
data.move(from, to);
|
||||
|
||||
are_equal = std::equal(data.begin(), data.end(), compare_data.begin());
|
||||
CHECK(are_equal);
|
||||
|
||||
// Move to the end.
|
||||
compare_from = compare_data.begin();
|
||||
std::advance(compare_from, 4);
|
||||
compare_to = compare_data.end();
|
||||
compare_data.splice(compare_to, compare_data, compare_from);
|
||||
|
||||
from = data.begin();
|
||||
std::advance(from, 4);
|
||||
to = data.end();
|
||||
data.move(from, to);
|
||||
|
||||
are_equal = std::equal(data.begin(), data.end(), compare_data.begin());
|
||||
CHECK(are_equal);
|
||||
|
||||
// Move nearby.
|
||||
compare_from = compare_data.begin();
|
||||
std::advance(compare_from, 4);
|
||||
compare_to = compare_data.begin();
|
||||
std::advance(compare_to, 6);
|
||||
compare_data.splice(compare_to, compare_data, compare_from);
|
||||
|
||||
from = data.begin();
|
||||
std::advance(from, 4);
|
||||
to = data.begin();
|
||||
std::advance(to, 6);
|
||||
data.move(from, to);
|
||||
|
||||
are_equal = std::equal(data.begin(), data.end(), compare_data.begin());
|
||||
CHECK(are_equal);
|
||||
|
||||
// Move to same place.
|
||||
compare_from = compare_data.begin();
|
||||
std::advance(compare_from, 4);
|
||||
compare_to = compare_data.begin();
|
||||
std::advance(compare_to, 4);
|
||||
compare_data.splice(compare_to, compare_data, compare_from);
|
||||
|
||||
from = data.begin();
|
||||
std::advance(from, 4);
|
||||
to = data.begin();
|
||||
std::advance(to, 4);
|
||||
data.move(from, to);
|
||||
|
||||
are_equal = std::equal(data.begin(), data.end(), compare_data.begin());
|
||||
CHECK(are_equal);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST_FIXTURE(SetupFixture, test_move_range)
|
||||
{
|
||||
CompareData compare_data(unsorted_data.begin(), unsorted_data.end());
|
||||
DataNDC data(unsorted_data.begin(), unsorted_data.end());
|
||||
|
||||
CompareData::iterator compare_begin;
|
||||
CompareData::iterator compare_end;
|
||||
CompareData::iterator compare_to;
|
||||
|
||||
DataNDC::const_iterator begin;
|
||||
DataNDC::const_iterator end;
|
||||
DataNDC::const_iterator to;
|
||||
|
||||
// Move to the beginning.
|
||||
compare_begin = compare_data.begin();
|
||||
std::advance(compare_begin, 3);
|
||||
compare_end = compare_begin;
|
||||
std::advance(compare_end, 3);
|
||||
compare_to = compare_data.begin();
|
||||
compare_data.splice(compare_to, compare_data, compare_begin, compare_end);
|
||||
|
||||
begin = data.begin();
|
||||
std::advance(begin, 3);
|
||||
end = begin;
|
||||
std::advance(end, 3);
|
||||
to = data.begin();
|
||||
data.move(begin, end, to);
|
||||
|
||||
are_equal = std::equal(data.begin(), data.end(), compare_data.begin());
|
||||
CHECK(are_equal);
|
||||
|
||||
// Move to the end.
|
||||
compare_begin = compare_data.begin();
|
||||
std::advance(compare_begin, 3);
|
||||
compare_end = compare_begin;
|
||||
std::advance(compare_end, 3);
|
||||
compare_to = compare_data.end();
|
||||
compare_data.splice(compare_to, compare_data, compare_begin, compare_end);
|
||||
|
||||
begin = data.begin();
|
||||
std::advance(begin, 3);
|
||||
end = begin;
|
||||
std::advance(end, 3);
|
||||
to = data.end();
|
||||
data.move(begin, end, to);
|
||||
|
||||
are_equal = std::equal(data.begin(), data.end(), compare_data.begin());
|
||||
CHECK(are_equal);
|
||||
|
||||
// Move nearby.
|
||||
compare_begin = compare_data.begin();
|
||||
std::advance(compare_begin, 2);
|
||||
compare_end = compare_begin;
|
||||
std::advance(compare_end, 3);
|
||||
compare_to = compare_data.begin();
|
||||
std::advance(compare_to, 7);
|
||||
compare_data.splice(compare_to, compare_data, compare_begin, compare_end);
|
||||
|
||||
begin = data.begin();
|
||||
std::advance(begin, 2);
|
||||
end = begin;
|
||||
std::advance(end, 3);
|
||||
to = data.begin();
|
||||
std::advance(to, 7);
|
||||
data.move(begin, end, to);
|
||||
|
||||
are_equal = std::equal(data.begin(), data.end(), compare_data.begin());
|
||||
CHECK(are_equal);
|
||||
|
||||
// Move to illegal place.
|
||||
begin = data.begin();
|
||||
std::advance(begin, 2);
|
||||
end = begin;
|
||||
std::advance(end, 3);
|
||||
to = data.begin();
|
||||
std::advance(to, 4);
|
||||
|
||||
CHECK_THROW(data.move(begin, end, to), etl::list_iterator);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@ -109,14 +109,14 @@ namespace
|
||||
|
||||
// Allocated p1, p4
|
||||
|
||||
CHECK_EQUAL(2, pool.available());
|
||||
CHECK_EQUAL(2U, pool.available());
|
||||
|
||||
Test_Data* p5 = pool.allocate();
|
||||
Test_Data* p6 = pool.allocate();
|
||||
|
||||
// Allocated p1, p4, p5, p6
|
||||
|
||||
CHECK_EQUAL(0, pool.available());
|
||||
CHECK_EQUAL(0U, pool.available());
|
||||
|
||||
CHECK(p5 != p1);
|
||||
CHECK(p5 != p4);
|
||||
@ -128,7 +128,7 @@ namespace
|
||||
|
||||
// Allocated p1, p4, p6
|
||||
|
||||
CHECK_EQUAL(1, pool.available());
|
||||
CHECK_EQUAL(1U, pool.available());
|
||||
|
||||
Test_Data* p7 = pool.allocate();
|
||||
|
||||
@ -150,16 +150,16 @@ namespace
|
||||
Test_Data* p;
|
||||
|
||||
p = pool.allocate();
|
||||
CHECK_EQUAL(3, pool.available());
|
||||
CHECK_EQUAL(3U, pool.available());
|
||||
|
||||
p = pool.allocate();
|
||||
CHECK_EQUAL(2, pool.available());
|
||||
CHECK_EQUAL(2U, pool.available());
|
||||
|
||||
p = pool.allocate();
|
||||
CHECK_EQUAL(1, pool.available());
|
||||
CHECK_EQUAL(1U, pool.available());
|
||||
|
||||
p = pool.allocate();
|
||||
CHECK_EQUAL(0, pool.available());
|
||||
CHECK_EQUAL(0U, pool.available());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -167,28 +167,28 @@ namespace
|
||||
{
|
||||
etl::pool<Test_Data, 4> pool;
|
||||
|
||||
CHECK(pool.max_size() == 4);
|
||||
CHECK(pool.max_size() == 4U);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_size)
|
||||
{
|
||||
etl::pool<Test_Data, 4> pool;
|
||||
CHECK_EQUAL(0, pool.size());
|
||||
CHECK_EQUAL(0U, pool.size());
|
||||
|
||||
Test_Data* p;
|
||||
|
||||
p = pool.allocate();
|
||||
CHECK_EQUAL(1, pool.size());
|
||||
CHECK_EQUAL(1U, pool.size());
|
||||
|
||||
p = pool.allocate();
|
||||
CHECK_EQUAL(2, pool.size());
|
||||
CHECK_EQUAL(2U, pool.size());
|
||||
|
||||
p = pool.allocate();
|
||||
CHECK_EQUAL(3, pool.size());
|
||||
CHECK_EQUAL(3U, pool.size());
|
||||
|
||||
p = pool.allocate();
|
||||
CHECK_EQUAL(4, pool.size());
|
||||
CHECK_EQUAL(4U, pool.size());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
|
||||
@ -199,10 +199,10 @@ namespace
|
||||
etl::queue<int, 4> queue;
|
||||
|
||||
queue.push() = 1;
|
||||
CHECK_EQUAL(1, queue.size());
|
||||
CHECK_EQUAL(1U, queue.size());
|
||||
|
||||
queue.push() = 2;
|
||||
CHECK_EQUAL(2, queue.size());
|
||||
CHECK_EQUAL(2U, queue.size());
|
||||
|
||||
CHECK_EQUAL(1, queue.front());
|
||||
|
||||
@ -297,7 +297,7 @@ namespace
|
||||
queue.push(1);
|
||||
queue.push(2);
|
||||
queue.pop();
|
||||
CHECK_EQUAL(1, queue.size());
|
||||
CHECK_EQUAL(1U, queue.size());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
|
||||
@ -125,7 +125,7 @@ namespace
|
||||
const char* K17 = "FW"; // 7
|
||||
const char* K18 = "FX"; // 8
|
||||
const char* K19 = "FY"; // 9
|
||||
|
||||
|
||||
std::string K[] = { K0, K1, K2, K3, K4, K5, K6, K7, K8, K9, K10, K11, K12, K13, K14, K15, K16, K17, K18, K19 };
|
||||
|
||||
std::vector<ElementNDC> initial_data;
|
||||
@ -361,14 +361,14 @@ namespace
|
||||
TEST_FIXTURE(SetupFixture, test_insert_value)
|
||||
{
|
||||
DataNDC data;
|
||||
|
||||
|
||||
data.insert(DataNDC::value_type(K0, N0)); // Inserted
|
||||
data.insert(DataNDC::value_type(K2, N2)); // Inserted
|
||||
data.insert(DataNDC::value_type(K1, N1)); // Inserted
|
||||
data.insert(DataNDC::value_type(K11, N1)); // Duplicate hash. Inserted
|
||||
data.insert(DataNDC::value_type(K1, N3)); // Duplicate key. Not inserted
|
||||
|
||||
CHECK_EQUAL(4, data.size());
|
||||
CHECK_EQUAL(4U, data.size());
|
||||
|
||||
DataNDC::iterator idata;
|
||||
|
||||
@ -376,7 +376,7 @@ namespace
|
||||
CHECK(idata != data.end());
|
||||
CHECK(idata->first == K0);
|
||||
CHECK(idata->second == N0);
|
||||
|
||||
|
||||
idata = data.find(K1);
|
||||
CHECK(idata != data.end());
|
||||
CHECK(idata->first == K1);
|
||||
@ -541,5 +541,41 @@ namespace
|
||||
|
||||
CHECK(initial1 != different);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST_FIXTURE(SetupFixture, test_hash_function)
|
||||
{
|
||||
DataNDC data;
|
||||
DataNDC::hasher hash_function = data.hash_function();
|
||||
|
||||
CHECK_EQUAL(simple_hash()(std::string("ABCDEF")), hash_function(std::string("ABCDEF")));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST_FIXTURE(SetupFixture, test_key_eq_function)
|
||||
{
|
||||
DataNDC data;
|
||||
DataNDC::key_equal key_eq = data.key_eq();
|
||||
|
||||
CHECK(key_eq(std::string("ABCDEF"), std::string("ABCDEF")));
|
||||
CHECK(!key_eq(std::string("ABCDEF"), std::string("ABCDEG")));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST_FIXTURE(SetupFixture, test_load_factor)
|
||||
{
|
||||
// Empty.
|
||||
DataNDC data;
|
||||
CHECK_CLOSE(0.0, data.load_factor(), 0.01);
|
||||
|
||||
// Half the buckets used.
|
||||
data.assign(initial_data.begin(), initial_data.begin() + (initial_data.size() / 2));
|
||||
CHECK_CLOSE(0.5, data.load_factor(), 0.01);
|
||||
|
||||
// All of the buckets used.
|
||||
data.clear();
|
||||
data.assign(initial_data.begin(), initial_data.end());
|
||||
CHECK_CLOSE(1.0, data.load_factor(), 0.01);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@ -7,13 +7,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "etl", "etl.vcxproj", "{C21D
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug No Uint 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
|
||||
|
||||
@ -190,6 +190,7 @@
|
||||
<ClInclude Include="..\..\functional.h" />
|
||||
<ClInclude Include="..\..\hash.h" />
|
||||
<ClInclude Include="..\..\ibitset.h" />
|
||||
<ClInclude Include="..\..\icache.h" />
|
||||
<ClInclude Include="..\..\ideque.h" />
|
||||
<ClInclude Include="..\..\iflat_multimap.h" />
|
||||
<ClInclude Include="..\..\iflat_multiset.h" />
|
||||
@ -222,7 +223,9 @@
|
||||
<ClInclude Include="..\..\list.h" />
|
||||
<ClInclude Include="..\..\log.h" />
|
||||
<ClInclude Include="..\..\flat_map.h" />
|
||||
<ClInclude Include="..\..\lru_cache.h" />
|
||||
<ClInclude Include="..\..\lru_cache.h">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug No Unit Tests|Win32'">true</ExcludedFromBuild>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\map.h" />
|
||||
<ClInclude Include="..\..\mru_cache.h" />
|
||||
<ClInclude Include="..\..\multimap.h" />
|
||||
|
||||
@ -360,30 +360,12 @@
|
||||
<ClInclude Include="..\..\priority_queue.h">
|
||||
<Filter>ETL\Containers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\ilru_cache.h">
|
||||
<Filter>ETL\Maths</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\imru_cache.h">
|
||||
<Filter>ETL\Maths</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\irr_cache.h">
|
||||
<Filter>ETL\Maths</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\jenkins.h">
|
||||
<Filter>ETL\Maths</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\lru_cache.h">
|
||||
<Filter>ETL\Maths</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\mru_cache.h">
|
||||
<Filter>ETL\Maths</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\murmur3.h">
|
||||
<Filter>ETL\Maths</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\rr_cache.h">
|
||||
<Filter>ETL\Maths</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\murmurhash3.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
@ -468,6 +450,27 @@
|
||||
<ClInclude Include="..\..\char_traits.h">
|
||||
<Filter>ETL\Utilities</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\icache.h">
|
||||
<Filter>ETL\Containers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\lru_cache.h">
|
||||
<Filter>ETL\Containers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\mru_cache.h">
|
||||
<Filter>ETL\Containers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\imru_cache.h">
|
||||
<Filter>ETL\Containers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\ilru_cache.h">
|
||||
<Filter>ETL\Containers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\rr_cache.h">
|
||||
<Filter>ETL\Containers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\irr_cache.h">
|
||||
<Filter>ETL\Containers</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\..\unittest-cpp\UnitTest++\AssertException.cpp">
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user