Fix pointer vector move operators

Optimise constructors and assignments for pointer vectors
This commit is contained in:
John Wellbelove 2020-07-26 13:10:38 +01:00
parent 089cff9c0f
commit bc780a6c44
5 changed files with 69 additions and 28 deletions

View File

@ -308,12 +308,7 @@ namespace etl
template <typename TIterator>
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 <typename TIterator>
void assign(TIterator first, TIterator last)
{
base_t::initialise();
while (first != last)
{
*p_end++ = (void*)*first++;
}
base_t::assign(first, last);
}
//*********************************************************************

View File

@ -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 <typename TIterator>
void assign(TIterator first, TIterator last)
typename etl::enable_if<!etl::is_pointer<TIterator>::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<void*>(*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 TIterator>
typename etl::enable_if<etl::is_pointer<TIterator>::value, void>::type
assign(TIterator first, TIterator last)
{
#if defined(ETL_DEBUG)
difference_type d = etl::distance(first, last);
ETL_ASSERT(static_cast<size_t>(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_)
{
}

View File

@ -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_)
{
}

View File

@ -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)
{

View File

@ -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)
{