diff --git a/include/etl/private/ivectorpointer.h b/include/etl/private/ivectorpointer.h index 46b9a07d..c9f1ee9c 100644 --- a/include/etl/private/ivectorpointer.h +++ b/include/etl/private/ivectorpointer.h @@ -308,12 +308,7 @@ namespace etl template void assign(TIterator first, TIterator last) { - base_t::initialise(); - - while (first != last) - { - *p_end++ = (void*)*first++; - } + base_t::assign(first, last); } //********************************************************************* @@ -717,12 +712,7 @@ namespace etl template void assign(TIterator first, TIterator last) { - base_t::initialise(); - - while (first != last) - { - *p_end++ = (void*)*first++; - } + base_t::assign(first, last); } //********************************************************************* diff --git a/include/etl/private/pvoidvector.h b/include/etl/private/pvoidvector.h index 6801812c..29ef41a0 100644 --- a/include/etl/private/pvoidvector.h +++ b/include/etl/private/pvoidvector.h @@ -211,7 +211,7 @@ namespace etl // Size up if necessary. if (p_end < p_new_end) { - etl::fill(p_end, p_new_end, value); + etl::fill(p_end, p_new_end, value); } p_end = p_new_end; @@ -316,14 +316,15 @@ namespace etl } //********************************************************************* - /// Assigns values to the vector. + /// Assigns values to the vector. Non-pointer /// If asserts or exceptions are enabled, emits vector_full if the vector does not have enough free space. /// If asserts or exceptions are enabled, emits vector_iterator if the iterators are reversed. ///\param first The iterator to the first element. ///\param last The iterator to the last element + 1. //********************************************************************* template - void assign(TIterator first, TIterator last) + typename etl::enable_if::value, void>::type + assign(TIterator first, TIterator last) { #if defined(ETL_DEBUG) difference_type d = etl::distance(first, last); @@ -334,10 +335,34 @@ namespace etl while (first != last) { - *p_end++ = const_cast(*first++); + *p_end++ = (void*)(*first++); } } + //********************************************************************* + /// Assigns values to the vector. Pointer + /// If asserts or exceptions are enabled, emits vector_full if the vector does not have enough free space. + /// If asserts or exceptions are enabled, emits vector_iterator if the iterators are reversed. + ///\param first The iterator to the first element. + ///\param last The iterator to the last element + 1. + //********************************************************************* + template + typename etl::enable_if::value, void>::type + assign(TIterator first, TIterator last) + { +#if defined(ETL_DEBUG) + difference_type d = etl::distance(first, last); + ETL_ASSERT(static_cast(d) <= CAPACITY, ETL_ERROR(vector_full)); +#endif + + initialise(); + + void** p_first = (void**)(first); + void** p_last = (void**)(last); + + p_end = etl::copy(p_first, p_last, p_buffer);; + } + //********************************************************************* /// Assigns values to the vector. /// If asserts or exceptions are enabled, emits vector_full if the vector does not have enough free space. @@ -346,14 +371,11 @@ namespace etl //********************************************************************* void assign(size_t n, value_type value) { - initialise(); - ETL_ASSERT(n <= CAPACITY, ETL_ERROR(vector_full)); - for (size_t current_size = 0; current_size < n; ++current_size) - { - *p_end++ = value; - } + initialise(); + + p_end = etl::fill_n(p_buffer, n, value); } //************************************************************************* @@ -514,6 +536,7 @@ namespace etl return *this; } #endif + //************************************************************************* /// Gets the current size of the vector. ///\return The current size of the vector. @@ -556,9 +579,9 @@ namespace etl /// Constructor. //********************************************************************* pvoidvector(void** p_buffer_, size_t MAX_SIZE) - : vector_base(MAX_SIZE), - p_buffer(p_buffer_), - p_end(p_buffer_) + : vector_base(MAX_SIZE) + , p_buffer(p_buffer_) + , p_end(p_buffer_) { } diff --git a/include/etl/vector.h b/include/etl/vector.h index f1ee479a..b154adee 100644 --- a/include/etl/vector.h +++ b/include/etl/vector.h @@ -940,9 +940,9 @@ namespace etl /// Constructor. //********************************************************************* ivector(T* p_buffer_, size_t MAX_SIZE) - : vector_base(MAX_SIZE), - p_buffer(p_buffer_), - p_end(p_buffer_) + : vector_base(MAX_SIZE) + , p_buffer(p_buffer_) + , p_end(p_buffer_) { } diff --git a/test/test_vector_pointer.cpp b/test/test_vector_pointer.cpp index 849649de..9bbff8b3 100644 --- a/test/test_vector_pointer.cpp +++ b/test/test_vector_pointer.cpp @@ -308,6 +308,21 @@ namespace CHECK(is_equal); } + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_assignment_from_pointer_range) + { + Data data(initial_data.data(), initial_data.data() + initial_data.size()); + Data other_data; + + other_data = data; + + CHECK_EQUAL(initial_data.size(), data.size()); + CHECK_EQUAL(initial_data.size(), other_data.size()); + + bool is_equal = std::equal(data.begin(), data.end(), other_data.begin()); + CHECK(is_equal); + } + //************************************************************************* TEST_FIXTURE(SetupFixture, test_const_assignment) { diff --git a/test/test_vector_pointer_external_buffer.cpp b/test/test_vector_pointer_external_buffer.cpp index fc6a39a4..cb579d6f 100644 --- a/test/test_vector_pointer_external_buffer.cpp +++ b/test/test_vector_pointer_external_buffer.cpp @@ -315,6 +315,19 @@ namespace CHECK(is_equal); } + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_assignment_from_pointer_range) + { + Data data(initial_data.data(), initial_data.data() + initial_data.size(), buffer1, SIZE); + Data other_data(buffer2, SIZE); + + other_data = data; + + bool is_equal = std::equal(data.begin(), data.end(), other_data.begin()); + + CHECK(is_equal); + } + //************************************************************************* TEST_FIXTURE(SetupFixture, test_const_assignment) {