Skip to content

Commit 4fdc199

Browse files
author
Guilhem Codron
committed
Generate mappings with mapped and generic events in one go
Generate mappings with mapped and generic events for on_entry, on_exit and unexpected events. Remove the dual pass processing done in state_machine.hpp since the improved get_event_mapping_impl_helper directly generate the good mapping.
1 parent ca3b05d commit 4fdc199

File tree

3 files changed

+87
-76
lines changed

3 files changed

+87
-76
lines changed

include/boost/sml.hpp

Lines changed: 59 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ struct remove_reference<T &&> {
216216
};
217217
template <class T>
218218
using remove_reference_t = typename remove_reference<T>::type;
219-
}
219+
} // namespace aux
220220
namespace aux {
221221
using swallow = int[];
222222
template <int...>
@@ -480,7 +480,7 @@ auto get_type_name(const char *ptr, index_sequence<Ns...>) {
480480
static const char str[] = {ptr[N + Ns]..., 0};
481481
return str;
482482
}
483-
}
483+
} // namespace detail
484484
template <class T>
485485
const char *get_type_name() {
486486
#if defined(_MSC_VER) && !defined(__clang__)
@@ -525,7 +525,7 @@ struct string<T> {
525525
}
526526
static auto c_str_impl(...) { return get_type_name<T>(); }
527527
};
528-
}
528+
} // namespace aux
529529
namespace back {
530530
namespace policies {
531531
struct defer_queue_policy__ {};
@@ -535,8 +535,8 @@ struct defer_queue : aux::pair<back::policies::defer_queue_policy__, defer_queue
535535
using rebind = T<U>;
536536
using flag = bool;
537537
};
538-
}
539-
}
538+
} // namespace policies
539+
} // namespace back
540540
namespace back {
541541
template <class... Ts>
542542
class queue_event {
@@ -627,7 +627,7 @@ struct deque_handler : queue_event_call<TEvents>... {
627627
}
628628
void *deque_{};
629629
};
630-
}
630+
} // namespace back
631631
namespace back {
632632
struct _ {};
633633
struct initial {};
@@ -709,7 +709,7 @@ template <class... TEvents>
709709
struct defer : deque_handler<TEvents...> {
710710
using deque_handler<TEvents...>::deque_handler;
711711
};
712-
}
712+
} // namespace back
713713
namespace back {
714714
template <class>
715715
class sm;
@@ -832,7 +832,7 @@ template <class T, class... Ts>
832832
struct convert_to_sm<T, aux::type_list<Ts...>> {
833833
using type = aux::type_list<sm_impl<T>, sm_impl<typename T::template rebind<Ts>>...>;
834834
};
835-
}
835+
} // namespace back
836836
namespace back {
837837
template <class>
838838
class sm;
@@ -919,7 +919,7 @@ struct transitions_sub<sm<TSM>> {
919919
return false;
920920
}
921921
};
922-
}
922+
} // namespace back
923923
namespace back {
924924
template <class>
925925
class sm;
@@ -1011,33 +1011,38 @@ struct get_state_mapping<sm<T>, TMappings, TUnexpected> {
10111011
};
10121012
template <class T, class TMappings, class TUnexpected>
10131013
using get_state_mapping_t = typename get_state_mapping<T, TMappings, TUnexpected>::type;
1014-
template <class>
1014+
template <class...>
10151015
transitions<aux::true_type> get_event_mapping_impl(...);
10161016
template <class T, class TMappings>
10171017
TMappings get_event_mapping_impl(event_mappings<T, TMappings> *);
1018-
template <class T, class... T1Mappings, class... T2Mappings>
1019-
unique_mappings_t<T1Mappings..., T2Mappings...> get_event_mapping_impl(event_mappings<T, aux::inherit<T1Mappings...>> *,
1020-
event_mappings<_, aux::inherit<T2Mappings...>> *);
1018+
template <class T1, class T2, class... T1Mappings, class... T2Mappings>
1019+
unique_mappings_t<T1Mappings..., T2Mappings...> get_event_mapping_impl(event_mappings<T1, aux::inherit<T1Mappings...>> *,
1020+
event_mappings<T2, aux::inherit<T2Mappings...>> *);
1021+
template <class E, class _, class TMappings>
1022+
using with_default_event_mapping_t = typename aux::conditional<
1023+
aux::is_same<transitions<aux::true_type>, decltype(get_event_mapping_impl<_>((TMappings *)0))>::value,
1024+
decltype(get_event_mapping_impl<E>((TMappings *)0)),
1025+
typename aux::conditional<
1026+
aux::is_same<transitions<aux::true_type>, decltype(get_event_mapping_impl<E>((TMappings *)0))>::value,
1027+
decltype(get_event_mapping_impl<_>((TMappings *)0)),
1028+
decltype(get_event_mapping_impl<E, _>((TMappings *)0, (TMappings *)0))>::type>::type;
10211029
template <class T, class TMappings>
1022-
struct get_event_mapping_impl_helper
1023-
: aux::conditional<aux::is_same<transitions<aux::true_type>, decltype(get_event_mapping_impl<_>((TMappings *)0))>::value,
1024-
decltype(get_event_mapping_impl<T>((TMappings *)0)),
1025-
decltype(get_event_mapping_impl<T>((TMappings *)0, (TMappings *)0))>::type {};
1030+
struct get_event_mapping_impl_helper : with_default_event_mapping_t<T, _, TMappings> {};
10261031
template <class T, class TMappings>
10271032
struct get_event_mapping_impl_helper<exception<T>, TMappings> : decltype(get_event_mapping_impl<exception<T>>((TMappings *)0)) {
10281033
};
1029-
template <class T1, class T2, class TMappings>
1030-
struct get_event_mapping_impl_helper<unexpected_event<T1, T2>, TMappings>
1031-
: decltype(get_event_mapping_impl<unexpected_event<T1, T2>>((TMappings *)0)) {};
1032-
template <class T1, class T2, class TMappings>
1033-
struct get_event_mapping_impl_helper<on_entry<T1, T2>, TMappings>
1034-
: decltype(get_event_mapping_impl<on_entry<T1, T2>>((TMappings *)0)) {};
1035-
template <class T1, class T2, class TMappings>
1036-
struct get_event_mapping_impl_helper<on_exit<T1, T2>, TMappings>
1037-
: decltype(get_event_mapping_impl<on_exit<T1, T2>>((TMappings *)0)) {};
1034+
template <class E, class _, class TMappings>
1035+
struct get_event_mapping_impl_helper<unexpected_event<_, E>, TMappings>
1036+
: with_default_event_mapping_t<unexpected_event<_, E>, unexpected_event<_, _>, TMappings> {};
1037+
template <class E, class _, class TMappings>
1038+
struct get_event_mapping_impl_helper<on_entry<_, E>, TMappings>
1039+
: with_default_event_mapping_t<on_entry<_, E>, on_entry<_, _>, TMappings> {};
1040+
template <class E, class _, class TMappings>
1041+
struct get_event_mapping_impl_helper<on_exit<_, E>, TMappings>
1042+
: with_default_event_mapping_t<on_exit<_, E>, on_exit<_, _>, TMappings> {};
10381043
template <class T, class TMappings>
10391044
using get_event_mapping_t = get_event_mapping_impl_helper<T, TMappings>;
1040-
}
1045+
} // namespace back
10411046
namespace back {
10421047
namespace policies {
10431048
struct dispatch_policy__ {};
@@ -1112,8 +1117,8 @@ struct fold_expr {
11121117
}
11131118
};
11141119
#endif
1115-
}
1116-
}
1120+
} // namespace policies
1121+
} // namespace back
11171122
namespace back {
11181123
template <class>
11191124
class sm;
@@ -1180,8 +1185,8 @@ void log_guard(const aux::type<TLogger> &, TDeps &deps, const aux::zero_wrapper<
11801185
bool result) {
11811186
return static_cast<aux::pool_type<TLogger &> &>(deps).value.template log_guard<SM>(guard.get(), event, result);
11821187
}
1183-
}
1184-
}
1188+
} // namespace policies
1189+
} // namespace back
11851190
namespace back {
11861191
namespace policies {
11871192
struct process_queue_policy__ {};
@@ -1190,14 +1195,14 @@ struct process_queue : aux::pair<back::policies::process_queue_policy__, process
11901195
template <class U>
11911196
using rebind = T<U>;
11921197
};
1193-
}
1194-
}
1198+
} // namespace policies
1199+
} // namespace back
11951200
namespace back {
11961201
namespace policies {
11971202
struct testing_policy__ {};
11981203
struct testing : aux::pair<testing_policy__, testing> {};
1199-
}
1200-
}
1204+
} // namespace policies
1205+
} // namespace back
12011206
namespace back {
12021207
namespace policies {
12031208
struct thread_safety_policy__ {
@@ -1217,8 +1222,8 @@ struct thread_safe : aux::pair<thread_safety_policy__, thread_safe<TLock>> {
12171222
}
12181223
TLock lock;
12191224
};
1220-
}
1221-
}
1225+
} // namespace policies
1226+
} // namespace back
12221227
namespace back {
12231228
struct no_policy : policies::thread_safety_policy__ {
12241229
using type = no_policy;
@@ -1257,7 +1262,7 @@ struct sm_policy {
12571262
template <class T>
12581263
using rebind = typename rebind_impl<T, TPolicies...>::type;
12591264
};
1260-
}
1265+
} // namespace back
12611266
namespace concepts {
12621267
struct callable_fallback {
12631268
void operator()();
@@ -1273,15 +1278,15 @@ template <class T, class R, class TBase, class... TArgs>
12731278
struct callable<T, R (TBase::*)(TArgs...)> : aux::true_type {};
12741279
template <class T, class R, class TBase, class... TArgs>
12751280
struct callable<T, R (TBase::*)(TArgs...) const> : aux::true_type {};
1276-
}
1281+
} // namespace concepts
12771282
namespace concepts {
12781283
template <class T>
12791284
decltype(aux::declval<T>().operator()()) composable_impl(int);
12801285
template <class>
12811286
void composable_impl(...);
12821287
template <class T>
12831288
struct composable : aux::is<aux::pool, decltype(composable_impl<T>(0))> {};
1284-
}
1289+
} // namespace concepts
12851290
#if !defined(BOOST_SML_DISABLE_EXCEPTIONS)
12861291
#if !(defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND))
12871292
#define BOOST_SML_DISABLE_EXCEPTIONS true
@@ -1427,12 +1432,12 @@ struct sm_impl : aux::conditional_t<aux::is_empty<typename TSM::sm>::value, aux:
14271432
bool process_internal_event(const TEvent &event, TDeps &deps, TSubs &subs, state_t &current_state) {
14281433
policies::log_process_event<sm_t>(aux::type<logger_t>{}, deps, event);
14291434
#if BOOST_SML_DISABLE_EXCEPTIONS
1430-
return process_event_impl<get_event_mapping_t<get_mapped_t<TEvent>, mappings>>(event, deps, subs, states_t{}, current_state)
1435+
return process_event_impl<get_event_mapping_t<get_mapped_t<TEvent>, mappings>>(event, deps, subs, states_t{},
1436+
current_state);
14311437
#else
14321438
return process_event_noexcept<get_event_mapping_t<get_mapped_t<TEvent>, mappings>>(event, deps, subs, current_state,
1433-
has_exceptions{})
1439+
has_exceptions{});
14341440
#endif
1435-
|| process_internal_generic_event(event, deps, subs, current_state);
14361441
}
14371442
template <class TMappings, class TEvent, class TDeps, class TSubs, class... TStates>
14381443
bool process_event_impl(const TEvent &event, TDeps &deps, TSubs &subs, const aux::type_list<TStates...> &states,
@@ -1738,7 +1743,7 @@ class sm {
17381743
deps_t deps_;
17391744
sub_sms_t sub_sms_;
17401745
};
1741-
}
1746+
} // namespace back
17421747
namespace front {
17431748
struct operator_base {};
17441749
struct action_base {};
@@ -1970,7 +1975,7 @@ class not_ : operator_base {
19701975
private:
19711976
T g;
19721977
};
1973-
}
1978+
} // namespace front
19741979
template <class T, __BOOST_SML_REQUIRES(concepts::callable<bool, T>::value)>
19751980
auto operator!(const T &t) {
19761981
return front::not_<aux::zero_wrapper<T>>(aux::zero_wrapper<T>{t});
@@ -1999,8 +2004,8 @@ struct defer : action_base {
19992004
}
20002005
}
20012006
};
2002-
}
2003-
}
2007+
} // namespace actions
2008+
} // namespace front
20042009
using testing = back::policies::testing;
20052010
template <class T>
20062011
using logger = back::policies::logger<T>;
@@ -2026,7 +2031,7 @@ auto transitional_impl(T &&t) -> aux::always<typename T::dst_state, typename T::
20262031
decltype(T::initial), decltype(T::history)>;
20272032
template <class T>
20282033
struct transitional : decltype(transitional_impl(aux::declval<T>())) {};
2029-
}
2034+
} // namespace concepts
20302035
namespace front {
20312036
namespace actions {
20322037
struct process {
@@ -2047,8 +2052,8 @@ struct process {
20472052
return process_impl<TEvent>{event};
20482053
}
20492054
};
2050-
}
2051-
}
2055+
} // namespace actions
2056+
} // namespace front
20522057
namespace front {
20532058
template <class, class>
20542059
struct transition_eg;
@@ -2066,7 +2071,7 @@ struct event {
20662071
}
20672072
auto operator()() const { return TEvent{}; }
20682073
};
2069-
}
2074+
} // namespace front
20702075
namespace front {
20712076
struct initial_state {};
20722077
struct history_state {};
@@ -2159,7 +2164,7 @@ struct state_sm<T, aux::enable_if_t<concepts::composable<T>::value>> {
21592164
using type = state<back::sm<back::sm_policy<T>>>;
21602165
};
21612166
#endif
2162-
}
2167+
} // namespace front
21632168
namespace front {
21642169
struct internal {};
21652170
template <class, class>
@@ -2593,7 +2598,7 @@ struct transition<state<internal>, state<S2>, front::event<E>, always, none> {
25932598
}
25942599
__BOOST_SML_ZERO_SIZE_ARRAY(aux::byte);
25952600
};
2596-
}
2601+
} // namespace front
25972602
using _ = back::_;
25982603
#if !(defined(_MSC_VER) && !defined(__clang__))
25992604
template <class TEvent>
@@ -2641,7 +2646,7 @@ constexpr auto operator""_e() {
26412646
return event<aux::string<T, Chrs...>>;
26422647
}
26432648
#endif
2644-
}
2649+
} // namespace literals
26452650
__BOOST_SML_UNUSED static front::state<back::terminate_state> X;
26462651
__BOOST_SML_UNUSED static front::history_state H;
26472652
__BOOST_SML_UNUSED static front::actions::defer defer;

