Added fast clear for types that are trivially destructible. (Integral and pointer types only for C++03)

This commit is contained in:
John Wellbelove 2018-01-27 15:40:03 +00:00
parent cb03b5f177
commit bf06775b51
23 changed files with 473 additions and 58 deletions

View File

@ -1797,9 +1797,17 @@ namespace etl
//*********************************************************************
void initialise()
{
while (current_size > 0)
if ETL_IF_CONSTEXPR(etl::is_trivially_destructible<T>::value)
{
destroy_element_back();
current_size = 0;
construct_count.clear();
}
else
{
while (current_size > 0)
{
destroy_element_back();
}
}
_begin = iterator(0, *this, p_buffer);

View File

@ -398,7 +398,24 @@ namespace etl
//*************************************************************************
void clear()
{
erase(begin(), end());
if ETL_IF_CONSTEXPR(etl::is_trivially_destructible<value_type>::value)
{
storage.release_all();
}
else
{
iterator itr = begin();
while (itr != end())
{
itr->~value_type();
storage.release(etl::addressof(*itr));
++itr;
}
}
construct_count.clear();
refmap_t::clear();
}
//*********************************************************************

View File

@ -349,7 +349,24 @@ namespace etl
//*************************************************************************
void clear()
{
erase(begin(), end());
if ETL_IF_CONSTEXPR(etl::is_trivially_destructible<value_type>::value)
{
storage.release_all();
}
else
{
iterator itr = begin();
while (itr != end())
{
itr->~value_type();
storage.release(etl::addressof(*itr));
++itr;
}
}
construct_count.clear();
refmap_t::clear();
}
//*********************************************************************

View File

@ -294,7 +294,7 @@ namespace etl
//*********************************************************************
void erase(iterator i_element)
{
i_element->~value_type();
etl::destroy_at(etl::addressof(*i_element));
storage.release(etl::addressof(*i_element));
refset_t::erase(i_element);
--construct_count;
@ -313,7 +313,7 @@ namespace etl
while (itr != last)
{
itr->~value_type();
etl::destroy_at(etl::addressof(*itr));
storage.release(etl::addressof(*itr));
++itr;
--construct_count;
@ -327,7 +327,24 @@ namespace etl
//*************************************************************************
void clear()
{
erase(begin(), end());
if ETL_IF_CONSTEXPR(etl::is_trivially_destructible<value_type>::value)
{
storage.release_all();
}
else
{
iterator itr = begin();
while (itr != end())
{
etl::destroy_at(etl::addressof(*itr));
storage.release(etl::addressof(*itr));
++itr;
}
}
construct_count.clear();
refset_t::clear();
}
//*********************************************************************

View File

@ -284,7 +284,7 @@ namespace etl
}
else
{
i_element->~value_type();
etl::destroy_at(etl::addressof(*i_element));
storage.release(etl::addressof(*i_element));
refset_t::erase(i_element);
--construct_count;
@ -298,7 +298,7 @@ namespace etl
//*********************************************************************
void erase(iterator i_element)
{
i_element->~value_type();
etl::destroy_at(etl::addressof(*i_element));
storage.release(etl::addressof(*i_element));
refset_t::erase(i_element);
--construct_count;
@ -317,7 +317,7 @@ namespace etl
while (itr != last)
{
itr->~value_type();
etl::destroy_at(etl::addressof(*itr));
storage.release(etl::addressof(*itr));
++itr;
--construct_count;
@ -331,7 +331,25 @@ namespace etl
//*************************************************************************
void clear()
{
erase(begin(), end());
if ETL_IF_CONSTEXPR(etl::is_trivially_destructible<value_type>::value)
{
storage.release_all();
}
else
{
iterator itr = begin();
while (itr != end())
{
etl::destroy_at(etl::addressof(*itr));
storage.release(etl::addressof(*itr));
++itr;
--construct_count;
}
}
construct_count.clear();
refset_t::clear();
}
//*********************************************************************

View File

@ -728,26 +728,33 @@ namespace etl
iterator i_node = begin();
iterator i_last_node;
// Find where we're currently at.
while ((i < n) && (i_node != end()))
if (empty())
{
++i;
i_last_node = i_node;
++i_node;
assign(n, value);
}
if (i_node != end())
else
{
// Reduce.
erase_after(i_last_node, end());
}
else if (i_node == end())
{
// Increase.
while (i < n)
// Find where we're currently at.
while ((i < n) && (i_node != end()))
{
i_last_node = insert_after(i_last_node, value);
++i;
i_last_node = i_node;
++i_node;
}
if (i_node != end())
{
// Reduce.
erase_after(i_last_node, end());
}
else if (i_node == end())
{
// Increase.
while (i < n)
{
i_last_node = insert_after(i_last_node, value);
++i;
}
}
}
}
@ -1226,15 +1233,23 @@ namespace etl
{
if (!empty())
{
node_t* p_first = start_node.next;
node_t* p_next;
// Erase the ones in between.
while (p_first != nullptr)
if ETL_IF_CONSTEXPR(etl::is_trivially_destructible<T>::value)
{
p_next = p_first->next; // Remember the next node.
destroy_data_node(static_cast<data_node_t&>(*p_first)); // Destroy the pool object.
p_first = p_next; // Move to the next node.
p_node_pool->release_all();
construct_count.clear();
}
else
{
node_t* p_first = start_node.next;
node_t* p_next;
// Erase the ones in between.
while (p_first != nullptr)
{
p_next = p_first->next; // Remember the next node.
destroy_data_node(static_cast<data_node_t&>(*p_first)); // Destroy the pool object.
p_first = p_next; // Move to the next node.
}
}
}

View File

@ -1442,13 +1442,21 @@ namespace etl
{
if (!empty())
{
node_t* p_first = terminal_node.next;
node_t* p_last = &terminal_node;
while (p_first != p_last)
if ETL_IF_CONSTEXPR(etl::is_trivially_destructible<T>::value)
{
destroy_data_node(static_cast<data_node_t&>(*p_first)); // Destroy the current node.
p_first = p_first->next; // Move to the next node.
p_node_pool->release_all();
construct_count.clear();
}
else
{
node_t* p_first = terminal_node.next;
node_t* p_last = &terminal_node;
while (p_first != p_last)
{
destroy_data_node(static_cast<data_node_t&>(*p_first)); // Destroy the current node.
p_first = p_first->next; // Move to the next node.
}
}
}

View File

@ -191,6 +191,17 @@ namespace etl
--construct_count;
}
//*************************************************************************
/// Clears the indexes.
//*************************************************************************
void index_clear()
{
in = 0;
out = 0;
current_size = 0;
construct_count.clear();
}
size_type in; ///< Where to input new data.
size_type out; ///< Where to get the oldest data.
size_type current_size; ///< The number of items in the queue.
@ -362,14 +373,21 @@ namespace etl
//*************************************************************************
void clear()
{
while (current_size > 0)
if ETL_IF_CONSTEXPR(etl::is_trivially_destructible<T>::value)
{
p_buffer[out].~T();
base_t::del_out();
base_t::index_clear();
}
else
{
while (current_size > 0)
{
p_buffer[out].~T();
base_t::del_out();
}
in = 0;
out = 0;
in = 0;
out = 0;
}
}
//*************************************************************************

View File

@ -622,7 +622,7 @@ namespace etl
//*************************************************************************
void clear()
{
erase(begin(), end());
lookup.clear();
}
//*********************************************************************

View File

@ -542,7 +542,7 @@ namespace etl
//*************************************************************************
void clear()
{
erase(begin(), end());
lookup.clear();
}
//*********************************************************************

View File

@ -554,7 +554,7 @@ namespace etl
//*************************************************************************
void clear()
{
erase(begin(), end());
lookup.clear();
}
//*********************************************************************

View File

@ -534,7 +534,7 @@ namespace etl
//*************************************************************************
void clear()
{
erase(begin(), end());
lookup.clear();
}
//*********************************************************************

View File

@ -44,6 +44,7 @@ SOFTWARE.
#include "debug_count.h"
#include "type_traits.h"
#include "parameter_type.h"
#include "type_traits.h"
#define ETL_FILE "15"
@ -183,6 +184,16 @@ namespace etl
--construct_count;
}
//*************************************************************************
/// Clears all of the indexes.
//*************************************************************************
void index_clear()
{
top_index = 0;
current_size = 0;
construct_count.clear();
}
size_type top_index; ///< The index of the top of the stack.
size_type current_size; ///< The number of items in the stack.
const size_type CAPACITY; ///< The maximum number of items in the stack.
@ -333,10 +344,17 @@ namespace etl
//*************************************************************************
void clear()
{
while (current_size > 0)
if ETL_IF_CONSTEXPR(etl::is_trivially_destructible<T>::value)
{
p_buffer[top_index].~T();
base_t::del_out();
base_t::index_clear();
}
else
{
while (current_size > 0)
{
p_buffer[top_index].~T();
base_t::del_out();
}
}
}

View File

@ -608,6 +608,27 @@ namespace
data.resize(SIZE);
data.clear();
CHECK(data.empty());
// Do it again to check that clear() didn't screw up the internals.
data.resize(SIZE);
CHECK_EQUAL(SIZE, data.size());
data.clear();
CHECK(data.empty());
}
//*************************************************************************
TEST(test_clear_pod)
{
DataInt data;
data.resize(SIZE);
data.clear();
CHECK(data.empty());
// Do it again to check that clear() didn't screw up the internals.
data.resize(SIZE);
data.clear();
CHECK(data.empty());
}
//*************************************************************************

View File

@ -52,11 +52,15 @@ namespace
typedef std::pair<int, DC> ElementDC;
typedef std::pair<int, NDC> ElementNDC;
typedef std::pair<int, int> ElementInt;
typedef etl::flat_map<int, DC, SIZE> DataDC;
typedef etl::flat_map<int, NDC, SIZE> DataNDC;
typedef etl::iflat_map<int, DC> IDataDC;
typedef etl::iflat_map<int, NDC> IDataNDC;
typedef etl::flat_map<int, int, SIZE> DataInt;
typedef std::map<int, DC> Compare_DataDC;
typedef std::map<int, NDC> Compare_DataNDC;
@ -159,6 +163,8 @@ namespace
std::vector<ElementNDC> excess_data;
std::vector<ElementNDC> different_data;
std::vector<ElementInt> int_data;
//*************************************************************************
template <typename T1, typename T2>
bool Check_Equal(T1 begin1, T1 end1, T2 begin2)
@ -207,10 +213,17 @@ namespace
ElementDC(5, M5), ElementDC(6, M6), ElementDC(7, M7), ElementDC(8, M8), ElementDC(9, M9)
};
ElementInt n5[] =
{
ElementInt(0, 0), ElementInt(1, 1), ElementInt(2, 2), ElementInt(3, 3), ElementInt(4, 4),
ElementInt(5, 5), ElementInt(6, 6), ElementInt(7, 7), ElementInt(8, 8), ElementInt(9, 9)
};
initial_data.assign(std::begin(n), std::end(n));
excess_data.assign(std::begin(n2), std::end(n2));
different_data.assign(std::begin(n3), std::end(n3));
initial_data_dc.assign(std::begin(n4), std::end(n4));
int_data.assign(std::begin(n5), std::end(n5));
}
};
@ -655,7 +668,26 @@ namespace
DataNDC data(compare_data.begin(), compare_data.end());
data.clear();
CHECK_EQUAL(data.size(), size_t(0));
// Do it again to check that clear() didn't screw up the internals.
data.assign(compare_data.begin(), compare_data.end());
CHECK_EQUAL(data.size(), compare_data.size());
data.clear();
CHECK_EQUAL(data.size(), size_t(0));
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_clear_pod)
{
DataInt data(int_data.begin(), int_data.end());
data.clear();
CHECK_EQUAL(data.size(), size_t(0));
// Do it again to check that clear() didn't screw up the internals.
data.assign(int_data.begin(), int_data.end());
CHECK_EQUAL(data.size(), int_data.size());
data.clear();
CHECK_EQUAL(data.size(), size_t(0));
}

