Merge remote-tracking branch 'origin/development'

# Conflicts:
#	include/etl/private/pvoidvector.h
This commit is contained in:
John Wellbelove 2018-12-09 12:15:42 +00:00
parent 30520892e1
commit bb9b07a837
25 changed files with 1306 additions and 78 deletions

View File

@ -916,6 +916,74 @@ namespace etl
return position;
}
//*************************************************************************
/// Emplaces data into the deque.
/// If asserts or exceptions are enabled, throws an etl::deque_full if the deque is full.
///\param insert_position>The insert position.
//*************************************************************************
#if ETL_CPP11_SUPPORTED && !defined(ETL_STLPORT) && !defined(ETL_NO_STL)
template <typename ... Args>
iterator emplace(const_iterator insert_position, Args && ... args)
{
iterator position(insert_position.index, *this, p_buffer);
ETL_ASSERT(!full(), ETL_ERROR(deque_full));
void* p;
if (insert_position == begin())
{
--_begin;
p = etl::addressof(*_begin);
++current_size;
ETL_INCREMENT_DEBUG_COUNT
position = _begin;
}
else if (insert_position == end())
{
p = etl::addressof(*_end);
++_end;
++current_size;
ETL_INCREMENT_DEBUG_COUNT
position = _end - 1;
}
else
{
// Are we closer to the front?
if (std::distance(_begin, position) < std::distance(position, _end - 1))
{
// Construct the _begin.
create_element_front(*_begin);
// Move the values.
std::copy(_begin + 1, position, _begin);
// Write the new value.
--position;
(*position).~T();
p = etl::addressof(*position);
}
else
{
// Construct the _end.
create_element_back(*(_end - 1));
// Move the values.
std::copy_backward(position, _end - 2, _end - 1);
// Write the new value.
(*position).~T();
p = etl::addressof(*position);
}
}
::new (p) T(std::forward<Args>(args)...);
return position;
}
#else
//*************************************************************************
/// Emplaces data into the deque.
/// If asserts or exceptions are enabled, throws an etl::deque_full if the deque is full.
@ -1175,6 +1243,7 @@ namespace etl
return position;
}
#endif // ETL_CPP11_SUPPORTED && !defined(ETL_STLPORT) && !defined(ETL_NO_STL)
//*************************************************************************
/// Inserts 'n' copies of a value into the deque.
@ -1508,6 +1577,26 @@ namespace etl
create_element_back(item);
}
#if ETL_CPP11_SUPPORTED && !defined(ETL_STLPORT) && !defined(ETL_NO_STL)
//*************************************************************************
/// Emplaces an item to the back of the deque.
/// If asserts or exceptions are enabled, throws an etl::deque_full if the deque is already full.
//*************************************************************************
template <typename ... Args>
void emplace_back(Args && ... args)
{
#if defined(ETL_CHECK_PUSH_POP)
ETL_ASSERT(!full(), ETL_ERROR(deque_full));
#endif
::new (&(*_end)) T(std::forward<Args>(args)...);
++_end;
++current_size;
ETL_INCREMENT_DEBUG_COUNT
}
#else
//*************************************************************************
/// Emplaces an item to the back of the deque.
/// If asserts or exceptions are enabled, throws an etl::deque_full if the deque is already full.
@ -1575,6 +1664,7 @@ namespace etl
++current_size;
ETL_INCREMENT_DEBUG_COUNT
}
#endif // ETL_CPP11_SUPPORTED && !defined(ETL_STLPORT) && !defined(ETL_NO_STL)
//*************************************************************************
/// Removes the oldest item from the deque.
@ -1600,6 +1690,26 @@ namespace etl
create_element_front(item);
}
#if ETL_CPP11_SUPPORTED && !defined(ETL_STLPORT) && !defined(ETL_NO_STL)
//*************************************************************************
/// Emplaces an item to the front of the deque.
/// If asserts or exceptions are enabled, throws an etl::deque_full if the deque is already full.
//*************************************************************************
template <typename ... Args>
void emplace_front(Args && ... args)
{
#if defined(ETL_CHECK_PUSH_POP)
ETL_ASSERT(!full(), ETL_ERROR(deque_full));
#endif
--_begin;
::new (&(*_begin)) T(std::forward<Args>(args)...);
++current_size;
ETL_INCREMENT_DEBUG_COUNT
}
#else
//*************************************************************************
/// Emplaces an item to the front of the deque.
/// If asserts or exceptions are enabled, throws an etl::deque_full if the deque is already full.
@ -1667,6 +1777,7 @@ namespace etl
++current_size;
ETL_INCREMENT_DEBUG_COUNT
}
#endif // ETL_CPP11_SUPPORTED && !defined(ETL_STLPORT) && !defined(ETL_NO_STL)
//*************************************************************************
/// Removes the oldest item from the deque.

View File

@ -347,20 +347,22 @@ namespace etl
//*************************************************************************
std::pair<iterator, bool> emplace(const value_type& value)
{
return insert(value);
return emplace(value.first, value.second);
}
#if ETL_CPP11_SUPPORTED && !defined(ETL_STLPORT) && !defined(ETL_NO_STL)
//*************************************************************************
/// Emplaces a value to the map.
//*************************************************************************
std::pair<iterator, bool> emplace(const key_type& key, const mapped_type& value)
template <typename ... Args>
std::pair<iterator, bool> emplace(const key_type& key, Args && ... args)
{
ETL_ASSERT(!full(), ETL_ERROR(flat_map_full));
// Create it.
value_type* pvalue = storage.allocate<value_type>();
::new ((void*)etl::addressof(pvalue->first)) key_type(key);
::new ((void*)etl::addressof(pvalue->second)) mapped_type(value);
::new ((void*)etl::addressof(pvalue->second)) mapped_type(std::forward<Args>(args)...);
iterator i_element = lower_bound(key);
@ -381,6 +383,8 @@ namespace etl
return result;
}
#else
//*************************************************************************
/// Emplaces a value to the map.
//*************************************************************************
@ -509,6 +513,8 @@ namespace etl
return result;
}
#endif // ETL_CPP11_SUPPORTED && !defined(ETL_STLPORT) && !defined(ETL_NO_STL)
//*********************************************************************
/// Erases an element.
///\param key The key to erase.

View File

@ -320,6 +320,26 @@ namespace etl
return refmap_t::insert_at(i_element, *pvalue);
}
#if ETL_CPP11_SUPPORTED && !defined(ETL_STLPORT) && !defined(ETL_NO_STL)
//*************************************************************************
/// Emplaces a value to the map.
//*************************************************************************
template <typename ... Args>
std::pair<iterator, bool> emplace(const key_type& key, Args && ... args)
{
ETL_ASSERT(!full(), ETL_ERROR(flat_multimap_full));
// Create it.
value_type* pvalue = storage.allocate<value_type>();
::new ((void*)etl::addressof(pvalue->first)) key_type(key);
::new ((void*)etl::addressof(pvalue->second)) mapped_type(std::forward<Args>(args)...);
iterator i_element = lower_bound(key);
ETL_INCREMENT_DEBUG_COUNT
return refmap_t::insert_at(i_element, *pvalue);
}
#else
//*************************************************************************
/// Emplaces a value to the map.
//*************************************************************************
@ -392,6 +412,8 @@ namespace etl
return refmap_t::insert_at(i_element, *pvalue);
}
#endif // ETL_CPP11_SUPPORTED && !defined(ETL_STLPORT) && !defined(ETL_NO_STL)
//*********************************************************************
/// Erases an element.
///\param key The key to erase.

