Merge remote-tracking branch 'origin/feature/rvalue-references' into development

# Conflicts:
#	include/etl/version.h
#	support/Release notes.txt
This commit is contained in:
John Wellbelove 2019-02-14 12:52:06 +01:00
parent ca786ce0c0
commit 4b1aa0d6b5
4 changed files with 283 additions and 18 deletions

View File

@ -38,6 +38,7 @@ SOFTWARE.
#include "stl/algorithm.h"
#include "stl/iterator.h"
#include "stl/functional.h"
#include "stl/utility.h"
#include "pool.h"
#include "container.h"
@ -377,6 +378,10 @@ namespace etl
typedef const T& const_reference;
typedef size_t size_type;
#if ETL_CPP11_SUPPORTED
typedef T&& rvalue_reference;
#endif
protected:
//*************************************************************************
@ -717,7 +722,22 @@ namespace etl
insert_node_after(start_node, data_node);
}
#if ETL_CPP11_SUPPORTED && !defined(ETL_STLPORT) && !defined(ETL_NO_STL)
#if ETL_CPP11_SUPPORTED
//*************************************************************************
/// Pushes a value to the front of the forward_list.
//*************************************************************************
void push_front(rvalue_reference value)
{
#if defined(ETL_CHECK_PUSH_POP)
ETL_ASSERT(!full(), ETL_ERROR(forward_list_full));
#endif
data_node_t& data_node = allocate_data_node(std::move(value));
insert_node_after(start_node, data_node);
}
#endif
#if ETL_CPP11_SUPPORTED && !defined(ETL_STLPORT)
//*************************************************************************
/// Emplaces a value to the front of the list..
//*************************************************************************
@ -792,7 +812,7 @@ namespace etl
ETL_INCREMENT_DEBUG_COUNT
insert_node_after(start_node, *p_data_node);
}
#endif // ETL_CPP11_SUPPORTED && !defined(ETL_STLPORT) && !defined(ETL_NO_STL)
#endif // ETL_CPP11_SUPPORTED && !defined(ETL_STLPORT)
//*************************************************************************
/// Removes a value from the front of the forward_list.
@ -870,7 +890,7 @@ namespace etl
return iterator(&data_node);
}
#if ETL_CPP11_SUPPORTED && !defined(ETL_STLPORT) && !defined(ETL_NO_STL)
#if ETL_CPP11_SUPPORTED && !defined(ETL_STLPORT)
//*************************************************************************
/// Emplaces a value to the forward_list after the specified position.
//*************************************************************************
@ -950,7 +970,7 @@ namespace etl
return iterator(p_data_node);
}
#endif // ETL_CPP11_SUPPORTED && !defined(ETL_STLPORT) && !defined(ETL_NO_STL)
#endif // ETL_CPP11_SUPPORTED && !defined(ETL_STLPORT)
//*************************************************************************
/// Inserts 'n' copies of a value to the forward_list after the specified position.
@ -1332,6 +1352,18 @@ namespace etl
return *this;
}
#if ETL_CPP11_SUPPORTED
//*************************************************************************
/// Move assignment operator.
//*************************************************************************
iforward_list& operator = (iforward_list&& rhs)
{
move_container(std::move(rhs));
return *this;
}
#endif
protected:
//*************************************************************************
@ -1381,6 +1413,63 @@ namespace etl
start_node.next = nullptr;
}
//*************************************************************************
/// Allocate a data_node_t.
//*************************************************************************
data_node_t& allocate_data_node(const_reference value)
{
data_node_t* p_node = p_node_pool->allocate<data_node_t>();
::new (&(p_node->value)) T(value);
ETL_INCREMENT_DEBUG_COUNT
return *p_node;
}
#if ETL_CPP11_SUPPORTED
//*************************************************************************
/// Allocate a data_node_t.
//*************************************************************************
data_node_t& allocate_data_node(rvalue_reference value)
{
data_node_t* p_node = p_node_pool->allocate<data_node_t>();
::new (&(p_node->value)) T(std::move(value));
ETL_INCREMENT_DEBUG_COUNT
return *p_node;
}
#endif
#if ETL_CPP11_SUPPORTED
//*************************************************************************
/// Move a forward list
//*************************************************************************
void move_container(iforward_list&& rhs)
{
if (&rhs != this)
{
this->initialise();
node_t* p_last_node = &start_node;
etl::iforward_list<T>::iterator first = rhs.begin();
etl::iforward_list<T>::iterator last = rhs.end();
// Add all of the elements.
while (first != last)
{
ETL_ASSERT(!full(), ETL_ERROR(forward_list_full));
data_node_t& data_node = this->allocate_data_node(std::move(*first++));
join(p_last_node, &data_node);
data_node.next = nullptr;
p_last_node = &data_node;
}
rhs.initialise();
}
}
#endif
private:
//*************************************************************************
@ -1433,18 +1522,6 @@ namespace etl
}
}
//*************************************************************************
/// Allocate a data_node_t.
//*************************************************************************
data_node_t& allocate_data_node(const T& value)
{
data_node_t* p_node = p_node_pool->allocate<data_node_t>();
::new (&(p_node->value)) T(value);
ETL_INCREMENT_DEBUG_COUNT
return *p_node;
}
//*************************************************************************
/// Destroy a data_node_t.
//*************************************************************************
@ -1521,6 +1598,17 @@ namespace etl
this->assign(other.cbegin(), other.cend());
}
#if ETL_CPP11_SUPPORTED
//*************************************************************************
/// Move constructor.
//*************************************************************************
forward_list(forward_list&& other)
: etl::iforward_list<T>(node_pool, MAX_SIZE, false)
{
this->move_container(std::move(other));
}
#endif
//*************************************************************************
/// Construct from range.
//*************************************************************************
@ -1563,6 +1651,19 @@ namespace etl
return *this;
}
#if ETL_CPP11_SUPPORTED
//*************************************************************************
/// Move assignment operator.
//*************************************************************************
forward_list& operator = (forward_list&& rhs)
{
this->move_container(std::move(rhs));
return *this;
}
#endif
private:
/// The pool of nodes used in the list.
@ -1631,6 +1732,29 @@ namespace etl
this->assign(other.cbegin(), other.cend());
}
#if ETL_CPP11_SUPPORTED
//*************************************************************************
/// Move constructor.
//*************************************************************************
forward_list(forward_list&& other)
: etl::iforward_list<T>(*other.p_node_pool, other.p_node_pool->max_size(), true)
{
if (this != &other)
{
this->initialise();
typename etl::iforward_list<T>::iterator itr = other.begin();
while (itr != other.end())
{
this->push_back(std::move(*itr));
++itr;
}
other.initialise();
}
}
#endif
//*************************************************************************
/// Construct from range.
//*************************************************************************
@ -1673,6 +1797,18 @@ namespace etl
return *this;
}
#if ETL_CPP11_SUPPORTED
//*************************************************************************
/// Move assignment operator.
//*************************************************************************
forward_list& operator = (forward_list&& rhs)
{
this->move_container(std::move(rhs));
return *this;
}
#endif
//*************************************************************************
/// Set the pool instance.
//*************************************************************************