View File

@ -50,11 +50,15 @@ namespace
typedef std::pair<int, DC> ElementDC;
typedef std::pair<int, NDC> ElementNDC;
typedef std::pair<int, int> ElementInt;
typedef etl::flat_multimap<int, DC, SIZE> DataDC;
typedef etl::flat_multimap<int, NDC, SIZE> DataNDC;
typedef etl::iflat_multimap<int, DC> IDataDC;
typedef etl::iflat_multimap<int, NDC> IDataNDC;
typedef etl::flat_multimap<int, int, SIZE> DataInt;
typedef std::multimap<int, DC> Compare_DataDC;
typedef std::multimap<int, NDC> Compare_DataNDC;
@ -84,6 +88,8 @@ namespace
std::vector<ElementNDC> different_data;
std::vector<ElementNDC> multi_data;
std::vector<ElementInt> int_data;
//*************************************************************************
template <typename T1, typename T2>
bool Check_Equal(T1 begin1, T1 end1, T2 begin2)
@ -166,10 +172,17 @@ namespace
ElementNDC(4, N5), ElementNDC(4, N6), ElementNDC(5, N7), ElementNDC(4, N8), ElementNDC(0, N9)
};
ElementInt n5[] =
{
ElementInt(0, 0), ElementInt(1, 1), ElementInt(2, 2), ElementInt(3, 3), ElementInt(4, 4),
ElementInt(5, 5), ElementInt(6, 6), ElementInt(7, 7), ElementInt(8, 8), ElementInt(9, 9)
};
initial_data.assign(std::begin(n), std::end(n));
excess_data.assign(std::begin(n2), std::end(n2));
different_data.assign(std::begin(n3), std::end(n3));
multi_data.assign(std::begin(n4), std::end(n4));
int_data.assign(std::begin(n5), std::end(n5));
}
};
@ -485,7 +498,27 @@ namespace
DataNDC data(compare_data.begin(), compare_data.end());
data.clear();
CHECK_EQUAL(data.size(), size_t(0));
// Do it again to check that clear() didn't screw up the internals.
data.assign(compare_data.begin(), compare_data.end());
CHECK_EQUAL(data.size(), compare_data.size());
data.clear();
CHECK_EQUAL(data.size(), size_t(0));
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_clear_pod)
{
DataInt data(int_data.begin(), int_data.end());
data.clear();
CHECK_EQUAL(data.size(), size_t(0));
// Do it again to check that clear() didn't screw up the internals.
data.assign(int_data.begin(), int_data.end());
CHECK_EQUAL(data.size(), int_data.size());
data.clear();
CHECK_EQUAL(data.size(), size_t(0));
}

