diff --git a/include/etl/queue.h b/include/etl/queue.h index b704d8a1c..99e4d50eb 100644 --- a/include/etl/queue.h +++ b/include/etl/queue.h @@ -337,90 +337,107 @@ namespace etl //************************************************************************* /// 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. + ///\param args The arguments to the constructor for the new item to push to the queue. //************************************************************************* template - void emplace(Args && ... args) + reference emplace(Args && ... args) { #if defined(ETL_CHECK_PUSH_POP) ETL_ASSERT(!full(), ETL_ERROR(queue_full)); #endif - ::new (&p_buffer[in]) T(etl::forward(args)...); + reference value = p_buffer[in]; + ::new (&value) T(etl::forward(args)...); add_in(); + return value; } #else //************************************************************************* - /// Constructs a value in the queue 'in place'. + /// Constructs a default constructed 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. //************************************************************************* - void emplace() + reference emplace() { #if defined(ETL_CHECK_PUSH_POP) ETL_ASSERT(!full(), ETL_ERROR(queue_full)); #endif - ::new (&p_buffer[in]) T(); + reference value = p_buffer[in]; + ::new (&value) T(); add_in(); + return value; } //************************************************************************* /// 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. + ///\param value1 The argument to use to construct the item to push to the queue. //************************************************************************* template - void emplace(const T1& value1) + reference emplace(const T1& value1) { #if defined(ETL_CHECK_PUSH_POP) ETL_ASSERT(!full(), ETL_ERROR(queue_full)); #endif - ::new (&p_buffer[in]) T(value1); + reference value = p_buffer[in]; + ::new (&value) T(value1); add_in(); + return value; } //************************************************************************* /// 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. + ///\param value1 The first argument to use to construct the item to push to the queue. + ///\param value2 The second argument to use to construct the item to push to the queue. //************************************************************************* template - void emplace(const T1& value1, const T2& value2) + reference 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); + reference value = p_buffer[in]; + ::new (&value) T(value1, value2); add_in(); + return value; } //************************************************************************* /// 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. + ///\param value1 The first argument to use to construct the item to push to the queue. + ///\param value2 The second argument to use to construct the item to push to the queue. + ///\param value3 The third argument to use to construct the item to push to the queue. //************************************************************************* template - void emplace(const T1& value1, const T2& value2, const T3& value3) + reference 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); + reference value = p_buffer[in]; + ::new (&value) T(value1, value2, value3); add_in(); + return value; } //************************************************************************* /// 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. + ///\param value1 The first argument to use to construct the item to push to the queue. + ///\param value2 The second argument to use to construct the item to push to the queue. + ///\param value3 The third argument to use to construct the item to push to the queue. + ///\param value4 The fourth argument 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) + reference 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); + reference value = p_buffer[in]; + ::new (&value) T(value1, value2, value3, value4); add_in(); + return value; } #endif diff --git a/test/test_queue.cpp b/test/test_queue.cpp index ff966e3f9..71d033f10 100644 --- a/test/test_queue.cpp +++ b/test/test_queue.cpp @@ -369,11 +369,17 @@ namespace { etl::queue queue; - queue.emplace(); - queue.emplace('b', 2, 2.3); - queue.emplace('c', 3, 3.4); - queue.emplace('d', 4, 4.5); - queue.emplace('e', 5, 5.6); + Item& item_a = queue.emplace(); + Item& item_b = queue.emplace('b', 2, 2.3); + Item& item_c = queue.emplace('c', 3, 3.4); + Item& item_d = queue.emplace('d', 4, 4.5); + Item& item_e = queue.emplace('e', 5, 5.6); + + CHECK(item_a == Item('a', 1, 1.2)); + CHECK(item_b == Item('b', 2, 2.3)); + CHECK(item_c == Item('c', 3, 3.4)); + CHECK(item_d == Item('d', 4, 4.5)); + CHECK(item_e == Item('e', 5, 5.6)); CHECK(queue.front() == Item('a', 1, 1.2)); queue.pop();