View File

@ -281,6 +281,25 @@ namespace etl
//*************************************************************************
/// Emplaces a value to the set.
//*************************************************************************
#if ETL_CPP11_SUPPORTED && !defined(ETL_STLPORT) && !defined(ETL_NO_STL)
template <typename ... Args>
std::pair<iterator, bool> emplace(Args && ... args)
{
ETL_ASSERT(!full(), ETL_ERROR(flat_multiset_full));
// Create it.
value_type* pvalue = storage.allocate<value_type>();
::new (pvalue) value_type(std::forward<Args>(args)...);
iterator i_element = lower_bound(*pvalue);
ETL_INCREMENT_DEBUG_COUNT
return std::pair<iterator, bool>(refset_t::insert_at(i_element, *pvalue));
}
#else
//*************************************************************************
/// Emplaces a value to the set.
//*************************************************************************
template <typename T1>
std::pair<iterator, bool> emplace(const T1& value1)
{
@ -349,6 +368,7 @@ namespace etl
ETL_INCREMENT_DEBUG_COUNT
return std::pair<iterator, bool>(refset_t::insert_at(i_element, *pvalue));
}
#endif // ETL_CPP11_SUPPORTED && !defined(ETL_STLPORT) && !defined(ETL_NO_STL)
//*********************************************************************
/// Erases an element.

View File

@ -284,6 +284,40 @@ namespace etl
//*************************************************************************
/// Emplaces a value to the set.
//*************************************************************************
#if ETL_CPP11_SUPPORTED && !defined(ETL_STLPORT) && !defined(ETL_NO_STL)
template <typename ... Args>
std::pair<iterator, bool> emplace(Args && ... args)
{
ETL_ASSERT(!full(), ETL_ERROR(flat_set_full));
std::pair<iterator, bool> result;
// Create it.
value_type* pvalue = storage.allocate<value_type>();
::new (pvalue) value_type(std::forward<Args>(args)...);
iterator i_element = lower_bound(*pvalue);
// Doesn't already exist?
if ((i_element == end() || (*i_element != *pvalue)))
{
ETL_INCREMENT_DEBUG_COUNT
result = refset_t::insert_at(i_element, *pvalue);
}
else
{
// Destroy it.
pvalue->~value_type();
storage.release(pvalue);
result = std::pair<iterator, bool>(end(), false);
}
return result;
}
#else
//*************************************************************************
/// Emplaces a value to the set.
//*************************************************************************
template <typename T1>
std::pair<iterator, bool> emplace(const T1& value1)
{
@ -295,7 +329,7 @@ namespace etl
value_type* pvalue = storage.allocate<value_type>();
::new (pvalue) value_type(value1);
iterator i_element = lower_bound(*pvalue);
iterator i_element = lower_bound(*pvalue);
// Doesn't already exist?
if ((i_element == end() || (*i_element != *pvalue)))
@ -412,6 +446,7 @@ namespace etl
return result;
}
#endif // ETL_CPP11_SUPPORTED && !defined(ETL_STLPORT) && !defined(ETL_NO_STL)
//*********************************************************************
/// Erases an element.

View File

@ -719,6 +719,22 @@ namespace etl
insert_node_after(start_node, data_node);
}
#if ETL_CPP11_SUPPORTED && !defined(ETL_STLPORT) && !defined(ETL_NO_STL)
//*************************************************************************
/// Emplaces a value to the front of the list..
//*************************************************************************
template <typename ... Args>
void emplace_front(Args && ... args)
{
#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<data_node_t>();
::new (&(p_data_node->value)) T(std::forward<Args>(args)...);
ETL_INCREMENT_DEBUG_COUNT
insert_node_after(start_node, *p_data_node);
}
#else
//*************************************************************************
/// Emplaces a value to the front of the list..
//*************************************************************************
@ -778,6 +794,7 @@ namespace etl
ETL_INCREMENT_DEBUG_COUNT
insert_node_after(start_node, *p_data_node);
}
#endif // ETL_CPP11_SUPPORTED && !defined(ETL_STLPORT) && !defined(ETL_NO_STL)
//*************************************************************************
/// Removes a value from the front of the forward_list.
@ -855,6 +872,23 @@ namespace etl
return iterator(&data_node);
}
#if ETL_CPP11_SUPPORTED && !defined(ETL_STLPORT) && !defined(ETL_NO_STL)
//*************************************************************************
/// Emplaces a value to the forward_list after the specified position.
//*************************************************************************
template <typename ... Args>
iterator emplace_after(iterator position, Args && ... args)
{
ETL_ASSERT(!full(), ETL_ERROR(forward_list_full));
data_node_t* p_data_node = p_node_pool->allocate<data_node_t>();
::new (&(p_data_node->value)) T(std::forward<Args>(args)...);
ETL_INCREMENT_DEBUG_COUNT
insert_node_after(*position.p_node, *p_data_node);
return iterator(p_data_node);
}
#else
//*************************************************************************
/// Emplaces a value to the forward_list after the specified position.
//*************************************************************************
@ -918,6 +952,7 @@ namespace etl
return iterator(p_data_node);
}
#endif // ETL_CPP11_SUPPORTED && !defined(ETL_STLPORT) && !defined(ETL_NO_STL)
//*************************************************************************
/// Inserts 'n' copies of a value to the forward_list after the specified position.

View File

