diff --git a/include/etl/deque.h b/include/etl/deque.h index b829da5d..f44389e2 100644 --- a/include/etl/deque.h +++ b/include/etl/deque.h @@ -49,7 +49,6 @@ SOFTWARE. #include "debug_count.h" #include "algorithm.h" #include "type_traits.h" -#include "parameter_type.h" #if ETL_CPP11_SUPPORTED && !defined(ETL_STLPORT) && !defined(ETL_NO_STL) #include @@ -1948,6 +1947,29 @@ namespace etl return *this; } +#if ETL_CPP11_SUPPORTED + //************************************************************************* + /// Move assignment operator. + //************************************************************************* + ideque& operator =(ideque&& rhs) + { + if (&rhs != this) + { + clear(); + iterator itr = rhs.begin(); + while (itr != rhs.end()) + { + push_back(std::move(*itr)); + ++itr; + } + + rhs.initialise(); + } + + return *this; + } +#endif + #ifdef ETL_IDEQUE_REPAIR_ENABLE //************************************************************************* /// Fix the internal pointers after a low level memory copy. diff --git a/include/etl/list.h b/include/etl/list.h index ed539543..3d62eb17 100644 --- a/include/etl/list.h +++ b/include/etl/list.h @@ -46,8 +46,8 @@ SOFTWARE. #include "debug_count.h" #include "nullptr.h" #include "type_traits.h" -#include "parameter_type.h" #include "algorithm.h" +#include "memory.h" #if ETL_CPP11_SUPPORTED && !defined(ETL_STLPORT) && !defined(ETL_NO_STL) #include @@ -418,6 +418,7 @@ namespace etl typedef const T* const_pointer; typedef T& reference; typedef const T& const_reference; + typedef T&& rvalue_reference; typedef size_t size_type; protected: @@ -429,7 +430,7 @@ namespace etl //************************************************************************* struct data_node_t : public node_t { - explicit data_node_t(parameter_t value_) + explicit data_node_t(const T& value_) : value(value_) { } @@ -823,7 +824,7 @@ namespace etl //************************************************************************* /// Assigns 'n' copies of a value to the list. //************************************************************************* - void assign(size_t n, parameter_t value) + void assign(size_t n, const T& value) { #if defined(ETL_DEBUG) ETL_ASSERT(n <= available(), ETL_ERROR(list_full)); @@ -843,7 +844,7 @@ namespace etl //************************************************************************* /// Pushes a value to the front of the list. //************************************************************************* - void push_front(parameter_t value) + void push_front(const T& value) { #if defined(ETL_CHECK_PUSH_POP) ETL_ASSERT(!full(), ETL_ERROR(list_full)); @@ -851,6 +852,19 @@ namespace etl insert_node(get_head(), allocate_data_node(value)); } +#if ETL_CPP11_SUPPORTED + //************************************************************************* + /// Pushes a value to the front of the list. + //************************************************************************* + void push_front(rvalue_reference value) + { +#if defined(ETL_CHECK_PUSH_POP) + ETL_ASSERT(!full(), ETL_ERROR(list_full)); +#endif + insert_node(get_head(), allocate_data_node(std::move(value))); + } +#endif + #if ETL_CPP11_SUPPORTED && !defined(ETL_STLPORT) && !defined(ETL_NO_STL) //************************************************************************* /// Emplaces a value to the front of the list. @@ -953,7 +967,7 @@ namespace etl //************************************************************************* /// Pushes a value to the back of the list. //************************************************************************* - void push_back(parameter_t value) + void push_back(const T& value) { #if defined(ETL_CHECK_PUSH_POP) ETL_ASSERT(!full(), ETL_ERROR(list_full)); @@ -961,6 +975,19 @@ namespace etl insert_node(terminal_node, allocate_data_node(value)); } +#if ETL_CPP11_SUPPORTED + //************************************************************************* + /// Pushes a value to the back of the list. + //************************************************************************* + void push_back(rvalue_reference value) + { +#if defined(ETL_CHECK_PUSH_POP) + ETL_ASSERT(!full(), ETL_ERROR(list_full)); +#endif + insert_node(terminal_node, allocate_data_node(std::move(value))); + } +#endif + //************************************************************************* /// Emplaces a value to the back of the list. //************************************************************************* @@ -1051,7 +1078,7 @@ namespace etl //************************************************************************* /// Inserts a value to the list at the specified position. //************************************************************************* - iterator insert(iterator position, const value_type& value) + iterator insert(iterator position, const_reference value) { ETL_ASSERT(!full(), ETL_ERROR(list_full)); @@ -1061,6 +1088,21 @@ namespace etl return iterator(data_node); } +#if ETL_CPP11_SUPPORTED + //************************************************************************* + /// Inserts a value to the list at the specified position. + //************************************************************************* + iterator insert(iterator position, rvalue_reference value) + { + ETL_ASSERT(!full(), ETL_ERROR(list_full)); + + data_node_t& data_node = allocate_data_node(std::move(value)); + insert_node(*position.p_node, data_node); + + return iterator(data_node); + } +#endif + //************************************************************************* /// Emplaces a value to the list at the specified position. //************************************************************************* @@ -1139,7 +1181,7 @@ namespace etl //************************************************************************* /// Inserts 'n' copies of a value to the list at the specified position. //************************************************************************* - void insert(iterator position, size_t n, const value_type& value) + void insert(iterator position, size_t n, const_reference value) { for (size_t i = 0; i < n; ++i) { @@ -1209,7 +1251,7 @@ namespace etl //************************************************************************* /// Resizes the list. //************************************************************************* - void resize(size_t n, parameter_t value) + void resize(size_t n, const_reference value) { ETL_ASSERT(n <= MAX_SIZE, ETL_ERROR(list_full)); @@ -1238,7 +1280,7 @@ namespace etl //************************************************************************* // Removes the values specified. //************************************************************************* - void remove(const value_type& value) + void remove(const_reference value) { iterator iValue = begin(); @@ -1327,6 +1369,25 @@ namespace etl } } +#if ETL_CPP11_SUPPORTED + //************************************************************************* + /// Splices from another list to this. + //************************************************************************* + void splice(iterator to, ilist&& other) + { + if (&other != this) + { + ilist::iterator itr = other.begin(); + while (itr != other.end()) + { + to = insert(to, std::move(*itr++)); + } + + other.erase(other.begin(), other.end()); + } + } +#endif + //************************************************************************* /// Splices an element from another list to this. //************************************************************************* @@ -1345,6 +1406,26 @@ namespace etl } } +#if ETL_CPP11_SUPPORTED + //************************************************************************* + /// Splices an element from another list to this. + //************************************************************************* + void splice(iterator to, ilist&& other, iterator from) + { + if (&other == this) + { + // Internal move. + move(to, from); + } + else + { + // From another list. + insert(to, std::move(*from)); + other.erase(from); + } + } +#endif + //************************************************************************* /// Splices a range of elements from another list to this. //************************************************************************* @@ -1363,6 +1444,32 @@ namespace etl } } +#if ETL_CPP11_SUPPORTED + //************************************************************************* + /// Splices a range of elements from another list to this. + //************************************************************************* + void splice(iterator to, ilist&& other, iterator first, iterator last) + { + if (&other == this) + { + // Internal move. + move(to, first, last); + } + else + { + // From another list. + ilist::iterator itr = first; + while (itr != last) + { + to = insert(to, std::move(*itr++)); + ++to; + } + + other.erase(first, last); + } + } +#endif + //************************************************************************* /// Merge another list into this one. Both lists should be sorted. //************************************************************************* @@ -1419,6 +1526,67 @@ namespace etl } } +#if ETL_CPP11_SUPPORTED + //************************************************************************* + /// Merge another list into this one. Both lists should be sorted. + //************************************************************************* + void merge(ilist&& other) + { + merge(std::move(other), std::less()); + } + + //************************************************************************* + /// Merge another list into this one. Both lists should be sorted. + //************************************************************************* + template + void merge(ilist&& other, TCompare compare) + { + if (!other.empty()) + { +#if defined(ETL_DEBUG) + ETL_ASSERT(etl::is_sorted(other.begin(), other.end(), compare), ETL_ERROR(list_unsorted)); + ETL_ASSERT(etl::is_sorted(begin(), end(), compare), ETL_ERROR(list_unsorted)); +#endif + + ilist::iterator other_begin = other.begin(); + ilist::iterator other_end = other.end(); + + ilist::iterator this_begin = begin(); + ilist::iterator this_end = end(); + + while ((this_begin != this_end) && (other_begin != other_end)) + { + // Find the place to insert. + while ((this_begin != this_end) && !(compare(*other_begin, *this_begin))) + { + ++this_begin; + } + + // Insert. + if (this_begin != this_end) + { + while ((other_begin != other_end) && (compare(*other_begin, *this_begin))) + { + insert(this_begin, std::move(*other_begin)); + ++other_begin; + } + } + } + + // Any left over? + if ((this_begin == this_end) && (other_begin != other_end)) + { + while (other_begin != other_end) + { + insert(this_end, std::move(*other_begin++)); + } + } + + other.clear(); + } + } +#endif + //************************************************************************* /// Sort using in-place merge sort algorithm. /// Uses 'less-than operator as the predicate. @@ -1554,6 +1722,30 @@ namespace etl return *this; } +#if ETL_CPP11_SUPPORTED + //************************************************************************* + /// Assignment operator. + //************************************************************************* + ilist& operator = (ilist&& rhs) + { + if (&rhs != this) + { + this->initialise(); + + iterator itr = rhs.begin(); + while (itr != rhs.end()) + { + push_back(std::move(*itr)); + ++itr; + } + + rhs.initialise(); + } + + return *this; + } +#endif + protected: //************************************************************************* @@ -1675,7 +1867,7 @@ namespace etl //************************************************************************* /// Allocate a data_node_t. //************************************************************************* - data_node_t& allocate_data_node(parameter_t value) + data_node_t& allocate_data_node(const_reference value) { ETL_ASSERT(p_node_pool != nullptr, ETL_ERROR(list_no_pool)); @@ -1686,6 +1878,22 @@ namespace etl return *p_data_node; } +#if ETL_CPP11_SUPPORTED + //************************************************************************* + /// Allocate a data_node_t. + //************************************************************************* + data_node_t& allocate_data_node(rvalue_reference value) + { + ETL_ASSERT(p_node_pool != nullptr, ETL_ERROR(list_no_pool)); + + data_node_t* p_data_node = p_node_pool->allocate(); + ::new (&(p_data_node->value)) T(std::move(value)); + ETL_INCREMENT_DEBUG_COUNT + + return *p_data_node; + } +#endif + //************************************************************************* /// Destroy a data_node_t. //************************************************************************* @@ -1715,7 +1923,6 @@ namespace etl //************************************************************************* /// A templated list implementation that uses a fixed size buffer. - ///\note 'merge' and 'splice' and are not supported. //************************************************************************* template class list : public etl::ilist @@ -1731,6 +1938,7 @@ namespace etl typedef const T* const_pointer; typedef T& reference; typedef const T& const_reference; + typedef T&& rvalue_reference; typedef size_t size_type; //************************************************************************* @@ -1761,7 +1969,7 @@ namespace etl //************************************************************************* /// Construct from size and value. //************************************************************************* - list(size_t initial_size, typename ilist::parameter_t value) + list(size_t initial_size, const T& value) : etl::ilist(node_pool, MAX_SIZE, false) { this->assign(initial_size, value); @@ -1779,6 +1987,29 @@ namespace etl } } +#if ETL_CPP11_SUPPORTED + //************************************************************************* + /// Move constructor. + //************************************************************************* + list(list&& other) + : etl::ilist(node_pool, MAX_SIZE, false) + { + if (this != &other) + { + this->initialise(); + + typename etl::ilist::iterator itr = other.begin(); + while (itr != other.end()) + { + this->push_back(std::move(*itr)); + ++itr; + } + + other.initialise(); + } + } +#endif + //************************************************************************* /// Construct from range. //************************************************************************* @@ -1813,6 +2044,30 @@ namespace etl return *this; } +#if ETL_CPP11_SUPPORTED + //************************************************************************* + /// Assignment operator. + //************************************************************************* + list& operator = (list&& rhs) + { + if (&rhs != this) + { + this->initialise(); + + typename etl::ilist::iterator itr = rhs.begin(); + while (itr != rhs.end()) + { + this->push_back(std::move(*itr)); + ++itr; + } + + rhs.initialise(); + } + + return *this; + } +#endif + private: /// The pool of nodes used in the list. @@ -1821,7 +2076,6 @@ namespace etl //************************************************************************* /// A templated list implementation that uses a fixed size buffer. - ///\note 'merge' and 'splice' and are not supported. //************************************************************************* template class list : public etl::ilist @@ -1873,7 +2127,7 @@ namespace etl //************************************************************************* /// Construct from size and value. //************************************************************************* - list(size_t initial_size, typename ilist::parameter_t value, etl::ipool& node_pool) + list(size_t initial_size, const T& value, etl::ipool& node_pool) : etl::ilist(node_pool, node_pool.max_size(), true) { this->assign(initial_size, value); @@ -1891,6 +2145,29 @@ namespace etl } } +#if ETL_CPP11_SUPPORTED + //************************************************************************* + /// Move constructor. + //************************************************************************* + list(list&& other) + : etl::ilist(*other.p_node_pool, other.p_node_pool->max_size(), true) + { + if (this != &other) + { + this->initialise(); + + typename etl::ilist::iterator itr = other.begin(); + while (itr != other.end()) + { + this->push_back(std::move(*itr)); + ++itr; + } + + other.initialise(); + } + } +#endif + //************************************************************************* /// Construct from range. //************************************************************************* @@ -1925,6 +2202,30 @@ namespace etl return *this; } +#if ETL_CPP11_SUPPORTED + //************************************************************************* + /// Assignment operator. + //************************************************************************* + list& operator = (list&& rhs) + { + if (&rhs != this) + { + this->initialise(); + + typename etl::ilist::iterator itr = rhs.begin(); + while (itr != rhs.end()) + { + this->push_back(std::move(*itr)); + ++itr; + } + + rhs.initialise(); + } + + return *this; + } +#endif + //************************************************************************* /// Set the pool instance. //************************************************************************* diff --git a/include/etl/memory.h b/include/etl/memory.h index 0be98a1b..b063dc1a 100644 --- a/include/etl/memory.h +++ b/include/etl/memory.h @@ -417,6 +417,18 @@ namespace etl ::new (p) T(value); } +#if ETL_CPP11_SUPPORTED + //***************************************************************************** + /// Copy construct an item at address p. + ///\ingroup memory + //***************************************************************************** + template + void create_copy_at(T* p, T&& value) + { + ::new (p) T(std::move(value)); + } +#endif + //***************************************************************************** /// Copy construct an item at address p. ///\ingroup memory @@ -462,6 +474,19 @@ namespace etl return *reinterpret_cast(p); } +#if ETL_CPP11_SUPPORTED + //***************************************************************************** + /// Construct an item at address p. + ///\ingroup memory + //***************************************************************************** + template + T& make_copy_at(T* p, T&& other) + { + ::new (p) T(std::move(other)); + return *reinterpret_cast(p); + } +#endif + //***************************************************************************** /// Construct an item at address p. ///\ingroup memory @@ -485,6 +510,17 @@ namespace etl return *reinterpret_cast(p); } + //***************************************************************************** + /// Construct an item at address p. + ///\ingroup memory + //***************************************************************************** + template + T& make_value_at(T* p, TParameter&& value) + { + ::new (p) T(std::move(value)); + return *reinterpret_cast(p); + } + //***************************************************************************** /// Construct an item at address p. ///\ingroup memory diff --git a/include/etl/type_traits_generator.h b/include/etl/type_traits_generator.h index 183d74ca..83b982bd 100644 --- a/include/etl/type_traits_generator.h +++ b/include/etl/type_traits_generator.h @@ -326,6 +326,13 @@ namespace etl template struct is_trivially_copy_assignable : etl::is_pod {}; #endif +#if ETL_CPP11_SUPPORTED + /// is_rvalue_reference + ///\ingroup type_traits + template struct is_rvalue_reference : etl::false_type {}; + template struct is_rvalue_reference : etl::true_type {}; +#endif + /// conditional ///\ingroup type_traits template struct conditional { typedef T type; }; @@ -347,7 +354,7 @@ namespace etl struct conditional_integral_constant { ETL_STATIC_ASSERT(etl::is_integral::value, "Not an integral type"); - static const T value = FALSE_VALUE; + static const T value = FALSE_VALUE; }; /// make_signed diff --git a/include/etl/vector.h b/include/etl/vector.h index 724712e8..8b3cf069 100644 --- a/include/etl/vector.h +++ b/include/etl/vector.h @@ -40,7 +40,6 @@ SOFTWARE. #include "platform.h" #include "algorithm.h" #include "type_traits.h" -#include "parameter_type.h" #include "error_handler.h" #include "memory.h" #include "container.h" @@ -86,6 +85,7 @@ namespace etl typedef T value_type; typedef T& reference; typedef const T& const_reference; + typedef T&& rvalue_reference; typedef T* pointer; typedef const T* const_pointer; typedef T* iterator; @@ -405,7 +405,7 @@ namespace etl /// If asserts or exceptions are enabled, emits vector_full if the vector is already full. ///\param value The value to add. //********************************************************************* - void push_back(parameter_t value) + void push_back(const_reference value) { #if defined(ETL_CHECK_PUSH_POP) ETL_ASSERT(size() != CAPACITY, ETL_ERROR(vector_full)); @@ -413,6 +413,21 @@ namespace etl create_back(value); } +#if ETL_CPP11_SUPPORTED + //********************************************************************* + /// Inserts a value at the end of the vector. + /// If asserts or exceptions are enabled, emits vector_full if the vector is already full. + ///\param value The value to add. + //********************************************************************* + void push_back(rvalue_reference value) + { +#if defined(ETL_CHECK_PUSH_POP) + ETL_ASSERT(size() != CAPACITY, ETL_ERROR(vector_full)); +#endif + create_back(std::move(value)); + } +#endif + #if ETL_CPP11_SUPPORTED && !defined(ETL_STLPORT) && !defined(ETL_NO_STL) && !ETL_VECTOR_FORCE_CPP03 //********************************************************************* /// Constructs a value at the end of the vector. @@ -513,7 +528,7 @@ namespace etl ///\param position The position to insert before. ///\param value The value to insert. //********************************************************************* - iterator insert(iterator position, parameter_t value) + iterator insert(iterator position, const_reference value) { ETL_ASSERT(size() + 1 <= CAPACITY, ETL_ERROR(vector_full)); @@ -524,13 +539,39 @@ namespace etl else { create_back(back()); - std::copy_backward(position, p_end - 1, p_end); + std::copy_backward(position, p_end - 2, p_end - 1); *position = value; } return position; } +#if ETL_CPP11_SUPPORTED + //********************************************************************* + /// Inserts a value to the vector. + /// If asserts or exceptions are enabled, emits vector_full if the vector is already full. + ///\param position The position to insert before. + ///\param value The value to insert. + //********************************************************************* + iterator insert(iterator position, rvalue_reference value) + { + ETL_ASSERT(size() + 1 <= CAPACITY, ETL_ERROR(vector_full)); + + if (position == end()) + { + create_back(std::move(value)); + } + else + { + create_back(std::move(back())); + std::move_backward(position, p_end - 2, p_end - 1); + *position = std::move(value); + } + + return position; + } +#endif + //************************************************************************* /// Emplaces a value to the vextor at the specified position. //************************************************************************* @@ -551,7 +592,7 @@ namespace etl { p = etl::addressof(*position); create_back(back()); - std::copy_backward(position, p_end - 1, p_end); + std::copy_backward(position, p_end - 2, p_end - 1); (*position).~T(); } @@ -576,7 +617,7 @@ namespace etl { p = etl::addressof(*position); create_back(back()); - std::copy_backward(position, p_end - 1, p_end); + std::copy_backward(position, p_end - 2, p_end - 1); (*position).~T(); } @@ -601,7 +642,7 @@ namespace etl { p = etl::addressof(*position); create_back(back()); - std::copy_backward(position, p_end - 1, p_end); + std::copy_backward(position, p_end - 2, p_end - 1); (*position).~T(); } @@ -626,7 +667,7 @@ namespace etl { p = etl::addressof(*position); create_back(back()); - std::copy_backward(position, p_end - 1, p_end); + std::copy_backward(position, p_end - 2, p_end - 1); (*position).~T(); } @@ -651,7 +692,7 @@ namespace etl { p = etl::addressof(*position); create_back(back()); - std::copy_backward(position, p_end - 1, p_end); + std::copy_backward(position, p_end - 2, p_end - 1); (*position).~T(); } @@ -701,15 +742,15 @@ namespace etl etl::uninitialized_copy_n(p_end - construct_old_n, construct_old_n, p_construct_old); ETL_ADD_DEBUG_COUNT(construct_old_n) - // Copy old. - etl::copy_n(p_buffer + insert_begin, copy_old_n, p_buffer + insert_end); + // Copy old. + etl::copy_n(p_buffer + insert_begin, copy_old_n, p_buffer + insert_end); // Construct new. etl::uninitialized_fill_n(p_end, construct_new_n, value); ETL_ADD_DEBUG_COUNT(construct_new_n) - // Copy new. - std::fill_n(p_buffer + insert_begin, copy_new_n, value); + // Copy new. + std::fill_n(p_buffer + insert_begin, copy_new_n, value); p_end += n; } @@ -758,15 +799,15 @@ namespace etl etl::uninitialized_copy_n(p_end - construct_old_n, construct_old_n, p_construct_old); ETL_ADD_DEBUG_COUNT(construct_old_n) - // Copy old. - etl::copy_n(p_buffer + insert_begin, copy_old_n, p_buffer + insert_end); + // Copy old. + etl::copy_n(p_buffer + insert_begin, copy_old_n, p_buffer + insert_end); // Construct new. etl::uninitialized_copy_n(first + copy_new_n, construct_new_n, p_end); ETL_ADD_DEBUG_COUNT(construct_new_n) - // Copy new. - etl::copy_n(first, copy_new_n, p_buffer + insert_begin); + // Copy new. + etl::copy_n(first, copy_new_n, p_buffer + insert_begin); p_end += count; } @@ -806,7 +847,7 @@ namespace etl // Destroy the elements left over at the end. etl::destroy(p_end - n_delete, p_end); ETL_SUBTRACT_DEBUG_COUNT(n_delete) - p_end -= n_delete; + p_end -= n_delete; } return first; @@ -825,6 +866,29 @@ namespace etl return *this; } +#if ETL_CPP11_SUPPORTED + //************************************************************************* + /// Move assignment operator. + //************************************************************************* + ivector& operator = (ivector&& rhs) + { + if (&rhs != this) + { + clear(); + iterator itr = rhs.begin(); + while (itr != rhs.end()) + { + push_back(std::move(*itr)); + ++itr; + } + + rhs.initialise(); + } + + return *this; + } +#endif + //************************************************************************* /// Gets the current size of the vector. ///\return The current size of the vector. @@ -888,7 +952,7 @@ namespace etl etl::destroy(p_buffer, p_end); ETL_SUBTRACT_DEBUG_COUNT(int32_t(std::distance(p_buffer, p_end))) - p_end = p_buffer; + p_end = p_buffer; } //************************************************************************* @@ -898,7 +962,7 @@ namespace etl { uintptr_t length = p_end - p_buffer; p_buffer = p_buffer_; - p_end = p_buffer_ + length; + p_end = p_buffer_ + length; } private: @@ -920,7 +984,7 @@ namespace etl //********************************************************************* /// Create a new element with a value at the back //********************************************************************* - inline void create_back(parameter_t value) + inline void create_back(const_reference value) { etl::create_copy_at(p_end, value); ETL_INCREMENT_DEBUG_COUNT @@ -928,6 +992,19 @@ namespace etl ++p_end; } +#if ETL_CPP11_SUPPORTED + //********************************************************************* + /// Create a new element with a value at the back + //********************************************************************* + inline void create_back(rvalue_reference value) + { + etl::create_copy_at(p_end, std::move(value)); + ETL_INCREMENT_DEBUG_COUNT + + ++p_end; + } +#endif + //********************************************************************* /// Destroy an element at the back. //********************************************************************* @@ -1035,7 +1112,12 @@ namespace etl { return !(lhs < rhs); } +} +#include "private/ivectorpointer.h" + +namespace etl +{ //*************************************************************************** /// A vector implementation that uses a fixed size buffer. ///\tparam T The element type. @@ -1114,14 +1196,6 @@ namespace etl this->assign(other.begin(), other.end()); } - //************************************************************************* - /// Destructor. - //************************************************************************* - ~vector() - { - this->clear(); - } - //************************************************************************* /// Assignment operator. //************************************************************************* @@ -1135,6 +1209,58 @@ namespace etl return *this; } +#if ETL_CPP11_SUPPORTED + //************************************************************************* + /// Move constructor. + //************************************************************************* + vector(vector&& other) + : etl::ivector(reinterpret_cast(&buffer), MAX_SIZE) + { + if (this != &other) + { + this->initialise(); + + typename etl::ivector::iterator itr = other.begin(); + while (itr != other.end()) + { + this->push_back(std::move(*itr)); + ++itr; + } + + other.initialise(); + } + } + + //************************************************************************* + /// Move assignment operator. + //************************************************************************* + vector& operator = (vector&& rhs) + { + if (&rhs != this) + { + this->clear(); + typename etl::ivector::iterator itr = rhs.begin(); + while (itr != rhs.end()) + { + this->push_back(std::move(*itr)); + ++itr; + } + + rhs.initialise(); + } + + return *this; + } +#endif + + //************************************************************************* + /// Destructor. + //************************************************************************* + ~vector() + { + this->clear(); + } + //************************************************************************* /// Fix the internal pointers after a low level memory copy. //************************************************************************* @@ -1230,7 +1356,10 @@ namespace etl vector(const vector& other) : etl::ivector(reinterpret_cast(&buffer), MAX_SIZE) { - this->assign(other.begin(), other.end()); + if (this != &other) + { + this->assign(other.begin(), other.end()); + } } //************************************************************************* @@ -1260,8 +1389,6 @@ namespace etl }; } -#include "private/ivectorpointer.h" - #ifdef ETL_COMPILER_GCC #pragma GCC diagnostic pop #endif diff --git a/include/etl/version.h b/include/etl/version.h index 833856aa..71b9bf12 100644 --- a/include/etl/version.h +++ b/include/etl/version.h @@ -38,8 +38,8 @@ SOFTWARE. ///\ingroup utilities #define ETL_VERSION_MAJOR 14 -#define ETL_VERSION_MINOR 6 -#define ETL_VERSION_PATCH 1 +#define ETL_VERSION_MINOR 7 +#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)) diff --git a/support/Release notes.txt b/support/Release notes.txt index a989ff64..11d1c787 100644 --- a/support/Release notes.txt +++ b/support/Release notes.txt @@ -1,3 +1,10 @@ +=============================================================================== +14.7.0 +Continuing updates for adding rvalue reference API to the containers. +etl::deque +etl::list +etl::vector + =============================================================================== 14.6.1 Fixed bugs in etl::flat_map 'operator[]' and 'insert'. diff --git a/test/data.h b/test/data.h index c43769e8..14b5f47c 100644 --- a/test/data.h +++ b/test/data.h @@ -152,4 +152,89 @@ std::ostream& operator << (std::ostream& s, const TestDataNDC& rhs) return s; } +//***************************************************************************** +// Movable. +//***************************************************************************** +template +class TestDataM : public etl::instance_count> +{ +public: + + explicit TestDataM(const T& value_) + : value(value_) + , valid(true) + { + } + + TestDataM(TestDataM&& other) + : value(other.value) + , valid(true) + { + other.value = T(); + other.valid = false; + } + + TestDataM& operator =(TestDataM&& other) + { + value = other.value; + valid = true; + + other.value = T(); + other.valid = false; + } + + bool operator < (const TestDataM& other) const + { + return value < other.value; + } + + bool operator > (const TestDataM& other) const + { + return other.value < value; + } + + bool operator <= (const TestDataM& other) const + { + return !(other.value < value); + } + + bool operator >= (const TestDataM& other) const + { + return !(value < other.value); + } + + operator bool() const + { + return valid; + } + + T value; + bool valid; + +private: + + TestDataM(const TestDataM& other) = delete; + TestDataM& operator =(const TestDataM& other) = delete; +}; + +template +bool operator == (const TestDataM& lhs, const TestDataM& rhs) +{ + return lhs.value == rhs.value; +} + +template +bool operator != (const TestDataM& lhs, const TestDataM& rhs) +{ + return lhs.value != rhs.value; +} + +template +std::ostream& operator << (std::ostream& s, const TestDataM& rhs) +{ + s << rhs.value; + return s; +} + + #endif diff --git a/test/test_deque.cpp b/test/test_deque.cpp index bd57e81f..44cdcf84 100644 --- a/test/test_deque.cpp +++ b/test/test_deque.cpp @@ -156,6 +156,34 @@ namespace CHECK(std::equal(deque1.begin(), deque1.end(), deque2.begin())); } + //************************************************************************* + TEST(test_move_constructor) + { + const size_t SIZE = 10U; + typedef etl::deque, SIZE> Data; + + std::unique_ptr p1(new uint32_t(1U)); + std::unique_ptr p2(new uint32_t(2U)); + std::unique_ptr p3(new uint32_t(3U)); + std::unique_ptr p4(new uint32_t(4U)); + + Data deque1; + deque1.push_back(std::move(p1)); + deque1.push_back(std::move(p2)); + deque1.push_back(std::move(p3)); + deque1.push_back(std::move(p4)); + + Data deque2(std::move(deque1)); + + CHECK_EQUAL(0U, deque1.size()); + CHECK_EQUAL(4U, deque2.size()); + + CHECK_EQUAL(1U, *deque2[0]); + CHECK_EQUAL(2U, *deque2[1]); + CHECK_EQUAL(3U, *deque2[2]); + CHECK_EQUAL(4U, *deque2[3]); + } + //************************************************************************* TEST(test_assignment) { @@ -168,6 +196,35 @@ namespace CHECK(std::equal(deque1.begin(), deque1.end(), deque2.begin())); } + //************************************************************************* + TEST(test_move_assignment) + { + const size_t SIZE = 10U; + typedef etl::deque, SIZE> Data; + + std::unique_ptr p1(new uint32_t(1U)); + std::unique_ptr p2(new uint32_t(2U)); + std::unique_ptr p3(new uint32_t(3U)); + std::unique_ptr p4(new uint32_t(4U)); + + Data deque1; + deque1.push_back(std::move(p1)); + deque1.push_back(std::move(p2)); + deque1.push_back(std::move(p3)); + deque1.push_back(std::move(p4)); + + Data deque2; + deque2 = std::move(deque1); + + CHECK_EQUAL(0U, deque1.size()); + CHECK_EQUAL(4U, deque2.size()); + + CHECK_EQUAL(1U, *deque2[0]); + CHECK_EQUAL(2U, *deque2[1]); + CHECK_EQUAL(3U, *deque2[2]); + CHECK_EQUAL(4U, *deque2[3]); + } + //************************************************************************* TEST(test_assignment_interface) { @@ -183,6 +240,40 @@ namespace CHECK(std::equal(deque1.begin(), deque1.end(), deque2.begin())); } + //************************************************************************* + TEST(test_move_assignment_interface) + { + const size_t SIZE = 10U; + typedef etl::deque, SIZE> Data; + typedef etl::ideque> IData; + + std::unique_ptr p1(new uint32_t(1U)); + std::unique_ptr p2(new uint32_t(2U)); + std::unique_ptr p3(new uint32_t(3U)); + std::unique_ptr p4(new uint32_t(4U)); + + Data deque1; + deque1.push_back(std::move(p1)); + deque1.push_back(std::move(p2)); + deque1.push_back(std::move(p3)); + deque1.push_back(std::move(p4)); + + Data deque2; + + IData& ideque1 = deque1; + IData& ideque2 = deque2; + + ideque2 = std::move(ideque1); + + CHECK_EQUAL(0U, deque1.size()); + CHECK_EQUAL(4U, deque2.size()); + + CHECK_EQUAL(1U, *deque2[0]); + CHECK_EQUAL(2U, *deque2[1]); + CHECK_EQUAL(3U, *deque2[2]); + CHECK_EQUAL(4U, *deque2[3]); + } + //************************************************************************* TEST(test_self_assignment) { @@ -1693,7 +1784,7 @@ namespace TEST(test_move) { const size_t SIZE = 10U; - typedef etl::deque, SIZE> Data; + typedef etl::deque, SIZE> Data; Data data1; diff --git a/test/test_list.cpp b/test/test_list.cpp index 02305747..2fa024cb 100644 --- a/test/test_list.cpp +++ b/test/test_list.cpp @@ -38,12 +38,14 @@ SOFTWARE. #include #include + namespace { SUITE(test_list) { typedef TestDataDC ItemDC; typedef TestDataNDC ItemNDC; + typedef TestDataM ItemM; const size_t SIZE = 10; @@ -54,6 +56,9 @@ namespace typedef etl::list DataInt; + typedef etl::list DataM; + typedef etl::ilist IDataM; + typedef std::list CompareData; typedef std::vector InitialData; @@ -199,6 +204,38 @@ namespace CHECK_EQUAL(compare_data.size() - 2, other_data.size()); } + //************************************************************************* + TEST(test_move_constructor) + { + ItemM p1(1U); + ItemM p2(2U); + ItemM p3(3U); + ItemM p4(4U); + + DataM data1; + data1.push_back(std::move(p1)); + data1.push_back(std::move(p2)); + data1.push_back(std::move(p3)); + data1.push_back(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(1U, (*itr++).value); + CHECK_EQUAL(2U, (*itr++).value); + CHECK_EQUAL(3U, (*itr++).value); + CHECK_EQUAL(4U, (*itr++).value); + } + //************************************************************************* TEST_FIXTURE(SetupFixture, test_iterator) { @@ -429,6 +466,35 @@ namespace CHECK(are_equal); } + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_insert_position_value_move) + { + ItemM p1(1U); + ItemM p2(2U); + ItemM p3(3U); + ItemM p4(4U); + + DataM data1; + data1.insert(data1.begin(), std::move(p1)); + data1.insert(data1.begin(), std::move(p2)); + data1.insert(data1.begin(), std::move(p3)); + data1.insert(data1.begin(), std::move(p4)); + + CHECK_EQUAL(4U, data1.size()); + + CHECK(!bool(p1)); + CHECK(!bool(p2)); + CHECK(!bool(p3)); + CHECK(!bool(p4)); + + DataM::const_iterator itr = data1.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_position_value) { @@ -554,6 +620,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) { @@ -681,6 +776,35 @@ namespace CHECK(are_equal); } + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_push_back_move) + { + ItemM p1(1U); + ItemM p2(2U); + ItemM p3(3U); + ItemM p4(4U); + + DataM data; + data.push_back(std::move(p1)); + data.push_back(std::move(p2)); + data.push_back(std::move(p3)); + data.push_back(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(1U, (*itr++).value); + CHECK_EQUAL(2U, (*itr++).value); + CHECK_EQUAL(3U, (*itr++).value); + CHECK_EQUAL(4U, (*itr++).value); + } + //************************************************************************* TEST_FIXTURE(SetupFixture, test_emplace_back) { @@ -894,7 +1018,6 @@ namespace //************************************************************************* TEST_FIXTURE(SetupFixture, test_assignment) { - CompareData compare_data(sorted_data.begin(), sorted_data.end()); DataNDC data(sorted_data.begin(), sorted_data.end()); DataNDC other_data; @@ -907,6 +1030,34 @@ namespace CHECK(are_equal); } + //************************************************************************* + TEST(test_move_assignment) + { + ItemM p1(1U); + ItemM p2(2U); + ItemM p3(3U); + ItemM p4(4U); + + DataM data1; + data1.push_back(std::move(p1)); + data1.push_back(std::move(p2)); + data1.push_back(std::move(p3)); + data1.push_back(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(1U, (*itr++).value); + CHECK_EQUAL(2U, (*itr++).value); + CHECK_EQUAL(3U, (*itr++).value); + CHECK_EQUAL(4U, (*itr++).value); + } + //************************************************************************* TEST_FIXTURE(SetupFixture, test_assignment_interface) { @@ -926,6 +1077,38 @@ namespace CHECK(are_equal); } + //************************************************************************* + TEST(test_move_assignment_interface) + { + ItemM p1(1U); + ItemM p2(2U); + ItemM p3(3U); + ItemM p4(4U); + + DataM data1; + data1.push_back(std::move(p1)); + data1.push_back(std::move(p2)); + data1.push_back(std::move(p3)); + data1.push_back(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(1U, (*itr++).value); + CHECK_EQUAL(2U, (*itr++).value); + CHECK_EQUAL(3U, (*itr++).value); + CHECK_EQUAL(4U, (*itr++).value); + } + //************************************************************************* TEST_FIXTURE(SetupFixture, test_self_assignment) { @@ -1565,6 +1748,7 @@ namespace DataNDC2 data0(merge_data0.begin(), merge_data0.end()); DataNDC2 data1(merge_data1.begin(), merge_data1.end()); + CompareData compare0(merge_data0.begin(), merge_data0.end()); CompareData compare1(merge_data1.begin(), merge_data1.end()); @@ -1644,8 +1828,6 @@ namespace data0.reverse(); data1.reverse(); - - CompareData compare0(merge_data0.begin(), merge_data0.end()); CompareData compare1(merge_data1.begin(), merge_data1.end()); @@ -1670,5 +1852,146 @@ namespace CHECK_THROW(data0.merge(data1), etl::list_unsorted); } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_merge_move) + { + ItemM p1(1U); + ItemM p2(2U); + ItemM p3(3U); + ItemM p4(4U); + + ItemM p5(5U); + ItemM p6(6U); + ItemM p7(7U); + ItemM p8(8U); + + DataM data1; + data1.push_back(std::move(p1)); + data1.push_back(std::move(p2)); + data1.push_back(std::move(p3)); + data1.push_back(std::move(p4)); + + DataM data2; + data2.push_back(std::move(p5)); + data2.push_back(std::move(p6)); + data2.push_back(std::move(p7)); + data2.push_back(std::move(p8)); + + data1.merge(std::move(data2)); + + CHECK_EQUAL(8U, data1.size()); + CHECK_EQUAL(0U, data2.size()); + + DataM::const_iterator itr = data1.begin(); + + CHECK_EQUAL(1U, (*itr++).value); + CHECK_EQUAL(2U, (*itr++).value); + CHECK_EQUAL(3U, (*itr++).value); + CHECK_EQUAL(4U, (*itr++).value); + CHECK_EQUAL(5U, (*itr++).value); + CHECK_EQUAL(6U, (*itr++).value); + CHECK_EQUAL(7U, (*itr++).value); + CHECK_EQUAL(8U, (*itr++).value); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_splice_move_range_same) + { + ItemM p1(1U); + ItemM p2(2U); + ItemM p3(3U); + ItemM p4(4U); + ItemM p5(5U); + ItemM p6(6U); + ItemM p7(7U); + ItemM p8(8U); + + DataM data; + data.push_back(std::move(p1)); + data.push_back(std::move(p2)); + data.push_back(std::move(p3)); + data.push_back(std::move(p4)); + data.push_back(std::move(p5)); + data.push_back(std::move(p6)); + data.push_back(std::move(p7)); + data.push_back(std::move(p8)); + + DataM::iterator begin; + DataM::iterator end; + DataM::iterator to; + + // Move nearby. + begin = data.begin(); + std::advance(begin, 4); + end = begin; + std::advance(end, 2); + to = data.begin(); + std::advance(to, 2); + data.splice(to, std::move(data), begin, end); + + CHECK_EQUAL(8U, data.size()); + + DataM::const_iterator itr = data.begin(); + + CHECK_EQUAL(1U, (*itr++).value); + CHECK_EQUAL(2U, (*itr++).value); + CHECK_EQUAL(5U, (*itr++).value); + CHECK_EQUAL(6U, (*itr++).value); + CHECK_EQUAL(3U, (*itr++).value); + CHECK_EQUAL(4U, (*itr++).value); + CHECK_EQUAL(7U, (*itr++).value); + CHECK_EQUAL(8U, (*itr++).value); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_splice_move_range_different) + { + ItemM p1(1U); + ItemM p2(2U); + ItemM p3(3U); + ItemM p4(4U); + ItemM p5(5U); + ItemM p6(6U); + ItemM p7(7U); + ItemM p8(8U); + + DataM data1; + data1.push_back(std::move(p1)); + data1.push_back(std::move(p2)); + data1.push_back(std::move(p3)); + data1.push_back(std::move(p4)); + + DataM data2; + data2.push_back(std::move(p5)); + data2.push_back(std::move(p6)); + data2.push_back(std::move(p7)); + data2.push_back(std::move(p8)); + + DataM::iterator begin; + DataM::iterator end; + DataM::iterator to; + + // Move. + begin = data2.begin(); + std::advance(begin, 1); + end = begin; + std::advance(end, 2); + to = data1.begin(); + std::advance(to, 2); + data1.splice(to, std::move(data2), begin, end); + + CHECK_EQUAL(6U, data1.size()); + CHECK_EQUAL(2U, data2.size()); + + DataM::const_iterator itr = data1.begin(); + + CHECK_EQUAL(1U, (*itr++).value); // 1 + CHECK_EQUAL(2U, (*itr++).value); // 2 + CHECK_EQUAL(6U, (*itr++).value); // 7 + CHECK_EQUAL(7U, (*itr++).value); // 6 + CHECK_EQUAL(3U, (*itr++).value); // 3 + CHECK_EQUAL(4U, (*itr++).value); // 4 + } }; } diff --git a/test/test_vector.cpp b/test/test_vector.cpp index 3b35ceac..d87f83de 100644 --- a/test/test_vector.cpp +++ b/test/test_vector.cpp @@ -514,6 +514,31 @@ namespace CHECK(is_equal); } + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_push_back_literal) + { + Compare_Data compare_data; + Data data; + + compare_data.push_back(1); + compare_data.push_back(2); + compare_data.push_back(3); + compare_data.push_back(4); + + data.push_back(1); + data.push_back(2); + data.push_back(3); + data.push_back(4); + + CHECK_EQUAL(compare_data.size(), data.size()); + + bool is_equal = std::equal(data.begin(), + data.end(), + compare_data.begin()); + + CHECK(is_equal); + } + //************************************************************************* TEST_FIXTURE(SetupFixture, test_push_back_excess) { diff --git a/test/test_vector_non_trivial.cpp b/test/test_vector_non_trivial.cpp index ab87b66e..530779f2 100644 --- a/test/test_vector_non_trivial.cpp +++ b/test/test_vector_non_trivial.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include "etl/vector.h" #include "data.h" @@ -188,6 +189,34 @@ namespace CHECK(data2 != data); } + //************************************************************************* + TEST(test_move_constructor) + { + const size_t SIZE = 10U; + typedef etl::vector, SIZE> Data; + + std::unique_ptr p1(new uint32_t(1U)); + std::unique_ptr p2(new uint32_t(2U)); + std::unique_ptr p3(new uint32_t(3U)); + std::unique_ptr p4(new uint32_t(4U)); + + Data data1; + data1.push_back(std::move(p1)); + data1.push_back(std::move(p2)); + data1.push_back(std::move(p3)); + data1.push_back(std::move(p4)); + + Data data2(std::move(data1)); + + CHECK_EQUAL(0U, data1.size()); + CHECK_EQUAL(4U, data2.size()); + + CHECK_EQUAL(1U, *data2[0]); + CHECK_EQUAL(2U, *data2[1]); + CHECK_EQUAL(3U, *data2[2]); + CHECK_EQUAL(4U, *data2[3]); + } + //************************************************************************* TEST_FIXTURE(SetupFixture, test_assignment) { @@ -203,6 +232,35 @@ namespace CHECK(is_equal); } + //************************************************************************* + TEST(test_move_assignment) + { + const size_t SIZE = 10U; + typedef etl::vector, SIZE> Data; + + std::unique_ptr p1(new uint32_t(1U)); + std::unique_ptr p2(new uint32_t(2U)); + std::unique_ptr p3(new uint32_t(3U)); + std::unique_ptr p4(new uint32_t(4U)); + + Data data1; + data1.push_back(std::move(p1)); + data1.push_back(std::move(p2)); + data1.push_back(std::move(p3)); + data1.push_back(std::move(p4)); + + Data data2; + data2 = std::move(data1); + + CHECK_EQUAL(0U, data1.size()); + CHECK_EQUAL(4U, data2.size()); + + CHECK_EQUAL(1U, *data2[0]); + CHECK_EQUAL(2U, *data2[1]); + CHECK_EQUAL(3U, *data2[2]); + CHECK_EQUAL(4U, *data2[3]); + } + //************************************************************************* TEST_FIXTURE(SetupFixture, test_assignment_iterface) { @@ -221,6 +279,40 @@ namespace CHECK(is_equal); } + //************************************************************************* + TEST(test_move_assignment_interface) + { + const size_t SIZE = 10U; + typedef etl::vector, SIZE> Data; + typedef etl::ivector> IData; + + std::unique_ptr p1(new uint32_t(1U)); + std::unique_ptr p2(new uint32_t(2U)); + std::unique_ptr p3(new uint32_t(3U)); + std::unique_ptr p4(new uint32_t(4U)); + + Data data1; + data1.push_back(std::move(p1)); + data1.push_back(std::move(p2)); + data1.push_back(std::move(p3)); + data1.push_back(std::move(p4)); + + Data data2; + + IData& idata1 = data1; + IData& idata2 = data2; + + idata2 = std::move(idata1); + + CHECK_EQUAL(0U, data1.size()); + CHECK_EQUAL(4U, data2.size()); + + CHECK_EQUAL(1U, *data2[0]); + CHECK_EQUAL(2U, *data2[1]); + CHECK_EQUAL(3U, *data2[2]); + CHECK_EQUAL(4U, *data2[3]); + } + //************************************************************************* TEST_FIXTURE(SetupFixture, test_self_assignment) { @@ -571,6 +663,80 @@ namespace CHECK(is_equal); } + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_push_back_unique_ptr) + { + etl::vector, SIZE> data; + + std::unique_ptr p1(new int(1)); + std::unique_ptr p2(new int(2)); + std::unique_ptr p3(new int(3)); + std::unique_ptr p4(new int(4)); + + data.push_back(std::move(p1)); + data.push_back(std::move(p2)); + data.push_back(std::move(p3)); + data.push_back(std::move(p4)); + + CHECK(!bool(p1)); + CHECK(!bool(p2)); + CHECK(!bool(p3)); + CHECK(!bool(p4)); + + CHECK_EQUAL(1, *data[0]); + CHECK_EQUAL(2, *data[1]); + CHECK_EQUAL(3, *data[2]); + CHECK_EQUAL(4, *data[3]); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_insert_int) + { + etl::vector data; + + int p1(1); + int p2(2); + int p3(3); + int p4(4); + + data.insert(data.begin(), p1); + data.insert(data.begin(), p2); + data.insert(data.begin(), p3); + data.insert(data.begin(), p4); + + CHECK_EQUAL(4, data[0]); + CHECK_EQUAL(3, data[1]); + CHECK_EQUAL(2, data[2]); + CHECK_EQUAL(1, data[3]); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_insert_unique_ptr) + { + etl::vector, SIZE> data; + + std::unique_ptr p1(new int(1)); + std::unique_ptr p2(new int(2)); + std::unique_ptr p3(new int(3)); + std::unique_ptr p4(new int(4)); + + data.insert(data.begin(), std::move(p1)); + data.insert(data.begin(), std::move(p2)); + data.insert(data.begin(), std::move(p3)); + data.insert(data.begin(), std::move(p4)); + + CHECK(!bool(p1)); + CHECK(!bool(p2)); + CHECK(!bool(p3)); + CHECK(!bool(p4)); + + CHECK_EQUAL(1, *data[3]); + CHECK_EQUAL(4, *data[0]); + CHECK_EQUAL(3, *data[1]); + CHECK_EQUAL(2, *data[2]); + + } + //************************************************************************* // To test the CPP03 versions then ETL_TEST_VECTOR_CPP11 must be set to 0 in vector.h TEST_FIXTURE(SetupFixture, test_emplace_back_multiple) diff --git a/test/vs2017/etl.vcxproj b/test/vs2017/etl.vcxproj index 961afff0..6679be4f 100644 --- a/test/vs2017/etl.vcxproj +++ b/test/vs2017/etl.vcxproj @@ -532,6 +532,7 @@ + diff --git a/test/vs2017/etl.vcxproj.filters b/test/vs2017/etl.vcxproj.filters index 84162b51..161a765b 100644 --- a/test/vs2017/etl.vcxproj.filters +++ b/test/vs2017/etl.vcxproj.filters @@ -720,6 +720,9 @@ ETL\Maths + + Source Files +