From c981bd0c9641c9129612dbe209f3729da63feb76 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Fri, 21 Jul 2017 10:56:12 +0100 Subject: [PATCH] Added emplace functions supporting up to four parameters to the following containers. forward_list list vector queue priority_queue stack # Conflicts: # src/vector.h # test/data.h # test/vs2017/random.csv --- src/forward_list.h | 60 ++++++++++ src/list.h | 184 +++++++++++++++++++++++++++++++ src/priority_queue.h | 70 +++++++++++- src/queue.h | 74 ++++++++++++- src/stack.h | 64 +++++++++++ src/vector.h | 64 +++++++++++ test/data.h | 4 +- test/test_forward_list.cpp | 29 +++++ test/test_list.cpp | 105 ++++++++++++++++++ test/test_priority_queue.cpp | 123 +++++++++++++++++---- test/test_queue.cpp | 39 +++++++ test/test_stack.cpp | 46 +++++++- test/test_unordered_multiset.cpp | 6 +- test/test_unordered_set.cpp | 6 +- test/test_vector_non_trivial.cpp | 25 ++++- 15 files changed, 863 insertions(+), 36 deletions(-) diff --git a/src/forward_list.h b/src/forward_list.h index cc2053d4..89962776 100644 --- a/src/forward_list.h +++ b/src/forward_list.h @@ -635,6 +635,66 @@ namespace etl insert_node_after(start_node, data_node); } + //************************************************************************* + /// Emplaces a value to the front of the list.. + //************************************************************************* + template + void emplace_front(const T1& value1) + { +#if defined(ETL_CHECK_PUSH_POP) + ETL_ASSERT(!full(), ETL_ERROR(forward_list_full)); +#endif + data_node_t* p_data_node = p_node_pool->allocate(); + ::new (&(p_data_node->value)) T(value1); + ++construct_count; + insert_node_after(start_node, *p_data_node); + } + + //************************************************************************* + /// Emplaces a value to the front of the list.. + //************************************************************************* + template + void emplace_front(const T1& value1, const T2& value2) + { +#if defined(ETL_CHECK_PUSH_POP) + ETL_ASSERT(!full(), ETL_ERROR(forward_list_full)); +#endif + data_node_t* p_data_node = p_node_pool->allocate(); + ::new (&(p_data_node->value)) T(value1, value2); + ++construct_count; + insert_node_after(start_node, *p_data_node); + } + + //************************************************************************* + /// Emplaces a value to the front of the list.. + //************************************************************************* + template + void emplace_front(const T1& value1, const T2& value2, const T3& value3) + { +#if defined(ETL_CHECK_PUSH_POP) + ETL_ASSERT(!full(), ETL_ERROR(forward_list_full)); +#endif + data_node_t* p_data_node = p_node_pool->allocate(); + ::new (&(p_data_node->value)) T(value1, value2, value3); + ++construct_count; + insert_node_after(start_node, *p_data_node); + } + + //************************************************************************* + /// Emplaces a value to the front of the list.. + //************************************************************************* + template + void emplace_front(const T1& value1, const T2& value2, const T3& value3, const T4& value4) + { +#if defined(ETL_CHECK_PUSH_POP) + ETL_ASSERT(!full(), ETL_ERROR(forward_list_full)); +#endif + data_node_t* p_data_node = p_node_pool->allocate(); + ::new (&(p_data_node->value)) T(value1, value2, value3, value4); + ++construct_count; + insert_node_after(start_node, *p_data_node); + } + //************************************************************************* /// Removes a value from the front of the forward_list. //************************************************************************* diff --git a/src/list.h b/src/list.h index 1aa38857..314d096d 100644 --- a/src/list.h +++ b/src/list.h @@ -769,6 +769,66 @@ namespace etl insert_node(get_head(), allocate_data_node(value)); } + //************************************************************************* + /// Emplaces a value to the front of the list.. + //************************************************************************* + template + void emplace_front(const T1& value1) + { +#if defined(ETL_CHECK_PUSH_POP) + ETL_ASSERT(!full(), ETL_ERROR(list_full)); +#endif + data_node_t* p_data_node = p_node_pool->allocate(); + ::new (&(p_data_node->value)) T(value1); + ++construct_count; + insert_node(get_head(), *p_data_node); + } + + //************************************************************************* + /// Emplaces a value to the front of the list.. + //************************************************************************* + template + void emplace_front(const T1& value1, const T2& value2) + { +#if defined(ETL_CHECK_PUSH_POP) + ETL_ASSERT(!full(), ETL_ERROR(list_full)); +#endif + data_node_t* p_data_node = p_node_pool->allocate(); + ::new (&(p_data_node->value)) T(value1, value2); + ++construct_count; + insert_node(get_head(), *p_data_node); + } + + //************************************************************************* + /// Emplaces a value to the front of the list.. + //************************************************************************* + template + void emplace_front(const T1& value1, const T2& value2, const T3& value3) + { +#if defined(ETL_CHECK_PUSH_POP) + ETL_ASSERT(!full(), ETL_ERROR(list_full)); +#endif + data_node_t* p_data_node = p_node_pool->allocate(); + ::new (&(p_data_node->value)) T(value1, value2, value3); + ++construct_count; + insert_node(get_head(), *p_data_node); + } + + //************************************************************************* + /// Emplaces a value to the front of the list.. + //************************************************************************* + template + void emplace_front(const T1& value1, const T2& value2, const T3& value3, const T4& value4) + { +#if defined(ETL_CHECK_PUSH_POP) + ETL_ASSERT(!full(), ETL_ERROR(list_full)); +#endif + data_node_t* p_data_node = p_node_pool->allocate(); + ::new (&(p_data_node->value)) T(value1, value2, value3, value4); + ++construct_count; + insert_node(get_head(), *p_data_node); + } + //************************************************************************* /// Removes a value from the front of the list. //************************************************************************* @@ -800,6 +860,66 @@ namespace etl insert_node(terminal_node, allocate_data_node(value)); } + //************************************************************************* + /// Emplaces a value to the back of the list.. + //************************************************************************* + template + void emplace_back(const T1& value1) + { +#if defined(ETL_CHECK_PUSH_POP) + ETL_ASSERT(!full(), ETL_ERROR(list_full)); +#endif + data_node_t* p_data_node = p_node_pool->allocate(); + ::new (&(p_data_node->value)) T(value1); + ++construct_count; + insert_node(terminal_node, *p_data_node); + } + + //************************************************************************* + /// Emplaces a value to the back of the list.. + //************************************************************************* + template + void emplace_back(const T1& value1, const T2& value2) + { +#if defined(ETL_CHECK_PUSH_POP) + ETL_ASSERT(!full(), ETL_ERROR(list_full)); +#endif + data_node_t* p_data_node = p_node_pool->allocate(); + ::new (&(p_data_node->value)) T(value1, value2); + ++construct_count; + insert_node(terminal_node, *p_data_node); + } + + //************************************************************************* + /// Emplaces a value to the back of the list.. + //************************************************************************* + template + void emplace_back(const T1& value1, const T2& value2, const T3& value3) + { +#if defined(ETL_CHECK_PUSH_POP) + ETL_ASSERT(!full(), ETL_ERROR(list_full)); +#endif + data_node_t* p_data_node = p_node_pool->allocate(); + ::new (&(p_data_node->value)) T(value1, value2, value3); + ++construct_count; + insert_node(terminal_node, *p_data_node); + } + + //************************************************************************* + /// Emplaces a value to the back of the list.. + //************************************************************************* + template + void emplace_back(const T1& value1, const T2& value2, const T3& value3, const T4& value4) + { +#if defined(ETL_CHECK_PUSH_POP) + ETL_ASSERT(!full(), ETL_ERROR(list_full)); +#endif + data_node_t* p_data_node = p_node_pool->allocate(); + ::new (&(p_data_node->value)) T(value1, value2, value3, value4); + ++construct_count; + insert_node(terminal_node, *p_data_node); + } + //************************************************************************* /// Removes a value from the back of the list. //************************************************************************* @@ -825,6 +945,70 @@ namespace etl return iterator(data_node); } + //************************************************************************* + /// Emplaces a value to the list at the specified position. + //************************************************************************* + template + iterator emplace(iterator position, const T1& value1) + { + ETL_ASSERT(!full(), ETL_ERROR(list_full)); + + data_node_t* p_data_node = p_node_pool->allocate(); + ::new (&(p_data_node->value)) T(value1); + ++construct_count; + insert_node(*position.p_node, *p_data_node); + + return iterator(*p_data_node); + } + + //************************************************************************* + /// Emplaces a value to the list at the specified position. + //************************************************************************* + template + iterator emplace(iterator position, const T1& value1, const T2& value2) + { + ETL_ASSERT(!full(), ETL_ERROR(list_full)); + + data_node_t* p_data_node = p_node_pool->allocate(); + ::new (&(p_data_node->value)) T(value1, value2); + ++construct_count; + insert_node(*position.p_node, *p_data_node); + + return iterator(*p_data_node); + } + + //************************************************************************* + /// Emplaces a value to the list at the specified position. + //************************************************************************* + template + iterator emplace(iterator position, const T1& value1, const T2& value2, const T3& value3) + { + ETL_ASSERT(!full(), ETL_ERROR(list_full)); + + data_node_t* p_data_node = p_node_pool->allocate(); + ::new (&(p_data_node->value)) T(value1, value2, value3); + ++construct_count; + insert_node(*position.p_node, *p_data_node); + + return iterator(*p_data_node); + } + + //************************************************************************* + /// Emplaces a value to the list at the specified position. + //************************************************************************* + template + iterator emplace(iterator position, const T1& value1, const T2& value2, const T3& value3, const T4& value4) + { + ETL_ASSERT(!full(), ETL_ERROR(list_full)); + + data_node_t* p_data_node = p_node_pool->allocate(); + ::new (&(p_data_node->value)) T(value1, value2, value3, value4); + ++construct_count; + insert_node(*position.p_node, *p_data_node); + + return iterator(*p_data_node); + } + //************************************************************************* /// Inserts 'n' copies of a value to the list at the specified position. //************************************************************************* diff --git a/src/priority_queue.h b/src/priority_queue.h index 89816012..cda9b7b4 100644 --- a/src/priority_queue.h +++ b/src/priority_queue.h @@ -153,7 +153,7 @@ namespace etl //************************************************************************* /// Adds a value to the queue. /// If asserts or exceptions are enabled, throws an etl::priority_queue_full - /// is the priority queue is already full, otherwise does nothing if full. + /// is the priority queue is already full. ///\param value The value to push to the queue. //************************************************************************* void push(parameter_t value) @@ -166,6 +166,74 @@ namespace etl std::push_heap(container.begin(), container.end(), TCompare()); } + //************************************************************************* + /// Emplaces a value to the queue. + /// If asserts or exceptions are enabled, throws an etl::priority_queue_full + /// is the priority queue is already full. + ///\param value The value to push to the queue. + //************************************************************************* + template + void emplace(const T1& value1) + { + ETL_ASSERT(!full(), ETL_ERROR(etl::priority_queue_full)); + + // Put element at end + container.emplace_back(value1); + // Make elements in container into heap + std::push_heap(container.begin(), container.end(), TCompare()); + } + + //************************************************************************* + /// Emplaces a value to the queue. + /// If asserts or exceptions are enabled, throws an etl::priority_queue_full + /// is the priority queue is already full. + ///\param value The value to push to the queue. + //************************************************************************* + template + void emplace(const T1& value1, const T2& value2) + { + ETL_ASSERT(!full(), ETL_ERROR(etl::priority_queue_full)); + + // Put element at end + container.emplace_back(value1, value2); + // Make elements in container into heap + std::push_heap(container.begin(), container.end(), TCompare()); + } + + //************************************************************************* + /// Emplaces a value to the queue. + /// If asserts or exceptions are enabled, throws an etl::priority_queue_full + /// is the priority queue is already full. + ///\param value The value to push to the queue. + //************************************************************************* + template + void emplace(const T1& value1, const T2& value2, const T3& value3) + { + ETL_ASSERT(!full(), ETL_ERROR(etl::priority_queue_full)); + + // Put element at end + container.emplace_back(value1, value2, value3); + // Make elements in container into heap + std::push_heap(container.begin(), container.end(), TCompare()); + } + + //************************************************************************* + /// Emplaces a value to the queue. + /// If asserts or exceptions are enabled, throws an etl::priority_queue_full + /// is the priority queue is already full. + ///\param value The value to push to the queue. + //************************************************************************* + template + void emplace(const T1& value1, const T2& value2, const T3& value3, const T4& value4) + { + ETL_ASSERT(!full(), ETL_ERROR(etl::priority_queue_full)); + + // Put element at end + container.emplace_back(value1, value2, value3, value4); + // Make elements in container into heap + std::push_heap(container.begin(), container.end(), TCompare()); + } + //************************************************************************* /// Assigns values to the priority queue. /// If asserts or exceptions are enabled, emits priority_queue_full if diff --git a/src/queue.h b/src/queue.h index cb8d2184..aeec2304 100644 --- a/src/queue.h +++ b/src/queue.h @@ -237,8 +237,7 @@ namespace etl //************************************************************************* /// Adds a value to the queue. - /// If asserts or exceptions are enabled, throws an etl::queue_full if the queue if already full, - /// otherwise does nothing if full. + /// If asserts or exceptions are enabled, throws an etl::queue_full if the queue if already full. ///\param value The value to push to the queue. //************************************************************************* void push(parameter_t value) @@ -256,8 +255,7 @@ namespace etl /// Allows a possibly more efficient 'push' by moving to the next input value /// and returning a reference to it. /// This may eliminate a copy by allowing direct construction in-place.
- /// If asserts or exceptions are enabled, throws an etl::queue_full is the queue is already full, - /// otherwise does nothing if full. + /// If asserts or exceptions are enabled, throws an etl::queue_full is the queue is already full. /// \return A reference to the position to 'push' to. //************************************************************************* reference push() @@ -275,6 +273,74 @@ namespace etl return p_buffer[next]; } + //************************************************************************* + /// Constructs a value in the queue 'in place'. + /// If asserts or exceptions are enabled, throws an etl::queue_full if the queue if already full. + ///\param value The value to use to construct the item to push to the queue. + //************************************************************************* + template + void emplace(const T1& value1) + { +#if defined(ETL_CHECK_PUSH_POP) + ETL_ASSERT(!full(), ETL_ERROR(queue_full)); +#endif + ::new (&p_buffer[in]) T(value1); + in = (in == (MAX_SIZE - 1)) ? 0 : in + 1; + ++current_size; + ++construct_count; + } + + //************************************************************************* + /// Constructs a value in the queue 'in place'. + /// If asserts or exceptions are enabled, throws an etl::queue_full if the queue if already full. + ///\param value The value to use to construct the item to push to the queue. + //************************************************************************* + template + void emplace(const T1& value1, const T2& value2) + { +#if defined(ETL_CHECK_PUSH_POP) + ETL_ASSERT(!full(), ETL_ERROR(queue_full)); +#endif + ::new (&p_buffer[in]) T(value1, value2); + in = (in == (MAX_SIZE - 1)) ? 0 : in + 1; + ++current_size; + ++construct_count; + } + + //************************************************************************* + /// Constructs a value in the queue 'in place'. + /// If asserts or exceptions are enabled, throws an etl::queue_full if the queue if already full. + ///\param value The value to use to construct the item to push to the queue. + //************************************************************************* + template + void emplace(const T1& value1, const T2& value2, const T3& value3) + { +#if defined(ETL_CHECK_PUSH_POP) + ETL_ASSERT(!full(), ETL_ERROR(queue_full)); +#endif + ::new (&p_buffer[in]) T(value1, value2, value3); + in = (in == (MAX_SIZE - 1)) ? 0 : in + 1; + ++current_size; + ++construct_count; + } + + //************************************************************************* + /// Constructs a value in the queue 'in place'. + /// If asserts or exceptions are enabled, throws an etl::queue_full if the queue if already full. + ///\param value The value to use to construct the item to push to the queue. + //************************************************************************* + template + void emplace(const T1& value1, const T2& value2, const T3& value3, const T4& value4) + { +#if defined(ETL_CHECK_PUSH_POP) + ETL_ASSERT(!full(), ETL_ERROR(queue_full)); +#endif + ::new (&p_buffer[in]) T(value1, value2, value3, value4); + in = (in == (MAX_SIZE - 1)) ? 0 : in + 1; + ++current_size; + ++construct_count; + } + //************************************************************************* /// Clears the queue to the empty state. //************************************************************************* diff --git a/src/stack.h b/src/stack.h index b226c1f5..0740c58d 100644 --- a/src/stack.h +++ b/src/stack.h @@ -222,6 +222,70 @@ namespace etl ++construct_count; } + //************************************************************************* + /// Constructs a value in the stack place'. + /// If asserts or exceptions are enabled, throws an etl::stack_full if the stack is already full. + ///\param value The value to push to the stack. + //************************************************************************* + template + void emplace(const T1& value1) + { +#if defined(ETL_CHECK_PUSH_POP) + ETL_ASSERT(!full(), ETL_ERROR(stack_full)); +#endif + top_index = current_size++; + ::new (&p_buffer[top_index]) T(value1); + ++construct_count; + } + + //************************************************************************* + /// Constructs a value in the stack place'. + /// If asserts or exceptions are enabled, throws an etl::stack_full if the stack is already full. + ///\param value The value to push to the stack. + //************************************************************************* + template + void emplace(const T1& value1, const T2& value2) + { +#if defined(ETL_CHECK_PUSH_POP) + ETL_ASSERT(!full(), ETL_ERROR(stack_full)); +#endif + top_index = current_size++; + ::new (&p_buffer[top_index]) T(value1, value2); + ++construct_count; + } + + //************************************************************************* + /// Constructs a value in the stack place'. + /// If asserts or exceptions are enabled, throws an etl::stack_full if the stack is already full. + ///\param value The value to push to the stack. + //************************************************************************* + template + void emplace(const T1& value1, const T2& value2, const T3& value3) + { +#if defined(ETL_CHECK_PUSH_POP) + ETL_ASSERT(!full(), ETL_ERROR(stack_full)); +#endif + top_index = current_size++; + ::new (&p_buffer[top_index]) T(value1, value2, value3); + ++construct_count; + } + + //************************************************************************* + /// Constructs a value in the stack place'. + /// If asserts or exceptions are enabled, throws an etl::stack_full if the stack is already full. + ///\param value The value to push to the stack. + //************************************************************************* + template + void emplace(const T1& value1, const T2& value2, const T3& value3, const T4& value4) + { +#if defined(ETL_CHECK_PUSH_POP) + ETL_ASSERT(!full(), ETL_ERROR(stack_full)); +#endif + top_index = current_size++; + ::new (&p_buffer[top_index]) T(value1, value2, value3, value4); + ++construct_count; + } + //************************************************************************* /// Allows a possibly more efficient 'push' by moving to the next input value /// and returning a reference to it. diff --git a/src/vector.h b/src/vector.h index 5eb7d6e4..68f7008f 100644 --- a/src/vector.h +++ b/src/vector.h @@ -468,6 +468,70 @@ namespace etl create_back(value); } + //********************************************************************* + /// Constructs 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. + //********************************************************************* + template + void emplace_back(const T1& value1) + { +#if defined(ETL_CHECK_PUSH_POP) + ETL_ASSERT(size() != CAPACITY, ETL_ERROR(vector_full)); +#endif + ::new (p_end) T(value1); + ++p_end; + ++construct_count; + } + + //********************************************************************* + /// Constructs 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. + //********************************************************************* + template + void emplace_back(const T1& value1, const T2& value2) + { +#if defined(ETL_CHECK_PUSH_POP) + ETL_ASSERT(size() != CAPACITY, ETL_ERROR(vector_full)); +#endif + ::new (p_end) T(value1, value2); + ++p_end; + ++construct_count; + } + + //********************************************************************* + /// Constructs 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. + //********************************************************************* + template + void emplace_back(const T1& value1, const T2& value2, const T3& value3) + { +#if defined(ETL_CHECK_PUSH_POP) + ETL_ASSERT(size() != CAPACITY, ETL_ERROR(vector_full)); +#endif + ::new (p_end) T(value1, value2, value3); + ++p_end; + ++construct_count; + } + + //********************************************************************* + /// Constructs 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. + //********************************************************************* + template + void emplace_back(const T1& value1, const T2& value2, const T3& value3, const T4& value4) + { +#if defined(ETL_CHECK_PUSH_POP) + ETL_ASSERT(size() != CAPACITY, ETL_ERROR(vector_full)); +#endif + ::new (p_end) T(value1, value2, value3, value4); + ++p_end; + ++construct_count; + } + //************************************************************************* /// Removes an element from the end of the vector. /// Does nothing if the vector is empty. diff --git a/test/data.h b/test/data.h index ed2ede64..4e3a5208 100644 --- a/test/data.h +++ b/test/data.h @@ -45,7 +45,7 @@ public: { } - TestDataDC(const T& value, int index = 0) + explicit TestDataDC(const T& value, int index = 0) : value(value), index(index) { @@ -92,7 +92,7 @@ class TestDataNDC { public: - TestDataNDC(const T& value, int index = 0) + explicit TestDataNDC(const T& value, int index = 0) : value(value), index(index) {} diff --git a/test/test_forward_list.cpp b/test/test_forward_list.cpp index cd733421..16818f3a 100644 --- a/test/test_forward_list.cpp +++ b/test/test_forward_list.cpp @@ -448,6 +448,35 @@ namespace CHECK(are_equal); } + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_emplace_front) + { + CompareDataNDC compare_data; + DataNDC data; + + compare_data.emplace_front("1"); + compare_data.emplace_front("2"); + compare_data.emplace_front("3"); + compare_data.emplace_front("4"); + compare_data.emplace_front("5"); + compare_data.emplace_front("6"); + + CHECK_NO_THROW(data.emplace_front("1")); + CHECK_NO_THROW(data.emplace_front("2")); + CHECK_NO_THROW(data.emplace_front("3")); + CHECK_NO_THROW(data.emplace_front("4")); + CHECK_NO_THROW(data.emplace_front("5")); + CHECK_NO_THROW(data.emplace_front("6")); + + CHECK_EQUAL(6U, data.size()); + CHECK_EQUAL(6, std::distance(data.begin(), data.end())); + + CHECK_EQUAL(std::distance(compare_data.begin(), compare_data.end()), data.size()); + + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); + CHECK(are_equal); + } + //************************************************************************* TEST_FIXTURE(SetupFixture, test_push_front_null) { diff --git a/test/test_list.cpp b/test/test_list.cpp index a39bb24f..ed52b1f8 100644 --- a/test/test_list.cpp +++ b/test/test_list.cpp @@ -377,6 +377,59 @@ namespace CHECK(are_equal); } + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_emplace_position_value) + { + const size_t INITIAL_SIZE = 4; + const ItemNDC VALUE = ItemNDC("1"); + const std::string INSERT_VALUE = "2"; + + CompareData compare_data(INITIAL_SIZE, VALUE); + DataNDC data(INITIAL_SIZE, VALUE); + + size_t offset = 2; + + DataNDC::iterator i_data = data.begin(); + std::advance(i_data, offset); + + CompareData::iterator i_compare_data = compare_data.begin(); + std::advance(i_compare_data, offset); + + data.emplace(i_data, INSERT_VALUE); + compare_data.emplace(i_compare_data, INSERT_VALUE); + + CHECK_EQUAL(compare_data.size(), data.size()); + + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); + + CHECK(are_equal); + + offset = 0; + + i_data = data.begin(); + std::advance(i_data, offset); + + i_compare_data = compare_data.begin(); + std::advance(i_compare_data, offset); + + data.emplace(i_data, INSERT_VALUE); + compare_data.emplace(i_compare_data, INSERT_VALUE); + + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); + + CHECK(are_equal); + + i_data = data.end(); + i_compare_data = compare_data.end(); + + data.emplace(i_data, VALUE); + compare_data.emplace(i_compare_data, VALUE); + + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); + + CHECK(are_equal); + } + //************************************************************************* TEST_FIXTURE(SetupFixture, test_insert_range) { @@ -449,6 +502,32 @@ namespace CHECK(are_equal); } + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_emplace_front) + { + CompareData compare_data; + DataNDC data; + + compare_data.emplace_front("1"); + compare_data.emplace_front("2"); + compare_data.emplace_front("3"); + compare_data.emplace_front("4"); + compare_data.emplace_front("5"); + compare_data.emplace_front("6"); + + CHECK_NO_THROW(data.emplace_front("1")); + CHECK_NO_THROW(data.emplace_front("2")); + CHECK_NO_THROW(data.emplace_front("3")); + CHECK_NO_THROW(data.emplace_front("4")); + CHECK_NO_THROW(data.emplace_front("5")); + CHECK_NO_THROW(data.emplace_front("6")); + + CHECK_EQUAL(compare_data.size(), data.size()); + + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); + CHECK(are_equal); + } + //************************************************************************* TEST_FIXTURE(SetupFixture, test_push_front_excess) { @@ -550,6 +629,32 @@ namespace CHECK(are_equal); } + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_emplace_back) + { + CompareData compare_data; + DataNDC data; + + compare_data.emplace_back("1"); + compare_data.emplace_back("2"); + compare_data.emplace_back("3"); + compare_data.emplace_back("4"); + compare_data.emplace_back("5"); + compare_data.emplace_back("6"); + + CHECK_NO_THROW(data.emplace_back("1")); + CHECK_NO_THROW(data.emplace_back("2")); + CHECK_NO_THROW(data.emplace_back("3")); + CHECK_NO_THROW(data.emplace_back("4")); + CHECK_NO_THROW(data.emplace_back("5")); + CHECK_NO_THROW(data.emplace_back("6")); + + CHECK_EQUAL(compare_data.size(), data.size()); + + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); + CHECK(are_equal); + } + //************************************************************************* TEST_FIXTURE(SetupFixture, test_push_back_excess) { diff --git a/test/test_priority_queue.cpp b/test/test_priority_queue.cpp index e8e6a67b..b35468c3 100644 --- a/test/test_priority_queue.cpp +++ b/test/test_priority_queue.cpp @@ -33,7 +33,37 @@ SOFTWARE. #include "priority_queue.h" namespace -{ +{ + struct Item + { + Item(char c_, int i_, double d_) + : c(c_), + i(i_), + d(d_) + { + } + + char c; + int i; + double d; + }; + + bool operator == (const Item& lhs, const Item& rhs) + { + return (lhs.c == rhs.c) && (lhs.i == rhs.i) && (lhs.d == rhs.d); + } + + bool operator < (const Item& lhs, const Item& rhs) + { + return (lhs.c < rhs.c); + } + + std::ostream& operator << (std::ostream& os, const Item& item) + { + os << item.c << "," << item.i << "," << item.d; + return os; + } + SUITE(test_priority_queue) { static const size_t SIZE = 4; @@ -216,6 +246,57 @@ namespace compare_priority_queue.push(4); CHECK_EQUAL(compare_priority_queue.size(), priority_queue.size()); CHECK_EQUAL(compare_priority_queue.top(), priority_queue.top()); + + priority_queue.pop(); + compare_priority_queue.pop(); + CHECK_EQUAL(compare_priority_queue.size(), priority_queue.size()); + CHECK_EQUAL(compare_priority_queue.top(), priority_queue.top()); + + priority_queue.pop(); + compare_priority_queue.pop(); + CHECK_EQUAL(compare_priority_queue.size(), priority_queue.size()); + CHECK_EQUAL(compare_priority_queue.top(), priority_queue.top()); + + priority_queue.pop(); + compare_priority_queue.pop(); + CHECK_EQUAL(compare_priority_queue.size(), priority_queue.size()); + CHECK_EQUAL(compare_priority_queue.top(), priority_queue.top()); + } + + //************************************************************************* + TEST(test_emplace) + { + etl::priority_queue priority_queue; + std::priority_queue compare_priority_queue; + + priority_queue.emplace('d', 4, 7.8); + compare_priority_queue.emplace('d', 4, 7.8); + + priority_queue.emplace('b', 2, 3.4); + compare_priority_queue.emplace('b', 2, 3.4); + + priority_queue.emplace('a', 1, 1.2); + compare_priority_queue.emplace('a', 1, 1.2); + + priority_queue.emplace('c', 3, 5.6); + compare_priority_queue.emplace('c', 3, 5.6); + CHECK_EQUAL(compare_priority_queue.size(), priority_queue.size()); + CHECK_EQUAL(compare_priority_queue.top(), priority_queue.top()); + + priority_queue.pop(); + compare_priority_queue.pop(); + CHECK_EQUAL(compare_priority_queue.size(), priority_queue.size()); + CHECK_EQUAL(compare_priority_queue.top(), priority_queue.top()); + + priority_queue.pop(); + compare_priority_queue.pop(); + CHECK_EQUAL(compare_priority_queue.size(), priority_queue.size()); + CHECK_EQUAL(compare_priority_queue.top(), priority_queue.top()); + + priority_queue.pop(); + compare_priority_queue.pop(); + CHECK_EQUAL(compare_priority_queue.size(), priority_queue.size()); + CHECK_EQUAL(compare_priority_queue.top(), priority_queue.top()); } //************************************************************************* @@ -321,31 +402,31 @@ namespace } //************************************************************************* - //TEST(test_assignment_interface) - //{ - // etl::priority_queue priority_queue1; - // - // priority_queue1.push(1); - // priority_queue1.push(4); - // priority_queue1.push(3); - // priority_queue1.push(2); + TEST(test_assignment_interface) + { + etl::priority_queue priority_queue1; + + priority_queue1.push(1); + priority_queue1.push(4); + priority_queue1.push(3); + priority_queue1.push(2); - // etl::priority_queue priority_queue2; + etl::priority_queue priority_queue2; - // etl::ipriority_queue ipriority_queue1 = priority_queue1; - // etl::ipriority_queue ipriority_queue2 = priority_queue2; + etl::ipriority_queue, std::less>& ipriority_queue1 = priority_queue1; + etl::ipriority_queue, std::less>& ipriority_queue2 = priority_queue2; - // ipriority_queue2 = ipriority_queue1; + ipriority_queue2 = ipriority_queue1; - // CHECK(priority_queue1.size() == priority_queue2.size()); + CHECK(priority_queue1.size() == priority_queue2.size()); - // while (!priority_queue1.empty()) - // { - // CHECK_EQUAL(priority_queue1.top(), priority_queue2.top()); - // priority_queue1.pop(); - // priority_queue2.pop(); - // } - //} + while (!priority_queue1.empty()) + { + CHECK_EQUAL(priority_queue1.top(), priority_queue2.top()); + priority_queue1.pop(); + priority_queue2.pop(); + } + } //************************************************************************* TEST(test_self_assignment) diff --git a/test/test_queue.cpp b/test/test_queue.cpp index 649e0689..4a62b3fb 100644 --- a/test/test_queue.cpp +++ b/test/test_queue.cpp @@ -34,6 +34,25 @@ SOFTWARE. namespace { + struct Item + { + Item(char c_, int i_, double d_) + : c(c_), + i(i_), + d(d_) + { + } + + char c; + int i; + double d; + }; + + bool operator == (const Item& lhs, const Item& rhs) + { + return (lhs.c == rhs.c) && (lhs.i == rhs.i) && (lhs.d == rhs.d); + } + SUITE(test_queue) { //************************************************************************* @@ -256,6 +275,26 @@ namespace CHECK(pass); } + //************************************************************************* + TEST(test_multiple_emplace) + { + etl::queue queue; + + queue.emplace('a', 1, 1.2); + queue.emplace('b', 2, 3.4); + queue.emplace('c', 3, 5.6); + queue.emplace('d', 4, 7.8); + + CHECK(queue.front() == Item('a', 1, 1.2)); + queue.pop(); + CHECK(queue.front() == Item('b', 2, 3.4)); + queue.pop(); + CHECK(queue.front() == Item('c', 3, 5.6)); + queue.pop(); + CHECK(queue.front() == Item('d', 4, 7.8)); + queue.pop(); + } + //************************************************************************* TEST(test_multiple_push_void) { diff --git a/test/test_stack.cpp b/test/test_stack.cpp index 62d3dbdb..448e691f 100644 --- a/test/test_stack.cpp +++ b/test/test_stack.cpp @@ -36,6 +36,25 @@ SOFTWARE. namespace { + struct Item + { + Item(char c_, int i_, double d_) + : c(c_), + i(i_), + d(d_) + { + } + + char c; + int i; + double d; + }; + + bool operator == (const Item& lhs, const Item& rhs) + { + return (lhs.c == rhs.c) && (lhs.i == rhs.i) && (lhs.d == rhs.d); + } + SUITE(test_stack) { typedef TestDataDC ItemDC; @@ -133,11 +152,36 @@ namespace CHECK_EQUAL(2U, stack.size()); CHECK_EQUAL(2, stack.top()); - stack.pop(); CHECK_EQUAL(1, stack.top()); } + //************************************************************************* + TEST(test_emplace) + { + etl::stack stack; + + stack.emplace('a', 1, 1.2); + CHECK_EQUAL(1U, stack.size()); + + stack.emplace('b', 2, 3.4); + CHECK_EQUAL(2U, stack.size()); + + stack.emplace('c', 3, 5.6); + CHECK_EQUAL(3U, stack.size()); + + stack.emplace('d', 4, 7.8); + CHECK_EQUAL(4U, stack.size()); + + CHECK(stack.top() == Item('d', 4, 7.8)); + stack.pop(); + CHECK(stack.top() == Item('c', 3, 5.6)); + stack.pop(); + CHECK(stack.top() == Item('b', 2, 3.4)); + stack.pop(); + CHECK(stack.top() == Item('a', 1, 1.2)); + } + //************************************************************************* TEST(test_push_void) { diff --git a/test/test_unordered_multiset.cpp b/test/test_unordered_multiset.cpp index 0806cd5c..05a084a5 100644 --- a/test/test_unordered_multiset.cpp +++ b/test/test_unordered_multiset.cpp @@ -496,7 +496,7 @@ namespace DataNDC data; DataNDC::hasher hash_function = data.hash_function(); - CHECK_EQUAL(simple_hash()(std::string("ABCDEF")), hash_function(std::string("ABCDEF"))); + CHECK_EQUAL(simple_hash()(NDC(std::string("ABCDEF"))), hash_function(NDC(std::string("ABCDEF")))); } //************************************************************************* @@ -505,8 +505,8 @@ namespace DataNDC data; DataNDC::key_equal key_eq = data.key_eq(); - CHECK(key_eq(std::string("ABCDEF"), std::string("ABCDEF"))); - CHECK(!key_eq(std::string("ABCDEF"), std::string("ABCDEG"))); + CHECK(key_eq(NDC(std::string("ABCDEF")), NDC(std::string("ABCDEF")))); + CHECK(!key_eq(NDC(std::string("ABCDEF")), NDC(std::string("ABCDEG")))); } //************************************************************************* diff --git a/test/test_unordered_set.cpp b/test/test_unordered_set.cpp index 00956a44..0bd1d20f 100644 --- a/test/test_unordered_set.cpp +++ b/test/test_unordered_set.cpp @@ -411,7 +411,7 @@ namespace DataNDC data; DataNDC::hasher hash_function = data.hash_function(); - CHECK_EQUAL(simple_hash()(std::string("ABCDEF")), hash_function(std::string("ABCDEF"))); + CHECK_EQUAL(simple_hash()(NDC(std::string("ABCDEF"))), hash_function(NDC(std::string("ABCDEF")))); } //************************************************************************* @@ -420,8 +420,8 @@ namespace DataNDC data; DataNDC::key_equal key_eq = data.key_eq(); - CHECK(key_eq(std::string("ABCDEF"), std::string("ABCDEF"))); - CHECK(!key_eq(std::string("ABCDEF"), std::string("ABCDEG"))); + CHECK(key_eq(NDC(std::string("ABCDEF")), NDC(std::string("ABCDEF")))); + CHECK(!key_eq(NDC(std::string("ABCDEF")), NDC(std::string("ABCDEG")))); } //************************************************************************* diff --git a/test/test_vector_non_trivial.cpp b/test/test_vector_non_trivial.cpp index def1c2df..b07f21d8 100644 --- a/test/test_vector_non_trivial.cpp +++ b/test/test_vector_non_trivial.cpp @@ -489,7 +489,7 @@ namespace { std::string value(" "); value[0] = char('A' + i); - compare_data.push_back(value); + compare_data.push_back(NDC(value)); data.push_back(NDC(value)); } @@ -537,6 +537,29 @@ namespace CHECK_THROW(data.push_back(NDC("Z")), etl::vector_full); } + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_emplace_back) + { + CompareDataNDC compare_data; + DataNDC data; + + for (size_t i = 0; i < SIZE; ++i) + { + std::string value(" "); + value[0] = char('A' + i); + compare_data.emplace_back(value); + data.emplace_back(value); + } + + 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_pop_back) {