Commit 71d7e003 authored by neverlord's avatar neverlord

maintenance

parent 7c297747
...@@ -36,7 +36,6 @@ ...@@ -36,7 +36,6 @@
#include "cppa/config.hpp" #include "cppa/config.hpp"
#include "cppa/ref_counted.hpp" #include "cppa/ref_counted.hpp"
#include "cppa/type_value_pair.hpp"
#include "cppa/uniform_type_info.hpp" #include "cppa/uniform_type_info.hpp"
#include "cppa/util/type_list.hpp" #include "cppa/util/type_list.hpp"
...@@ -166,8 +165,6 @@ class abstract_tuple : public ref_counted ...@@ -166,8 +165,6 @@ class abstract_tuple : public ref_counted
inline const_iterator& operator*() { return *this; } inline const_iterator& operator*() { return *this; }
//inline operator type_value_pair() const { return {type(), value()}; }
}; };
inline const_iterator begin() const { return {this}; } inline const_iterator begin() const { return {this}; }
......
...@@ -185,6 +185,11 @@ struct tdata<> ...@@ -185,6 +185,11 @@ struct tdata<>
inline bool operator==(tdata const&) const { return true; } inline bool operator==(tdata const&) const { return true; }
inline tuple_impl_info impl_type() const
{
return statically_typed;
}
}; };
template<bool IsBoxed, bool IsFunction, typename Head, typename T> template<bool IsBoxed, bool IsFunction, typename Head, typename T>
......
...@@ -177,11 +177,10 @@ struct invoke_policy_impl<wildcard_position::nil, Pattern, util::type_list<Ts... ...@@ -177,11 +177,10 @@ struct invoke_policy_impl<wildcard_position::nil, Pattern, util::type_list<Ts...
return shortcut_failed; return shortcut_failed;
} }
static bool can_invoke(std::type_info const& arg_types, template<class Tuple>
detail::abstract_tuple const&) static bool can_invoke(std::type_info const& arg_types, Tuple const&)
{ {
return arg_types == typeid(filtered_pattern); return arg_types == typeid(filtered_pattern);
} }
template<class Target, typename PtrType, typename Tuple> template<class Target, typename PtrType, typename Tuple>
...@@ -256,11 +255,13 @@ struct invoke_policy_impl<wildcard_position::leading, ...@@ -256,11 +255,13 @@ struct invoke_policy_impl<wildcard_position::leading,
util::type_list<anything>, util::type_list<anything>,
util::type_list<> > util::type_list<> >
{ {
template<class Tuple>
static inline bool can_invoke(std::type_info const&, static inline bool can_invoke(std::type_info const&,
detail::abstract_tuple const&) Tuple const&)
{ {
return true; return true;
} }
template<class Target, typename PtrType, class Tuple> template<class Target, typename PtrType, class Tuple>
static bool invoke(Target& target, static bool invoke(Target& target,
std::type_info const&, std::type_info const&,
...@@ -277,8 +278,9 @@ struct invoke_policy_impl<wildcard_position::trailing, Pattern, util::type_list< ...@@ -277,8 +278,9 @@ struct invoke_policy_impl<wildcard_position::trailing, Pattern, util::type_list<
{ {
typedef util::type_list<Ts...> filtered_pattern; typedef util::type_list<Ts...> filtered_pattern;
template<class Tuple>
static bool can_invoke(std::type_info const& arg_types, static bool can_invoke(std::type_info const& arg_types,
detail::abstract_tuple const& tup) Tuple const& tup)
{ {
if (arg_types == typeid(filtered_pattern)) if (arg_types == typeid(filtered_pattern))
{ {
...@@ -797,14 +799,6 @@ class projected_fun ...@@ -797,14 +799,6 @@ class projected_fun
static constexpr bool has_manipulator = static constexpr bool has_manipulator =
util::tl_exists<leaves_list, is_manipulator_leaf>::value; util::tl_exists<leaves_list, is_manipulator_leaf>::value;
void init()
{
m_dummy.second.fill(true);
m_cache.resize(cache_size);
for(size_t i = 0; i < cache_size; ++i) m_cache[i].first = nullptr;
m_cache_begin = m_cache_end = 0;
}
template<typename... Args> template<typename... Args>
projected_fun(Args&&... args) : m_leaves(std::forward<Args>(args)...) projected_fun(Args&&... args) : m_leaves(std::forward<Args>(args)...)
{ {
...@@ -821,28 +815,104 @@ class projected_fun ...@@ -821,28 +815,104 @@ class projected_fun
init(); init();
} }
typedef std::array<bool, eval_order::size> cache_entry; bool invoke(any_tuple const& tup)
{
if (has_manipulator)
return invoke(any_tuple{tup});
return _invoke(tup);
}
typedef std::pair<std::type_info const*, cache_entry> cache_element; bool invoke(any_tuple& tup)
{
if (!has_manipulator)
return _invoke(static_cast<any_tuple const&>(tup));
return _invoke(tup);
}
//mutable std::vector<cache_element> m_cache; bool invoke(any_tuple&& tup)
{
any_tuple tmp{tup};
return invoke(tmp);
}
template<typename... Args>
bool operator()(Args&&... args)
{
typedef detail::tdata<typename pj_fwd<has_manipulator, Args>::type...>
tuple_type;
// applies implicit conversions etc
tuple_type tup{std::forward<Args>(args)...};
auto& type_token = typeid(typename tuple_type::types);
auto enabled_begin = get_cache_entry(&type_token, tup);
typedef typename util::if_else_c<
has_manipulator,
tuple_type&,
util::wrapped<tuple_type const&>
>::type
ref_type;
typedef typename util::if_else_c<
has_manipulator,
void*,
util::wrapped<void const*>
>::type
ptr_type;
eval_order token;
invoke_helper<decltype(m_leaves), decltype(enabled_begin)> fun{m_leaves, enabled_begin};
return util::static_foreach<0, eval_order::size>
::eval_or(token,
fun,
type_token,
detail::statically_typed,
static_cast<ptr_type>(nullptr),
static_cast<ref_type>(tup));
}
template<class... Rhs>
projected_fun<Leaves..., Rhs...>
or_else(projected_fun<Rhs...> const& other) const
{
detail::tdata<ge_reference_wrapper<Leaves>...,
ge_reference_wrapper<Rhs>... > all_leaves;
collect_tdata(all_leaves, m_leaves, other.leaves());
return {all_leaves};
}
inline detail::tdata<Leaves...> const& leaves() const
{
return m_leaves;
}
private:
// structure: tdata< tdata<type_list<...>, ...>,
// tdata<type_list<...>, ...>,
// ...>
detail::tdata<Leaves...> m_leaves;
static constexpr size_t cache_size = 10; static constexpr size_t cache_size = 10;
typedef std::array<bool, eval_order::size> cache_entry;
typedef typename cache_entry::iterator cache_entry_iterator;
typedef std::pair<std::type_info const*, cache_entry> cache_element;
mutable util::fixed_vector<cache_element, cache_size> m_cache;
util::fixed_vector<cache_element, cache_size> m_cache;
// ring buffer like access to m_cache // ring buffer like access to m_cache
mutable size_t m_cache_begin; size_t m_cache_begin;
mutable size_t m_cache_end; size_t m_cache_end;
mutable cache_element m_dummy; cache_element m_dummy;
static inline void advance_(size_t& i) static inline void advance_(size_t& i)
{ {
i = (i + 1) % cache_size; i = (i + 1) % cache_size;
} }
inline size_t find_token_pos(std::type_info const* type_token) const inline size_t find_token_pos(std::type_info const* type_token)
{ {
for (size_t i = m_cache_begin ; i != m_cache_end; advance_(i)) for (size_t i = m_cache_begin ; i != m_cache_end; advance_(i))
{ {
...@@ -851,15 +921,18 @@ class projected_fun ...@@ -851,15 +921,18 @@ class projected_fun
return m_cache_end; return m_cache_end;
} }
typename cache_entry::iterator get_cache_entry(std::type_info const* type_token, template<class Tuple>
detail::abstract_tuple const& value) const cache_entry_iterator get_cache_entry(std::type_info const* type_token,
Tuple const& value)
{ {
CPPA_REQUIRE(type_token != nullptr); CPPA_REQUIRE(type_token != nullptr);
if (value.impl_type() == detail::dynamically_typed)
{
return m_dummy.second.begin();
}
size_t i = find_token_pos(type_token); size_t i = find_token_pos(type_token);
// if we didn't found a cache entry ... // if we didn't found a cache entry ...
if (i == m_cache_end) if (i == m_cache_end)
{
if (value.impl_type() == detail::statically_typed)
{ {
// ... 'create' one // ... 'create' one
advance_(m_cache_end); advance_(m_cache_end);
...@@ -870,20 +943,19 @@ class projected_fun ...@@ -870,20 +943,19 @@ class projected_fun
util::static_foreach<0, eval_order::size> util::static_foreach<0, eval_order::size>
::_(token, fun, *type_token, value); ::_(token, fun, *type_token, value);
} }
else
{
// return "dummy" cache entry with all functions enabled
// (dynamically typed tuple)
return m_dummy.second.begin();
}
// m_cache is always sorted,
// due to emplace(upper_bound, ...) insertions
}
return m_cache[i].second.begin(); return m_cache[i].second.begin();
} }
void init()
{
m_dummy.second.fill(true);
m_cache.resize(cache_size);
for(size_t i = 0; i < cache_size; ++i) m_cache[i].first = nullptr;
m_cache_begin = m_cache_end = 0;
}
template<typename AbstractTuple, typename NativeDataPtr> template<typename AbstractTuple, typename NativeDataPtr>
bool _do_invoke(AbstractTuple& vals, NativeDataPtr ndp) const bool _do_invoke(AbstractTuple& vals, NativeDataPtr ndp)
{ {
std::type_info const* type_token = vals.type_token(); std::type_info const* type_token = vals.type_token();
auto enabled_begin = get_cache_entry(type_token, vals); auto enabled_begin = get_cache_entry(type_token, vals);
...@@ -898,92 +970,19 @@ class projected_fun ...@@ -898,92 +970,19 @@ class projected_fun
vals); vals);
} }
bool _invoke(any_tuple const& tup) const bool _invoke(any_tuple const& tup)
{ {
auto const& cvals = *(tup.cvals()); auto const& cvals = *(tup.cvals());
return _do_invoke(cvals, cvals.native_data()); return _do_invoke(cvals, cvals.native_data());
} }
bool _invoke(any_tuple& tup) const bool _invoke(any_tuple& tup)
{ {
tup.force_detach(); tup.force_detach();
auto& vals = *(tup.vals()); auto& vals = *(tup.vals());
return _do_invoke(vals, vals.mutable_native_data()); return _do_invoke(vals, vals.mutable_native_data());
} }
bool invoke(any_tuple const& tup) const
{
if (has_manipulator)
return invoke(any_tuple{tup});
return _invoke(tup);
}
bool invoke(any_tuple& tup) const
{
if (!has_manipulator)
return _invoke(static_cast<any_tuple const&>(tup));
return _invoke(tup);
}
bool invoke(any_tuple&& tup) const
{
any_tuple tmp{tup};
return invoke(tmp);
}
template<typename... Args>
bool operator()(Args&&... args) const
{
return invoke(make_cow_tuple(std::forward<Args>(args)...));
/*
typedef detail::tdata<typename pj_fwd<has_manipulator, Args>::type...>
tuple_type;
// applies implicit conversions etc
tuple_type tup{std::forward<Args>(args)...};
typedef typename util::if_else_c<
has_manipulator,
tuple_type&,
util::wrapped<tuple_type const&>
>::type
ref_type;
typedef typename util::if_else_c<
has_manipulator,
void*,
util::wrapped<void const*>
>::type
ptr_type;
eval_order token;
invoke_helper<decltype(m_leaves)> fun{m_leaves};
return util::static_foreach<0, eval_order::size>
::eval_or(token,
fun,
typeid(util::type_list<typename util::rm_ref<Args>::type...>),
detail::statically_typed,
static_cast<ptr_type>(nullptr),
static_cast<ref_type>(tup));
*/
}
template<class... Rhs>
projected_fun<Leaves..., Rhs...>
or_else(projected_fun<Rhs...> const& other) const
{
detail::tdata<ge_reference_wrapper<Leaves>...,
ge_reference_wrapper<Rhs>... > all_leaves;
collect_tdata(all_leaves, m_leaves, other.m_leaves);
return {all_leaves};
}
//private:
// structure: tdata< tdata<type_list<...>, ...>,
// tdata<type_list<...>, ...>,
// ...>
detail::tdata<Leaves...> m_leaves;
}; };
template<class List> template<class List>
...@@ -1021,18 +1020,12 @@ pj_concat(Arg0 const& arg0, Args const&... args) ...@@ -1021,18 +1020,12 @@ pj_concat(Arg0 const& arg0, Args const&... args)
>::type >::type
>::type >::type
all_leaves; all_leaves;
collect_tdata(all_leaves, arg0.m_leaves, args.m_leaves...); collect_tdata(all_leaves, arg0.leaves(), args.leaves()...);
return {all_leaves}; return {all_leaves};
} }
#define VERBOSE(LineOfCode) cout << #LineOfCode << " = " << (LineOfCode) << endl #define VERBOSE(LineOfCode) cout << #LineOfCode << " = " << (LineOfCode) << endl
template<typename... Args>
any_tuple make_any_tuple(Args&&... args)
{
return make_cow_tuple(std::forward<Args>(args)...);
}
template<bool IsFun, typename T> template<bool IsFun, typename T>
struct vg_fwd_ struct vg_fwd_
{ {
...@@ -1354,7 +1347,7 @@ size_t test__tuple() ...@@ -1354,7 +1347,7 @@ size_t test__tuple()
CPPA_CHECK_NOT_INVOKED(f02, (2, 1)); CPPA_CHECK_NOT_INVOKED(f02, (2, 1));
CPPA_CHECK_INVOKED(f02, (42, 21)); CPPA_CHECK_INVOKED(f02, (42, 21));
CPPA_CHECK(f02.invoke(make_any_tuple(42, 21))); CPPA_CHECK(f02.invoke(make_cow_tuple(42, 21)));
CPPA_CHECK_EQUAL("f02", invoked); CPPA_CHECK_EQUAL("f02", invoked);
invoked = ""; invoked = "";
...@@ -1391,13 +1384,13 @@ size_t test__tuple() ...@@ -1391,13 +1384,13 @@ size_t test__tuple()
CPPA_CHECK_NOT_INVOKED(f07, (0)); CPPA_CHECK_NOT_INVOKED(f07, (0));
CPPA_CHECK_NOT_INVOKED(f07, (1)); CPPA_CHECK_NOT_INVOKED(f07, (1));
CPPA_CHECK_INVOKED(f07, (2)); CPPA_CHECK_INVOKED(f07, (2));
CPPA_CHECK(f07.invoke(make_any_tuple(2))); CPPA_CHECK(f07.invoke(make_cow_tuple(2)));
int f08_val = 666; int f08_val = 666;
auto f08 = _on<int>() >> [&](int& mref) { mref = 8; invoked = "f08"; }; auto f08 = _on<int>() >> [&](int& mref) { mref = 8; invoked = "f08"; };
CPPA_CHECK_INVOKED(f08, (f08_val)); CPPA_CHECK_INVOKED(f08, (f08_val));
CPPA_CHECK_EQUAL(8, f08_val); CPPA_CHECK_EQUAL(8, f08_val);
any_tuple f08_any_val = make_any_tuple(666); any_tuple f08_any_val = make_cow_tuple(666);
CPPA_CHECK(f08.invoke(f08_any_val)); CPPA_CHECK(f08.invoke(f08_any_val));
CPPA_CHECK_EQUAL(8, f08_any_val.get_as<int>(0)); CPPA_CHECK_EQUAL(8, f08_any_val.get_as<int>(0));
...@@ -1406,7 +1399,7 @@ size_t test__tuple() ...@@ -1406,7 +1399,7 @@ size_t test__tuple()
CPPA_CHECK_NOT_INVOKED(f09, ("hello lambda", f09_val)); CPPA_CHECK_NOT_INVOKED(f09, ("hello lambda", f09_val));
CPPA_CHECK_INVOKED(f09, ("0", f09_val)); CPPA_CHECK_INVOKED(f09, ("0", f09_val));
CPPA_CHECK_EQUAL(9, f09_val); CPPA_CHECK_EQUAL(9, f09_val);
any_tuple f09_any_val = make_any_tuple("0", 666); any_tuple f09_any_val = make_cow_tuple("0", 666);
CPPA_CHECK(f09.invoke(f09_any_val)); CPPA_CHECK(f09.invoke(f09_any_val));
CPPA_CHECK_EQUAL(9, f09_any_val.get_as<int>(1)); CPPA_CHECK_EQUAL(9, f09_any_val.get_as<int>(1));
f09_any_val.get_as_mutable<int>(1) = 666; f09_any_val.get_as_mutable<int>(1) = 666;
...@@ -1468,6 +1461,8 @@ size_t test__tuple() ...@@ -1468,6 +1461,8 @@ size_t test__tuple()
CPPA_CHECK(f11("10")); CPPA_CHECK(f11("10"));
CPPA_CHECK_EQUAL(10, f11_fun); CPPA_CHECK_EQUAL(10, f11_fun);
exit(0);
auto old_pf = auto old_pf =
( (
on(42) >> []() { }, on(42) >> []() { },
...@@ -1653,18 +1648,18 @@ size_t test__tuple() ...@@ -1653,18 +1648,18 @@ size_t test__tuple()
//VERBOSE(f0(make_cow_tuple(1, 2))); //VERBOSE(f0(make_cow_tuple(1, 2)));
VERBOSE(f0(3, 3)); VERBOSE(f0(3, 3));
VERBOSE(f0.invoke(make_any_tuple(3, 3))); VERBOSE(f0.invoke(make_cow_tuple(3, 3)));
VERBOSE(f0.invoke(make_any_tuple(2, 2))); VERBOSE(f0.invoke(make_cow_tuple(2, 2)));
VERBOSE(f0.invoke(make_any_tuple(3, 2))); VERBOSE(f0.invoke(make_cow_tuple(3, 2)));
VERBOSE(f0.invoke(make_any_tuple(1.f))); VERBOSE(f0.invoke(make_cow_tuple(1.f)));
auto f1 = cfun<token1>([](float, int) { cout << "f1!" << endl; }, _x1 < 6, tofloat); auto f1 = cfun<token1>([](float, int) { cout << "f1!" << endl; }, _x1 < 6, tofloat);
VERBOSE(f1.invoke(make_any_tuple(5, 6))); VERBOSE(f1.invoke(make_cow_tuple(5, 6)));
VERBOSE(f1.invoke(make_any_tuple(6, 7))); VERBOSE(f1.invoke(make_cow_tuple(6, 7)));
auto i2 = make_any_tuple(1, 2); auto i2 = make_cow_tuple(1, 2);
VERBOSE(f0.invoke(*i2.vals()->type_token(), i2.vals()->impl_type(), i2.vals()->native_data(), *(i2.vals()))); VERBOSE(f0.invoke(*i2.vals()->type_token(), i2.vals()->impl_type(), i2.vals()->native_data(), *(i2.vals())));
VERBOSE(f1.invoke(*i2.vals()->type_token(), i2.vals()->impl_type(), i2.vals()->native_data(), *(i2.vals()))); VERBOSE(f1.invoke(*i2.vals()->type_token(), i2.vals()->impl_type(), i2.vals()->native_data(), *(i2.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