Commit 71d7e003 authored by neverlord's avatar neverlord

maintenance

parent 7c297747
......@@ -36,7 +36,6 @@
#include "cppa/config.hpp"
#include "cppa/ref_counted.hpp"
#include "cppa/type_value_pair.hpp"
#include "cppa/uniform_type_info.hpp"
#include "cppa/util/type_list.hpp"
......@@ -166,8 +165,6 @@ class abstract_tuple : public ref_counted
inline const_iterator& operator*() { return *this; }
//inline operator type_value_pair() const { return {type(), value()}; }
};
inline const_iterator begin() const { return {this}; }
......
......@@ -185,6 +185,11 @@ struct tdata<>
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>
......
......@@ -177,11 +177,10 @@ struct invoke_policy_impl<wildcard_position::nil, Pattern, util::type_list<Ts...
return shortcut_failed;
}
static bool can_invoke(std::type_info const& arg_types,
detail::abstract_tuple const&)
template<class Tuple>
static bool can_invoke(std::type_info const& arg_types, Tuple const&)
{
return arg_types == typeid(filtered_pattern);
}
template<class Target, typename PtrType, typename Tuple>
......@@ -256,11 +255,13 @@ struct invoke_policy_impl<wildcard_position::leading,
util::type_list<anything>,
util::type_list<> >
{
template<class Tuple>
static inline bool can_invoke(std::type_info const&,
detail::abstract_tuple const&)
Tuple const&)
{
return true;
}
template<class Target, typename PtrType, class Tuple>
static bool invoke(Target& target,
std::type_info const&,
......@@ -277,8 +278,9 @@ struct invoke_policy_impl<wildcard_position::trailing, Pattern, util::type_list<
{
typedef util::type_list<Ts...> filtered_pattern;
template<class Tuple>
static bool can_invoke(std::type_info const& arg_types,
detail::abstract_tuple const& tup)
Tuple const& tup)
{
if (arg_types == typeid(filtered_pattern))
{
......@@ -797,14 +799,6 @@ class projected_fun
static constexpr bool has_manipulator =
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>
projected_fun(Args&&... args) : m_leaves(std::forward<Args>(args)...)
{
......@@ -821,28 +815,104 @@ class projected_fun
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;
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
mutable size_t m_cache_begin;
mutable size_t m_cache_end;
size_t m_cache_begin;
size_t m_cache_end;
mutable cache_element m_dummy;
cache_element m_dummy;
static inline void advance_(size_t& i)
{
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))
{
......@@ -851,15 +921,18 @@ class projected_fun
return m_cache_end;
}
typename cache_entry::iterator get_cache_entry(std::type_info const* type_token,
detail::abstract_tuple const& value) const
template<class Tuple>
cache_entry_iterator get_cache_entry(std::type_info const* type_token,
Tuple const& value)
{
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);
// if we didn't found a cache entry ...
if (i == m_cache_end)
{
if (value.impl_type() == detail::statically_typed)
{
// ... 'create' one
advance_(m_cache_end);
......@@ -870,20 +943,19 @@ class projected_fun
util::static_foreach<0, eval_order::size>
::_(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();
}
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>
bool _do_invoke(AbstractTuple& vals, NativeDataPtr ndp) const
bool _do_invoke(AbstractTuple& vals, NativeDataPtr ndp)
{
std::type_info const* type_token = vals.type_token();
auto enabled_begin = get_cache_entry(type_token, vals);
......@@ -898,92 +970,19 @@ class projected_fun
vals);
}
bool _invoke(any_tuple const& tup) const
bool _invoke(any_tuple const& tup)
{
auto const& cvals = *(tup.cvals());
return _do_invoke(cvals, cvals.native_data());
}
bool _invoke(any_tuple& tup) const
bool _invoke(any_tuple& tup)
{
tup.force_detach();
auto& vals = *(tup.vals());
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>
......@@ -1021,18 +1020,12 @@ pj_concat(Arg0 const& arg0, Args const&... args)
>::type
>::type
all_leaves;
collect_tdata(all_leaves, arg0.m_leaves, args.m_leaves...);
collect_tdata(all_leaves, arg0.leaves(), args.leaves()...);
return {all_leaves};
}
#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>
struct vg_fwd_
{
......@@ -1354,7 +1347,7 @@ size_t test__tuple()
CPPA_CHECK_NOT_INVOKED(f02, (2, 1));
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);
invoked = "";
......@@ -1391,13 +1384,13 @@ size_t test__tuple()
CPPA_CHECK_NOT_INVOKED(f07, (0));
CPPA_CHECK_NOT_INVOKED(f07, (1));
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;
auto f08 = _on<int>() >> [&](int& mref) { mref = 8; invoked = "f08"; };
CPPA_CHECK_INVOKED(f08, (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_EQUAL(8, f08_any_val.get_as<int>(0));
......@@ -1406,7 +1399,7 @@ size_t test__tuple()
CPPA_CHECK_NOT_INVOKED(f09, ("hello lambda", f09_val));
CPPA_CHECK_INVOKED(f09, ("0", 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_EQUAL(9, f09_any_val.get_as<int>(1));
f09_any_val.get_as_mutable<int>(1) = 666;
......@@ -1468,6 +1461,8 @@ size_t test__tuple()
CPPA_CHECK(f11("10"));
CPPA_CHECK_EQUAL(10, f11_fun);
exit(0);
auto old_pf =
(
on(42) >> []() { },
......@@ -1653,18 +1648,18 @@ size_t test__tuple()
//VERBOSE(f0(make_cow_tuple(1, 2)));
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_any_tuple(3, 2)));
VERBOSE(f0.invoke(make_any_tuple(1.f)));
VERBOSE(f0.invoke(make_cow_tuple(2, 2)));
VERBOSE(f0.invoke(make_cow_tuple(3, 2)));
VERBOSE(f0.invoke(make_cow_tuple(1.f)));
auto f1 = cfun<token1>([](float, int) { cout << "f1!" << endl; }, _x1 < 6, tofloat);
VERBOSE(f1.invoke(make_any_tuple(5, 6)));
VERBOSE(f1.invoke(make_any_tuple(6, 7)));
VERBOSE(f1.invoke(make_cow_tuple(5, 6)));
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(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