mirror of
https://github.com/ETLCPP/etl.git
synced 2026-04-30 19:09:10 +08:00
Added rvalue reference push_back & insert.
This commit is contained in:
parent
fa891b9dbc
commit
9266920e2a
@ -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 T& value)
|
||||
{
|
||||
#if defined(ETL_CHECK_PUSH_POP)
|
||||
ETL_ASSERT(size() != CAPACITY, ETL_ERROR(vector_full));
|
||||
@ -413,6 +413,19 @@ namespace etl
|
||||
create_back(value);
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// 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(T&& value)
|
||||
{
|
||||
#if defined(ETL_CHECK_PUSH_POP)
|
||||
ETL_ASSERT(size() != CAPACITY, ETL_ERROR(vector_full));
|
||||
#endif
|
||||
create_back(std::move(value));
|
||||
}
|
||||
|
||||
#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 +526,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 T& value)
|
||||
{
|
||||
ETL_ASSERT(size() + 1 <= CAPACITY, ETL_ERROR(vector_full));
|
||||
|
||||
@ -524,13 +537,37 @@ 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;
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// 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, T&& 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;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Emplaces a value to the vextor at the specified position.
|
||||
//*************************************************************************
|
||||
@ -551,7 +588,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 +613,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 +638,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 +663,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 +688,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 +738,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 +795,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 +843,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;
|
||||
@ -888,7 +925,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 +935,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 +957,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 T& value)
|
||||
{
|
||||
etl::create_copy_at(p_end, value);
|
||||
ETL_INCREMENT_DEBUG_COUNT
|
||||
@ -928,6 +965,17 @@ namespace etl
|
||||
++p_end;
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Create a new element with a value at the back
|
||||
//*********************************************************************
|
||||
inline void create_back(T&& value)
|
||||
{
|
||||
etl::create_copy_at(p_end, std::move(value));
|
||||
ETL_INCREMENT_DEBUG_COUNT
|
||||
|
||||
++p_end;
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Destroy an element at the back.
|
||||
//*********************************************************************
|
||||
@ -1035,7 +1083,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.
|
||||
@ -1260,8 +1313,6 @@ namespace etl
|
||||
};
|
||||
}
|
||||
|
||||
#include "private/ivectorpointer.h"
|
||||
|
||||
#ifdef ETL_COMPILER_GCC
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
@ -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)
|
||||
{
|
||||
|
||||
@ -31,6 +31,7 @@
|
||||
#include <vector>
|
||||
#include <array>
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
|
||||
#include "etl/vector.h"
|
||||
#include "data.h"
|
||||
@ -571,6 +572,80 @@ namespace
|
||||
CHECK(is_equal);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST_FIXTURE(SetupFixture, test_push_back_unique_ptr)
|
||||
{
|
||||
etl::vector<std::unique_ptr<int>, SIZE> data;
|
||||
|
||||
std::unique_ptr<int> p1(new int(1));
|
||||
std::unique_ptr<int> p2(new int(2));
|
||||
std::unique_ptr<int> p3(new int(3));
|
||||
std::unique_ptr<int> 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<int, SIZE> 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<std::unique_ptr<int>, SIZE> data;
|
||||
|
||||
std::unique_ptr<int> p1(new int(1));
|
||||
std::unique_ptr<int> p2(new int(2));
|
||||
std::unique_ptr<int> p3(new int(3));
|
||||
std::unique_ptr<int> 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)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user