Merge remote-tracking branch 'origin/development'

# Conflicts:
#	library.properties
#	test/codeblocks/ETL.depend
#	test/codeblocks/ETL.layout
This commit is contained in:
John Wellbelove 2017-09-21 14:25:34 +01:00
parent 68c964a45a
commit 9acfc2c9a6
9 changed files with 404 additions and 54 deletions

View File

@ -1,5 +1,5 @@
name=Embedded Template Library
version=9.6.0
version=9.6.1
author= John Wellbelove <john.wellbelove@etlcpp.com>
maintainer=John Wellbelove <john.wellbelove@etlcpp.com>
sentence=A C++ template library tailored for embedded systems.

View File

@ -126,6 +126,19 @@ namespace etl
--current_size;
}
//*************************************************************************
/// Removes the oldest item from the queue and pushes it to the destination.
/// Undefined behaviour if the queue is already empty.
/// NOTE: The destination must be an intrusize container that supports a push(TLink) member function.
//*************************************************************************
template <typename TContainer>
void pop_into(TContainer& destination)
{
link_type* p_link = p_front;
pop();
destination.push(*p_link);
}
//*************************************************************************
/// Clears the queue to the empty state.
//*************************************************************************

View File

@ -114,6 +114,39 @@ namespace etl
--current_size;
}
//*************************************************************************
/// Removes the oldest item from the queue and pushes it to the destination.
/// Undefined behaviour if the queue is already empty.
/// NOTE: The destination must be an intrusize container that supports a push(TLink) member function.
//*************************************************************************
template <typename TContainer>
void pop_into(TContainer& destination)
{
link_type* p_link = p_top;
pop();
destination.push(*p_link);
}
//*************************************************************************
/// Reverses the stack order.
//*************************************************************************
void reverse()
{
link_type* previous = nullptr;
link_type* current = p_top;
link_type* next;
while (current != nullptr)
{
next = current->etl_next;
current->etl_next = previous;
previous = current;
current = next;
}
p_top = previous;
}
//*************************************************************************
/// Clears the stack to the empty state.
//*************************************************************************

View File

