Commit f0cd281c authored by neverlord's avatar neverlord

optimized matching impl

parent 7c9b8cf5
......@@ -96,6 +96,11 @@ struct abstract_tuple : ref_counted
return *this;
}
inline const_iterator operator+(size_t offset)
{
return {m_tuple, m_pos + offset};
}
inline size_t position() const { return m_pos; }
void const* value() const { return m_tuple.at(m_pos); }
......
......@@ -58,18 +58,17 @@ class decorated_tuple : public abstract_tuple
typedef util::fixed_vector<size_t, sizeof...(ElementTypes)> vector_type;
typedef cow_ptr<abstract_tuple> ptr_type;
typedef cow_ptr<abstract_tuple> cow_pointer_type;
using abstract_tuple::const_iterator;
decorated_tuple(ptr_type&& d, vector_type const& v) : m_decorated(std::move(d))
static cow_pointer_type create(cow_pointer_type d, vector_type const& v)
{
init(v);
return {(new decorated_tuple(std::move(d)))->init(v)};
}
decorated_tuple(ptr_type const& d, vector_type const& v) : m_decorated(d)
// creates a subtuple form @p d with sizeof...(ElementTypes) elements
static cow_pointer_type create(cow_pointer_type d)
{
init(v);
return {(new decorated_tuple(std::move(d)))->init()};
}
virtual void* mutable_at(size_t pos)
......@@ -108,9 +107,13 @@ class decorated_tuple : public abstract_tuple
private:
ptr_type m_decorated;
cow_pointer_type m_decorated;
type_value_pair m_data[sizeof...(ElementTypes)];
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)
......@@ -119,8 +122,9 @@ class decorated_tuple : public abstract_tuple
std::copy(other.begin(), other.end(), m_data);
}
void init(vector_type const& v)
decorated_tuple* init(vector_type const& v)
{
CPPA_REQUIRE(m_decorated->size() >= sizeof...(ElementTypes));
CPPA_REQUIRE(v.size() == sizeof...(ElementTypes));
CPPA_REQUIRE(*(std::max_element(v.begin(), v.end())) < m_decorated->size());
for (size_t i = 0; i < sizeof...(ElementTypes); ++i)
......@@ -129,6 +133,19 @@ class decorated_tuple : public abstract_tuple
m_data[i].first = m_decorated->type_at(x);
m_data[i].second = m_decorated->at(x);
}
return this;
}
decorated_tuple* init()
{
CPPA_REQUIRE(m_decorated->size() >= sizeof...(ElementTypes));
// copy first n elements
for (size_t i = 0; i < sizeof...(ElementTypes); ++i)
{
m_data[i].first = m_decorated->type_at(i);
m_data[i].second = m_decorated->at(i);
}
return this;
}
decorated_tuple& operator=(decorated_tuple const&) = delete;
......
......@@ -117,8 +117,11 @@ class pattern
+ (ignore_arg_n ? 0 : 1);
static_assert(args_size <= size, "too many arguments");
auto& arr = detail::static_types_array<Types...>::arr;
functor f(*this, arr);
// "polymophic lambda"
init_helper f(m_ptrs, arr);
// init elements [0, N)
util::static_foreach<0, args_size>::_(m_data, f);
// init elements [N, size)
for (size_t i = args_size; i < size; ++i)
{
m_ptrs[i].first = arr[i];
......@@ -130,23 +133,19 @@ class pattern
private:
struct functor;
friend class functor;
struct functor
struct init_helper
{
pattern& p;
detail::types_array<Types...>& arr;
size_t i;
functor(pattern& pp, detail::types_array<Types...>& tarr)
: p(pp), arr(tarr), i(0) { }
type_value_pair* iter_to;
type_value_pair_const_iterator iter_from;
init_helper(type_value_pair* pp, detail::types_array<Types...>& tarr)
: iter_to(pp), iter_from(tarr.begin()) { }
template<typename T>
void operator()(option<T> const& what)
{
p.m_ptrs[i].first = arr[i];
p.m_ptrs[i].second = (what) ? &(*what) : nullptr;
++i;
iter_to->first = iter_from.type();
iter_to->second = (what) ? &(*what) : nullptr;
++iter_to;
++iter_from;
}
};
......
......@@ -76,19 +76,18 @@ class tuple
friend class any_tuple;
typedef detail::tuple_vals<ElementTypes...> data_type;
typedef detail::decorated_tuple<ElementTypes...> decorated_type;
cow_ptr<detail::abstract_tuple> m_vals;
struct ptr_ctor { };
struct priv_ctor { };
template<typename CowPtr>
tuple(ptr_ctor const&, CowPtr&& ptr) : m_vals(std::forward<CowPtr>(ptr))
{
}
tuple(priv_ctor, cow_ptr<detail::abstract_tuple>&& ptr) : m_vals(std::move(ptr)) { }
public:
typedef util::type_list<ElementTypes...> types;
typedef cow_ptr<detail::abstract_tuple> cow_ptr_type;
static constexpr size_t num_elements = sizeof...(ElementTypes);
......@@ -120,21 +119,24 @@ class tuple
tuple& operator=(tuple&&) = default;
tuple& operator=(tuple const&) = default;
static tuple from(cow_ptr<detail::abstract_tuple>&& ptr)
static tuple from(cow_ptr_type ptr)
{
if (ptr->size() == sizeof...(ElementTypes))
{
return tuple(ptr_ctor(), std::move(ptr));
// *this == *ptr
return {priv_ctor(), std::move(ptr)};
}
static tuple from(cow_ptr<detail::abstract_tuple> const& ptr)
else
{
return tuple(ptr_ctor(), ptr);
// *this is a subtuple of *ptr
return {priv_ctor(), decorated_type::create(std::move(ptr))};
}
}
static tuple from(cow_ptr<detail::abstract_tuple> const& ptr,
static tuple from(cow_ptr_type ptr,
util::fixed_vector<size_t, num_elements> const& mv)
{
return tuple(ptr_ctor(),
new detail::decorated_tuple<ElementTypes...>(ptr, mv));
return {priv_ctor(), decorated_type::create(std::move(ptr), mv)};
}
/**
......
......@@ -48,7 +48,19 @@ namespace cppa {
template<class ResultTuple, class Tuple, typename... P>
option<ResultTuple> tuple_cast_impl(Tuple const& tup, pattern<P...> const& p)
{
typedef typename pattern<P...>::filtered_types filtered_types;
typedef util::type_list<P...> types;
static constexpr int apos = util::tl_find<types, anything>::value;
// no anything in given template parameter pack
// or anything at end of template parameter pack
if (apos == -1 || apos == (sizeof...(P) - 1))
{
if (detail::matches(tup, p))
{
return {ResultTuple::from(tup.vals())};
}
}
else
{
typename pattern<P...>::mapping_vector mv;
if (detail::matches(tup, p, &mv))
{
......@@ -58,10 +70,10 @@ option<ResultTuple> tuple_cast_impl(Tuple const& tup, pattern<P...> const& p)
}
else
{
typedef typename detail::decorated_tuple_from_type_list<filtered_types>::type decorated;
return {ResultTuple::from(tup.vals(), mv)};
}
}
}
return { };
}
......@@ -69,17 +81,21 @@ option<ResultTuple> tuple_cast_impl(Tuple const& tup, pattern<P...> const& p)
template<class ResultTuple, class Tuple, typename... T>
option<ResultTuple> tuple_cast_impl(Tuple const& tup)
{
typedef util::type_list<T...> types;
static constexpr int apos = util::tl_find<types, anything>::value;
// no anything in given template parameter pack
if (util::tl_find<util::type_list<T...>, anything>::value == -1)
// or anything at end of template parameter pack
if (apos == -1 || apos == (sizeof...(T) - 1))
{
auto& tarr = detail::static_types_array<T...>::arr;
if (tup.size() == sizeof...(T))
if (tup.size() >= sizeof...(T))
{
for (size_t i = 0; i < sizeof...(T); ++i)
auto& tarr = detail::static_types_array<T...>::arr;
static constexpr int end = (apos == -1) ? sizeof...(T) : apos;
for (int i = 0; i < end; ++i)
{
if (tarr[i] != tup.type_at(i)) return { };
}
// always a perfect match
// always a perfect match or subtuple
return {ResultTuple::from(tup.vals())};
}
}
......
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