Commit a7a39a66 authored by Dominik Charousset's avatar Dominik Charousset

Fix interface checking in typed actors

parent ec70ae90
...@@ -78,53 +78,27 @@ struct ctm_cmp<typed_mpi<In, L, R>, ...@@ -78,53 +78,27 @@ struct ctm_cmp<typed_mpi<In, L, R>,
typed_mpi<In, R, empty_type_list>> typed_mpi<In, R, empty_type_list>>
: std::true_type { }; : std::true_type { };
template <class A, class B, int Pos = 0> template <class Xs, class Ys>
struct ctm_impl { // : std::integral_constant<int, -2> { constexpr int ctm_impl(int pos) {
// -2 means: to few message handlers defined return tl_empty<Xs>::value
static constexpr int value = (tl_size<A>::value < tl_size<B>::value) ? -1 // consumed each X
? -2 : (tl_exists<Ys, tbind<ctm_cmp, typename tl_head<Xs>::type>::template type>::value
: -3; ? ctm_impl<typename tl_tail<Xs>::type, Ys>(pos + 1)
}; : pos);
}
template <int Pos>
struct ctm_impl<empty_type_list, empty_type_list, Pos> template <class Xs, class Ys>
: std::integral_constant<int, -1> {
// everything's fine, -1 means: no mismatch found (both sets are empty)
};
template <class X, class... Xs, class... Ys, int Pos>
struct ctm_impl<type_list<X, Xs...>, type_list<Ys...>, Pos> {
using next_ys =
typename tl_filter_not<
type_list<Ys...>,
tbind<ctm_cmp, X>::template type
>::type;
static constexpr int value =
// check if filter_not did remove something
sizeof...(Ys) == tl_size<next_ys>::value
? Pos // error at this position
: ctm_impl<type_list<Xs...>, next_ys, Pos + 1>::value;
};
template <class X, class... Xs, class... Ys, int Pos>
constexpr int ctm_impl<type_list<X, Xs...>, type_list<Ys...>, Pos>::value;
template <class X, class Y>
struct ctm { struct ctm {
// -3 means too many handler, -2 means too few, -1 means OK, everything else // -3 means too many handler, -2 means too few, -1 means OK, everything else
// mismatch at that position // mismatch at that position
static constexpr size_t num_xs = tl_size<X>::value; static constexpr size_t num_xs = tl_size<Xs>::value;
static constexpr size_t num_ys = tl_size<Y>::value; static constexpr size_t num_ys = tl_size<Ys>::value;
/* static constexpr int value = num_xs == num_ys ? ctm_impl<Xs, Ys>(0)
static constexpr int value = num_xs != num_ys : (num_xs < num_ys ? -2 : -3);
? num_xs > num_ys ? -3 : -2
: ctm_impl<X, Y, 0>::value;
*/
static constexpr int value = ctm_impl<X, Y, 0>::value;
}; };
template <class X, class Y> template <class Xs, class Ys>
constexpr int ctm<X,Y>::value; constexpr int ctm<Xs, Ys>::value;
} // namespace detail } // namespace detail
} // namespace caf } // namespace caf
......
...@@ -135,30 +135,30 @@ struct type_checker<type_pair<Opt1, Opt2>, F1, F2> { ...@@ -135,30 +135,30 @@ struct type_checker<type_pair<Opt1, Opt2>, F1, F2> {
} }
}; };
template <int X, int Pos> template <int X, int Pos, class A>
struct static_error_printer { struct static_error_printer {
static_assert(X != Pos, "unexpected handler some position > 20"); static_assert(X != Pos, "unexpected handler some position > 20");
}; };
template <int X> template <int X, class A>
struct static_error_printer<X, -3> { struct static_error_printer<X, -3, A> {
static_assert(X == -1, "too few message handlers defined"); static_assert(X == -1, "too few message handlers defined");
}; };
template <int X> template <int X, class A>
struct static_error_printer<X, -2> { struct static_error_printer<X, -2, A> {
static_assert(X == -1, "too many message handlers defined"); static_assert(X == -1, "too many message handlers defined");
}; };
template <int X> template <int X, class A>
struct static_error_printer<X, -1> { struct static_error_printer<X, -1, A> {
// everything' fine // everything' fine
}; };
#define CAF_STATICERR(Pos) \ #define CAF_STATICERR(Pos) \
template <int X> \ template <int X, class A> \
struct static_error_printer< X, Pos > { \ struct static_error_printer< X, Pos, A > { \
static_assert(X == -1, "unexpected handler at position " #Pos ); \ static_assert(X == -1, "unexpected handler at position " #Pos ); \
} }
...@@ -174,7 +174,8 @@ template <class A, class B, template <class, class> class Predicate> ...@@ -174,7 +174,8 @@ template <class A, class B, template <class, class> class Predicate>
struct static_asserter { struct static_asserter {
static void verify_match() { static void verify_match() {
static constexpr int x = Predicate<A, B>::value; static constexpr int x = Predicate<A, B>::value;
static_error_printer<x, x> dummy; using type_at_x = typename tl_at<B, (x < 0 ? 0 : x)>::type;
static_error_printer<x, x, type_at_x> dummy;
static_cast<void>(dummy); static_cast<void>(dummy);
} }
}; };
......
...@@ -219,6 +219,8 @@ private: ...@@ -219,6 +219,8 @@ private:
detail::type_list<typename detail::deduce_mpi<Ts>::type...>, detail::type_list<typename detail::deduce_mpi<Ts>::type...>,
detail::is_hidden_msg_handler detail::is_hidden_msg_handler
>::type; >::type;
static_assert(detail::tl_is_distinct<mpi>::value,
"multiple handler defintions found");
detail::static_asserter<signatures, mpi, detail::ctm>::verify_match(); detail::static_asserter<signatures, mpi, detail::ctm>::verify_match();
// final (type-erasure) step // final (type-erasure) step
intrusive_ptr<detail::behavior_impl> ptr = std::move(bp); intrusive_ptr<detail::behavior_impl> ptr = std::move(bp);
......
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