From 59eab34162e79198fa15f2e39621ec6235e90f91 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Fri, 6 Jun 2025 17:27:43 +0100 Subject: [PATCH] Used mem_copy and mem_move to optimise vectors of pointers --- include/etl/private/pvoidvector.h | 50 +++++++++++++++++++++++-------- test/test_vector_pointer.cpp | 23 ++++++++++++++ 2 files changed, 60 insertions(+), 13 deletions(-) diff --git a/include/etl/private/pvoidvector.h b/include/etl/private/pvoidvector.h index 02c05fe7..641b1868 100644 --- a/include/etl/private/pvoidvector.h +++ b/include/etl/private/pvoidvector.h @@ -367,7 +367,7 @@ namespace etl void** p_first = (void**)(first); void** p_last = (void**)(last); - p_end = etl::copy(p_first, p_last, p_buffer); + p_end = etl::mem_copy(p_first, p_last, p_buffer) + (p_last - p_first); } //********************************************************************* @@ -451,7 +451,7 @@ namespace etl if (position_ != end()) { ++p_end; - etl::copy_backward(position_, end() - 1, end()); + etl::mem_move(position_, end() - 1, position_ + 1); *position_ = value; } else @@ -482,7 +482,7 @@ namespace etl if (position_ != end()) { ++p_end; - etl::copy_backward(position_, end() - 1, end()); + etl::mem_move(position_, end() - 1, position_ + 1); *position_ = ETL_NULLPTR; } else @@ -512,7 +512,7 @@ namespace etl if (position_ != end()) { ++p_end; - etl::copy_backward(position_, end() - 1, end()); + etl::mem_move(position_, end() - 1, position_ + 1); *position_ = value; } else @@ -542,7 +542,7 @@ namespace etl iterator position_ = to_iterator(position); - etl::copy_backward(position_, p_end, p_end + n); + etl::mem_move(position_, p_end, position_ + n); etl::fill_n(position_, n, value); p_end += n; @@ -554,13 +554,14 @@ namespace etl //********************************************************************* /// Inserts a range of values to the vector. /// If asserts or exceptions are enabled, emits vector_full if the vector does not have enough free space. - /// For fundamental and pointer types. + /// For non-pointer iterators. ///\param position The position to insert before. ///\param first The first element to add. ///\param last The last + 1 element to add. //********************************************************************* template - void insert(const_iterator position, TIterator first, TIterator last) + typename etl::enable_if::value, void>::type + insert(const_iterator position, TIterator first, TIterator last) { size_t count = etl::distance(first, last); @@ -568,11 +569,34 @@ namespace etl ETL_ASSERT_OR_RETURN((size() + count) <= CAPACITY, ETL_ERROR(vector_full)); - etl::copy_backward(position_, p_end, p_end + count); + etl::mem_move(position_, p_end, position_ + count); etl::copy(first, last, position_); p_end += count; } + //********************************************************************* + /// Inserts a range of values to the vector. + /// If asserts or exceptions are enabled, emits vector_full if the vector does not have enough free space. + /// For pointer iterators. + ///\param position The position to insert before. + ///\param first The first element to add. + ///\param last The last + 1 element to add. + //********************************************************************* + template + typename etl::enable_if::value, void>::type + insert(const_iterator position, TIterator first, TIterator last) + { + size_t count = etl::distance(first, last); + + iterator position_ = to_iterator(position); + + ETL_ASSERT_OR_RETURN((size() + count) <= CAPACITY, ETL_ERROR(vector_full)); + + etl::mem_move(position_, p_end, position_ + count); + etl::mem_copy((void**)first, (void**)last, position_); + p_end += count; + } + //********************************************************************* /// Erases an element. ///\param i_element Iterator to the element. @@ -580,7 +604,7 @@ namespace etl //********************************************************************* iterator erase(iterator i_element) { - etl::copy(i_element + 1, end(), i_element); + etl::mem_copy(i_element + 1, end(), i_element); --p_end; return i_element; @@ -595,7 +619,7 @@ namespace etl { iterator i_element_ = to_iterator(i_element); - etl::copy(i_element_ + 1, end(), i_element_); + etl::mem_copy(i_element_ + 1, end(), i_element_); --p_end; return i_element_; @@ -614,7 +638,7 @@ namespace etl iterator first_ = to_iterator(first); iterator last_ = to_iterator(last); - etl::copy(last_, end(), first_); + etl::mem_copy(last_, end(), first_); size_t n_delete = static_cast(etl::distance(first, last)); // Just adjust the count. @@ -632,7 +656,7 @@ namespace etl { this->initialise(); this->resize(rhs.size()); - etl::copy_n(rhs.data(), rhs.size(), this->data()); + etl::mem_copy(rhs.data(), rhs.size(), this->data()); } return *this; @@ -648,7 +672,7 @@ namespace etl { this->initialise(); this->resize(rhs.size()); - etl::copy_n(rhs.data(), rhs.size(), this->data()); + etl::mem_copy(rhs.data(), rhs.size(), this->data()); rhs.initialise(); } diff --git a/test/test_vector_pointer.cpp b/test/test_vector_pointer.cpp index bba84c1d..f59c8d29 100644 --- a/test/test_vector_pointer.cpp +++ b/test/test_vector_pointer.cpp @@ -1394,6 +1394,29 @@ namespace } } + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_insert_position_pointer_range) + { + const size_t INITIAL_SIZE = 5; + + for (size_t offset = 0; offset <= INITIAL_SIZE; ++offset) + { + Compare_Data compare_data; + Data data; + + data.assign(initial_data.data(), initial_data.data() + INITIAL_SIZE); + compare_data.assign(initial_data.begin(), initial_data.begin() + INITIAL_SIZE); + data.insert(data.data() + offset, insert_data.data(), insert_data.data() + insert_data.size()); + compare_data.insert(compare_data.begin() + offset, insert_data.begin(), insert_data.end()); + + bool is_equal = std::equal(data.begin(), + data.end(), + compare_data.begin()); + + CHECK(is_equal); + } + } + //************************************************************************* TEST_FIXTURE(SetupFixture, test_const_insert_position_range) {