@ -7,7 +7,7 @@ Embedded Template Library.
https://github.com/ETLCPP/etl
http://www.etlcpp.com
Copyright(c) 2014 jwellbelove
Copyright(c) 2014 jwellbelove, Mark Kitson
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
@ -157,12 +157,39 @@ namespace etl
//*************************************************************************
queue_base(size_type max_size)
: in(0),
out(0),
current_size(0),
CAPACITY(max_size)
out(0),
current_size(0),
CAPACITY(max_size)
{
}
//*************************************************************************
/// Increments (and wraps) the 'in' index value to record a queue addition.
//*************************************************************************
void add_in()
{
if (++in == CAPACITY)
{
in = 0;
}
++current_size;
++construct_count;
}
//*************************************************************************
/// Decrements (and wraps) the 'out' index value to record a queue deletion.
//*************************************************************************
void del_out()
{
if (++out == CAPACITY)
{
out = 0;
}
--current_size;
--construct_count;
}
size_type in; ///< Where to input new data.
size_type out; ///< Where to get the oldest data.
size_type current_size; ///< The number of items in the queue.
@ -196,6 +223,7 @@ namespace etl
private:
typedef typename etl::parameter_type<T>::type parameter_t;
typedef typename etl::queue_base base_t;
public:
@ -246,9 +274,7 @@ namespace etl
ETL_ASSERT(!full(), ETL_ERROR(queue_full));
#endif
::new (&p_buffer[in]) T(value);
in = (in == (CAPACITY - 1)) ? 0 : in + 1;
++current_size;
++construct_count;
base_t::add_in();
}
//*************************************************************************
@ -265,10 +291,7 @@ namespace etl
#if defined(ETL_CHECK_PUSH_POP)
ETL_ASSERT(!full(), ETL_ERROR(queue_full));
#endif
::new (&p_buffer[in]) T();
in = (in == (CAPACITY - 1)) ? 0 : in + 1;
++current_size;
++construct_count;
base_t::add_in();
return p_buffer[next];
}
@ -285,9 +308,7 @@ namespace etl
ETL_ASSERT(!full(), ETL_ERROR(queue_full));
#endif
::new (&p_buffer[in]) T(value1);
in = (in == (CAPACITY - 1)) ? 0 : in + 1;
++current_size;
++construct_count;
base_t::add_in();
}
//*************************************************************************
@ -302,9 +323,7 @@ namespace etl
ETL_ASSERT(!full(), ETL_ERROR(queue_full));
#endif
::new (&p_buffer[in]) T(value1, value2);
in = (in == (CAPACITY - 1)) ? 0 : in + 1;
++current_size;
++construct_count;
base_t::add_in();
}
//*************************************************************************
@ -319,9 +338,7 @@ namespace etl
ETL_ASSERT(!full(), ETL_ERROR(queue_full));
#endif
::new (&p_buffer[in]) T(value1, value2, value3);
in = (in == (CAPACITY - 1)) ? 0 : in + 1;
++current_size;
++construct_count;
base_t::add_in();
}
//*************************************************************************
@ -336,9 +353,7 @@ namespace etl
ETL_ASSERT(!full(), ETL_ERROR(queue_full));
#endif
::new (&p_buffer[in]) T(value1, value2, value3, value4);
in = (in == (CAPACITY - 1)) ? 0 : in + 1;
++current_size;
++construct_count;
base_t::add_in();
}
//*************************************************************************
@ -349,9 +364,7 @@ namespace etl
while (current_size > 0)
{
p_buffer[out].~T();
out = (out == (CAPACITY - 1)) ? 0 : out + 1;
--current_size;
--construct_count;
base_t::del_out();
}
in = 0;
@ -369,9 +382,7 @@ namespace etl
ETL_ASSERT(!empty(), ETL_ERROR(queue_empty));
#endif
p_buffer[out].~T();
out = (out == (CAPACITY - 1)) ? 0 : out + 1;
--current_size;
--construct_count;
base_t::del_out();
}
//*************************************************************************
@ -384,6 +395,19 @@ namespace etl
pop();
}
//*************************************************************************
/// Gets the oldest value and removes it from the front of the queue and
/// pushes it to the destination container.
/// If asserts or exceptions are enabled, throws an etl::queue_empty if the queue is empty.
/// NOTE: The destination must support a push(T) member function.
//*************************************************************************
template <typename TContainer>
void pop_into(TContainer& destination)
{
destination.push(front());
pop();
}
//*************************************************************************
/// Assignment operator.
//*************************************************************************
@ -391,6 +415,7 @@ namespace etl
{
if (&rhs != this)
{
clear();
clone(rhs);
}
@ -404,6 +429,8 @@ namespace etl
//*************************************************************************
void clone(const iqueue& other)
{
clear();
size_t index = other.out;
for (size_t i = 0; i < other.size(); ++i)

View File

@ -7,7 +7,7 @@ Embedded Template Library.
https://github.com/ETLCPP/etl
http://www.etlcpp.com
Copyright(c) 2014 jwellbelove
Copyright(c) 2014 jwellbelove, Mark Kitson
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
@ -163,6 +163,25 @@ namespace etl
{
}
//*************************************************************************
/// Increments the indexes value to record a stack addition.
//*************************************************************************
void add_in()
{
top_index = current_size++;
++construct_count;
}
//*************************************************************************
/// Decrements the indexes value to record a queue deletion.
//*************************************************************************
void del_out()
{
--top_index;
--current_size;
--construct_count;
}
size_type top_index; ///< The index of the top of the stack.
size_type current_size; ///< The number of items in the stack.
const size_type CAPACITY; ///< The maximum number of items in the stack.
@ -174,8 +193,8 @@ namespace etl
///\brief This is the base for all stacks that contain a particular type.
///\details Normally a reference to this type will be taken from a derived stack.
///\code
/// etl::stack<int, 10> myQueue;
/// etl::istack<int>& iQueue = myQueue;
/// etl::stack<int, 10> myStack;
/// etl::istack<int>& iStack = myStack;
///\endcode
/// \warning This stack cannot be used for concurrent access from multiple threads.
/// \tparam T The type of value that the stack holds.
@ -195,6 +214,7 @@ namespace etl
private:
typedef typename etl::parameter_type<T>::type parameter_t;
typedef typename etl::stack_base base_t;
public:
@ -217,9 +237,8 @@ namespace etl
#if defined(ETL_CHECK_PUSH_POP)
ETL_ASSERT(!full(), ETL_ERROR(stack_full));
#endif
top_index = current_size++;
base_t::add_in();
::new (&p_buffer[top_index]) T(value);
++construct_count;
}
//*************************************************************************
@ -233,9 +252,8 @@ namespace etl
#if defined(ETL_CHECK_PUSH_POP)
ETL_ASSERT(!full(), ETL_ERROR(stack_full));
#endif
top_index = current_size++;
base_t::add_in();
::new (&p_buffer[top_index]) T(value1);
++construct_count;
}
//*************************************************************************
@ -249,9 +267,8 @@ namespace etl
#if defined(ETL_CHECK_PUSH_POP)
ETL_ASSERT(!full(), ETL_ERROR(stack_full));
#endif
top_index = current_size++;
base_t::add_in();
::new (&p_buffer[top_index]) T(value1, value2);
++construct_count;
}
//*************************************************************************
@ -265,9 +282,8 @@ namespace etl
#if defined(ETL_CHECK_PUSH_POP)
ETL_ASSERT(!full(), ETL_ERROR(stack_full));
#endif
top_index = current_size++;
base_t::add_in();
::new (&p_buffer[top_index]) T(value1, value2, value3);
++construct_count;
}
//*************************************************************************
@ -281,9 +297,8 @@ namespace etl
#if defined(ETL_CHECK_PUSH_POP)
ETL_ASSERT(!full(), ETL_ERROR(stack_full));
#endif
top_index = current_size++;
base_t::add_in();
::new (&p_buffer[top_index]) T(value1, value2, value3, value4);
++construct_count;
}
//*************************************************************************
@ -298,9 +313,7 @@ namespace etl
#if defined(ETL_CHECK_PUSH_POP)
ETL_ASSERT(!full(), ETL_ERROR(stack_full));
#endif
top_index = current_size++;
::new (&p_buffer[top_index]) T();
++construct_count;
base_t::add_in();
return p_buffer[top_index];
}
@ -322,9 +335,7 @@ namespace etl
while (current_size > 0)
{
p_buffer[top_index].~T();
--top_index;
--current_size;
--construct_count;
base_t::del_out();
}
}
@ -337,9 +348,7 @@ namespace etl
ETL_ASSERT(!empty(), ETL_ERROR(stack_empty));
#endif
p_buffer[top_index].~T();
--top_index;
--current_size;
--construct_count;
base_t::del_out();
}
//*************************************************************************
@ -351,6 +360,26 @@ namespace etl
pop();
}
//*************************************************************************
/// Removes the oldest item from the top of the stack and pushes it to the
/// destination container.
/// NOTE: The destination must support a push(T) member function.
//*************************************************************************
template <typename TContainer>
void pop_into(TContainer& destination)
{
destination.push(top());
pop();
}
//*************************************************************************
/// Reverses the stack.
//*************************************************************************
void reverse()
{
std::reverse(p_buffer, p_buffer + current_size);
}
//*************************************************************************
/// Assignment operator.
//*************************************************************************
@ -358,6 +387,7 @@ namespace etl
{
if (&rhs != this)
{
clear();
clone(rhs);
}

View File

@ -213,6 +213,44 @@ namespace
CHECK(queueC.empty());
}
//*************************************************************************
TEST(test_pop_into)
{
Data data1(1);
Data data2(2);
Data data3(3);
etl::intrusive_queue<Data, link0> queue1;
etl::intrusive_queue<Data, link0> queue2;
queue1.push(data1);
queue1.push(data2);
queue1.push(data3);
queue1.pop_into(queue2);
CHECK_EQUAL(2U, queue1.size());
CHECK_EQUAL(data2, queue1.front());
CHECK_EQUAL(1U, queue2.size());
CHECK_EQUAL(data1, queue2.front());
CHECK_EQUAL(data1, queue2.back());
queue1.pop_into(queue2);
CHECK_EQUAL(1U, queue1.size());
CHECK_EQUAL(data3, queue1.front());
CHECK_EQUAL(2U, queue2.size());
CHECK_EQUAL(data1, queue2.front());
CHECK_EQUAL(data2, queue2.back());
queue1.pop_into(queue2);
CHECK_EQUAL(0U, queue1.size());
CHECK_EQUAL(3U, queue2.size());
CHECK_EQUAL(data1, queue2.front());
CHECK_EQUAL(data3, queue2.back());
}
//*************************************************************************
TEST(test_front_const)
{

View File

@ -202,6 +202,41 @@ namespace
CHECK(stackC.empty());
}
//*************************************************************************
TEST(test_pop_into)
{
Data data1(1);
Data data2(2);
Data data3(3);
etl::intrusive_stack<Data, link0> stack1;
etl::intrusive_stack<Data, link0> stack2;
stack1.push(data1);
stack1.push(data2);
stack1.push(data3);
stack1.pop_into(stack2);
CHECK_EQUAL(2U, stack1.size());
CHECK_EQUAL(data2, stack1.top());
CHECK_EQUAL(1U, stack2.size());
CHECK_EQUAL(data3, stack2.top());
stack1.pop_into(stack2);
CHECK_EQUAL(1U, stack1.size());
CHECK_EQUAL(data1, stack1.top());
CHECK_EQUAL(2U, stack2.size());
CHECK_EQUAL(data2, stack2.top());
stack1.pop_into(stack2);
CHECK_EQUAL(0U, stack1.size());
CHECK_EQUAL(3U, stack2.size());
CHECK_EQUAL(data1, stack2.top());
}
//*************************************************************************
TEST(test_top_const)
{
@ -222,5 +257,56 @@ namespace
stackD.pop();
CHECK_EQUAL(stackD.top(), stackDR.top());
}
//*************************************************************************
TEST(test_reverse1)
{
Data data1(1);
etl::intrusive_stack<Data, link0> stack;
stack.push(data1);
stack.reverse();
CHECK_EQUAL(1U, stack.size());
CHECK_EQUAL(stack.top(), data1);
}
//*************************************************************************
TEST(test_reverse5)
{
Data data1(1);
Data data2(2);
Data data3(3);
Data data4(4);
Data data5(5);
etl::intrusive_stack<Data, link0> stack;
stack.push(data1);
stack.push(data2);
stack.push(data3);
stack.push(data4);
stack.push(data5);
stack.reverse();
CHECK_EQUAL(5U, stack.size());
CHECK_EQUAL(stack.top(), data1);
stack.pop();
CHECK_EQUAL(stack.top(), data2);
stack.pop();
CHECK_EQUAL(stack.top(), data3);
stack.pop();
CHECK_EQUAL(stack.top(), data4);
stack.pop();
CHECK_EQUAL(stack.top(), data5);
}
};
}

