Commit 3ba13c13 authored by neverlord's avatar neverlord

optimization

parent fdb4df86
......@@ -31,24 +31,41 @@ using std::endl;
using namespace cppa;
template<typename AbstractTuple>
struct invoke_policy_helper
template<typename... T>
struct dummy_tuple
{
size_t i;
AbstractTuple& tup;
invoke_policy_helper(AbstractTuple& tp) : i(0), tup(tp) { }
template<typename T>
void operator()(ge_mutable_reference_wrapper<T>& storage)
typedef void* ptr_type;
typedef void const* const_ptr_type;
ptr_type data[sizeof...(T) > 0 ? sizeof...(T) : 1];
inline const_ptr_type at(size_t p) const
{
storage = *reinterpret_cast<T*>(tup.mutable_at(i++));
return data[p];
}
template<typename T>
void operator()(ge_mutable_reference_wrapper<const T>& storage)
inline ptr_type mutable_at(size_t p)
{
storage = *reinterpret_cast<T const*>(tup.at(i++));
return const_cast<ptr_type>(data[p]);
}
void*& operator[](size_t p)
{
return data[p];
}
};
template<size_t N, typename... Tn>
typename util::at<N, Tn...>::type const& get(dummy_tuple<Tn...> const& tv)
{
static_assert(N < sizeof...(Tn), "N >= tv.size()");
return *reinterpret_cast<typename util::at<N, Tn...>::type const*>(tv.at(N));
}
template<size_t N, typename... Tn>
typename util::at<N, Tn...>::type& get_ref(dummy_tuple<Tn...>& tv)
{
static_assert(N < sizeof...(Tn), "N >= tv.size()");
return *reinterpret_cast<typename util::at<N, Tn...>::type*>(tv.mutable_at(N));
}
template<typename T>
struct gref_wrapped
{
......@@ -101,80 +118,85 @@ struct rm_all_refs
template<wildcard_position, class Pattern, class FilteredPattern>
struct invoke_policy_impl;
template<class Pattern, class FilteredPattern>
struct invoke_policy_impl<wildcard_position::nil, Pattern, FilteredPattern>
template<class Pattern, typename... Ts>
struct invoke_policy_impl<wildcard_position::nil, Pattern, util::type_list<Ts...> >
{
typedef typename detail::tdata_from_type_list<
FilteredPattern
>::type
native_data_type;
typedef util::type_list<Ts...> filtered_pattern;
typedef typename detail::static_types_array_from_type_list<
FilteredPattern
>::type
arr_type;
typedef detail::tdata<Ts...> native_data_type;
typedef typename detail::static_types_array<Ts...> arr_type;
enum shortcut_result
{
no_shortcut_available,
shortcut_failed,
shortcut_succeeded
};
template<class Target, class Tup>
static inline bool shortcut(Target&, Tup&, bool&)
static inline shortcut_result shortcut(Target&, Tup&)
{
return false;
return no_shortcut_available;
}
template<class Target, typename... T>
static inline bool shortcut(Target& target,
static inline shortcut_result shortcut(Target& target,
detail::tdata<T...> const& tup,
bool& shortcut_result,
typename util::enable_if<
util::tl_binary_forall<
util::type_list<
typename rm_all_refs<T>::type...
>,
FilteredPattern,
filtered_pattern,
std::is_same
>
>::type* = 0)
{
shortcut_result = util::unchecked_apply_tuple<bool>(target, tup);
return true;
if (util::unchecked_apply_tuple<bool>(target, tup))
return shortcut_succeeded;
return shortcut_failed;
}
template<class Target, typename... T>
static inline bool shortcut(Target& target,
static inline shortcut_result shortcut(Target& target,
detail::tdata<T...>& tup,
bool& shortcut_result,
typename util::enable_if<
util::tl_binary_forall<
util::type_list<
typename rm_all_refs<T>::type...
>,
FilteredPattern,
filtered_pattern,
std::is_same
>
>::type* = 0)
{
//static_assert(false, "");
shortcut_result = util::unchecked_apply_tuple<bool>(target, tup);
return true;
if (util::unchecked_apply_tuple<bool>(target, tup))
return shortcut_succeeded;
return shortcut_failed;
}
template<class Target, typename NativeArg, typename Tuple>
template<class Target, typename PtrType, typename Tuple, typename ValueIter>
static bool invoke(Target& target,
std::type_info const& arg_types,
detail::tuple_impl_info timpl,
NativeArg* native_arg,
PtrType* native_arg,
ValueIter vbegin,
ValueIter vend,
Tuple& tup)
{
bool shortcut_result = false;
if (shortcut(target, tup, shortcut_result))
switch (shortcut(target, tup) )
{
return shortcut_result;
case shortcut_succeeded: return true;
case shortcut_failed: return false;
default: ; // nop
}
else if (arg_types == typeid(FilteredPattern))
if (arg_types == typeid(filtered_pattern))
{
if (native_arg)
{
typedef typename util::if_else_c<
std::is_const<NativeArg>::value,
std::is_const<PtrType>::value,
native_data_type const*,
util::wrapped<native_data_type*>
>::type
......@@ -187,11 +209,11 @@ struct invoke_policy_impl<wildcard_position::nil, Pattern, FilteredPattern>
else if (timpl == detail::dynamically_typed)
{
auto& arr = arr_type::arr;
if (tup.size() != FilteredPattern::size)
if (tup.size() != filtered_pattern::size)
{
return false;
}
for (size_t i = 0; i < FilteredPattern::size; ++i)
for (size_t i = 0; i < filtered_pattern::size; ++i)
{
if (arr[i] != tup.type_at(i))
{
......@@ -205,34 +227,19 @@ struct invoke_policy_impl<wildcard_position::nil, Pattern, FilteredPattern>
return false;
}
// either dynamically typed or statically typed but not a native tuple
typedef typename detail::tdata_from_type_list<
typename util::tl_map<
typename util::if_else<
std::is_const<Tuple>,
typename util::tl_map<Pattern, std::add_const>::type,
util::wrapped<Pattern>
>::type,
gref_mutable_wrapped
>::type
>::type
ttup_type;
typedef dummy_tuple<PtrType*, Ts...> ttup_type;
ttup_type ttup;
std::copy(vbegin, vend, std::begin(ttup.data));
// ... we restore it here again
typedef typename util::if_else<
std::is_const<Tuple>,
std::is_const<PtrType>,
ttup_type const&,
util::wrapped<ttup_type&>
>::type
ttup_ref;
//typename PolicyToken::wrapped_refs ttup;
invoke_policy_helper<Tuple> helper{tup};
util::static_foreach<0, FilteredPattern::size>::_ref(ttup, helper);
//return util::apply_tuple(target, ttup);
ttup_ref ttup_fwd = ttup;
return util::unchecked_apply_tuple<bool>(target, ttup_fwd);
return util::unchecked_apply_tuple<bool>(target, static_cast<ttup_ref>(ttup));
}
};
......@@ -241,56 +248,49 @@ struct invoke_policy_impl<wildcard_position::leading,
util::type_list<anything>,
util::type_list<> >
{
template<class Target, typename NativeArg, class Tuple>
template<class Target, typename PtrType, class Tuple, typename ValueIter>
static bool invoke(Target& target,
std::type_info const&,
detail::tuple_impl_info,
NativeArg*,
PtrType*,
ValueIter,
ValueIter,
Tuple&)
{
return target();
}
};
template<class Pattern, class FilteredPattern>
struct invoke_policy_impl<wildcard_position::trailing, Pattern, FilteredPattern>
template<class Pattern, typename... Ts>
struct invoke_policy_impl<wildcard_position::trailing, Pattern, util::type_list<Ts...> >
{
template<class Target, typename NativeArg, class Tuple>
typedef util::type_list<Ts...> filtered_pattern;
template<class Target, typename PtrType, class Tuple, typename ValueIter>
static bool invoke(Target& target,
std::type_info const&,
detail::tuple_impl_info,
NativeArg*,
PtrType*,
ValueIter vbegin,
ValueIter,
Tuple& tup)
{
typedef typename detail::static_types_array_from_type_list<
FilteredPattern
>::type
arr_type;
typedef detail::static_types_array<Ts...> arr_type;
auto& arr = arr_type::arr;
if (tup.size() < FilteredPattern::size)
if (tup.size() < filtered_pattern::size)
{
return false;
}
for (size_t i = 0; i < FilteredPattern::size; ++i)
for (size_t i = 0; i < filtered_pattern::size; ++i)
{
if (arr[i] != tup.type_at(i))
{
return false;
}
}
typedef typename detail::tdata_from_type_list<
typename util::tl_map<
typename util::if_else<
std::is_const<Tuple>,
typename util::tl_map<FilteredPattern, std::add_const>::type,
util::wrapped<FilteredPattern>
>::type,
gref_mutable_wrapped
>::type
>::type
ttup_type;
typedef dummy_tuple<Ts...> ttup_type;
ttup_type ttup;
std::copy(vbegin, (vbegin + sizeof...(Ts)), std::begin(ttup.data));
typedef typename util::if_else<
std::is_const<Tuple>,
......@@ -299,12 +299,7 @@ struct invoke_policy_impl<wildcard_position::trailing, Pattern, FilteredPattern>
>::type
ttup_ref;
//typename PolicyToken::wrapped_refs ttup;
invoke_policy_helper<Tuple> helper{tup};
util::static_foreach<0, FilteredPattern::size>::_ref(ttup, helper);
//return util::apply_tuple(target, ttup);
ttup_ref ttup_fwd = ttup;
return util::unchecked_apply_tuple<bool>(target, ttup_fwd);
return util::unchecked_apply_tuple<bool>(target, static_cast<ttup_ref>(ttup));
}
};
......@@ -674,12 +669,9 @@ struct invoke_helper
};
template<typename T>
struct is_manipulator_leaf;
template<typename First, typename Second>
struct is_manipulator_leaf<std::pair<First, Second> >
struct is_manipulator_leaf
{
static constexpr bool value = Second::manipulates_args;
static constexpr bool value = T::second_type::manipulates_args;
};
void collect_tdata(detail::tdata<>&)
......@@ -759,33 +751,55 @@ class projected_fun
projected_fun(projected_fun const&) = default;
bool _invoke(any_tuple const& tup) const
template<class Buffer, typename AbstractTuple, typename NativeDataPtr>
bool _do_invoke(Buffer& buf, AbstractTuple& vals, NativeDataPtr ndp) const
{
eval_order token;
invoke_helper<decltype(m_leaves)> fun{m_leaves};
auto& cvals = *(tup.cvals());
for (size_t i = 0; i < vals.size(); ++i)
buf.push_back(const_cast<void*>(vals.at(i)));
return util::static_foreach<0, eval_order::size>
::eval_or(token,
fun,
*(cvals.type_token()),
cvals.impl_type(),
cvals.native_data(),
cvals);
*(vals.type_token()),
vals.impl_type(),
ndp,
buf.begin(),
buf.end(),
vals);
}
bool _invoke(any_tuple const& tup) const
{
auto const& cvals = *(tup.cvals());
if (cvals.size() < 10)
{
util::fixed_vector<void*, 10> buf;
return _do_invoke(buf, cvals, cvals.native_data());
}
else
{
std::vector<void*> buf;
buf.reserve(cvals.size());
return _do_invoke(buf, cvals, cvals.native_data());
}
}
bool _invoke(any_tuple& tup) const
{
eval_order token;
invoke_helper<decltype(m_leaves)> fun{m_leaves};
tup.force_detach();
auto& vals = *(tup.vals());
return util::static_foreach<0, eval_order::size>
::eval_or(token,
fun,
*(vals.type_token()),
vals.impl_type(),
vals.mutable_native_data(),
vals);
if (vals.size() < 10)
{
util::fixed_vector<void*, 10> buf;
return _do_invoke(buf, vals, vals.mutable_native_data());
}
else
{
std::vector<void*> buf;
buf.reserve(vals.size());
return _do_invoke(buf, vals, vals.mutable_native_data());
}
}
bool invoke(any_tuple const& tup) const
......@@ -830,6 +844,10 @@ class projected_fun
>::type
ptr_type;
util::fixed_vector<void*, sizeof...(Args)> buf;
for (size_t i = 0; i < sizeof...(Args); ++i)
buf.push_back(const_cast<void*>(tup.at(i)));
eval_order token;
invoke_helper<decltype(m_leaves)> fun{m_leaves};
return util::static_foreach<0, eval_order::size>
......@@ -838,6 +856,8 @@ class projected_fun
typeid(util::type_list<typename util::rm_ref<Args>::type...>),
detail::statically_typed,
static_cast<ptr_type>(nullptr),
buf.begin(),
buf.end(),
static_cast<ref_type>(tup));
}
......@@ -1366,7 +1386,7 @@ size_t test__tuple()
make_cow_tuple(1, 2, 3)
};
constexpr size_t numInvokes = 100000000;
constexpr size_t numInvokes = 1000000;
auto xvals = make_cow_tuple(1, 2, "3");
......@@ -1482,7 +1502,7 @@ size_t test__tuple()
}
}
//exit(0);
exit(0);
/*
VERBOSE(f00(42, 42));
......
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