@ -851,8 +851,26 @@ namespace etl
insert_node(get_head(), allocate_data_node(value));
}
#if ETL_CPP11_SUPPORTED && !defined(ETL_STLPORT) && !defined(ETL_NO_STL)
//*************************************************************************
/// Emplaces a value to the front of the list..
/// Emplaces a value to the front of the list.
//*************************************************************************
template <typename ... Args>
void emplace_front(Args && ... args)
{
#if defined(ETL_CHECK_PUSH_POP)
ETL_ASSERT(!full(), ETL_ERROR(list_full));
#endif
ETL_ASSERT(p_node_pool != nullptr, ETL_ERROR(list_no_pool));
data_node_t* p_data_node = p_node_pool->allocate<data_node_t>();
::new (&(p_data_node->value)) T(std::forward<Args>(args)...);
ETL_INCREMENT_DEBUG_COUNT
insert_node(get_head(), *p_data_node);
}
#else
//*************************************************************************
/// Emplaces a value to the front of the list.
//*************************************************************************
template <typename T1>
void emplace_front(const T1& value1)
@ -869,7 +887,7 @@ namespace etl
}
//*************************************************************************
/// Emplaces a value to the front of the list..
/// Emplaces a value to the front of the list.
//*************************************************************************
template <typename T1, typename T2>
void emplace_front(const T1& value1, const T2& value2)
@ -886,7 +904,7 @@ namespace etl
}
//*************************************************************************
/// Emplaces a value to the front of the list..
/// Emplaces a value to the front of the list.
//*************************************************************************
template <typename T1, typename T2, typename T3>
void emplace_front(const T1& value1, const T2& value2, const T3& value3)
@ -903,7 +921,7 @@ namespace etl
}
//*************************************************************************
/// Emplaces a value to the front of the list..
/// Emplaces a value to the front of the list.
//*************************************************************************
template <typename T1, typename T2, typename T3, typename T4>
void emplace_front(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
@ -918,6 +936,7 @@ namespace etl
ETL_INCREMENT_DEBUG_COUNT
insert_node(get_head(), *p_data_node);
}
#endif // ETL_CPP11_SUPPORTED && !defined(ETL_STLPORT) && !defined(ETL_NO_STL)
//*************************************************************************
/// Removes a value from the front of the list.
@ -932,7 +951,7 @@ namespace etl
}
//*************************************************************************
/// Pushes a value to the back of the list..
/// Pushes a value to the back of the list.
//*************************************************************************
void push_back(parameter_t value)
{
@ -943,8 +962,23 @@ namespace etl
}
//*************************************************************************
/// Emplaces a value to the back of the list..
/// Emplaces a value to the back of the list.
//*************************************************************************
#if ETL_CPP11_SUPPORTED && !defined(ETL_STLPORT) && !defined(ETL_NO_STL)
template <typename ... Args>
void emplace_back(Args && ... args)
{
#if defined(ETL_CHECK_PUSH_POP)
ETL_ASSERT(!full(), ETL_ERROR(list_full));
#endif
ETL_ASSERT(p_node_pool != nullptr, ETL_ERROR(list_no_pool));
data_node_t* p_data_node = p_node_pool->allocate<data_node_t>();
::new (&(p_data_node->value)) T(std::forward<Args>(args)...);
ETL_INCREMENT_DEBUG_COUNT
insert_node(terminal_node, *p_data_node);
}
#else
template <typename T1>
void emplace_back(const T1& value1)
{
@ -959,9 +993,6 @@ namespace etl
insert_node(terminal_node, *p_data_node);
}
//*************************************************************************
/// Emplaces a value to the back of the list..
//*************************************************************************
template <typename T1, typename T2>
void emplace_back(const T1& value1, const T2& value2)
{
@ -976,9 +1007,6 @@ namespace etl
insert_node(terminal_node, *p_data_node);
}
//*************************************************************************
/// Emplaces a value to the back of the list..
//*************************************************************************
template <typename T1, typename T2, typename T3>
void emplace_back(const T1& value1, const T2& value2, const T3& value3)
{
@ -993,9 +1021,6 @@ namespace etl
insert_node(terminal_node, *p_data_node);
}
//*************************************************************************
/// Emplaces a value to the back of the list..
//*************************************************************************
template <typename T1, typename T2, typename T3, typename T4>
void emplace_back(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
{
@ -1009,6 +1034,7 @@ namespace etl
ETL_INCREMENT_DEBUG_COUNT
insert_node(terminal_node, *p_data_node);
}
#endif // ETL_CPP11_SUPPORTED && !defined(ETL_STLPORT) && !defined(ETL_NO_STL)
//*************************************************************************
/// Removes a value from the back of the list.
@ -1038,6 +1064,21 @@ namespace etl
//*************************************************************************
/// Emplaces a value to the list at the specified position.
//*************************************************************************
#if ETL_CPP11_SUPPORTED && !defined(ETL_STLPORT) && !defined(ETL_NO_STL)
template <typename ... Args>
iterator emplace(iterator position, Args && ... args)
{
ETL_ASSERT(!full(), ETL_ERROR(list_full));
ETL_ASSERT(p_node_pool != nullptr, ETL_ERROR(list_no_pool));
data_node_t* p_data_node = p_node_pool->allocate<data_node_t>();
::new (&(p_data_node->value)) T(std::forward<Args>(args)...);
ETL_INCREMENT_DEBUG_COUNT
insert_node(*position.p_node, *p_data_node);
return iterator(*p_data_node);
}
#else
template <typename T1>
iterator emplace(iterator position, const T1& value1)
{
@ -1052,9 +1093,6 @@ namespace etl
return iterator(*p_data_node);
}
//*************************************************************************
/// Emplaces a value to the list at the specified position.
//*************************************************************************
template <typename T1, typename T2>
iterator emplace(iterator position, const T1& value1, const T2& value2)
{
@ -1069,9 +1107,6 @@ namespace etl
return iterator(*p_data_node);
}
//*************************************************************************
/// Emplaces a value to the list at the specified position.
//*************************************************************************
template <typename T1, typename T2, typename T3>
iterator emplace(iterator position, const T1& value1, const T2& value2, const T3& value3)
{
@ -1086,9 +1121,6 @@ namespace etl
return iterator(*p_data_node);
}
//*************************************************************************
/// Emplaces a value to the list at the specified position.
//*************************************************************************
template <typename T1, typename T2, typename T3, typename T4>
iterator emplace(iterator position, const T1& value1, const T2& value2, const T3& value3, const T4& value4)
{
@ -1102,6 +1134,7 @@ namespace etl
return iterator(*p_data_node);
}
#endif // ETL_CPP11_SUPPORTED && !defined(ETL_STLPORT) && !defined(ETL_NO_STL)
//*************************************************************************
/// Inserts 'n' copies of a value to the list at the specified position.

View File

@ -173,11 +173,6 @@ namespace etl
return p;
}
//*************************************************************************
/// Allocate storage for an object from the pool and create with 2 parameters.
/// If asserts or exceptions are enabled and there are no more free items an
/// etl::pool_no_allocation if thrown, otherwise a nullptr is returned.
//*************************************************************************
template <typename T, typename T1, typename T2>
T* create(const T1& value1, const T2& value2)
{
@ -191,11 +186,6 @@ namespace etl
return p;
}
//*************************************************************************
/// Allocate storage for an object from the pool and create with 3 parameters.
/// If asserts or exceptions are enabled and there are no more free items an
/// etl::pool_no_allocation if thrown, otherwise a nullptr is returned.
//*************************************************************************
template <typename T, typename T1, typename T2, typename T3>
T* create(const T1& value1, const T2& value2, const T3& value3)
{
@ -209,11 +199,6 @@ namespace etl
return p;
}
//*************************************************************************
/// Allocate storage for an object from the pool and create with 4 parameters.
/// If asserts or exceptions are enabled and there are no more free items an
/// etl::pool_no_allocation if thrown, otherwise a nullptr is returned.
//*************************************************************************
template <typename T, typename T1, typename T2, typename T3, typename T4>
T* create(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
{

View File

@ -48,6 +48,8 @@ SOFTWARE.
#undef ETL_FILE
#define ETL_FILE "12"
#define ETL_PRIORITY_QUEUE_FORCE_CPP03 1
//*****************************************************************************
///\defgroup queue queue
/// A priority queue with the capacity defined at compile time,
@ -168,6 +170,24 @@ namespace etl
std::push_heap(container.begin(), container.end(), compare);
}
#if ETL_CPP11_SUPPORTED && !defined(ETL_STLPORT) && !defined(ETL_NO_STL) && !ETL_PRIORITY_QUEUE_FORCE_CPP03
//*************************************************************************
/// 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 <typename ... Args>
void emplace(Args && ... args)
{
ETL_ASSERT(!full(), ETL_ERROR(etl::priority_queue_full));
// Put element at end
container.emplace_back(std::forward<Args>(args)...);
// Make elements in container into heap
std::push_heap(container.begin(), container.end(), compare);
}
#else
//*************************************************************************
/// Emplaces a value to the queue.
/// If asserts or exceptions are enabled, throws an etl::priority_queue_full
@ -235,6 +255,7 @@ namespace etl
// Make elements in container into heap
std::push_heap(container.begin(), container.end(), compare);
}
#endif // ETL_CPP11_SUPPORTED && !defined(ETL_STLPORT) && !defined(ETL_NO_STL)
//*************************************************************************
/// Assigns values to the priority queue.

