From bf06775b5102a9623606d8cfbcb0b2852aa81721 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Sat, 27 Jan 2018 15:40:03 +0000 Subject: [PATCH] Added fast clear for types that are trivially destructible. (Integral and pointer types only for C++03) --- src/deque.h | 12 +++++-- src/flat_map.h | 19 ++++++++++- src/flat_multimap.h | 19 ++++++++++- src/flat_multiset.h | 23 +++++++++++-- src/flat_set.h | 26 ++++++++++++--- src/forward_list.h | 61 ++++++++++++++++++++++------------- src/list.h | 20 ++++++++---- src/queue.h | 28 +++++++++++++--- src/reference_flat_map.h | 2 +- src/reference_flat_multimap.h | 2 +- src/reference_flat_multiset.h | 2 +- src/reference_flat_set.h | 2 +- src/stack.h | 24 ++++++++++++-- test/test_deque.cpp | 21 ++++++++++++ test/test_flat_map.cpp | 32 ++++++++++++++++++ test/test_flat_multimap.cpp | 33 +++++++++++++++++++ test/test_flat_multiset.cpp | 34 +++++++++++++++++-- test/test_flat_set.cpp | 29 +++++++++++++++++ test/test_forward_list.cpp | 24 +++++++++++++- test/test_list.cpp | 25 +++++++++++++- test/test_queue.cpp | 45 ++++++++++++++++++++++++++ test/test_stack.cpp | 45 ++++++++++++++++++++++++++ test/vs2017/etl.vcxproj | 3 +- 23 files changed, 473 insertions(+), 58 deletions(-) diff --git a/src/deque.h b/src/deque.h index 533795df..6171131c 100644 --- a/src/deque.h +++ b/src/deque.h @@ -1797,9 +1797,17 @@ namespace etl //********************************************************************* void initialise() { - while (current_size > 0) + if ETL_IF_CONSTEXPR(etl::is_trivially_destructible::value) { - destroy_element_back(); + current_size = 0; + construct_count.clear(); + } + else + { + while (current_size > 0) + { + destroy_element_back(); + } } _begin = iterator(0, *this, p_buffer); diff --git a/src/flat_map.h b/src/flat_map.h index 26132748..6ca6f8ed 100644 --- a/src/flat_map.h +++ b/src/flat_map.h @@ -398,7 +398,24 @@ namespace etl //************************************************************************* void clear() { - erase(begin(), end()); + if ETL_IF_CONSTEXPR(etl::is_trivially_destructible::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(); } //********************************************************************* diff --git a/src/flat_multimap.h b/src/flat_multimap.h index e6315c13..41246cb2 100644 --- a/src/flat_multimap.h +++ b/src/flat_multimap.h @@ -349,7 +349,24 @@ namespace etl //************************************************************************* void clear() { - erase(begin(), end()); + if ETL_IF_CONSTEXPR(etl::is_trivially_destructible::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(); } //********************************************************************* diff --git a/src/flat_multiset.h b/src/flat_multiset.h index 10dbc9c9..ff88bb21 100644 --- a/src/flat_multiset.h +++ b/src/flat_multiset.h @@ -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) + { + 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(); } //********************************************************************* diff --git a/src/flat_set.h b/src/flat_set.h index abaf5c07..dec75bc1 100644 --- a/src/flat_set.h +++ b/src/flat_set.h @@ -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) + { + 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(); } //********************************************************************* diff --git a/src/forward_list.h b/src/forward_list.h index 2ac02e55..4be5bca8 100644 --- a/src/forward_list.h +++ b/src/forward_list.h @@ -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::value) { - p_next = p_first->next; // Remember the next node. - destroy_data_node(static_cast(*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(*p_first)); // Destroy the pool object. + p_first = p_next; // Move to the next node. + } } } diff --git a/src/list.h b/src/list.h index 4ba169a2..97c08724 100644 --- a/src/list.h +++ b/src/list.h @@ -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::value) { - destroy_data_node(static_cast(*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(*p_first)); // Destroy the current node. + p_first = p_first->next; // Move to the next node. + } } } diff --git a/src/queue.h b/src/queue.h index 75fc8ceb..16c3de56 100644 --- a/src/queue.h +++ b/src/queue.h @@ -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::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; + } } //************************************************************************* diff --git a/src/reference_flat_map.h b/src/reference_flat_map.h index eda76782..bfd66da4 100644 --- a/src/reference_flat_map.h +++ b/src/reference_flat_map.h @@ -622,7 +622,7 @@ namespace etl //************************************************************************* void clear() { - erase(begin(), end()); + lookup.clear(); } //********************************************************************* diff --git a/src/reference_flat_multimap.h b/src/reference_flat_multimap.h index 5af87cc1..6076596d 100644 --- a/src/reference_flat_multimap.h +++ b/src/reference_flat_multimap.h @@ -542,7 +542,7 @@ namespace etl //************************************************************************* void clear() { - erase(begin(), end()); + lookup.clear(); } //********************************************************************* diff --git a/src/reference_flat_multiset.h b/src/reference_flat_multiset.h index 25e88d58..d0a2cd53 100644 --- a/src/reference_flat_multiset.h +++ b/src/reference_flat_multiset.h @@ -554,7 +554,7 @@ namespace etl //************************************************************************* void clear() { - erase(begin(), end()); + lookup.clear(); } //********************************************************************* diff --git a/src/reference_flat_set.h b/src/reference_flat_set.h index 361f6036..ef9f6089 100644 --- a/src/reference_flat_set.h +++ b/src/reference_flat_set.h @@ -534,7 +534,7 @@ namespace etl //************************************************************************* void clear() { - erase(begin(), end()); + lookup.clear(); } //********************************************************************* diff --git a/src/stack.h b/src/stack.h index 96bf282f..5c2b0056 100644 --- a/src/stack.h +++ b/src/stack.h @@ -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::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(); + } } } diff --git a/test/test_deque.cpp b/test/test_deque.cpp index 7a0719d9..503e561d 100644 --- a/test/test_deque.cpp +++ b/test/test_deque.cpp @@ -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()); } //************************************************************************* diff --git a/test/test_flat_map.cpp b/test/test_flat_map.cpp index dd3768a4..149b2406 100644 --- a/test/test_flat_map.cpp +++ b/test/test_flat_map.cpp @@ -52,11 +52,15 @@ namespace typedef std::pair ElementDC; typedef std::pair ElementNDC; + typedef std::pair ElementInt; + typedef etl::flat_map DataDC; typedef etl::flat_map DataNDC; typedef etl::iflat_map IDataDC; typedef etl::iflat_map IDataNDC; + typedef etl::flat_map DataInt; + typedef std::map Compare_DataDC; typedef std::map Compare_DataNDC; @@ -159,6 +163,8 @@ namespace std::vector excess_data; std::vector different_data; + std::vector int_data; + //************************************************************************* template 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)); } diff --git a/test/test_flat_multimap.cpp b/test/test_flat_multimap.cpp index 0765984b..0e573278 100644 --- a/test/test_flat_multimap.cpp +++ b/test/test_flat_multimap.cpp @@ -50,11 +50,15 @@ namespace typedef std::pair ElementDC; typedef std::pair ElementNDC; + typedef std::pair ElementInt; + typedef etl::flat_multimap DataDC; typedef etl::flat_multimap DataNDC; typedef etl::iflat_multimap IDataDC; typedef etl::iflat_multimap IDataNDC; + typedef etl::flat_multimap DataInt; + typedef std::multimap Compare_DataDC; typedef std::multimap Compare_DataNDC; @@ -84,6 +88,8 @@ namespace std::vector different_data; std::vector multi_data; + std::vector int_data; + //************************************************************************* template 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)); } diff --git a/test/test_flat_multiset.cpp b/test/test_flat_multiset.cpp index d787c274..882774d8 100644 --- a/test/test_flat_multiset.cpp +++ b/test/test_flat_multiset.cpp @@ -51,6 +51,8 @@ namespace typedef etl::flat_multiset DataNDC; typedef etl::iflat_multiset IDataNDC; + typedef etl::flat_multiset DataInt; + typedef std::multiset Compare_DataDC; typedef std::multiset Compare_DataNDC; @@ -101,6 +103,8 @@ namespace std::vector different_data; std::vector multi_data; + std::vector 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)); } diff --git a/test/test_flat_set.cpp b/test/test_flat_set.cpp index 8b841a56..35def29d 100644 --- a/test/test_flat_set.cpp +++ b/test/test_flat_set.cpp @@ -51,6 +51,8 @@ namespace typedef etl::flat_set DataNDC; typedef etl::iflat_set IDataNDC; + typedef etl::flat_set DataInt; + typedef std::set Compare_DataDC; typedef std::set Compare_DataNDC; @@ -99,6 +101,8 @@ namespace std::vector initial_data; std::vector excess_data; std::vector different_data; + + std::vector 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)); } diff --git a/test/test_forward_list.cpp b/test/test_forward_list.cpp index 37063637..11ca2e11 100644 --- a/test/test_forward_list.cpp +++ b/test/test_forward_list.cpp @@ -53,6 +53,8 @@ namespace typedef etl::forward_list DataNDC; typedef etl::iforward_list IDataNDC; + typedef etl::forward_list DataInt; + typedef std::forward_list CompareDataDC; typedef std::forward_list CompareDataNDC; typedef std::vector 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()); } //************************************************************************* diff --git a/test/test_list.cpp b/test/test_list.cpp index 1bb66cd3..cef78918 100644 --- a/test/test_list.cpp +++ b/test/test_list.cpp @@ -52,6 +52,8 @@ namespace typedef etl::list DataNDC2; typedef etl::ilist IDataNDC; + typedef etl::list DataInt; + typedef std::list CompareData; typedef std::vector 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()); } //************************************************************************* diff --git a/test/test_queue.cpp b/test/test_queue.cpp index 16cdbced..d6c3bc00 100644 --- a/test/test_queue.cpp +++ b/test/test_queue.cpp @@ -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 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()); } //************************************************************************* diff --git a/test/test_stack.cpp b/test/test_stack.cpp index 49a5da9c..4810c410 100644 --- a/test/test_stack.cpp +++ b/test/test_stack.cpp @@ -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 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 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()); } //************************************************************************* diff --git a/test/vs2017/etl.vcxproj b/test/vs2017/etl.vcxproj index fca63a9b..49eab9a4 100644 --- a/test/vs2017/etl.vcxproj +++ b/test/vs2017/etl.vcxproj @@ -78,8 +78,7 @@ false - - + stdcpp14 Console