View File

@ -51,6 +51,8 @@ namespace
typedef etl::flat_multiset<NDC, SIZE> DataNDC;
typedef etl::iflat_multiset<NDC> IDataNDC;
typedef etl::flat_multiset<int, SIZE> DataInt;
typedef std::multiset<DC> Compare_DataDC;
typedef std::multiset<NDC> Compare_DataNDC;
@ -101,6 +103,8 @@ namespace
std::vector<NDC> different_data;
std::vector<NDC> multi_data;
std::vector<int> int_data;
//*************************************************************************
struct SetupFixture
{
@ -126,10 +130,16 @@ namespace
N0, N0, N1, N2, N3, N1, N3, N3, N4, N2
};
int n5[] =
{
10, 11, 12, 13, 14, 15, 16, 17, 18, 19
};
initial_data.assign(std::begin(n), std::end(n));
excess_data.assign(std::begin(n2), std::end(n2));
different_data.assign(std::begin(n3), std::end(n3));
multi_data.assign(std::begin(n4), std::end(n4));
int_data.assign(std::begin(n5), std::end(n5));
}
};
@ -432,8 +442,8 @@ namespace
data.erase(i_data, i_data_end);
bool isEqual = std::equal(data.begin(),
data.end(),
compare_data.begin());
data.end(),
compare_data.begin());
CHECK(isEqual);
}
@ -445,7 +455,27 @@ namespace
DataNDC data(compare_data.begin(), compare_data.end());
data.clear();
CHECK_EQUAL(data.size(), size_t(0));
// Do it again to check that clear() didn't screw up the internals.
data.assign(compare_data.begin(), compare_data.end());
CHECK_EQUAL(data.size(), compare_data.size());
data.clear();
CHECK_EQUAL(data.size(), size_t(0));
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_clear_pod)
{
DataInt data(int_data.begin(), int_data.end());
data.clear();
CHECK_EQUAL(data.size(), size_t(0));
// Do it again to check that clear() didn't screw up the internals.
data.assign(int_data.begin(), int_data.end());
CHECK_EQUAL(data.size(), int_data.size());
data.clear();
CHECK_EQUAL(data.size(), size_t(0));
}