View File

@ -49,6 +49,8 @@ SOFTWARE.
#undef ETL_FILE
#define ETL_FILE "13"
#define ETL_QUEUE_FORCE_CPP03 1
//*****************************************************************************
///\defgroup queue queue
/// A First-in / first-out queue with the capacity defined at compile time,
@ -316,6 +318,22 @@ namespace etl
add_in();
}
#if ETL_CPP11_SUPPORTED && !defined(ETL_STLPORT) && !defined(ETL_NO_STL) && !ETL_QUEUE_FORCE_CPP03
//*************************************************************************
/// 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 <typename ... Args>
void emplace(Args && ... args)
{
#if defined(ETL_CHECK_PUSH_POP)
ETL_ASSERT(!full(), ETL_ERROR(queue_full));
#endif
::new (&p_buffer[in]) T(std::forward<Args>(args)...);
add_in();
}
#else
//*************************************************************************
/// 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.
@ -375,6 +393,7 @@ namespace etl
::new (&p_buffer[in]) T(value1, value2, value3, value4);
add_in();
}
#endif // ETL_CPP11_SUPPORTED && !defined(ETL_STLPORT) && !defined(ETL_NO_STL)
//*************************************************************************
/// Clears the queue to the empty state.

View File

@ -44,6 +44,8 @@ SOFTWARE.
#undef ETL_FILE
#define ETL_FILE "48"
#define ETL_QUEUE_MPMC_MUTEX_FORCE_CPP03 0
namespace etl
{
template <const size_t MEMORY_MODEL = etl::memory_model::MEMORY_MODEL_LARGE>
@ -162,6 +164,88 @@ namespace etl
return result;
}
#if ETL_CPP11_SUPPORTED && !defined(ETL_STLPORT) && !defined(ETL_NO_STL) && !ETL_QUEUE_MPMC_MUTEX_FORCE_CPP03
//*************************************************************************
/// 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.
//*************************************************************************
template <typename ... Args>
bool emplace(Args&&... args)
{
access.lock();
bool result = emplace_implementation(std::forward<Args>(args)...);
access.unlock();
return result;
}
#else
//*************************************************************************
/// 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.
//*************************************************************************
template <typename T1>
bool emplace(const T1& value1)
{
access.lock();
bool result = emplace_implementation(value1);
access.unlock();
return result;
}
//*************************************************************************
/// 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.
//*************************************************************************
template <typename T1, typename T2>
bool emplace(const T1& value1, const T2& value2)
{
access.lock();
bool result = emplace_implementation(value1, value2);
access.unlock();
return result;
}
//*************************************************************************
/// 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.
//*************************************************************************
template <typename T1, typename T2, typename T3>
bool emplace(const T1& value1, const T2& value2, const T3& value3)
{
access.lock();
bool result = emplace_implementation(value1, value2, value3);
access.unlock();
return result;
}
//*************************************************************************
/// 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.
//*************************************************************************
template <typename T1, typename T2, typename T3, typename T4>
bool emplace(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
{
access.lock();
bool result = emplace_implementation(value1, value2, value3, value4);
access.unlock();
return result;
}
#endif
//*************************************************************************
/// Pop a value from the queue.
//*************************************************************************
@ -294,6 +378,113 @@ namespace etl
return false;
}
#if ETL_CPP11_SUPPORTED && !defined(ETL_STLPORT) && !defined(ETL_NO_STL) && !ETL_QUEUE_MPMC_MUTEX_FORCE_CPP03
//*************************************************************************
/// Constructs a value in the queue 'in place'.
//*************************************************************************
template <typename ... Args>
bool emplace_implementation(Args&&... args)
{
if (current_size != MAX_SIZE)
{
::new (&p_buffer[write_index]) T(std::forward<Args>(args)...);
write_index = get_next_index(write_index, MAX_SIZE);
++current_size;
return true;
}
// Queue is full.
return false;
}
#else
//*************************************************************************
/// Constructs a value in the queue 'in place'.
//*************************************************************************
template <typename T1>
bool emplace_implementation(const T1& value1)
{
if (current_size != MAX_SIZE)
{
::new (&p_buffer[write_index]) T(value1);
write_index = get_next_index(write_index, MAX_SIZE);
++current_size;
return true;
}
// Queue is full.
return false;
}
//*************************************************************************
/// Constructs a value in the queue 'in place'.
//*************************************************************************
template <typename T1, typename T2>
bool emplace_implementation(const T1& value1, const T2& value2)
{
if (current_size != MAX_SIZE)
{
::new (&p_buffer[write_index]) T(value1, value2);
write_index = get_next_index(write_index, MAX_SIZE);
++current_size;
return true;
}
// Queue is full.
return false;
}
//*************************************************************************
/// Constructs a value in the queue 'in place'.
//*************************************************************************
template <typename T1, typename T2, typename T3>
bool emplace_implementation(const T1& value1, const T2& value2, const T3& value3)
{
if (current_size != MAX_SIZE)
{
::new (&p_buffer[write_index]) T(value1, value2, value3);
write_index = get_next_index(write_index, MAX_SIZE);
++current_size;
return true;
}
// Queue is full.
return false;
}
//*************************************************************************
/// Constructs a value in the queue 'in place'.
//*************************************************************************
template <typename T1, typename T2, typename T3, typename T4>
bool emplace_implementation(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
{
if (current_size != MAX_SIZE)
{
::new (&p_buffer[write_index]) T(value1, value2, value3, value4);
write_index = get_next_index(write_index, MAX_SIZE);
++current_size;
return true;
}
// Queue is full.
return false;
}
#endif
//*************************************************************************
/// Pop a value from the queue.
//*************************************************************************

View File

@ -44,6 +44,8 @@ SOFTWARE.
#undef ETL_FILE
#define ETL_FILE "47"
#define ETL_QUEUE_ATOMIC_FORCE_CPP03 0
namespace etl
{
template <const size_t MEMORY_MODEL = etl::memory_model::MEMORY_MODEL_LARGE>
@ -222,6 +224,123 @@ namespace etl
return false;
}
#if ETL_CPP11_SUPPORTED && !defined(ETL_STLPORT) && !defined(ETL_NO_STL) && !ETL_QUEUE_ATOMIC_FORCE_CPP03
//*************************************************************************
/// 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.
//*************************************************************************
template <typename ... Args>
bool emplace(Args&&... args)
{
size_type write_index = write.load(etl::memory_order_relaxed);
size_type next_index = get_next_index(write_index, RESERVED);
if (next_index != read.load(etl::memory_order_acquire))
{
::new (&p_buffer[write_index]) T(std::forward<Args>(args)...);
write.store(next_index, etl::memory_order_release);
return true;
}
// Queue is full.
return false;
}
#else
//*************************************************************************
/// 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.
//*************************************************************************
template <typename T1>
bool emplace(const T1& value1)
{
size_type write_index = write.load(etl::memory_order_relaxed);
size_type next_index = get_next_index(write_index, RESERVED);
if (next_index != read.load(etl::memory_order_acquire))
{
::new (&p_buffer[write_index]) T(value1);
write.store(next_index, etl::memory_order_release);
return true;
}
// Queue is full.
return false;
}
//*************************************************************************
/// 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.
//*************************************************************************
template <typename T1, typename T2>
bool emplace(const T1& value1, const T2& value2)
{
size_type write_index = write.load(etl::memory_order_relaxed);
size_type next_index = get_next_index(write_index, RESERVED);
if (next_index != read.load(etl::memory_order_acquire))
{
::new (&p_buffer[write_index]) T(value1, value2);
write.store(next_index, etl::memory_order_release);
return true;
}
// Queue is full.
return false;
}
//*************************************************************************
/// 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.
//*************************************************************************
template <typename T1, typename T2, typename T3>
bool emplace(const T1& value1, const T2& value2, const T3& value3)
{
size_type write_index = write.load(etl::memory_order_relaxed);
size_type next_index = get_next_index(write_index, RESERVED);
if (next_index != read.load(etl::memory_order_acquire))
{
::new (&p_buffer[write_index]) T(value1, value2, value3);
write.store(next_index, etl::memory_order_release);
return true;
}
// Queue is full.
return false;
}
//*************************************************************************
/// 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.
//*************************************************************************
template <typename T1, typename T2, typename T3, typename T4>
bool emplace(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
{
size_type write_index = write.load(etl::memory_order_relaxed);
size_type next_index = get_next_index(write_index, RESERVED);
if (next_index != read.load(etl::memory_order_acquire))
{
::new (&p_buffer[write_index]) T(value1, value2, value3, value4);
write.store(next_index, etl::memory_order_release);
return true;
}
// Queue is full.
return false;
}
#endif
//*************************************************************************
/// Pop a value from the queue.
//*************************************************************************

View File

@ -43,6 +43,8 @@ SOFTWARE.
#undef ETL_FILE
#define ETL_FILE "46"
#define ETL_QUEUE_ISR_FORCE_CPP03 0
namespace etl
{
template <typename T, const size_t MEMORY_MODEL = etl::memory_model::MEMORY_MODEL_LARGE>
@ -69,6 +71,19 @@ namespace etl
return push_implementation(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.
//*************************************************************************
#if ETL_CPP11_SUPPORTED && !defined(ETL_STLPORT) && !defined(ETL_NO_STL) && !ETL_QUEUE_ISR_FORCE_CPP03
template <typename ... Args>
bool emplace_from_isr(Args&&... args)
{
return emplace_implementation(std::forward<Args>(args)...);
}
#endif
//*************************************************************************
/// Pop a value from the queue from an ISR
//*************************************************************************
@ -179,6 +194,120 @@ namespace etl
return false;
}
#if ETL_CPP11_SUPPORTED && !defined(ETL_STLPORT) && !defined(ETL_NO_STL) && !ETL_QUEUE_ISR_FORCE_CPP03
//*************************************************************************
/// 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 <typename ... Args>
bool emplace_implementation(Args&&... args)
{
if (current_size != MAX_SIZE)
{
::new (&p_buffer[write_index]) T(std::forward<Args>(args)...);
write_index = get_next_index(write_index, MAX_SIZE);
++current_size;
return true;
}
// Queue is full.
return false;
}
#else
//*************************************************************************
/// 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.
//*************************************************************************
template <typename T1>
bool emplace_implementation(const T1& value1)
{
if (current_size != MAX_SIZE)
{
::new (&p_buffer[write_index]) T(value1);
write_index = get_next_index(write_index, MAX_SIZE);
++current_size;
return true;
}
// Queue is full.
return false;
}
//*************************************************************************
/// 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.
//*************************************************************************
template <typename T1, typename T2>
bool emplace_implementation(const T1& value1, const T2& value2)
{
if (current_size != MAX_SIZE)
{
::new (&p_buffer[write_index]) T(value1, value2);
write_index = get_next_index(write_index, MAX_SIZE);
++current_size;
return true;
}
// Queue is full.
return false;
}
//*************************************************************************
/// 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.
//*************************************************************************
template <typename T1, typename T2, typename T3>
bool emplace_implementation(const T1& value1, const T2& value2, const T3& value3)
{
if (current_size != MAX_SIZE)
{
::new (&p_buffer[write_index]) T(value1, value2, value3);
write_index = get_next_index(write_index, MAX_SIZE);
++current_size;
return true;
}
// Queue is full.
return false;
}
//*************************************************************************
/// 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.
//*************************************************************************
template <typename T1, typename T2, typename T3, typename T4>
bool emplace_implementation(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
{
if (current_size != MAX_SIZE)
{
::new (&p_buffer[write_index]) T(value1, value2, value3, value4);
write_index = get_next_index(write_index, MAX_SIZE);
++current_size;
return true;
}
// Queue is full.
return false;
}
#endif
//*************************************************************************
/// Pop a value from the queue.
//*************************************************************************
@ -299,6 +428,88 @@ namespace etl
return result;
}
//*************************************************************************
/// 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.
//*************************************************************************
#if ETL_CPP11_SUPPORTED && !defined(ETL_STLPORT) && !defined(ETL_NO_STL) && !ETL_QUEUE_ISR_FORCE_CPP03
template <typename ... Args>
bool emplace(Args&&... args)
{
TAccess::lock();
bool result = this->emplace_implementation(std::forward<Args>(args)...);
TAccess::unlock();
return result;
}
#else
//*************************************************************************
/// 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.
//*************************************************************************
template <typename T1>
bool emplace(const T1& value1)
{
TAccess::lock();
bool result = this->emplace_implementation(value1);
TAccess::unlock();
return result;
}
//*************************************************************************
/// 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.
//*************************************************************************
template <typename T1, typename T2>
bool emplace(const T1& value1, const T2& value2)
{
TAccess::lock();
bool result = this->emplace_implementation(value1, value2);
TAccess::unlock();
return result;
}
//*************************************************************************
/// 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.
//*************************************************************************
template <typename T1, typename T2, typename T3>
bool emplace(const T1& value1, const T2& value2, const T3& value3)
{
TAccess::lock();
bool result = this->emplace_implementation(value1, value2, value3);
TAccess::unlock();
return result;
}
//*************************************************************************
/// 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.
//*************************************************************************
template <typename T1, typename T2, typename T3, typename T4>
bool emplace(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
{
TAccess::lock();
bool result = this->emplace_implementation(value1, value2, value3, value4);
TAccess::unlock();
return result;
}
#endif
//*************************************************************************
/// Pop a value from the queue.
//*************************************************************************

View File

@ -262,6 +262,22 @@ namespace etl
::new (&p_buffer[top_index]) T(value);
}
#if ETL_CPP11_SUPPORTED && !defined(ETL_STLPORT) && !defined(ETL_NO_STL)
//*************************************************************************
/// 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 <typename ... Args>
void emplace(Args && ... args)
{
#if defined(ETL_CHECK_PUSH_POP)
ETL_ASSERT(!full(), ETL_ERROR(stack_full));
#endif
base_t::add_in();
::new (&p_buffer[top_index]) T(std::forward<Args>(args)...);
}
#else
//*************************************************************************
/// Constructs a value in the stack place'.
/// If asserts or exceptions are enabled, throws an etl::stack_full if the stack is already full.
@ -321,6 +337,7 @@ namespace etl
base_t::add_in();
::new (&p_buffer[top_index]) T(value1, value2, value3, value4);
}
#endif // ETL_CPP11_SUPPORTED && !defined(ETL_STLPORT) && !defined(ETL_NO_STL)
//*************************************************************************
/// Gets a const reference to the value at the top of the stack.<br>

View File

@ -51,6 +51,8 @@ SOFTWARE.
#undef ETL_FILE
#define ETL_FILE "24"
#define ETL_VARIANT_FORCE_CPP03 1
//*****************************************************************************
///\defgroup variant variant
/// A class that can contain one a several specified types in a type safe manner.
@ -711,7 +713,22 @@ namespace etl
type_id = other.type_id;
}
#if !ETL_CPP11_SUPPORTED || defined(ETL_STLPORT)
#if ETL_CPP11_SUPPORTED && !defined(ETL_STLPORT) && !defined(ETL_NO_STL) && !ETL_VARIANT_FORCE_CPP03
//*************************************************************************
/// Emplace with variadic constructor parameters.
//*************************************************************************
template <typename T, typename... Args>
T& emplace(Args&&... args)
{
ETL_STATIC_ASSERT(Type_Is_Supported<T>::value, "Unsupported type");
destruct_current();
::new (static_cast<T*>(data)) T(std::forward<Args>(args)...);
type_id = Type_Id_Lookup<T>::type_id;
return *static_cast<T*>(data);
}
#else
//***************************************************************************
/// Emplace with one constructor parameter.
//***************************************************************************
@ -769,22 +786,6 @@ namespace etl
::new (static_cast<T*>(data)) T(value1, value2, value3, value4);
type_id = Type_Id_Lookup<T>::type_id;
return *static_cast<T*>(data);
}
#else
//*************************************************************************
/// Emplace with variadic constructor parameters.
//*************************************************************************
template <typename T, typename... Args>
T& emplace(Args&&... args)
{
ETL_STATIC_ASSERT(Type_Is_Supported<T>::value, "Unsupported type");
destruct_current();
::new (static_cast<T*>(data)) T(std::forward<Args>(args)...);
type_id = Type_Id_Lookup<T>::type_id;
return *static_cast<T*>(data);
}
#endif

View File

@ -63,6 +63,8 @@ SOFTWARE.
#pragma GCC diagnostic ignored "-Wunused-variable"
#endif
#define ETL_VECTOR_FORCE_CPP03 1
//*****************************************************************************
///\defgroup vector vector
/// A vector with the capacity defined at compile time.
@ -411,6 +413,23 @@ namespace etl
create_back(value);
}
#if ETL_CPP11_SUPPORTED && !defined(ETL_STLPORT) && !defined(ETL_NO_STL) && !ETL_VECTOR_FORCE_CPP03
//*********************************************************************
/// Constructs a value at the end of the vector.
/// If asserts or exceptions are enabled, emits vector_full if the vector is already full.
///\param value The value to add.
//*********************************************************************
template <typename ... Args>
void emplace_back(Args && ... args)
{
#if defined(ETL_CHECK_PUSH_POP)
ETL_ASSERT(size() != CAPACITY, ETL_ERROR(vector_full));
#endif
::new (p_end) T(std::forward<Args>(args)...);
++p_end;
ETL_INCREMENT_DEBUG_COUNT
}
#else
//*********************************************************************
/// Constructs a value at the end of the vector.
/// If asserts or exceptions are enabled, emits vector_full if the vector is already full.
@ -474,6 +493,7 @@ namespace etl
++p_end;
ETL_INCREMENT_DEBUG_COUNT
}
#endif // ETL_CPP11_SUPPORTED && !defined(ETL_STLPORT) && !defined(ETL_NO_STL) && !ETL_VECTOR_FORCE_CPP03
//*************************************************************************
/// Removes an element from the end of the vector.
@ -514,6 +534,32 @@ namespace etl
//*************************************************************************
/// Emplaces a value to the vextor at the specified position.
//*************************************************************************
#if ETL_CPP11_SUPPORTED && !defined(ETL_STLPORT) && !defined(ETL_NO_STL)
template <typename ... Args>
iterator emplace(iterator position, Args && ... args)
{
ETL_ASSERT(!full(), ETL_ERROR(vector_full));
void* p;
if (position == end())
{
p = p_end++;
ETL_INCREMENT_DEBUG_COUNT
}
else
{
p = etl::addressof(*position);
create_back(back());
std::copy_backward(position, p_end - 1, p_end);
(*position).~T();
}
::new (p) T(std::forward<Args>(args)...);
return position;
}
#else
template <typename T1>
iterator emplace(iterator position, const T1& value1)
{
@ -539,9 +585,6 @@ namespace etl
return position;
}
//*************************************************************************
/// Emplaces a value to the vextor at the specified position.
//*************************************************************************
template <typename T1, typename T2>
iterator emplace(iterator position, const T1& value1, const T2& value2)
{
@ -567,9 +610,6 @@ namespace etl
return position;
}
//*************************************************************************
/// Emplaces a value to the vextor at the specified position.
//*************************************************************************
template <typename T1, typename T2, typename T3>
iterator emplace(iterator position, const T1& value1, const T2& value2, const T3& value3)
{
@ -595,9 +635,6 @@ namespace etl
return position;
}
//*************************************************************************
/// Emplaces a value to the vextor at the specified position.
//*************************************************************************
template <typename T1, typename T2, typename T3, typename T4>
iterator emplace(iterator position, const T1& value1, const T2& value2, const T3& value3, const T4& value4)
{
@ -622,6 +659,7 @@ namespace etl
return position;
}
#endif // ETL_CPP11_SUPPORTED && !defined(ETL_STLPORT) && !defined(ETL_NO_STL)
//*********************************************************************
/// Inserts 'n' values to the vector.

