Commit 53e5796f authored by Dominik Charousset's avatar Dominik Charousset

maintenance

parent 3f194ef3
......@@ -45,6 +45,9 @@ namespace cppa { namespace detail {
struct abstract_tuple : ref_counted
{
abstract_tuple() = default;
abstract_tuple(abstract_tuple const&);
// mutators
virtual void* mutable_at(size_t pos) = 0;
......@@ -64,17 +67,22 @@ struct abstract_tuple : ref_counted
{
size_t m_pos;
abstract_tuple const& m_tuple;
abstract_tuple const* m_tuple;
public:
const_iterator(abstract_tuple const& tup, size_t pos = 0) : m_pos(pos), m_tuple(tup) { }
inline const_iterator(abstract_tuple const* tup, size_t pos = 0)
: m_pos(pos), m_tuple(tup)
{
}
const_iterator(const_iterator const&) = default;
const_iterator& operator=(const_iterator const&) = default;
inline bool operator==(const_iterator const& other) const
{
CPPA_REQUIRE(&(other.m_tuple) == &(other.m_tuple));
CPPA_REQUIRE(other.m_tuple == other.m_tuple);
return other.m_pos == m_pos;
}
......@@ -122,19 +130,25 @@ struct abstract_tuple : ref_counted
inline size_t position() const { return m_pos; }
void const* value() const { return m_tuple.at(m_pos); }
inline void const* value() const
{
return m_tuple->at(m_pos);
}
uniform_type_info const* type() const { return m_tuple.type_at(m_pos); }
inline uniform_type_info const* type() const
{
return m_tuple->type_at(m_pos);
}
const_iterator& operator*() { return *this; }
inline const_iterator& operator*() { return *this; }
operator type_value_pair() const { return {type(), value()}; }
inline operator type_value_pair() const { return {type(), value()}; }
};
inline const_iterator begin() const { return {*this}; }
inline const_iterator begin() const { return {this}; }
inline const_iterator end() const { return {*this, size()}; }
inline const_iterator end() const { return {this, size()}; }
};
......
......@@ -82,6 +82,7 @@ class decorated_tuple : public abstract_tuple
virtual void* mutable_at(size_t pos)
{
CPPA_REQUIRE(pos < size());
CPPA_REQUIRE(m_mapping[pos] < m_decorated->size());
return m_decorated->mutable_at(m_mapping[pos]);
}
......@@ -98,12 +99,14 @@ class decorated_tuple : public abstract_tuple
virtual void const* at(size_t pos) const
{
CPPA_REQUIRE(pos < size());
CPPA_REQUIRE(m_mapping[pos] < m_decorated->size());
return m_decorated->at(m_mapping[pos]);
}
virtual uniform_type_info const* type_at(size_t pos) const
{
CPPA_REQUIRE(pos < size());
CPPA_REQUIRE(m_mapping[pos] < m_decorated->size());
return m_decorated->type_at(m_mapping[pos]);
}
......@@ -112,21 +115,24 @@ class decorated_tuple : public abstract_tuple
return typeid(decorated_tuple);
}
cow_pointer_type& decorated()
{
return m_decorated;
}
cow_pointer_type const& decorated() const
{
return m_decorated;
}
private:
cow_pointer_type m_decorated;
vector_type m_mapping;
decorated_tuple(cow_pointer_type const& d) : m_decorated(d) { }
decorated_tuple(cow_pointer_type&& d) : m_decorated(std::move(d)) { }
decorated_tuple(decorated_tuple const& other)
: abstract_tuple()
, m_decorated(other.m_decorated)
, m_mapping(other.m_mapping)
{
}
decorated_tuple(decorated_tuple const&) = default;
decorated_tuple* init(vector_type const& v)
{
......@@ -143,7 +149,7 @@ class decorated_tuple : public abstract_tuple
CPPA_REQUIRE(m_decorated->size() >= sizeof...(ElementTypes));
size_t i = 0;
m_mapping.resize(sizeof...(ElementTypes));
std::generate(m_mapping.begin(), m_mapping.end(), [&](){return i++;});
std::generate(m_mapping.begin(), m_mapping.end(), [&]() {return i++;});
return this;
}
......@@ -152,7 +158,7 @@ class decorated_tuple : public abstract_tuple
CPPA_REQUIRE((m_decorated->size() - offset) == sizeof...(ElementTypes));
size_t i = offset;
m_mapping.resize(sizeof...(ElementTypes));
std::generate(m_mapping.begin(), m_mapping.end(), [&](){return i++;});
std::generate(m_mapping.begin(), m_mapping.end(), [&]() {return i++;});
return this;
}
......
......@@ -31,6 +31,7 @@
#ifndef TUPLE_CAST_IMPL_HPP
#define TUPLE_CAST_IMPL_HPP
#include "cppa/match.hpp"
#include "cppa/pattern.hpp"
#include "cppa/type_value_pair.hpp"
......@@ -50,252 +51,84 @@ enum class tuple_cast_impl_id
wildcard_in_between
};
template<tuple_cast_impl_id, class Result, typename... T>
struct tuple_cast_impl;
template<class Result, typename... T>
struct tuple_cast_impl<tuple_cast_impl_id::no_wildcard, Result, T...>
// covers wildcard_in_between and multiple_wildcards
template<pattern_characteristic, class Result, typename... T>
struct tuple_cast_impl
{
static constexpr size_t size =
util::tl_count_not<
util::type_list<T...>,
util::tbind<std::is_same, anything>::type>::value;
typedef util::fixed_vector<size_t, size> mapping_vector;
template<class Tuple>
inline static bool types_match(Tuple const& tup)
{
auto& impl_typeid = tup.impl_type();
if ( impl_typeid == typeid(tuple_vals<T...>)
|| impl_typeid == typeid(decorated_tuple<T...>))
{
return true;
}
else if (impl_typeid == typeid(object_array))
{
if (tup.size() == sizeof...(T))
{
auto& tarr = static_types_array<T...>::arr;
for (size_t i = 0; i < sizeof...(T); ++i)
{
if (tarr[i] != tup.type_at(i)) return false;
}
return true;
}
}
return false;
}
template<class Tuple>
static option<Result> _(Tuple const& tup, pattern<T...> const& p)
inline static option<Result> _(Tuple const& tup)
{
if (types_match(tup))
{
if ( p.has_values() == false
|| std::equal(tup.begin(), tup.end(), p.begin(),
values_only_eq))
{
return {Result::from(tup.vals())};
}
}
mapping_vector mv;
if (match<T...>(tup, mv)) return {Result::from(tup.vals(), mv)};
return {};
}
template<class Tuple>
static option<Result> _(Tuple const& tup)
inline static option<Result> _(Tuple const& tup, pattern<T...> const& p)
{
if (types_match(tup))
{
return {Result::from(tup.vals())};
}
mapping_vector mv;
if (match(tup, p)) return {Result::from(tup.vals(), mv)};
return {};
}
};
template<class Result, typename... T>
struct tuple_cast_impl<tuple_cast_impl_id::trailing_wildcard, Result, T...>
struct tuple_cast_impl<pattern_characteristic::no_wildcard, Result, T...>
{
static_assert(sizeof...(T) > 1, "tuple_cast<anything> (empty result)");
template<class Tuple>
inline static option<Result> _(Tuple const& tup, pattern<T...> const& p)
static inline option<Result> _(Tuple const& tup)
{
if (tup.size() >= (sizeof...(T) - 1))
{
// skip last element (wildcard)
auto end = tup.end();
--end;
if (std::equal(tup.begin(), end, p.begin(),
(p.has_values() ? full_eq
: types_only_eq)))
{
return {Result::subtuple(tup.vals())};
}
}
return {};
}
template<class Tuple>
static option<Result> _(Tuple const& tup)
{
if (tup.size() >= (sizeof...(T) - 1))
{
auto& tarr = static_types_array<T...>::arr;
for (size_t i = 0; i < (sizeof...(T) - 1); ++i)
{
if (tarr[i] != tup.type_at(i)) return { };
}
return {Result::subtuple(tup.vals())};
}
if (match<T...>(tup)) return {Result::from(tup.vals())};
return {};
}
template<class Tuple>
static inline option<Result> _(Tuple const& tup, pattern<T...> const& p)
{
if (match(tup, p)) return {Result::from(tup.vals())};
return {};
}
};
template<class Result, typename... T>
struct tuple_cast_impl<tuple_cast_impl_id::leading_wildcard, Result, T...>
struct tuple_cast_impl<pattern_characteristic::trailing_wildcard, Result, T...>
{
static_assert(sizeof...(T) > 1, "tuple_cast<anything> (empty result)");
template<class Tuple>
inline static option<Result> _(Tuple const& tup, pattern<T...> const& p)
inline static option<Result> _(Tuple const& tup)
{
if (tup.size() >= (sizeof...(T) - 1))
{
size_t offset = tup.size() - (sizeof...(T) - 1);
// skip first elements in tuple
auto begin = tup.begin();
begin += offset;
// skip first element (wildcard) of pattern
auto pbegin = p.begin();
++pbegin;
if (std::equal(begin, tup.end(), pbegin,
(p.has_values() ? full_eq
: types_only_eq)))
{
return {Result::offset_subtuple(tup.vals(), offset)};
}
}
if (match<T...>(tup)) return {Result::subtuple(tup.vals())};
return {};
}
template<class Tuple>
static option<Result> _(Tuple const& tup)
inline static option<Result> _(Tuple const& tup, pattern<T...> const& p)
{
if (tup.size() >= (sizeof...(T) - 1))
{
size_t offset = tup.size() - (sizeof...(T) - 1);
auto& tarr = static_types_array<T...>::arr;
for (size_t i = offset, j = 1; i < tup.size(); ++i, ++j)
{
if (tarr[j] != tup.type_at(i)) return { };
}
return {Result::offset_subtuple(tup.vals(), offset)};
}
if (match(tup, p)) return {Result::subtuple(tup.vals())};
return {};
}
};
template<class Result, typename... T>
struct tuple_cast_impl<tuple_cast_impl_id::wildcard_in_between, Result, T...>
struct tuple_cast_impl<pattern_characteristic::leading_wildcard, Result, T...>
{
static_assert(sizeof...(T) > 1, "tuple_cast<anything> (empty result)");
typedef util::type_list<T...> types;
typedef typename util::tl_filter_not<types, util::tbind<std::is_same, anything>::type>::type
filtered_types;
// mapping vector type
static constexpr size_t filtered_size = filtered_types::size;
typedef util::fixed_vector<size_t, filtered_types::size> mapping_vector;
// iterator types
typedef type_value_pair_const_iterator pattern_iterator;
typedef abstract_tuple::const_iterator const_iterator;
inline static bool matches(mapping_vector& mv,
const_iterator tbegin,
const_iterator tend,
pattern_iterator pbegin,
pattern_iterator pend)
{
while (!(pbegin == pend && tbegin == tend))
{
if (pbegin == pend)
{
// reached end of pattern while some values remain unmatched
return false;
}
else if (pbegin.type() == nullptr) // nullptr == wildcard (anything)
{
// perform submatching
++pbegin;
if (pbegin == pend)
{
// always true at the end of the pattern
return true;
}
// safe current mapping as fallback
auto s = mv.size();
// iterate over tuple values until we found a match
for (; tbegin != tend; ++tbegin)
{
if (matches(mv, tbegin, tend, pbegin, pend)) return true;
// restore mapping to fallback (delete invalid mappings)
mv.resize(s);
}
return false; // no submatch found
}
else if (full_eq(tbegin, *pbegin))
{
mv.push_back(tbegin.position());
}
else
{
return false; // no match
}
// next iteration
++tbegin;
++pbegin;
}
return true; // pbegin == pend && tbegin == tend
}
template<class Tuple>
inline static option<Result> _(Tuple const& tup, pattern<T...> const& p)
inline static option<Result> _(Tuple const& tup)
{
util::fixed_vector<size_t, Result::num_elements> mv;
if (matches(mv, tup.begin(), tup.end(), p.begin(), p.end()))
{
return {Result::from(tup.vals(), mv)};
}
size_t o = tup.size() - (sizeof...(T) - 1);
if (match<T...>(tup)) return {Result::offset_subtuple(tup.vals(), o)};
return {};
}
template<class Tuple>
static option<Result> _(Tuple const& tup)
inline static option<Result> _(Tuple const& tup, pattern<T...> const& p)
{
util::fixed_vector<size_t, Result::num_elements> mv;
auto& tarr = static_types_array<T...>::arr;
if (matches(mv, tup.begin(), tup.end(), tarr.begin(), tarr.end()))
{
return {Result::from(tup.vals(), mv)};
}
size_t o = tup.size() - (sizeof...(T) - 1);
if (match(tup, p)) return {Result::offset_subtuple(tup.vals(), o)};
return {};
}
};
template<typename... T>
struct select_tuple_cast_impl
{
typedef util::type_list<T...> types;
typedef util::tl_find<types, anything> result1;
typedef typename result1::rest_list rest_list;
static constexpr int wc1 = result1::value;
static constexpr int wc2 =
(wc1 < 0)
? -1
: (util::tl_find<rest_list, anything>::value + wc1 + 1);
static constexpr tuple_cast_impl_id value =
(wc1 == -1)
? tuple_cast_impl_id::no_wildcard
: ((wc1 == 0 && wc2 == -1)
? tuple_cast_impl_id::leading_wildcard
: ((wc1 == (sizeof...(T) - 1) && wc2 == -1)
? tuple_cast_impl_id::trailing_wildcard
: tuple_cast_impl_id::wildcard_in_between));
};
} }
#endif // TUPLE_CAST_IMPL_HPP
......@@ -71,8 +71,61 @@ constexpr pattern_characteristic get_pattern_characteristic()
namespace detail {
template<pattern_characteristic, typename...> struct matcher;
} // namespace cppa
} // namespace detail
template<pattern_characteristic PC, typename... Ts>
struct match_impl;
/**
*
*/
template<typename... Ts>
inline bool match(any_tuple const& tup)
{
typedef util::type_list<Ts...> tl;
return match_impl<get_pattern_characteristic<tl>(), Ts...>::_(tup);
}
/**
*
*/
template<typename... Ts>
inline bool match(any_tuple const& tup,
util::fixed_vector<
size_t,
util::tl_count_not<
util::type_list<Ts...>,
util::tbind<std::is_same, anything>::type>::value>& mv)
{
typedef util::type_list<Ts...> tl;
return match_impl<get_pattern_characteristic<tl>(), Ts...>::_(tup, mv);
}
/**
*
*/
template<typename... Ts>
inline bool match(any_tuple const& tup, pattern<Ts...> const& ptrn)
{
typedef util::type_list<Ts...> tl;
return match_impl<get_pattern_characteristic<tl>(), Ts...>::_(tup, ptrn);
}
/**
*
*/
template<typename... Ts>
inline bool match(any_tuple const& tup,
pattern<Ts...> const& ptrn,
typename pattern<Ts...>::mapping_vector& mv)
{
typedef util::type_list<Ts...> tl;
return match_impl<get_pattern_characteristic<tl>(), Ts...>::_(tup,
ptrn,
mv);
}
// implementation for zero or one wildcards
template<pattern_characteristic PC, typename... Ts>
struct match_impl
{
......@@ -80,12 +133,14 @@ struct match_impl
{
return detail::matcher<PC, Ts...>::tmatch(tup);
}
template<size_t Size>
static inline bool _(any_tuple const& tup,
util::fixed_vector<size_t, Size>& mv)
{
return detail::matcher<PC, Ts...>::tmatch(tup, mv);
}
static inline bool _(any_tuple const& tup,
pattern<Ts...> const& p)
{
......@@ -93,6 +148,7 @@ struct match_impl
&& ( p.has_values() == false
|| detail::matcher<PC, Ts...>::vmatch(tup, p));
}
static inline bool _(any_tuple const& tup,
pattern<Ts...> const& p,
typename pattern<Ts...>::mapping_vector& mv)
......@@ -103,20 +159,24 @@ struct match_impl
}
};
// implementation for multiple wildcards
template<typename... Ts>
struct match_impl<pattern_characteristic::multiple_wildcards, Ts...>
{
static constexpr auto PC = pattern_characteristic::multiple_wildcards;
static inline bool _(any_tuple const& tup)
{
return detail::matcher<PC, Ts...>::tmatch(tup);
}
template<size_t Size>
static inline bool _(any_tuple const& tup,
util::fixed_vector<size_t, Size>& mv)
{
return detail::matcher<PC, Ts...>::tmatch(tup, mv);
}
static inline bool _(any_tuple const& tup, pattern<Ts...> const& p)
{
if (p.has_values())
......@@ -127,6 +187,7 @@ struct match_impl<pattern_characteristic::multiple_wildcards, Ts...>
}
return detail::matcher<PC, Ts...>::tmatch(tup);
}
static inline bool _(any_tuple const& tup, pattern<Ts...> const& p,
typename pattern<Ts...>::mapping_vector& mv)
{
......@@ -140,43 +201,6 @@ struct match_impl<pattern_characteristic::multiple_wildcards, Ts...>
}
};
template<typename... Ts>
inline bool match(any_tuple const& tup)
{
typedef util::type_list<Ts...> tl;
return match_impl<get_pattern_characteristic<tl>(), Ts...>::_(tup);
}
template<typename... Ts>
inline bool match(any_tuple const& tup,
util::fixed_vector<
size_t,
util::tl_count_not<
util::type_list<Ts...>,
util::tbind<std::is_same, anything>::type>::value>& mv)
{
typedef util::type_list<Ts...> tl;
return match_impl<get_pattern_characteristic<tl>(), Ts...>::_(tup, mv);
}
template<typename... Ts>
inline bool match(any_tuple const& tup, pattern<Ts...> const& ptrn)
{
typedef util::type_list<Ts...> tl;
return match_impl<get_pattern_characteristic<tl>(), Ts...>::_(tup, ptrn);
}
template<typename... Ts>
inline bool match(any_tuple const& tup,
pattern<Ts...> const& ptrn,
typename pattern<Ts...>::mapping_vector& mv)
{
typedef util::type_list<Ts...> tl;
return match_impl<get_pattern_characteristic<tl>(), Ts...>::_(tup,
ptrn,
mv);
}
/******************************************************************************\
** implementation details **
\******************************************************************************/
......@@ -189,12 +213,14 @@ struct matcher<pattern_characteristic::no_wildcard, T...>
{
static inline bool tmatch(any_tuple const& tup)
{
// match implementation type if possible
auto& impl_typeid = tup.impl_type();
if ( impl_typeid == typeid(tuple_vals<T...>)
|| impl_typeid == typeid(decorated_tuple<T...>))
{
return true;
}
// always use a full dynamic match for object arrays
else if ( impl_typeid == typeid(detail::object_array)
&& tup.size() == sizeof...(T))
{
......@@ -204,6 +230,7 @@ struct matcher<pattern_characteristic::no_wildcard, T...>
}
return false;
}
static inline bool tmatch(any_tuple const& tup,
util::fixed_vector<size_t, sizeof...(T)>& mv)
{
......@@ -216,6 +243,7 @@ struct matcher<pattern_characteristic::no_wildcard, T...>
}
return false;
}
static inline bool vmatch(any_tuple const& tup, pattern<T...> const& ptrn)
{
return std::equal(tup.begin(), tup.end(), ptrn.begin(),
......@@ -227,6 +255,7 @@ template<typename... T>
struct matcher<pattern_characteristic::trailing_wildcard, T...>
{
static constexpr size_t size = sizeof...(T) - 1;
static inline bool tmatch(any_tuple const& tup)
{
if (tup.size() >= size)
......@@ -238,6 +267,7 @@ struct matcher<pattern_characteristic::trailing_wildcard, T...>
}
return false;
}
static inline bool tmatch(any_tuple const& tup,
util::fixed_vector<size_t, size>& mv)
{
......@@ -250,6 +280,7 @@ struct matcher<pattern_characteristic::trailing_wildcard, T...>
}
return false;
}
static inline bool vmatch(any_tuple const& tup, pattern<T...> const& ptrn)
{
auto begin = tup.begin();
......@@ -279,6 +310,7 @@ template<typename... T>
struct matcher<pattern_characteristic::leading_wildcard, T...>
{
static constexpr size_t size = sizeof...(T) - 1;
static inline bool tmatch(any_tuple const& tup)
{
auto tup_size = tup.size();
......@@ -287,13 +319,15 @@ struct matcher<pattern_characteristic::leading_wildcard, T...>
auto& tarr = static_types_array<T...>::arr;
auto begin = tup.begin();
begin += (tup_size - size);
return std::equal(begin, tup.end(), tarr.begin(),
return std::equal(begin, tup.end(),
(tarr.begin() + 1), // skip 'anything'
detail::types_only_eq);
}
return false;
}
static inline bool tmatch(any_tuple const& tup,
util::fixed_vector<size_t, size>& mv)
util::fixed_vector<size_t, size>& mv)
{
if (tmatch(tup))
{
......@@ -304,11 +338,13 @@ struct matcher<pattern_characteristic::leading_wildcard, T...>
}
return false;
}
static inline bool vmatch(any_tuple const& tup, pattern<T...> const& ptrn)
{
auto begin = tup.begin();
begin += (tup.size() - size);
return std::equal(begin, tup.end(), ptrn.begin() + 1,
return std::equal(begin, tup.end(),
ptrn.begin() + 1, // skip 'anything'
detail::values_only_eq);
}
};
......@@ -318,12 +354,14 @@ struct matcher<pattern_characteristic::wildcard_in_between, T...>
{
static constexpr int signed_wc_pos =
util::tl_find<util::type_list<T...>, anything>::value;
static constexpr size_t size = sizeof...(T);
static constexpr size_t wc_pos = static_cast<size_t>(signed_wc_pos);
static_assert( signed_wc_pos != -1
&& signed_wc_pos != 0
&& signed_wc_pos != (sizeof...(T) - 1),
"illegal wildcard position");
static constexpr size_t wc_pos = static_cast<size_t>(signed_wc_pos);
static constexpr size_t size = sizeof...(T) - 1;
static inline bool tmatch(any_tuple const& tup)
{
auto tup_size = tup.size();
......@@ -338,14 +376,15 @@ struct matcher<pattern_characteristic::wildcard_in_between, T...>
// second range [X2, N)
begin = end = tup.end();
begin -= (size - (wc_pos + 1));
auto arr_begin = tarr.begin() + wc_pos + 1;
auto arr_begin = tarr.begin() + (wc_pos + 1);
return std::equal(begin, end, arr_begin, detail::types_only_eq);
}
}
return false;
}
static inline bool tmatch(any_tuple const& tup,
util::fixed_vector<size_t, size>& mv)
util::fixed_vector<size_t, size - 1>& mv)
{
if (tmatch(tup))
{
......@@ -362,6 +401,7 @@ struct matcher<pattern_characteristic::wildcard_in_between, T...>
}
return false;
}
static inline bool vmatch(any_tuple const& tup, pattern<T...> const& ptrn)
{
// first range
......@@ -386,6 +426,7 @@ struct matcher<pattern_characteristic::multiple_wildcards, T...>
static constexpr size_t wc_count =
util::tl_count<util::type_list<T...>,
util::tbind<std::is_same, anything>::type>::value;
static_assert(sizeof...(T) > wc_count, "only wildcards given");
template<class TupleIter, class PatternIter,
......@@ -463,6 +504,7 @@ struct matcher<pattern_characteristic::multiple_wildcards, T...>
}
return false;
}
static inline bool vmatch(any_tuple const& tup,
pattern<T...> const& ptrn,
typename pattern<T...>::mapping_vector const& mv)
......
......@@ -33,6 +33,7 @@
#include <type_traits>
#include "cppa/match.hpp"
#include "cppa/option.hpp"
#include "cppa/pattern.hpp"
......@@ -50,7 +51,8 @@ auto tuple_cast(any_tuple const& tup, pattern<T...> const& p)
{
typedef typename pattern<T...>::filtered_types filtered_types;
typedef typename tuple_from_type_list<filtered_types>::type tuple_type;
static constexpr auto impl = detail::select_tuple_cast_impl<T...>::value;
static constexpr auto impl =
get_pattern_characteristic<util::type_list<T...>>();
return detail::tuple_cast_impl<impl, tuple_type, T...>::_(tup, p);
}
......@@ -67,7 +69,8 @@ auto tuple_cast(any_tuple const& tup)
{
typedef decltype(tuple_cast<T...>(tup)) result_type;
typedef typename result_type::value_type tuple_type;
static constexpr auto impl = detail::select_tuple_cast_impl<T...>::value;
static constexpr auto impl =
get_pattern_characteristic<util::type_list<T...>>();
return detail::tuple_cast_impl<impl, tuple_type, T...>::_(tup);
}
......
......@@ -73,9 +73,7 @@ class fixed_vector
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) { }
fixed_vector(fixed_vector const& other) : m_size(other.m_size)
{
......@@ -120,12 +118,6 @@ class fixed_vector
m_data[m_size++] = what;
}
inline void push_back(T&& what)
{
CPPA_REQUIRE(!full());
m_data[m_size++] = std::move(what);
}
inline reference at(size_type pos)
{
CPPA_REQUIRE(pos < m_size);
......@@ -140,11 +132,13 @@ class fixed_vector
inline reference operator[](size_type pos)
{
CPPA_REQUIRE(pos < m_size);
return at(pos);
}
inline const_reference operator[](size_type pos) const
{
CPPA_REQUIRE(pos < m_size);
return at(pos);
}
......@@ -165,12 +159,12 @@ class fixed_vector
inline iterator end()
{
return (static_cast<iterator>(m_data) + m_size);
return begin() + m_size;
}
inline const_iterator end() const
{
return (static_cast<const_iterator>(m_data) + m_size);
return begin() + m_size;
}
inline const_iterator cend() const
......@@ -222,13 +216,13 @@ class fixed_vector
inline reference back()
{
CPPA_REQUIRE(m_size > 0);
CPPA_REQUIRE(!empty());
return m_data[m_size - 1];
}
inline const_reference back() const
{
CPPA_REQUIRE(m_size > 0);
CPPA_REQUIRE(!empty());
return m_data[m_size - 1];
}
......
......@@ -378,6 +378,7 @@ struct tl_prepend<type_list<T...>, What>
// list list::filter(predicate)
// list list::filter_not(predicate)
template<class List, bool... Selected>
struct tl_filter_impl;
......
......@@ -48,4 +48,6 @@ bool abstract_tuple::equals(const abstract_tuple &other) const
return true;
}
abstract_tuple::abstract_tuple(abstract_tuple const&) : ref_counted() { }
} } // namespace cppa::detail
......@@ -32,6 +32,7 @@ size_t test__tuple()
CPPA_TEST(test__tuple);
// check type correctness of make_tuple()
auto t0 = make_tuple("1", 2);
CPPA_CHECK((std::is_same<decltype(t0), cppa::tuple<std::string, int>>::value));
auto t0_0 = get<0>(t0);
auto t0_1 = get<1>(t0);
// check implicit type conversion
......@@ -51,12 +52,24 @@ size_t test__tuple()
{
auto& v0 = *v0opt;
CPPA_CHECK((std::is_same<decltype(v0), tuple<std::string>&>::value));
auto& v0_0 = get<0>(v0);
CPPA_CHECK((std::is_same<decltype(v0_0), std::string const&>::value));
CPPA_CHECK((std::is_same<decltype(get<0>(v0)), std::string const&>::value));
CPPA_CHECK_EQUAL(v0.size(), 1);
CPPA_CHECK_EQUAL(v0_0, "1");
CPPA_CHECK_EQUAL(get<0>(v0), "1");
CPPA_CHECK_EQUAL(get<0>(t0), get<0>(v0));
// check cow semantics
cout << " t0: " << t0.vals().get() << endl
<< " v0: " << v0.vals().get() << endl
<< "*v0: " << dynamic_cast<detail::decorated_tuple<std::string> const*>(v0.vals().get())->decorated().get() << endl
<< "at0: " << at0.vals().get() << endl;
cout << "&get<0>(t0): " << (&get<0>(t0)) << endl
<< "&get<0>(v0): " << (&get<0>(v0)) << endl
<< " at0.at(0): " << (at0.at(0)) << endl;
CPPA_CHECK_EQUAL(&get<0>(t0), &get<0>(v0)); // point to the same
get_ref<0>(t0) = "hello world"; // detaches t0 from v0
CPPA_CHECK_EQUAL(get<0>(t0), "hello world"); // t0 contains new value
......
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