Commit c2f33c2e authored by neverlord's avatar neverlord

fixed vector api update + unit test

parent b453aabb
...@@ -261,3 +261,4 @@ cppa/util/static_foreach.hpp ...@@ -261,3 +261,4 @@ cppa/util/static_foreach.hpp
cppa/type_value_pair.hpp cppa/type_value_pair.hpp
examples/dining_philosophers.cpp examples/dining_philosophers.cpp
cppa/detail/disablable_delete.hpp cppa/detail/disablable_delete.hpp
unit_testing/test__fixed_vector.cpp
...@@ -31,16 +31,28 @@ ...@@ -31,16 +31,28 @@
#ifndef FIXED_VECTOR_HPP #ifndef FIXED_VECTOR_HPP
#define FIXED_VECTOR_HPP #define FIXED_VECTOR_HPP
#include <iterator>
#include <algorithm> #include <algorithm>
#include <stdexcept> #include <stdexcept>
#include <type_traits>
#include <initializer_list>
#include "cppa/config.hpp"
namespace cppa { namespace util { namespace cppa { namespace util {
// @warning does not perform any bound checks /**
* @brief A vector with a fixed maximum size.
*
* This implementation is highly optimized for arithmetic types and refuses
* any non-arithmetic template parameter.
*/
template<typename T, size_t MaxSize> template<typename T, size_t MaxSize>
class fixed_vector class fixed_vector
{ {
static_assert(std::is_arithmetic<T>::value, "T must be an arithmetic type");
size_t m_size; size_t m_size;
// support for MaxSize == 0 // support for MaxSize == 0
...@@ -56,6 +68,9 @@ class fixed_vector ...@@ -56,6 +68,9 @@ class fixed_vector
typedef T* iterator; typedef T* iterator;
typedef T const* const_iterator; typedef T const* const_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
constexpr fixed_vector() : m_size(0) constexpr fixed_vector() : m_size(0)
{ {
} }
...@@ -65,6 +80,12 @@ class fixed_vector ...@@ -65,6 +80,12 @@ class fixed_vector
std::copy(other.m_data, other.m_data + other.m_size, m_data); std::copy(other.m_data, other.m_data + other.m_size, m_data);
} }
fixed_vector(std::initializer_list<T> init) : m_size(init.size())
{
CPPA_REQUIRE(init.size() <= MaxSize);
std::copy(init.begin(), init.end(), m_data);
}
inline size_type size() const inline size_type size() const
{ {
return m_size; return m_size;
...@@ -87,24 +108,38 @@ class fixed_vector ...@@ -87,24 +108,38 @@ class fixed_vector
inline void push_back(T const& what) inline void push_back(T const& what)
{ {
CPPA_REQUIRE(!full());
m_data[m_size++] = what; m_data[m_size++] = what;
} }
inline void push_back(T&& what) inline void push_back(T&& what)
{ {
CPPA_REQUIRE(!full());
m_data[m_size++] = std::move(what); m_data[m_size++] = std::move(what);
} }
inline reference operator[](size_t pos) inline reference at(size_type pos)
{ {
CPPA_REQUIRE(pos < m_size);
return m_data[pos]; return m_data[pos];
} }
inline const_reference operator[](size_t pos) const inline const_reference at(size_type pos) const
{ {
CPPA_REQUIRE(pos < m_size);
return m_data[pos]; return m_data[pos];
} }
inline reference operator[](size_type pos)
{
return at(pos);
}
inline const_reference operator[](size_type pos) const
{
return at(pos);
}
inline iterator begin() inline iterator begin()
{ {
return m_data; return m_data;
...@@ -115,6 +150,11 @@ class fixed_vector ...@@ -115,6 +150,11 @@ class fixed_vector
return m_data; return m_data;
} }
inline const_iterator cbegin() const
{
return begin();
}
inline iterator end() inline iterator end()
{ {
return (static_cast<T*>(m_data) + m_size); return (static_cast<T*>(m_data) + m_size);
...@@ -125,6 +165,81 @@ class fixed_vector ...@@ -125,6 +165,81 @@ class fixed_vector
return (static_cast<T const*>(m_data) + m_size); return (static_cast<T const*>(m_data) + m_size);
} }
inline const_iterator cend() const
{
return end();
}
inline reverse_iterator rbegin()
{
return reverse_iterator(end());
}
inline const_reverse_iterator rbegin() const
{
return reverse_iterator(end());
}
inline const_reverse_iterator crbegin() const
{
return rbegin();
}
inline reverse_iterator rend()
{
return reverse_iterator(begin());
}
inline const_reverse_iterator rend() const
{
return reverse_iterator(begin());
}
inline const_reverse_iterator crend() const
{
return rend();
}
inline reference front()
{
CPPA_REQUIRE(!empty());
return m_data[0];
}
inline const_reference front() const
{
CPPA_REQUIRE(!empty());
return m_data[0];
}
inline reference back()
{
CPPA_REQUIRE(m_size > 0);
return m_data[m_size - 1];
}
inline const_reference back() const
{
CPPA_REQUIRE(m_size > 0);
return m_data[m_size - 1];
}
inline T* data()
{
return m_data;
}
inline T const* data() const
{
return m_data;
}
/**
* @brief Inserts elements to specified position in the container.
* @warning This member function is implemented for <tt>pos == end()</tt>
* only by now. The user has to guarantee that the size of the
* sequence [first, last) fits into the vector.
*/
template<class InputIterator> template<class InputIterator>
inline void insert(iterator pos, inline void insert(iterator pos,
InputIterator first, InputIterator first,
......
...@@ -6,6 +6,7 @@ noinst_PROGRAMS = unit_tests ...@@ -6,6 +6,7 @@ noinst_PROGRAMS = unit_tests
unit_tests_SOURCES = main.cpp \ unit_tests_SOURCES = main.cpp \
ping_pong.cpp \ ping_pong.cpp \
test__atom.cpp \ test__atom.cpp \
test__fixed_vector.cpp \
test__intrusive_ptr.cpp \ test__intrusive_ptr.cpp \
test__local_group.cpp \ test__local_group.cpp \
test__pattern.cpp \ test__pattern.cpp \
......
...@@ -165,6 +165,7 @@ int main(int argc, char** argv) ...@@ -165,6 +165,7 @@ int main(int argc, char** argv)
RUN_TEST(test__primitive_variant); RUN_TEST(test__primitive_variant);
RUN_TEST(test__intrusive_ptr); RUN_TEST(test__intrusive_ptr);
RUN_TEST(test__type_list); RUN_TEST(test__type_list);
RUN_TEST(test__fixed_vector);
RUN_TEST(test__tuple); RUN_TEST(test__tuple);
RUN_TEST(test__serialization); RUN_TEST(test__serialization);
RUN_TEST(test__spawn); RUN_TEST(test__spawn);
......
...@@ -63,6 +63,7 @@ size_t test__intrusive_ptr(); ...@@ -63,6 +63,7 @@ size_t test__intrusive_ptr();
size_t test__serialization(); size_t test__serialization();
size_t test__local_group(); size_t test__local_group();
size_t test__primitive_variant(); size_t test__primitive_variant();
size_t test__fixed_vector();
void test__queue_performance(); void test__queue_performance();
......
#include <string>
#include <typeinfo>
#include <iostream>
#include <algorithm>
#include "test.hpp"
#include "cppa/util/fixed_vector.hpp"
using std::cout;
using std::endl;
using std::equal;
using cppa::util::fixed_vector;
size_t test__fixed_vector()
{
CPPA_TEST(test__fixed_vector);
int arr1[] {1, 2, 3, 4};
fixed_vector<int, 4> vec1 {1, 2, 3, 4};
fixed_vector<int, 5> vec2 {4, 3, 2, 1};
fixed_vector<int, 4> vec3;
for (int i = 1; i <= 4; ++i) vec3.push_back(i);
fixed_vector<int, 4> vec4 {1, 2};
fixed_vector<int, 2> vec5 {3, 4};
vec4.insert(vec4.end(), vec5.begin(), vec5.end());
CPPA_CHECK_EQUAL(vec1.size(), 4);
CPPA_CHECK_EQUAL(vec2.size(), 4);
CPPA_CHECK_EQUAL(vec3.size(), 4);
CPPA_CHECK_EQUAL(vec4.size(), 4);
CPPA_CHECK_EQUAL(vec5.size(), 2);
CPPA_CHECK_EQUAL(vec1.full(), true);
CPPA_CHECK_EQUAL(vec2.full(), false);
CPPA_CHECK_EQUAL(vec3.full(), true);
CPPA_CHECK_EQUAL(vec4.full(), true);
CPPA_CHECK_EQUAL(vec5.full(), true);
CPPA_CHECK_EQUAL(vec4.full(), true);
CPPA_CHECK(std::equal(vec1.begin(), vec1.end(), arr1));
CPPA_CHECK(std::equal(vec2.rbegin(), vec2.rend(), arr1));
CPPA_CHECK_EQUAL(vec4.size(), vec1.size());
if (vec4.size() == vec1.size())
CPPA_CHECK(std::equal(vec4.begin(), vec4.end(), arr1));
return CPPA_TEST_RESULT;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment