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

maintenance

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