View File

@ -51,6 +51,8 @@ namespace
typedef etl::flat_set<NDC, SIZE> DataNDC;
typedef etl::iflat_set<NDC> IDataNDC;
typedef etl::flat_set<int, SIZE> DataInt;
typedef std::set<DC> Compare_DataDC;
typedef std::set<NDC> Compare_DataNDC;
@ -99,6 +101,8 @@ namespace
std::vector<NDC> initial_data;
std::vector<NDC> excess_data;
std::vector<NDC> different_data;
std::vector<int> int_data;
//*************************************************************************
struct SetupFixture
@ -120,9 +124,15 @@ namespace
N10, N11, N12, N13, N14, N15, N16, N17, N18, N19
};
int n4[] =
{
10, 11, 12, 13, 14, 15, 16, 17, 18, 19
};
initial_data.assign(std::begin(n), std::end(n));
excess_data.assign(std::begin(n2), std::end(n2));
different_data.assign(std::begin(n3), std::end(n3));
int_data.assign(std::begin(n4), std::end(n4));
}
};
@ -434,7 +444,26 @@ namespace
DataNDC data(compare_data.begin(), compare_data.end());
data.clear();
CHECK_EQUAL(data.size(), size_t(0));
// Do it again to check that clear() didn't screw up the internals.
data.assign(compare_data.begin(), compare_data.end());
CHECK_EQUAL(data.size(), compare_data.size());
data.clear();
CHECK_EQUAL(data.size(), size_t(0));
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_clear_pod)
{
DataInt data(int_data.begin(), int_data.end());
data.clear();
CHECK_EQUAL(data.size(), size_t(0));
// Do it again to check that clear() didn't screw up the internals.
data.assign(int_data.begin(), int_data.end());
CHECK_EQUAL(data.size(), int_data.size());
data.clear();
CHECK_EQUAL(data.size(), size_t(0));
}

View File

@ -53,6 +53,8 @@ namespace
typedef etl::forward_list<ItemNDC, SIZE> DataNDC;
typedef etl::iforward_list<ItemNDC> IDataNDC;
typedef etl::forward_list<int, SIZE> DataInt;
typedef std::forward_list<ItemDC> CompareDataDC;
typedef std::forward_list<ItemNDC> CompareDataNDC;
typedef std::vector<ItemNDC> InitialDataNDC;
@ -249,8 +251,28 @@ namespace
{
DataNDC data(sorted_data.begin(), sorted_data.end());
data.clear();
CHECK(data.empty());
// Do it again to check that clear() didn't screw up the internals.
data.assign(sorted_data.begin(), sorted_data.end());
CHECK_EQUAL(SIZE, data.size());
data.clear();
CHECK_EQUAL(size_t(0), data.size());
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_clear_pod)
{
DataInt data(SIZE, 1);
data.clear();
CHECK(data.empty());
// Do it again to check that clear() didn't screw up the internals.
data.resize(SIZE);
CHECK_EQUAL(SIZE, data.size());
data.clear();
CHECK_EQUAL(size_t(0), data.size());
}
//*************************************************************************

View File

@ -52,6 +52,8 @@ namespace
typedef etl::list<ItemNDC, 2 * SIZE> DataNDC2;
typedef etl::ilist<ItemNDC> IDataNDC;
typedef etl::list<int, SIZE> DataInt;
typedef std::list<ItemNDC> CompareData;
typedef std::vector<ItemNDC> InitialData;
@ -272,9 +274,30 @@ namespace
TEST_FIXTURE(SetupFixture, test_clear)
{
DataNDC data(sorted_data.begin(), sorted_data.end());
data.clear();
data.clear();
CHECK_EQUAL(0U, data.size());
// Do it again to check that clear() didn't screw up the internals.
data.assign(sorted_data.begin(), sorted_data.end());
CHECK_EQUAL(SIZE, data.size());
data.clear();
CHECK_EQUAL(size_t(0), data.size());
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_clear_pod)
{
DataInt data(SIZE, 1);
data.clear();
CHECK(data.empty());
// Do it again to check that clear() didn't screw up the internals.
data.resize(SIZE);
CHECK_EQUAL(SIZE, data.size());
data.clear();
CHECK_EQUAL(size_t(0), data.size());
}
//*************************************************************************

