Commit e4a39512 authored by neverlord's avatar neverlord

on_param_match()

parent 4af5605a
......@@ -103,6 +103,7 @@ nobase_library_include_HEADERS = \
cppa/detail/empty_tuple.hpp \
cppa/detail/get_behavior.hpp \
cppa/detail/group_manager.hpp \
cppa/detail/implicit_conversions.hpp \
cppa/detail/intermediate.hpp \
cppa/detail/invokable.hpp \
cppa/detail/list_member.hpp \
......@@ -184,6 +185,7 @@ nobase_library_include_HEADERS = \
cppa/util/fixed_vector.hpp \
cppa/util/has_copy_member_fun.hpp \
cppa/util.hpp \
cppa/util/is_array_of.hpp \
cppa/util/if_else.hpp \
cppa/util/is_comparable.hpp \
cppa/util/is_copyable.hpp \
......
......@@ -228,3 +228,5 @@ cppa/pattern.hpp
cppa/detail/pattern_details.hpp
unit_testing/test__pattern.cpp
cppa/util/fixed_vector.hpp
cppa/detail/implicit_conversions.hpp
cppa/util/is_array_of.hpp
#ifndef IMPLICIT_CONVERSIONS_HPP
#define IMPLICIT_CONVERSIONS_HPP
#include <string>
#include <type_traits>
#include "cppa/actor.hpp"
#include "cppa/util/is_array_of.hpp"
#include "cppa/util/replace_type.hpp"
namespace cppa { class local_actor; }
namespace cppa { namespace detail {
template<typename T>
struct implicit_conversions
{
typedef typename util::replace_type<T, std::string,
std::is_same<T, const char*>,
std::is_same<T, char*>,
util::is_array_of<T, char>,
util::is_array_of<T, const char> >::type
subtype1;
typedef typename util::replace_type<subtype1, std::u16string,
std::is_same<subtype1, const char16_t*>,
std::is_same<subtype1, char16_t*>,
util::is_array_of<subtype1, char16_t>>::type
subtype2;
typedef typename util::replace_type<subtype2, std::u32string,
std::is_same<subtype2, const char32_t*>,
std::is_same<subtype2, char32_t*>,
util::is_array_of<subtype2, char32_t>>::type
subtype3;
typedef typename util::replace_type<subtype3, actor_ptr,
std::is_same<actor*,T>,
std::is_same<local_actor*,T>>::type
type;
};
} } // namespace cppa::detail
#endif // IMPLICIT_CONVERSIONS_HPP
......@@ -11,14 +11,18 @@
#include "cppa/any_tuple.hpp"
#include "cppa/invoke_rules.hpp"
#include "cppa/util/type_list.hpp"
#include "cppa/util/duration.hpp"
#include "cppa/util/eval_first_n.hpp"
#include "cppa/util/callable_trait.hpp"
#include "cppa/util/type_list_apply.hpp"
#include "cppa/util/filter_type_list.hpp"
#include "cppa/detail/boxed.hpp"
#include "cppa/detail/unboxed.hpp"
#include "cppa/detail/invokable.hpp"
#include "cppa/detail/ref_counted_impl.hpp"
#include "cppa/detail/implicit_conversions.hpp"
namespace cppa { namespace detail {
......@@ -46,23 +50,20 @@ template<typename... TypeList>
class invoke_rule_builder
{
typedef pattern<TypeList...> pattern_type;
typedef typename util::type_list_apply<util::type_list<TypeList...>,
detail::implicit_conversions>::type
converted_type_list;
typedef typename pattern_type_from_type_list<converted_type_list>::type
pattern_type;
//typedef pattern<TypeList...> pattern_type;
typedef std::unique_ptr<pattern_type> pattern_ptr_type;
pattern_ptr_type m_pattern;
typedef typename pattern_type::tuple_view_type tuple_view_type;
/*
typedef cppa::util::type_list<TypeList...> plain_types;
typedef typename cppa::util::filter_type_list<anything, plain_types>::type
filtered_types;
typedef typename cppa::tuple_view_type_from_type_list<filtered_types>::type
tuple_view_type;
*/
public:
template<typename... Args>
......@@ -80,6 +81,29 @@ class invoke_rule_builder
};
class on_the_fly_invoke_rule_builder
{
public:
template<typename F>
invoke_rules operator>>(F&& f)
{
typedef typename util::get_callable_trait<F>::type ctrait;
typedef typename ctrait::arg_types raw_types;
static_assert(raw_types::size > 0, "functor has no arguments");
typedef typename util::type_list_apply<raw_types, util::rm_ref>::type
types;
typedef typename pattern_type_from_type_list<types>::type
pattern_type;
typedef typename pattern_type::tuple_view_type tuple_view_type;
typedef invokable_impl<tuple_view_type, pattern_type, F> impl;
std::unique_ptr<pattern_type> pptr(new pattern_type);
return invokable_ptr(new impl(std::move(pptr), std::forward<F>(f)));
}
};
} } // cppa::detail
namespace cppa {
......@@ -93,6 +117,11 @@ constexpr typename detail::boxed<T>::type val()
//constexpr detail::boxed<anything> any_vals = detail::boxed<anything>();
constexpr anything any_vals = anything();
constexpr detail::on_the_fly_invoke_rule_builder on_param_match()
{
return { };
}
template<typename Arg0, typename... Args>
detail::invoke_rule_builder<typename detail::unboxed<Arg0>::type,
typename detail::unboxed<Args>::type...>
......
......@@ -9,6 +9,9 @@
#include "cppa/any_tuple.hpp"
#include "cppa/uniform_type_info.hpp"
#include "cppa/util/type_list.hpp"
#include "cppa/util/type_list_apply.hpp"
#include "cppa/detail/tdata.hpp"
#include "cppa/detail/pattern_details.hpp"
......@@ -81,6 +84,15 @@ class pattern<T0, Tn...>
};
template<typename TypeList>
struct pattern_type_from_type_list;
template<typename... Types>
struct pattern_type_from_type_list<util::type_list<Types...>>
{
typedef pattern<Types...> type;
};
} // namespace cppa
#endif // PATTERN_HPP
......@@ -20,59 +20,13 @@
#include "cppa/util/is_legal_tuple_type.hpp"
#include "cppa/detail/tuple_vals.hpp"
namespace cppa { class local_actor; }
namespace cppa { namespace detail {
/**
* @brief <tt>is_array_of<T,U>::value == true</tt> if and only
* if T is an array of U.
*/
template<typename T, typename U>
struct is_array_of
{
typedef typename std::remove_all_extents<T>::type step1_type;
typedef typename std::remove_cv<step1_type>::type step2_type;
static const bool value = std::is_array<T>::value
&& std::is_same<step2_type, U>::value;
};
template<typename T>
struct chars_to_string
{
typedef typename util::replace_type<T, std::string,
std::is_same<T, const char*>,
std::is_same<T, char*>,
is_array_of<T, char>,
is_array_of<T, const char> >::type
subtype1;
typedef typename util::replace_type<subtype1, std::u16string,
std::is_same<subtype1, const char16_t*>,
std::is_same<subtype1, char16_t*>,
is_array_of<subtype1, char16_t>>::type
subtype2;
typedef typename util::replace_type<subtype2, std::u32string,
std::is_same<subtype2, const char32_t*>,
std::is_same<subtype2, char32_t*>,
is_array_of<subtype2, char32_t>>::type
subtype3;
typedef typename util::replace_type<subtype3, actor_ptr,
std::is_same<actor*,T>,
std::is_same<local_actor*,T>>::type
type;
};
} } // namespace cppa::detail
#include "cppa/detail/implicit_conversions.hpp"
namespace cppa {
// forward declaration
class any_tuple;
class local_actor;
/**
* @brief Describes a fixed-length tuple.
......@@ -189,8 +143,8 @@ struct tuple_type_from_type_list<util::type_list<Types...>>
template<typename... Types>
typename tuple_type_from_type_list<
typename util::type_list_apply<util::type_list<Types...>,
detail::chars_to_string>::type>::type
typename util::type_list_apply<util::type_list<Types...>,
detail::implicit_conversions>::type>::type
make_tuple(const Types&... args)
{
return { args... };
......
#ifndef CPPA_UTIL_CALLABLE_TRAIT
#define CPPA_UTIL_CALLABLE_TRAIT
#include <type_traits>
#include "cppa/util/type_list.hpp"
namespace cppa { namespace util {
......@@ -36,6 +38,30 @@ struct callable_trait<ResultType (*)(Args...)>
typedef type_list<Args...> arg_types;
};
template<bool IsFun, bool IsMemberFun, typename C>
struct get_callable_trait_helper
{
typedef callable_trait<C> type;
};
template<typename C>
struct get_callable_trait_helper<false, false, C>
{
typedef callable_trait<decltype(&C::operator())> type;
};
template<typename C>
struct get_callable_trait
{
typedef typename
get_callable_trait_helper<
( std::is_function<C>::value
|| std::is_function<typename std::remove_pointer<C>::type>::value),
std::is_member_function_pointer<C>::value,
C>::type
type;
};
} } // namespace cppa::util
#endif // CPPA_UTIL_CALLABLE_TRAIT
#ifndef IS_ARRAY_OF_HPP
#define IS_ARRAY_OF_HPP
#include <type_traits>
namespace cppa { namespace util {
/**
* @brief <tt>is_array_of<T,U>::value == true</tt> if and only
* if T is an array of U.
*/
template<typename T, typename U>
struct is_array_of
{
typedef typename std::remove_all_extents<T>::type step1_type;
typedef typename std::remove_cv<step1_type>::type step2_type;
static const bool value = std::is_array<T>::value
&& std::is_same<step2_type, U>::value;
};
} } // namespace cppa::util
#endif // IS_ARRAY_OF_HPP
......@@ -42,57 +42,75 @@ void fun(const std::string&)
size_t test__tuple()
{
CPPA_TEST(test__tuple);
bool p1_invoked = false;
bool p2_invoked = false;
bool p3_invoked = false;
bool p4_invoked = false;
auto reset_invoke_states = [&]() {
p1_invoked = p2_invoked = p3_invoked = p4_invoked = false;
constexpr size_t num_patterns = 6;
bool pattern_invoked[num_patterns];
auto reset_invoke_states = [&]()
{
for (size_t i = 0; i < num_patterns; ++i)
{
pattern_invoked[i] = false;
}
};
reset_invoke_states();
auto patterns =
(
on<int, anything, int>() >> [&](int v1, int v2)
{
CPPA_CHECK_EQUAL(v1, 1);
CPPA_CHECK_EQUAL(v2, 3);
p1_invoked = true;
pattern_invoked[0] = true;
},
on<std::string>() >> [&](const std::string& str)
{
CPPA_CHECK_EQUAL(str, "hello foo");
p2_invoked = true;
pattern_invoked[1] = true;
},
on(std::string("1"), val<int>(), any_vals) >> [&]()
on("1", val<int>(), any_vals) >> [&](int value)
{
p3_invoked = true;
CPPA_CHECK_EQUAL(value, 2);
pattern_invoked[2] = true;
},
//on<int, std::string, anything>() >> [&](const std::string& str)
on(1, val<std::string>(), any_vals) >> [&](const std::string& str)
{
CPPA_CHECK_EQUAL(str, "2");
p4_invoked = true;
pattern_invoked[3] = true;
},
on<atom("Foo"), int>() >> [&](int value)
{
CPPA_CHECK_EQUAL(value, 1);
pattern_invoked[4] = true;
},
on_param_match() >> [&](double v1, const float& v2)
{
CPPA_CHECK_EQUAL(v1, 1.0);
CPPA_CHECK_EQUAL(v2, 2.0f);
pattern_invoked[5] = true;
}
);
patterns(make_tuple(1, "2", 3));
CPPA_CHECK(p1_invoked);
CPPA_CHECK(pattern_invoked[0]);
reset_invoke_states();
patterns(make_tuple("hello foo"));
CPPA_CHECK(p2_invoked);
CPPA_CHECK(pattern_invoked[1]);
reset_invoke_states();
patterns(make_tuple("1", 2, 3));
CPPA_CHECK(p3_invoked);
CPPA_CHECK(pattern_invoked[2]);
reset_invoke_states();
patterns(make_tuple(1, "2", "3"));
CPPA_CHECK(p4_invoked);
CPPA_CHECK(pattern_invoked[3]);
reset_invoke_states();
patterns(make_tuple(atom("Foo"), 1));
CPPA_CHECK(pattern_invoked[4]);
reset_invoke_states();
patterns(make_tuple(1.0, 2.0f));
CPPA_CHECK(pattern_invoked[5]);
reset_invoke_states();
/*
......
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