include/boost/sml/back/mappings.hpp

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -135,37 +135,43 @@ struct get_state_mapping<sm<T>, TMappings, TUnexpected> {
135135
template <class T, class TMappings, class TUnexpected>
136136
using get_state_mapping_t = typename get_state_mapping<T, TMappings, TUnexpected>::type;
137137

138-
template <class>
138+
template <class...>
139139
transitions<aux::true_type> get_event_mapping_impl(...);
140140

141141
template <class T, class TMappings>
142142
TMappings get_event_mapping_impl(event_mappings<T, TMappings> *);
143143

144-
template <class T, class... T1Mappings, class... T2Mappings>
145-
unique_mappings_t<T1Mappings..., T2Mappings...> get_event_mapping_impl(event_mappings<T, aux::inherit<T1Mappings...>> *,
146-
event_mappings<_, aux::inherit<T2Mappings...>> *);
144+
template <class T1, class T2, class... T1Mappings, class... T2Mappings>
145+
unique_mappings_t<T1Mappings..., T2Mappings...> get_event_mapping_impl(event_mappings<T1, aux::inherit<T1Mappings...>> *,
146+
event_mappings<T2, aux::inherit<T2Mappings...>> *);
147+
148+
template <class E, class _, class TMappings>
149+
using with_default_event_mapping_t = typename aux::conditional<
150+
aux::is_same<transitions<aux::true_type>, decltype(get_event_mapping_impl<_>((TMappings *)0))>::value,
151+
decltype(get_event_mapping_impl<E>((TMappings *)0)),
152+
typename aux::conditional<
153+
aux::is_same<transitions<aux::true_type>, decltype(get_event_mapping_impl<E>((TMappings *)0))>::value,
154+
decltype(get_event_mapping_impl<_>((TMappings *)0)),
155+
decltype(get_event_mapping_impl<E, _>((TMappings *)0, (TMappings *)0))>::type>::type;
147156

148157
template <class T, class TMappings>
149-
struct get_event_mapping_impl_helper
150-
: aux::conditional<aux::is_same<transitions<aux::true_type>, decltype(get_event_mapping_impl<_>((TMappings *)0))>::value,
151-
decltype(get_event_mapping_impl<T>((TMappings *)0)),
152-
decltype(get_event_mapping_impl<T>((TMappings *)0, (TMappings *)0))>::type {};
158+
struct get_event_mapping_impl_helper : with_default_event_mapping_t<T, _, TMappings> {};
153159

154160
template <class T, class TMappings>
155161
struct get_event_mapping_impl_helper<exception<T>, TMappings> : decltype(get_event_mapping_impl<exception<T>>((TMappings *)0)) {
156162
};
157163

158-
template <class T1, class T2, class TMappings>
159-
struct get_event_mapping_impl_helper<unexpected_event<T1, T2>, TMappings>
160-
: decltype(get_event_mapping_impl<unexpected_event<T1, T2>>((TMappings *)0)) {};
164+
template <class E, class _, class TMappings>
165+
struct get_event_mapping_impl_helper<unexpected_event<_, E>, TMappings>
166+
: with_default_event_mapping_t<unexpected_event<_, E>, unexpected_event<_, _>, TMappings> {};
161167

162-
template <class T1, class T2, class TMappings>
163-
struct get_event_mapping_impl_helper<on_entry<T1, T2>, TMappings>
164-
: decltype(get_event_mapping_impl<on_entry<T1, T2>>((TMappings *)0)) {};
168+
template <class E, class _, class TMappings>
169+
struct get_event_mapping_impl_helper<on_entry<_, E>, TMappings>
170+
: with_default_event_mapping_t<on_entry<_, E>, on_entry<_, _>, TMappings> {};
165171

166-
template <class T1, class T2, class TMappings>
167-
struct get_event_mapping_impl_helper<on_exit<T1, T2>, TMappings>
168-
: decltype(get_event_mapping_impl<on_exit<T1, T2>>((TMappings *)0)) {};
172+
template <class E, class _, class TMappings>
173+
struct get_event_mapping_impl_helper<on_exit<_, E>, TMappings>
174+
: with_default_event_mapping_t<on_exit<_, E>, on_exit<_, _>, TMappings> {};
169175

170176
template <class T, class TMappings>
171177
using get_event_mapping_t = get_event_mapping_impl_helper<T, TMappings>;

0 commit comments

Comments
 (0)