54 template<
class T,
class... Ts>
55 struct are_bare_types<std::tuple<T, Ts...>>
57 static const bool value =
58 ! std::is_reference<T>::value
59 && are_bare_types<Ts...>::value;
63 struct are_bare_types<std::tuple<T>>
65 static const bool value =
66 ! std::is_reference<T>::value;
70 template<
class T,
class U>
75 template<
class T,
class... Ts>
76 struct is_within<T, std::tuple<T, Ts...>>
80 template<
class T,
class U,
class... Ts>
81 struct is_within<T, std::tuple<U, Ts...>>
82 : is_within<T, std::tuple<Ts...>>
88 : action_traits<decltype(&std::remove_reference_t<F>::operator())>
91 template<
class R,
class T,
class... As>
92 struct action_traits<R (T::*)(As...)>
93 : action_traits<R (T::*)(As...) const>
96 template<
class R,
class T,
class... As>
97 struct action_traits<R (T::*)(As...) const>
99 static constexpr auto arity =
sizeof...(As);
101 using result_type = R;
104 using arg_type = std::tuple_element_t<I, std::tuple<As...>>;
109 using arg0_type =
typename action_traits<F>::template arg_type<0>;
112 template<
class T,
class F,
class... Fs>
113 struct are_actions_allowed
115 static const bool value =
116 is_within<std::remove_reference_t<arg0_type<F>>, T>::value
117 && are_actions_allowed<T, Fs...>::value;
120 template<
class T,
class F>
121 struct are_actions_allowed<T, F>
123 static const bool value =
124 is_within<std::remove_reference_t<arg0_type<F>>, T>::value;
130 static_assert(are_bare_types<visitable_types>::value
131 ,
"Visitable types cannot be references");
136 -> std::enable_if_t<is_within<T, visitable_types>::value,
void>
138 if (std::get<action_type<T>>(actions))
140 std::get<action_type<T>>(actions)(t);
146 template<
class... Fs>
150 ,
"Unexpected action passed");
152 fill_in(actions, std::forward<Fs>(fs)...);
161 template<
class T,
class F>
162 static void assign_action(T&& t, F&& f)
164 std::get<action_type<arg0_type<F>>>(std::forward<T>(t)) = std::forward<F>(f);
167 template<
class T,
class... Fs>
168 static void fill_in(T&& t, Fs&&... fs)
170 int dummy[
sizeof...(Fs)] =
171 { (assign_action(std::forward<T>(t), std::forward<Fs>(fs)), 0)... };
178 using action_type = std::function<void (T&)>;
181 struct make_action_types;
183 template<
class... Ts>
184 struct make_action_types<std::tuple<Ts...>>
186 using type = std::tuple<action_type<Ts>...>;
190 using action_types =
typename make_action_types<visitable_types>::type;
192 action_types actions;