Commit f812b653 authored by neverlord's avatar neverlord

maintenance

parent a2a4e20d
......@@ -67,8 +67,7 @@ struct abstract_tuple : ref_counted
bool equals(abstract_tuple const& other) const;
// iterator support
class const_iterator //: public std::iterator<std::bidirectional_iterator_tag,
// type_value_pair>
class const_iterator
{
size_t m_pos;
......
......@@ -80,17 +80,19 @@ class invokable
template<class Tuple, class Pattern>
struct abstract_invokable : public invokable
{
std::unique_ptr<Pattern> m_pattern;
abstract_invokable(std::unique_ptr<Pattern>&& pptr) : m_pattern(std::move(pptr))
Pattern m_pattern;
abstract_invokable() { }
template<typename... Args>
abstract_invokable(Args&&... args) : m_pattern(std::forward<Args>(args)...)
{
}
bool types_match(any_tuple const& value) const
{
return match_types(value, *m_pattern);
return match_types(value, m_pattern);
}
bool could_invoke(any_tuple const& value) const
{
return match(value, *m_pattern);
return match(value, m_pattern);
}
};
......@@ -135,30 +137,30 @@ class invokable_impl : public abstract_invokable<Tuple, Pattern>
public:
template<typename F>
invokable_impl(F&& fun, std::unique_ptr<Pattern>&& pptr)
: super(std::move(pptr)), m_iimpl(std::forward<F>(fun))
template<typename F, typename... Args>
invokable_impl(F&& fun, Args&&... args)
: super(std::forward<Args>(args)...), m_iimpl(std::forward<F>(fun))
{
}
bool invoke(any_tuple const& value) const
{
return invoke_impl(tuple_cast(value, *(this->m_pattern)));
return invoke_impl(tuple_cast(value, this->m_pattern));
}
bool unsafe_invoke(any_tuple const& value) const
{
return invoke_impl(unsafe_tuple_cast(value, *(this->m_pattern)));
return invoke_impl(unsafe_tuple_cast(value, this->m_pattern));
}
intermediate* get_intermediate(any_tuple const& value)
{
return get_intermediate_impl(tuple_cast(value, *(this->m_pattern)));
return get_intermediate_impl(tuple_cast(value, this->m_pattern));
}
intermediate* get_unsafe_intermediate(any_tuple const& value)
{
return get_intermediate_impl(unsafe_tuple_cast(value, *(this->m_pattern)));
return get_intermediate_impl(unsafe_tuple_cast(value, this->m_pattern));
}
};
......@@ -168,19 +170,18 @@ struct invokable_impl<false, NumArgs, Fun, Tuple, Pattern> : public invokable_im
{
typedef invokable_impl<true, NumArgs, Fun, Tuple, Pattern> super;
template<typename F>
invokable_impl(F&& fun, std::unique_ptr<Pattern>&& pptr)
: super(std::forward<F>(fun), std::move(pptr))
invokable_impl(F&& fun) : super(std::forward<F>(fun))
{
}
bool unsafe_invoke(any_tuple const& value) const
{
auto tup = forced_tuple_cast(value, *(this->m_pattern));
auto tup = forced_tuple_cast(value, this->m_pattern);
util::apply_tuple((this->m_iimpl).m_fun, tup);
return true;
}
intermediate* get_unsafe_intermediate(any_tuple const& value)
{
(this->m_iimpl).m_args = forced_tuple_cast(value, *(this->m_pattern));
(this->m_iimpl).m_args = forced_tuple_cast(value, this->m_pattern);
return &(this->m_iimpl);
}
};
......@@ -210,26 +211,26 @@ class invokable_impl<true, 0, Fun, Tuple, Pattern> : public abstract_invokable<T
public:
template<typename F>
invokable_impl(F&& fun, std::unique_ptr<Pattern>&& pptr)
: super(std::move(pptr)), m_iimpl(std::forward<F>(fun))
template<typename F, typename... Args>
invokable_impl(F&& fun, Args&&... args)
: super(std::forward<Args>(args)...), m_iimpl(std::forward<F>(fun))
{
}
bool invoke(any_tuple const& data) const
{
return match(data, *(this->m_pattern)) ? m_iimpl() : false;
return match(data, this->m_pattern) ? m_iimpl() : false;
}
bool unsafe_invoke(any_tuple const& value) const
{
return unsafe_vmatch(value, *(this->m_pattern)) ? m_iimpl() : false;
return unsafe_vmatch(value, this->m_pattern) ? m_iimpl() : false;
}
intermediate* get_intermediate(any_tuple const& value)
{
return match(value, *(this->m_pattern)) ? &m_iimpl : nullptr;
return match(value, this->m_pattern) ? &m_iimpl : nullptr;
}
intermediate* get_unsafe_intermediate(any_tuple const& value)
{
return unsafe_vmatch(value, *(this->m_pattern)) ? &m_iimpl : nullptr;
return unsafe_vmatch(value, this->m_pattern) ? &m_iimpl : nullptr;
}
};
......@@ -259,17 +260,19 @@ struct select_invokable_impl
typedef invokable_impl<false, arg_types::size, Fun, tuple_type, Pattern> type2;
};
template<typename Fun, class Pattern>
std::unique_ptr<invokable> get_invokable_impl(Fun&& fun,
std::unique_ptr<Pattern>&& pptr)
template<class Pattern, typename Fun, typename Data>
std::unique_ptr<invokable> get_invokable_impl(Fun&& fun, Data&& dt)
{
typedef select_invokable_impl<Fun, Pattern> result;
bool check_values = pptr->has_values();
typedef typename select_invokable_impl<Fun, Pattern>::type1 result;
return std::unique_ptr<invokable>(
check_values ? new typename result::type1(std::forward<Fun>(fun),
std::move(pptr))
: new typename result::type2(std::forward<Fun>(fun),
std::move(pptr)));
new result(std::forward<Fun>(fun), std::forward<Data>(dt)));
}
template<class Pattern, typename Fun>
std::unique_ptr<invokable> get_invokable_impl(Fun&& fun)
{
typedef typename select_invokable_impl<Fun, Pattern>::type2 result;
return std::unique_ptr<invokable>(new result(std::forward<Fun>(fun)));
}
} } // namespace cppa::detail
......
......@@ -64,6 +64,10 @@ struct tdata<>
constexpr tdata() { }
inline tdata(tdata&&) { }
inline tdata(tdata const&) { }
// swallow "arg_match" silently
constexpr tdata(util::wrapped<util::arg_match_t> const&) { }
......@@ -87,10 +91,7 @@ struct tdata<>
throw std::out_of_range("");
}
inline bool operator==(tdata const&) const
{
return true;
}
inline bool operator==(tdata const&) const { return true; }
};
......@@ -183,6 +184,9 @@ struct tdata<option<Head>, Tail...> : tdata<Tail...>
template<typename... Args>
tdata(util::wrapped<Head> const&, Args const&... vals) : super(vals...) { }
tdata(tdata<>&&) : super(), head() { }
tdata(tdata<> const&) : super(), head() { }
// allow (partial) initialization from a different tdata
template<typename... Y>
tdata(tdata<Y...> const& other) : super(other.tail()), head(other.head) { }
......
......@@ -101,12 +101,17 @@ class rvalue_builder
typedef typename pattern_from_type_list<converted_types>::type
pattern_type;
std::unique_ptr<pattern_type> m_ptr;
typedef typename pattern_type::data_type pattern_data;
pattern_data m_data;
bool m_has_values;
template<typename F>
partial_function cr_rvalue(F&& f, std::integral_constant<bool, true>)
{
return get_invokable_impl(std::forward<F>(f), std::move(m_ptr));
return m_has_values ? get_invokable_impl<pattern_type>(std::forward<F>(f),
std::move(m_data))
: get_invokable_impl<pattern_type>(std::forward<F>(f));
}
template<typename F>
......@@ -119,15 +124,19 @@ class rvalue_builder
typedef typename tl_apply<raw_types,rm_ref>::type new_types;
typedef typename tl_concat<converted_types,new_types>::type types;
typedef typename pattern_from_type_list<types>::type epattern;
std::unique_ptr<epattern> pptr(extend_pattern<epattern>(m_ptr.get()));
return get_invokable_impl(std::forward<F>(f), std::move(pptr));
return m_has_values ? get_invokable_impl<epattern>(std::forward<F>(f),
std::move(m_data))
: get_invokable_impl<epattern>(std::forward<F>(f));
}
public:
template<typename... Args>
rvalue_builder(Args const&... args) : m_ptr(new pattern_type(args...))
rvalue_builder(Args&&... args) : m_data(std::forward<Args>(args)...)
{
static constexpr bool all_boxed =
util::tl_forall<util::type_list<Args...>, is_boxed>::value;
m_has_values = !all_boxed;
}
......@@ -158,8 +167,7 @@ class on_the_fly_rvalue_builder
static_assert(raw_types::size > 0, "functor has no arguments");
typedef typename tl_apply<raw_types,rm_ref>::type types;
typedef typename pattern_from_type_list<types>::type pattern_type;
std::unique_ptr<pattern_type> pptr(new pattern_type);
return get_invokable_impl(std::forward<F>(f), std::move(pptr));
return get_invokable_impl<pattern_type>(std::forward<F>(f));
}
};
......
......@@ -85,11 +85,11 @@ template<typename... Types>
class pattern
{
static_assert(sizeof...(Types) > 0, "empty pattern");
template<class ExtendedType, class BasicType>
friend ExtendedType* extend_pattern(BasicType const* p);
static_assert(sizeof...(Types) > 0, "empty pattern");
pattern(pattern const&) = delete;
pattern& operator=(pattern const&) = delete;
......@@ -102,6 +102,8 @@ class pattern
typedef util::type_list<Types...> types;
typedef typename types::head head_type;
typedef typename util::tl_filter_not<types, is_anything>::type
filtered_types;
......@@ -113,9 +115,9 @@ class pattern
typedef std::reverse_iterator<const_iterator> reverse_const_iterator;
inline const_iterator begin() const { return m_ptrs; }
inline const_iterator begin() const { return std::begin(m_ptrs); }
inline const_iterator end() const { return m_ptrs + size; }
inline const_iterator end() const { return std::end(m_ptrs); }
inline reverse_const_iterator rbegin() const
{
......@@ -127,10 +129,10 @@ class pattern
return reverse_const_iterator{begin()};
}
inline const_iterator vbegin() const { return m_vbegin; }
inline const_iterator vend() const { return m_vend; }
inline bool has_values() const { return m_has_values; }
pattern() : m_has_values(false)
{
auto& arr = detail::static_types_array<Types...>::arr;
......@@ -139,20 +141,52 @@ class pattern
m_ptrs[i].first = arr[i];
m_ptrs[i].second = nullptr;
}
m_vbegin = m_vend = begin();
m_vend = begin();
}
template<typename... Args>
pattern(head_type const& arg0, Args&&... args)
: m_data(arg0, std::forward<Args>(args)...)
{
init<head_type, Args...>();
}
template<typename... Args>
pattern(head_type&& arg0, Args&&... args)
: m_data(std::move(arg0), std::forward<Args>(args)...)
{
init<head_type, Args...>();
}
template<typename... Args>
pattern(util::wrapped<head_type> const& arg0, Args const&... args)
: m_data(arg0, std::forward<Args>(args)...)
{
init<util::wrapped<head_type>, Args...>();
}
template<typename... Args>
pattern(detail::tdata<Args...> const& data) : m_data(data)
{
init<Args...>();
}
template<typename... Args>
pattern(detail::tdata<Args...>&& data) : m_data(std::move(data))
{
init<Args...>();
}
typedef detail::tdata<option<Types>...> data_type;
private:
template<typename Arg0, typename... Args>
pattern(Arg0 const& arg0, Args const&... args) : m_data(arg0, args...)
void init()
{
using std::is_same;
using namespace util;
static constexpr bool all_boxed =
util::tl_forall<type_list<Arg0, Args...>,
detail::is_boxed >::value;
m_has_values = !all_boxed;
typedef typename type_list<Arg0, Args...>::back arg_n;
static constexpr bool ignore_arg_n = is_same<arg_n, arg_match_t>::value;
typedef typename util::type_list<Arg0, Args...>::back arg_n;
static constexpr bool ignore_arg_n =
std::is_same<arg_n, util::arg_match_t>::value;
// ignore extra arg_match_t argument
static constexpr size_t args_size = sizeof...(Args)
+ (ignore_arg_n ? 0 : 1);
......@@ -168,49 +202,40 @@ class pattern
m_ptrs[i].first = arr[i];
m_ptrs[i].second = nullptr;
}
init_value_iterators();
init_vend();
m_has_values = (vend() != begin());
}
inline bool has_values() const { return m_has_values; }
private:
typedef type_value_pair tvp_array[size];
// a polymophic functor
struct init_helper
{
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()) { }
size_t i;
tvp_array& m_ptrs;
detail::types_array<Types...>& m_arr;
init_helper(tvp_array& ptrs, detail::types_array<Types...>& tarr)
: i(0), m_ptrs(ptrs), m_arr(tarr) { }
template<typename T>
void operator()(option<T> const& what)
inline void operator()(option<T> const& what)
{
iter_to->first = iter_from.type();
iter_to->second = (what) ? &(*what) : nullptr;
++iter_to;
++iter_from;
m_ptrs[i].first = m_arr[i];
m_ptrs[i].second = (what) ? &(*what) : nullptr;
++i;
}
};
void init_value_iterators()
{
auto pred = [](type_value_pair const& tvp) { return tvp.second != 0; };
auto last = end();
m_vbegin = std::find_if(begin(), last, pred);
if (m_vbegin == last)
{
m_vbegin = m_vend = begin();
}
else
inline void init_vend()
{
m_vend = std::find_if(rbegin(), rend(), pred).base();
}
m_vend = std::find_if(
rbegin(), rend(),
[](type_value_pair const& tvp) { return tvp.second != 0; }
).base();
}
detail::tdata<option<Types>...> m_data;
bool m_has_values;
type_value_pair m_ptrs[size];
const_iterator m_vbegin;
detail::tdata<option<Types>...> m_data;
tvp_array m_ptrs;
const_iterator m_vend;
};
......@@ -230,7 +255,7 @@ ExtendedType* extend_pattern(BasicType const* p)
auto& arr = tarr::arr;
typename ExtendedType::init_helper f(et->m_ptrs, arr);
util::static_foreach<0, BasicType::size>::_(et->m_data, f);
et->init_value_iterators();
et->init_vend();
}
return et;
}
......
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