View File

@ -353,15 +353,65 @@ namespace
queue.pop_into(i);
CHECK_EQUAL(1, i);
CHECK_EQUAL(3U, queue.size());
queue.pop_into(i);
CHECK_EQUAL(2, i);
CHECK_EQUAL(2U, queue.size());
queue.pop_into(i);
CHECK_EQUAL(3, i);
CHECK_EQUAL(1U, queue.size());
queue.pop_into(i);
CHECK_EQUAL(4, i);
CHECK_EQUAL(0U, queue.size());
}
//*************************************************************************
TEST(test_pop_into_queue)
{
etl::queue<int, 4> queue1;
etl::queue<int, 4> queue2;
queue1.push(1);
queue1.push(2);
queue1.push(3);
queue1.push(4);
queue1.pop_into(queue2);
CHECK_EQUAL(1U, queue2.size());
CHECK_EQUAL(1, queue2.front());
CHECK_EQUAL(1, queue2.back());
queue1.pop_into(queue2);
CHECK_EQUAL(2U, queue2.size());
CHECK_EQUAL(1, queue2.front());
CHECK_EQUAL(2, queue2.back());
queue1.pop_into(queue2);
CHECK_EQUAL(3U, queue2.size());
CHECK_EQUAL(1, queue2.front());
CHECK_EQUAL(3, queue2.back());
queue1.pop_into(queue2);
CHECK_EQUAL(4U, queue2.size());
CHECK_EQUAL(1, queue2.front());
CHECK_EQUAL(4, queue2.back());
int i;
queue2.pop_into(i);
CHECK_EQUAL(1, i);
queue2.pop_into(i);
CHECK_EQUAL(2, i);
queue2.pop_into(i);
CHECK_EQUAL(3, i);
queue2.pop_into(i);
CHECK_EQUAL(4, i);
}
//*************************************************************************