View File

@ -53,6 +53,26 @@ namespace
return (lhs.c == rhs.c) && (lhs.i == rhs.i) && (lhs.d == rhs.d);
}
struct ItemNTD
{
ItemNTD()
{
p = new char;
}
ItemNTD(const ItemNTD&)
: p(new char)
{
}
~ItemNTD()
{
delete p;
}
char* p;
};
SUITE(test_queue)
{
//*************************************************************************
@ -98,6 +118,31 @@ namespace
queue.push(2);
queue.clear();
CHECK_EQUAL(0U, queue.size());
// Do it again to check that clear() didn't screw up the internals.
queue.push(1);
queue.push(2);
CHECK_EQUAL(2U, queue.size());
queue.clear();
CHECK_EQUAL(0U, queue.size());
}
//*************************************************************************
TEST(test_clear_non_pod)
{
etl::queue<ItemNTD, 4> queue;
queue.push(ItemNTD());
queue.push(ItemNTD());
queue.clear();
CHECK_EQUAL(0U, queue.size());
// Do it again to check that clear() didn't screw up the internals.
queue.push(ItemNTD());
queue.push(ItemNTD());
CHECK_EQUAL(2U, queue.size());
queue.clear();
CHECK_EQUAL(0U, queue.size());
}
//*************************************************************************

View File

@ -55,6 +55,26 @@ namespace
return (lhs.c == rhs.c) && (lhs.i == rhs.i) && (lhs.d == rhs.d);
}
struct ItemNTD
{
ItemNTD()
{
p = new char;
}
ItemNTD(const ItemNTD&)
: p(new char)
{
}
~ItemNTD()
{
delete p;
}
char* p;
};
SUITE(test_stack)
{
typedef TestDataDC<std::string> ItemDC;
@ -138,6 +158,31 @@ namespace
stack.push(2);
stack.clear();
CHECK_EQUAL(0U, stack.size());
// Do it again to check that clear() didn't screw up the internals.
stack.push(1);
stack.push(2);
CHECK_EQUAL(2U, stack.size());
stack.clear();
CHECK_EQUAL(0U, stack.size());
}
//*************************************************************************
TEST(test_clear_non_pod)
{
etl::stack<ItemNTD, 4> stack;
stack.push(ItemNTD());
stack.push(ItemNTD());
stack.clear();
CHECK_EQUAL(0U, stack.size());
// Do it again to check that clear() didn't screw up the internals.
stack.push(ItemNTD());
stack.push(ItemNTD());
CHECK_EQUAL(2U, stack.size());
stack.clear();
CHECK_EQUAL(0U, stack.size());
}
//*************************************************************************

View File

@ -78,8 +78,7 @@
<UndefinePreprocessorDefinitions>
</UndefinePreprocessorDefinitions>
<MultiProcessorCompilation>false</MultiProcessorCompilation>
<LanguageStandard>
</LanguageStandard>
<LanguageStandard>stdcpp14</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>