View File

@ -38,8 +38,8 @@ SOFTWARE.
///\ingroup utilities
#define ETL_VERSION_MAJOR 14
#define ETL_VERSION_MINOR 10
#define ETL_VERSION_PATCH 2
#define ETL_VERSION_MINOR 11
#define ETL_VERSION_PATCH 0
#define ETL_VERSION ETL_STRINGIFY(ETL_VERSION_MAJOR) ETL_STRINGIFY(ETL_VERSION_MINOR) ETL_STRINGIFY(ETL_VERSION_PATCH)
#define ETL_VERSION_W ETL_WIDE_STRING(ETL_CONCAT(ETL_CONCAT(ETL_VERSION_MAJOR, ETL_VERSION_MINOR), ETL_VERSION_PATCH))

View File

@ -1,3 +1,7 @@
===============================================================================
14.11.0
Added rvalue reference interfaces to forward_list.
===============================================================================
14.10.2
Fix for unordered_multimap, unordered_set and unordered_multiset insert and erase bug.

View File

@ -48,11 +48,15 @@ namespace
typedef TestDataDC<std::string> ItemDC;
typedef TestDataNDC<std::string> ItemNDC;
typedef TestDataM<uint32_t> ItemM;
typedef etl::forward_list<ItemDC, SIZE> DataDC;
typedef etl::forward_list<ItemNDC, SIZE> DataNDC;
typedef etl::iforward_list<ItemNDC> IDataNDC;
typedef etl::forward_list<ItemM, SIZE> DataM;
typedef etl::iforward_list<ItemM> IDataM;
typedef etl::forward_list<int, SIZE> DataInt;
typedef std::forward_list<ItemDC> CompareDataDC;
@ -170,6 +174,98 @@ namespace
CHECK(std::equal(data.begin(), data.end(), other_data.begin()));
}
//*************************************************************************
TEST(test_move_constructor)
{
ItemM p1(1U);
ItemM p2(2U);
ItemM p3(3U);
ItemM p4(4U);
DataM data1;
data1.push_front(std::move(p1));
data1.push_front(std::move(p2));
data1.push_front(std::move(p3));
data1.push_front(std::move(p4));
CHECK(!bool(p1));
CHECK(!bool(p2));
CHECK(!bool(p3));
CHECK(!bool(p4));
DataM data2(std::move(data1));
CHECK_EQUAL(0U, data1.size());
CHECK_EQUAL(4U, data2.size());
DataM::const_iterator itr = data2.begin();
CHECK_EQUAL(4U, (*itr++).value);
CHECK_EQUAL(3U, (*itr++).value);
CHECK_EQUAL(2U, (*itr++).value);
CHECK_EQUAL(1U, (*itr++).value);
}
//*************************************************************************
TEST(test_move_assignment)
{
ItemM p1(1U);
ItemM p2(2U);
ItemM p3(3U);
ItemM p4(4U);
DataM data1;
data1.push_front(std::move(p1));
data1.push_front(std::move(p2));
data1.push_front(std::move(p3));
data1.push_front(std::move(p4));
DataM data2;
data2 = std::move(data1);
CHECK_EQUAL(0U, data1.size());
CHECK_EQUAL(4U, data2.size());
DataM::const_iterator itr = data2.begin();
CHECK_EQUAL(4U, (*itr++).value);
CHECK_EQUAL(3U, (*itr++).value);
CHECK_EQUAL(2U, (*itr++).value);
CHECK_EQUAL(1U, (*itr++).value);
}
//*************************************************************************
TEST(test_move_assignment_interface)
{
ItemM p1(1U);
ItemM p2(2U);
ItemM p3(3U);
ItemM p4(4U);
DataM data1;
data1.push_front(std::move(p1));
data1.push_front(std::move(p2));
data1.push_front(std::move(p3));
data1.push_front(std::move(p4));
DataM data2;
IDataM& idata1 = data1;
IDataM& idata2 = data2;
idata2 = std::move(idata1);
CHECK_EQUAL(0U, data1.size());
CHECK_EQUAL(4U, data2.size());
DataM::const_iterator itr = data2.begin();
CHECK_EQUAL(4U, (*itr++).value);
CHECK_EQUAL(3U, (*itr++).value);
CHECK_EQUAL(2U, (*itr++).value);
CHECK_EQUAL(1U, (*itr++).value);
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_iterator)
{
@ -501,6 +597,35 @@ namespace
CHECK(are_equal);
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_push_front_move)
{
ItemM p1(1U);
ItemM p2(2U);
ItemM p3(3U);
ItemM p4(4U);
DataM data;
data.push_front(std::move(p1));
data.push_front(std::move(p2));
data.push_front(std::move(p3));
data.push_front(std::move(p4));
CHECK_EQUAL(4U, data.size());
CHECK(!bool(p1));
CHECK(!bool(p2));
CHECK(!bool(p3));
CHECK(!bool(p4));
DataM::const_iterator itr = data.begin();
CHECK_EQUAL(4U, (*itr++).value);
CHECK_EQUAL(3U, (*itr++).value);
CHECK_EQUAL(2U, (*itr++).value);
CHECK_EQUAL(1U, (*itr++).value);
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_emplace_front)
{