View File

@ -228,24 +228,70 @@ namespace
{
etl::stack<int, 4> stack;
int i;
stack.push(1);
stack.push(2);
stack.push(3);
stack.push(4);
int i;
stack.pop_into(i);
CHECK_EQUAL(4, i);
CHECK_EQUAL(3U, stack.size());
stack.pop_into(i);
CHECK_EQUAL(3, i);
CHECK_EQUAL(2U, stack.size());
stack.pop_into(i);
CHECK_EQUAL(2, i);
CHECK_EQUAL(1U, stack.size());
stack.pop_into(i);
CHECK_EQUAL(1, i);
CHECK_EQUAL(0U, stack.size());
}
//*************************************************************************
TEST(test_pop_into_stack)
{
etl::stack<int, 4> stack1;
etl::stack<int, 4> stack2;
stack1.push(1);
stack1.push(2);
stack1.push(3);
stack1.push(4);
stack1.pop_into(stack2);
CHECK_EQUAL(1U, stack2.size());
CHECK_EQUAL(4, stack2.top());
stack1.pop_into(stack2);
CHECK_EQUAL(2U, stack2.size());
CHECK_EQUAL(3, stack2.top());
stack1.pop_into(stack2);
CHECK_EQUAL(3U, stack2.size());
CHECK_EQUAL(2, stack2.top());
stack1.pop_into(stack2);
CHECK_EQUAL(4U, stack2.size());
CHECK_EQUAL(1, stack2.top());
int i;
stack2.pop_into(i);
CHECK_EQUAL(1, i);
stack2.pop_into(i);
CHECK_EQUAL(2, i);
stack2.pop_into(i);
CHECK_EQUAL(3, i);
stack2.pop_into(i);
CHECK_EQUAL(4, i);
}
//*************************************************************************
@ -447,5 +493,32 @@ namespace
CHECK_EQUAL(1, stack.top());
stack.pop();
}
//*************************************************************************
TEST(test_reverse)
{
etl::stack<int, 4> stack;
stack.push(1);
stack.push(2);
stack.push(3);
stack.push(4);
stack.reverse();
int i;
stack.pop_into(i);
CHECK_EQUAL(1, i);
stack.pop_into(i);
CHECK_EQUAL(2, i);
stack.pop_into(i);
CHECK_EQUAL(3, i);
stack.pop_into(i);
CHECK_EQUAL(4, i);
}
};
}