Commit f0cd281c authored by neverlord's avatar neverlord

optimized matching impl

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