View File

@ -46,7 +46,6 @@ set(TEST_SOURCE_FILES
test_enum_type.cpp
test_error_handler.cpp
test_exception.cpp
# test_factory.cpp
test_fixed_iterator.cpp
test_flat_map.cpp
test_flat_multimap.cpp
@ -119,6 +118,8 @@ set(TEST_SOURCE_FILES
test_xor_checksum.cpp
test_xor_rotate_checksum.cpp
${CMAKE_SOURCE_DIR}/src/crc16_modbus.cpp
# Compile the source level ecl_timer here as test has provided a ecl_user.h file
${PROJECT_SOURCE_DIR}/../src/c/ecl_timer.c
)

View File

@ -349,6 +349,8 @@ namespace
queue.emplace('c', 3, 5.6);
queue.emplace('d', 4, 7.8);
CHECK_EQUAL(4U, queue.size());
CHECK(queue.front() == Item('a', 1, 1.2));
queue.pop();
CHECK(queue.front() == Item('b', 2, 3.4));

View File

@ -69,10 +69,10 @@ namespace
int d;
};
// bool operator ==(const Data& lhs, const Data& rhs)
// {
// return (lhs.a == rhs.a) && (lhs.b == rhs.b) && (lhs.c == rhs.c) && (lhs.d == rhs.d);
// }
bool operator ==(const Data& lhs, const Data& rhs)
{
return (lhs.a == rhs.a) && (lhs.b == rhs.b) && (lhs.c == rhs.c) && (lhs.d == rhs.d);
}
// std::ostream& operator <<(std::ostream& os, const Data& data)
// {
@ -143,6 +143,30 @@ namespace
CHECK(!queue.pop(i));
}
//*************************************************************************
TEST(test_multiple_emplace)
{
etl::queue_mpmc_mutex<Data, 4> queue;
queue.emplace(1);
queue.emplace(1, 2);
queue.emplace(1, 2, 3);
queue.emplace(1, 2, 3, 4);
CHECK_EQUAL(4U, queue.size());
Data popped;
queue.pop(popped);
CHECK(popped == Data(1, 2, 3, 4));
queue.pop(popped);
CHECK(popped == Data(1, 2, 3, 4));
queue.pop(popped);
CHECK(popped == Data(1, 2, 3, 4));
queue.pop(popped);
CHECK(popped == Data(1, 2, 3, 4));
}
//*************************************************************************
TEST(test_size_push_pop_iqueue)
{

View File

@ -74,10 +74,10 @@ namespace
typedef etl::queue_mpmc_mutex<int, 255, etl::memory_model::MEMORY_MODEL_SMALL> QueueInt255;
// bool operator ==(const Data& lhs, const Data& rhs)
// {
// return (lhs.a == rhs.a) && (lhs.b == rhs.b) && (lhs.c == rhs.c) && (lhs.d == rhs.d);
// }
bool operator ==(const Data& lhs, const Data& rhs)
{
return (lhs.a == rhs.a) && (lhs.b == rhs.b) && (lhs.c == rhs.c) && (lhs.d == rhs.d);
}
// std::ostream& operator <<(std::ostream& os, const Data& data)
// {
@ -148,6 +148,30 @@ namespace
CHECK(!queue.pop(i));
}
//*************************************************************************
TEST(test_multiple_emplace)
{
etl::queue_mpmc_mutex<Data, 4, etl::memory_model::MEMORY_MODEL_SMALL> queue;
queue.emplace(1);
queue.emplace(1, 2);
queue.emplace(1, 2, 3);
queue.emplace(1, 2, 3, 4);
Data popped;
CHECK_EQUAL(4U, queue.size());
queue.pop(popped);
CHECK(popped == Data(1, 2, 3, 4));
queue.pop(popped);
CHECK(popped == Data(1, 2, 3, 4));
queue.pop(popped);
CHECK(popped == Data(1, 2, 3, 4));
queue.pop(popped);
CHECK(popped == Data(1, 2, 3, 4));
}
//*************************************************************************
TEST(test_size_push_pop_iqueue)
{

View File

@ -42,6 +42,35 @@ SOFTWARE.
namespace
{
struct Data
{
Data(int a_, int b_ = 2, int c_ = 3, int d_ = 4)
: a(a_),
b(b_),
c(c_),
d(d_)
{
}
Data()
: a(0),
b(0),
c(0),
d(0)
{
}
int a;
int b;
int c;
int d;
};
bool operator ==(const Data& lhs, const Data& rhs)
{
return (lhs.a == rhs.a) && (lhs.b == rhs.b) && (lhs.c == rhs.c) && (lhs.d == rhs.d);
}
SUITE(test_queue_atomic)
{
//*************************************************************************
@ -188,6 +217,30 @@ namespace
CHECK(!queue.pop());
}
//*************************************************************************
TEST(test_multiple_emplace)
{
etl::queue_spsc_atomic<Data, 4> queue;
queue.emplace(1);
queue.emplace(1, 2);
queue.emplace(1, 2, 3);
queue.emplace(1, 2, 3, 4);
CHECK_EQUAL(4U, queue.size());
Data popped;
queue.pop(popped);
CHECK(popped == Data(1, 2, 3, 4));
queue.pop(popped);
CHECK(popped == Data(1, 2, 3, 4));
queue.pop(popped);
CHECK(popped == Data(1, 2, 3, 4));
queue.pop(popped);
CHECK(popped == Data(1, 2, 3, 4));
}
//*************************************************************************
TEST(test_clear)
{

View File

@ -42,6 +42,35 @@ SOFTWARE.
namespace
{
struct Data
{
Data(int a_, int b_ = 2, int c_ = 3, int d_ = 4)
: a(a_),
b(b_),
c(c_),
d(d_)
{
}
Data()
: a(0),
b(0),
c(0),
d(0)
{
}
int a;
int b;
int c;
int d;
};
bool operator ==(const Data& lhs, const Data& rhs)
{
return (lhs.a == rhs.a) && (lhs.b == rhs.b) && (lhs.c == rhs.c) && (lhs.d == rhs.d);
}
typedef etl::queue_spsc_atomic<int, 4, etl::memory_model::MEMORY_MODEL_SMALL> QueueInt;
typedef etl::iqueue_spsc_atomic<int, etl::memory_model::MEMORY_MODEL_SMALL> IQueueInt;
@ -206,6 +235,30 @@ namespace
CHECK_EQUAL(254U, queue.size());
}
//*************************************************************************
TEST(test_multiple_emplace)
{
etl::queue_spsc_atomic<Data, 4, etl::memory_model::MEMORY_MODEL_SMALL> queue;
queue.emplace(1);
queue.emplace(1, 2);
queue.emplace(1, 2, 3);
queue.emplace(1, 2, 3, 4);
CHECK_EQUAL(4U, queue.size());
Data popped;
queue.pop(popped);
CHECK(popped == Data(1, 2, 3, 4));
queue.pop(popped);
CHECK(popped == Data(1, 2, 3, 4));
queue.pop(popped);
CHECK(popped == Data(1, 2, 3, 4));
queue.pop(popped);
CHECK(popped == Data(1, 2, 3, 4));
}
//*************************************************************************
TEST(test_clear)
{

View File

@ -69,6 +69,35 @@ namespace
bool Access::called_lock;
bool Access::called_unlock;
struct Data
{
Data(int a_, int b_ = 2, int c_ = 3, int d_ = 4)
: a(a_),
b(b_),
c(c_),
d(d_)
{
}
Data()
: a(0),
b(0),
c(0),
d(0)
{
}
int a;
int b;
int c;
int d;
};
bool operator ==(const Data& lhs, const Data& rhs)
{
return (lhs.a == rhs.a) && (lhs.b == rhs.b) && (lhs.c == rhs.c) && (lhs.d == rhs.d);
}
SUITE(test_queue_isr)
{
//*************************************************************************
@ -374,6 +403,30 @@ namespace
CHECK(!queue.pop_from_isr());
}
//*************************************************************************
TEST(test_multiple_emplace)
{
etl::queue_spsc_isr<Data, 4, Access> queue;
queue.emplace(1);
queue.emplace(1, 2);
queue.emplace(1, 2, 3);
queue.emplace(1, 2, 3, 4);
CHECK_EQUAL(4U, queue.size());
Data popped;
queue.pop(popped);
CHECK(popped == Data(1, 2, 3, 4));
queue.pop(popped);
CHECK(popped == Data(1, 2, 3, 4));
queue.pop(popped);
CHECK(popped == Data(1, 2, 3, 4));
queue.pop(popped);
CHECK(popped == Data(1, 2, 3, 4));
}
//*************************************************************************
TEST(test_clear)
{

View File

@ -69,6 +69,35 @@ namespace
bool Access::called_lock;
bool Access::called_unlock;
struct Data
{
Data(int a_, int b_ = 2, int c_ = 3, int d_ = 4)
: a(a_),
b(b_),
c(c_),
d(d_)
{
}
Data()
: a(0),
b(0),
c(0),
d(0)
{
}
int a;
int b;
int c;
int d;
};
bool operator ==(const Data& lhs, const Data& rhs)
{
return (lhs.a == rhs.a) && (lhs.b == rhs.b) && (lhs.c == rhs.c) && (lhs.d == rhs.d);
}
typedef etl::queue_spsc_isr<int, 4, Access, etl::memory_model::MEMORY_MODEL_SMALL> QueueInt;
typedef etl::iqueue_spsc_isr<int, Access, etl::memory_model::MEMORY_MODEL_SMALL> IQueueInt;
@ -392,6 +421,30 @@ namespace
CHECK_EQUAL(255U, queue.size());
}
//*************************************************************************
TEST(test_multiple_emplace)
{
etl::queue_spsc_isr<Data, 4, Access, etl::memory_model::MEMORY_MODEL_SMALL> queue;
queue.emplace(1);
queue.emplace(1, 2);
queue.emplace(1, 2, 3);
queue.emplace(1, 2, 3, 4);
CHECK_EQUAL(4U, queue.size());
Data popped;
queue.pop(popped);
CHECK(popped == Data(1, 2, 3, 4));
queue.pop(popped);
CHECK(popped == Data(1, 2, 3, 4));
queue.pop(popped);
CHECK(popped == Data(1, 2, 3, 4));
queue.pop(popped);
CHECK(popped == Data(1, 2, 3, 4));
}
//*************************************************************************
TEST(test_clear)
{

View File

@ -571,6 +571,107 @@ namespace
CHECK(is_equal);
}
//*************************************************************************
// To test the CPP03 versions then ETL_TEST_VECTOR_CPP11 must be set to 0 in vector.h
TEST_FIXTURE(SetupFixture, test_emplace_back_multiple)
{
class Data
{
public:
std::string a;
size_t b;
double c;
const char *d;
Data(std::string w) : a(w), b(0), c(0.0), d(0){}
Data(std::string w, size_t x) : a(w), b(x), c(0.0), d(0){}
Data(std::string w, size_t x, double y) : a(w), b(x), c(y), d(0){}
Data(std::string w, size_t x, double y, const char *z) : a(w), b(x), c(y), d(z){}
bool operator == (const Data &other) const
{
return (a == other.a) && (b == other.b) && (c == other.c) && (d == other.d);
}
};
std::vector<Data> compare_data;
etl::vector<Data, SIZE * 4> data;
std::string s;
for (size_t i = 0; i < SIZE; ++i)
{
s += "x";
// 4 arguments
compare_data.emplace_back(s, i, static_cast<double>(i) + 0.1234, "emplace_back");
data.emplace_back(s, i, static_cast<double>(i) + 0.1234, "emplace_back");
// 3 arguments
compare_data.emplace_back(s, i, static_cast<double>(i) + 0.1234);
data.emplace_back(s, i, static_cast<double>(i) + 0.1234);
// 2 arguments
compare_data.emplace_back(s, i);
data.emplace_back(s, i);
// 1 argument
compare_data.emplace_back(s);
data.emplace_back(s);
}
CHECK_EQUAL(compare_data.size(), data.size());
const bool is_equal = std::equal(data.begin(),
data.end(),
compare_data.begin());
CHECK(is_equal);
}
//*************************************************************************
// The C++11 variadic version uses non-const rvalue references so has the ability
// to emplace non-const reference members, the pre-C++11 const reference overloads
// does not have the ability to pass const reference parameters to non-const
// constructor parameters (like the members in Data below)
// So this is only tested on C++11 onwards
TEST_FIXTURE(SetupFixture, test_emplace_back_non_const_references)
{
#if ETL_CPP11_SUPPORTED && !defined(ETL_STLPORT) && !defined(ETL_NO_STL) && !ETL_VECTOR_FORCE_CPP03
class Data
{
public:
std::string &a;
size_t &b;
double &c;
const char *d;
Data(std::string &w, size_t &x, double &y, const char *z) : a(w), b(x), c(y), d(z){}
bool operator == (const Data &other) const
{
return (a == other.a) && (b == other.b) && (c == other.c) && (d == other.d);
}
};
std::vector<Data> compare_data;
etl::vector<Data, SIZE * 3> data;
std::string a = "test_test_test";
size_t b = 9999;
double c = 123.456;
const char *d = "abcdefghijklmnopqrstuvwxyz";
for (size_t i = 0; i < SIZE; ++i)
{
data.emplace_back(a, b, c, d);
compare_data.emplace_back(a, b, c, d);
}
CHECK_EQUAL(compare_data.size(), data.size());
const bool is_equal = std::equal(data.begin(),
data.end(),
compare_data.begin());
CHECK(is_equal);
#endif // ETL_CPP11_SUPPORTED && !defined(ETL_STLPORT) && !defined(ETL_NO_STL)
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_pop_back)
{