9 #if defined(_MSC_VER) && !defined(__clang__) 10 #define COMPILING_WITH_MSVC 12 #if (__cplusplus < 201305L && _MSC_VER < 1900) 13 #error "[Boost].SML requires C++14 support (Clang-3.4+, GCC-5.1+, MSVC-2015+)" 15 #define BOOST_SML_VERSION 1'1'0 16 #define BOOST_SML_NAMESPACE_BEGIN \ 19 inline namespace v1_1_0 { 20 #define BOOST_SML_NAMESPACE_END \ 24 #if defined(__clang__) 25 #define __BOOST_SML_UNUSED __attribute__((unused)) 26 #define __BOOST_SML_VT_INIT \ 28 #define __BOOST_SML_ZERO_SIZE_ARRAY(...) __VA_ARGS__ _[0] 29 #define __BOOST_SML_ZERO_SIZE_ARRAY_CREATE(...) 30 #define __BOOST_SML_TEMPLATE_KEYWORD template 31 #pragma clang diagnostic push 32 #pragma clang diagnostic ignored "-Wgnu-string-literal-operator-template" 33 #pragma clang diagnostic ignored "-Wzero-length-array" 34 #elif defined(__GNUC__) 35 #if !defined(__has_builtin) 36 #define __BOOST_SML_DEFINED_HAS_BUILTIN 37 #define __has_builtin(...) 0 39 #define __BOOST_SML_UNUSED __attribute__((unused)) 40 #define __BOOST_SML_VT_INIT \ 42 #define __BOOST_SML_ZERO_SIZE_ARRAY(...) __VA_ARGS__ _[0] 43 #define __BOOST_SML_ZERO_SIZE_ARRAY_CREATE(...) __VA_ARGS__ ? __VA_ARGS__ : 1 44 #define __BOOST_SML_TEMPLATE_KEYWORD template 45 #pragma GCC diagnostic push 46 #pragma GCC diagnostic ignored "-Wpedantic" 47 #elif defined(COMPILING_WITH_MSVC) 48 #define __BOOST_SML_DEFINED_HAS_BUILTIN 49 #define __has_builtin(...) __has_builtin##__VA_ARGS__ 50 #define __has_builtin__make_integer_seq(...) 1 51 #define __BOOST_SML_UNUSED 52 #define __BOOST_SML_VT_INIT 53 #define __BOOST_SML_ZERO_SIZE_ARRAY(...) 54 #define __BOOST_SML_ZERO_SIZE_ARRAY_CREATE(...) __VA_ARGS__ ? __VA_ARGS__ : 1 55 #if (defined(COMPILING_WITH_MSVC) && _MSC_VER >= 1910) // MSVC 2017 56 #define __BOOST_SML_TEMPLATE_KEYWORD template 58 #define __BOOST_SML_TEMPLATE_KEYWORD 60 #pragma warning(disable : 4503) 61 #pragma warning(disable : 4200) 63 BOOST_SML_NAMESPACE_BEGIN
64 #define __BOOST_SML_REQUIRES(...) typename aux::enable_if<__VA_ARGS__, int>::type = 0 66 using byte =
unsigned char;
72 template <
class,
class>
76 using type = type_list;
80 using type = bool_list;
82 template <
class... Ts>
83 struct inherit : Ts... {
92 template <
class T, T V>
93 struct integral_constant {
94 using type = integral_constant;
95 static constexpr T value = V;
97 using true_type = integral_constant<bool, true>;
98 using false_type = integral_constant<bool, false>;
99 template <
class... Ts>
102 struct always : true_type {};
104 struct never : false_type {};
105 template <
bool B,
class T,
class F>
109 template <
class T,
class F>
110 struct conditional<false, T, F> {
113 template <
bool B,
class T,
class F>
114 using conditional_t =
typename conditional<B, T, F>::type;
115 template <
bool B,
class T =
void>
118 struct enable_if<true, T> {
121 template <
bool B,
class T =
void>
122 using enable_if_t =
typename enable_if<B, T>::type;
123 template <
class,
class>
124 struct is_same : false_type {};
126 struct is_same<T, T> : true_type {};
127 template <
class T,
class U>
128 #if defined(COMPILING_WITH_MSVC) 129 struct is_base_of : integral_constant<bool, __is_base_of(T, U)> {
132 using is_base_of = integral_constant<bool, __is_base_of(T, U)>;
134 template <
class T,
class... TArgs>
135 decltype(T(declval<TArgs>()...), true_type{}) test_is_constructible(
int);
136 template <
class,
class...>
137 false_type test_is_constructible(...);
138 template <
class T,
class... TArgs>
139 #if defined(COMPILING_WITH_MSVC) 140 struct is_constructible : decltype(test_is_constructible<T, TArgs...>(0)) {
143 using is_constructible = decltype(test_is_constructible<T, TArgs...>(0));
145 template <
class T,
class U>
146 struct is_empty_base : T {
150 struct is_empty : aux::integral_constant<bool, sizeof(is_empty_base<T, none_type>) == sizeof(none_type)> {};
152 struct function_traits;
153 template <
class R,
class... TArgs>
154 struct function_traits<R (*)(TArgs...)> {
155 using args = type_list<TArgs...>;
157 template <
class R,
class... TArgs>
158 struct function_traits<R(TArgs...)> {
159 using args = type_list<TArgs...>;
161 template <
class R,
class T,
class... TArgs>
162 struct function_traits<R (T::*)(TArgs...)> {
163 using args = type_list<TArgs...>;
165 template <
class R,
class T,
class... TArgs>
166 struct function_traits<R (T::*)(TArgs...) const> {
167 using args = type_list<TArgs...>;
169 #if __cplusplus > 201402L && __cpp_noexcept_function_type >= 201510 170 template <
class R,
class... TArgs>
171 struct function_traits<R (*)(TArgs...) noexcept> {
172 using args = type_list<TArgs...>;
174 template <
class R,
class... TArgs>
175 struct function_traits<R(TArgs...) noexcept> {
176 using args = type_list<TArgs...>;
178 template <
class R,
class T,
class... TArgs>
179 struct function_traits<R (T::*)(TArgs...) noexcept> {
180 using args = type_list<TArgs...>;
182 template <
class R,
class T,
class... TArgs>
183 struct function_traits<R (T::*)(TArgs...) const noexcept> {
184 using args = type_list<TArgs...>;
188 using function_traits_t =
typename function_traits<T>::args;
190 struct remove_const {
194 struct remove_const<const T> {
198 using remove_const_t =
typename remove_const<T>::type;
200 struct remove_reference {
204 struct remove_reference<T &> {
208 struct remove_reference<T &&> {
212 using remove_reference_t =
typename remove_reference<T>::type;
215 using swallow =
int[];
217 struct index_sequence {
218 using type = index_sequence;
220 #if __has_builtin(__make_integer_seq) 221 template <
class T, T...>
222 struct integer_sequence;
224 struct integer_sequence<int, Ns...> {
225 using type = index_sequence<Ns...>;
228 struct make_index_sequence_impl {
229 using type =
typename __make_integer_seq<integer_sequence, int, N>::type;
232 template <
class,
class>
234 template <
int... I1,
int... I2>
235 struct concat<index_sequence<I1...>, index_sequence<I2...>> : index_sequence<I1..., (sizeof...(I1) + I2)...> {};
237 struct make_index_sequence_impl
238 : concat<typename make_index_sequence_impl<N / 2>::type, typename make_index_sequence_impl<N - N / 2>::type>::type {};
240 struct make_index_sequence_impl<0> : index_sequence<> {};
242 struct make_index_sequence_impl<1> : index_sequence<0> {};
245 using make_index_sequence =
typename make_index_sequence_impl<N>::type;
248 using type = type_list<>;
254 template <
class... Ts>
255 struct join<type_list<Ts...>> : type_list<Ts...> {};
256 template <
class... T1s,
class... T2s>
257 struct join<type_list<T1s...>, type_list<T2s...>> : type_list<T1s..., T2s...> {};
258 template <
class... T1s,
class... T2s,
class... T3s>
259 struct join<type_list<T1s...>, type_list<T2s...>, type_list<T3s...>> : type_list<T1s..., T2s..., T3s...> {};
260 template <
class... T1s,
class... T2s,
class... Ts>
261 struct join<type_list<T1s...>, type_list<T2s...>, Ts...> : join<type_list<T1s..., T2s...>, Ts...> {};
262 template <
class... Ts,
class... T1s,
class... T2s,
class... T3s,
class... T4s,
class... T5s,
class... T6s,
class... T7s,
263 class... T8s,
class... T9s,
class... T10s,
class... T11s,
class... T12s,
class... T13s,
class... T14s,
class... T15s,
264 class... T16s,
class... Us>
265 struct join<type_list<Ts...>, type_list<T1s...>, type_list<T2s...>, type_list<T3s...>, type_list<T4s...>, type_list<T5s...>,
266 type_list<T6s...>, type_list<T7s...>, type_list<T8s...>, type_list<T9s...>, type_list<T10s...>, type_list<T11s...>,
267 type_list<T12s...>, type_list<T13s...>, type_list<T14s...>, type_list<T15s...>, type_list<T16s...>, Us...>
268 : join<type_list<Ts..., T1s..., T2s..., T3s..., T4s..., T5s..., T6s..., T7s..., T8s..., T9s..., T10s..., T11s..., T12s...,
269 T13s..., T14s..., T15s..., T16s...>,
271 template <
class... TArgs>
272 using join_t =
typename join<TArgs...>::type;
273 template <
class,
class...>
275 template <
class T1,
class T2,
class... Rs,
class... Ts>
276 struct unique_impl<type<T1, Rs...>, T2, Ts...>
277 : conditional_t<is_base_of<type<T2>, T1>::value, unique_impl<type<inherit<T1>, Rs...>, Ts...>,
278 unique_impl<type<inherit<T1, type<T2>>, Rs..., T2>, Ts...>> {};
279 template <
class T1,
class... Rs>
280 struct unique_impl<type<T1, Rs...>> : type_list<Rs...> {};
281 template <
class... Ts>
282 struct unique : unique_impl<type<none_type>, Ts...> {};
284 struct unique<T> : type_list<T> {};
285 template <
class... Ts>
286 using unique_t =
typename unique<Ts...>::type;
287 template <
class,
class...>
290 struct is_unique<T> : true_type {};
291 template <
class T1,
class T2,
class... Ts>
292 struct is_unique<T1, T2, Ts...>
293 : conditional_t<is_base_of<type<T2>, T1>::value, false_type, is_unique<inherit<T1, type<T2>>, Ts...>> {};
294 template <
class... Ts>
295 using is_unique_t = is_unique<none_type, Ts...>;
296 template <
template <
class...>
class,
class>
298 template <
template <
class...>
class T,
template <
class...>
class U,
class... Ts>
299 struct apply<T, U<Ts...>> {
300 using type = T<Ts...>;
302 template <
template <
class...>
class T,
class D>
303 using apply_t =
typename apply<T, D>::type;
304 template <
int,
class T>
306 explicit tuple_type(
const T &
object) : value(object) {}
309 template <
class,
class...>
311 template <
int... Ns,
class... Ts>
312 struct tuple_impl<index_sequence<Ns...>, Ts...> : tuple_type<Ns, Ts>... {
313 explicit tuple_impl(Ts... ts) : tuple_type<Ns, Ts>(ts)... {}
316 struct tuple_impl<index_sequence<0>> {
317 __BOOST_SML_ZERO_SIZE_ARRAY(byte);
319 template <
class... Ts>
320 using tuple = tuple_impl<make_index_sequence<
sizeof...(Ts)>, Ts...>;
321 template <int N, class T>
322 T &get_by_id(tuple_type<N, T> *
object) {
323 return static_cast<tuple_type<N, T> &
>(*object).value;
326 struct pool_type_base {
327 __BOOST_SML_ZERO_SIZE_ARRAY(byte);
330 struct pool_type : pool_type_base {
331 explicit pool_type(T
object) : value{
object} {}
332 template <
class TObject>
333 pool_type(init i, TObject
object) : value{i,
object} {}
337 struct missing_ctor_parameter {
338 static constexpr
auto value =
false;
339 auto operator()()
const {
return T{}(); }
340 template <class U, __BOOST_SML_REQUIRES(!aux::is_base_of<pool_type_base, U>::value && aux::is_constructible<U>::value)>
344 #if !defined(COMPILING_WITH_MSVC) 345 template <class TMissing, __BOOST_SML_REQUIRES(!aux::is_base_of<pool_type_base, TMissing>::value)>
346 operator TMissing &()
const {
347 static_assert(missing_ctor_parameter<TMissing>::value,
348 "State Machine is missing a constructor parameter! Check out the `missing_ctor_parameter` error to see the " 354 missing_ctor_parameter<T> try_get(...) {
358 T try_get(
const pool_type<T> *
object) {
359 return object->value;
362 const T &try_get(
const pool_type<const T &> *
object) {
363 return object->value;
366 T &try_get(
const pool_type<T &> *
object) {
367 return object->value;
369 template <
class T,
class TPool>
371 return static_cast<pool_type<T> &
>(p).value;
373 template <
class T,
class TPool>
374 const T &cget(
const TPool &p) {
375 return static_cast<const pool_type<T> &
>(p).value;
377 template <
class... Ts>
378 struct pool : pool_type<Ts>... {
379 using boost_di_inject__ = type_list<Ts...>;
381 explicit pool(Ts... ts) : pool_type<Ts>(ts)... {}
382 template <
class... TArgs>
383 pool(init,
const pool<TArgs...> &p) : pool_type<Ts>(try_get<aux::remove_const_t<aux::remove_reference_t<Ts>>>(&p))... {}
384 template <
class... TArgs>
385 pool(
const pool<TArgs...> &p) : pool_type<Ts>(
init{}, p)... {}
389 using boost_di_inject__ = type_list<>;
391 template <
class... Ts>
392 explicit pool(Ts &&...) {}
393 __BOOST_SML_ZERO_SIZE_ARRAY(byte);
395 template <
int,
class>
396 struct type_id_type {};
397 template <
class,
class...>
399 template <
int... Ns,
class... Ts>
400 struct type_id_impl<index_sequence<Ns...>, Ts...> : type_id_type<Ns, Ts>... {};
401 template <
class... Ts>
402 struct type_id : type_id_impl<make_index_sequence<sizeof...(Ts)>, Ts...> {};
403 template <
class R,
class T,
int N>
404 constexpr R get_id(type_id_type<N, T> *) {
405 return static_cast<R
>(N);
407 template <
template <
class...>
class,
class T>
408 struct is : false_type {};
409 template <
template <
class...>
class T,
class... Ts>
410 struct is<T, T<Ts...>> : true_type {};
413 template <
template <
class...>
class T,
class... Ts>
414 struct size<T<Ts...>> {
415 static constexpr
auto value =
sizeof...(Ts);
417 #if defined(COMPILING_WITH_MSVC) 418 constexpr
int max_impl() {
return 0; }
419 constexpr
int max_impl(
int r) {
return r; }
420 constexpr
int max_impl(
int r,
int i) {
return r > i ? r : i; }
421 constexpr
int max_impl(
int r,
int i,
int ints...) {
return i > r ? max_impl(i, ints) : max_impl(r, ints); }
423 constexpr
int max() {
424 return max_impl(Ts...);
428 constexpr
int max() {
430 (void)swallow{0, (Ts > max ? max = Ts : max)...};
434 template <
class TExpr,
class =
void>
435 struct zero_wrapper : TExpr {
437 explicit zero_wrapper(
const TExpr &expr) : TExpr(expr) {}
438 const TExpr &
get()
const {
return *
this; }
440 template <
class,
class>
441 struct zero_wrapper_impl;
442 template <
class TExpr,
class... TArgs>
443 struct zero_wrapper_impl<TExpr, type_list<TArgs...>> {
444 auto operator()(TArgs... args)
const {
return reinterpret_cast<const TExpr &
>(*this)(args...); }
445 __BOOST_SML_ZERO_SIZE_ARRAY(byte);
447 template <
class TExpr>
448 struct zero_wrapper<TExpr, void_t<decltype(+declval<TExpr>())>>
449 : zero_wrapper_impl<TExpr, function_traits_t<decltype(&TExpr::operator())>> {
451 template <
class... Ts>
452 zero_wrapper(Ts &&...) {}
453 const TExpr &
get()
const {
return reinterpret_cast<const TExpr &
>(*this); }
456 template <
class,
int N,
int... Ns>
457 auto get_type_name(
const char *ptr, index_sequence<Ns...>) {
458 static const char str[] = {ptr[N + Ns]..., 0};
463 const char *get_type_name() {
464 #if defined(COMPILING_WITH_MSVC) 465 return detail::get_type_name<T, 34>(__FUNCSIG__, make_index_sequence<
sizeof(__FUNCSIG__) - 34 - 8>{});
466 #elif defined(__clang__) 467 return detail::get_type_name<T, 58>(__PRETTY_FUNCTION__, make_index_sequence<
sizeof(__PRETTY_FUNCTION__) - 58 - 2>{});
468 #elif defined(__GNUC__) 469 return detail::get_type_name<T, 63>(__PRETTY_FUNCTION__, make_index_sequence<
sizeof(__PRETTY_FUNCTION__) - 63 - 2>{});
472 template <
class T, T...>
474 template <
char... Chrs>
475 struct string<char, Chrs...> {
477 static auto c_str() {
478 static constexpr
char str[] = {Chrs..., 0};
485 static auto c_str() {
return c_str_impl((T *)0); }
487 static decltype(U::c_str()) c_str_impl(U *) {
490 static auto c_str_impl(...) {
return get_type_name<T>(); }
495 struct defer_queue_policy__ {};
496 template <
template <
class...>
class T>
497 struct defer_queue : aux::pair<back::policies::defer_queue_policy__, defer_queue<T>> {
505 template <
class... Ts>
507 using ids_t = aux::type_id<Ts...>;
508 static constexpr
auto alignment = aux::max<
alignof(Ts)...>();
509 static constexpr
auto size = aux::max<
sizeof(Ts)...>();
511 static void dtor_impl(aux::byte *data) {
513 reinterpret_cast<T *
>(data)->~T();
516 static void move_impl(aux::byte (&data)[size], queue_event &&other) {
517 new (&data) T(static_cast<T &&>(*reinterpret_cast<T *>(other.data)));
521 queue_event(queue_event &&other) : id(other.id), dtor(other.dtor), move(other.move) {
522 move(data, static_cast<queue_event &&>(other));
524 queue_event &operator=(queue_event &&other) {
530 move(data, static_cast<queue_event &&>(other));
533 queue_event(
const queue_event &) =
delete;
534 queue_event &operator=(
const queue_event &) =
delete;
536 queue_event(T
object) {
537 id = aux::get_id<int, T>((ids_t *)0);
538 dtor = &dtor_impl<T>;
539 move = &move_impl<T>;
540 new (&data) T(static_cast<T &&>(
object));
542 ~queue_event() { dtor(data); }
543 alignas(alignment) aux::byte data[size];
547 void (*dtor)(aux::byte *);
548 void (*move)(aux::byte (&)[size], queue_event &&);
550 template <
class TEvent>
551 class queue_event_call {
552 using call_t = void (*)(
void *,
const TEvent &);
555 queue_event_call() =
default;
556 explicit queue_event_call(
const call_t &call) : call{call} {}
559 template <
class... TEvents>
560 struct queue_handler : queue_event_call<TEvents>... {
561 queue_handler() =
default;
562 template <
class TQueue,
class =
typename TQueue::container_type>
563 explicit queue_handler(TQueue &queue)
564 : queue_event_call<TEvents>(queue_handler::push_impl<TQueue, TEvents>)..., queue_{&queue} {}
565 template <
class TEvent>
566 void operator()(
const TEvent &event) {
567 static_cast<queue_event_call<TEvent> *
>(
this)->
call(queue_, event);
571 template <
class TQueue,
class TEvent>
572 static auto push_impl(
void *queue,
const TEvent &event) {
573 static_cast<TQueue *
>(queue)->push(event);
577 template <
class... TEvents>
578 struct deque_handler : queue_event_call<TEvents>... {
579 deque_handler() =
default;
580 template <
class TDeque,
class =
typename TDeque::allocator_type>
581 explicit deque_handler(TDeque &deque)
582 : queue_event_call<TEvents>(deque_handler::push_impl<TDeque, TEvents>)..., deque_{&deque} {}
583 template <
class TEvent>
584 void operator()(
const TEvent &event) {
585 static_cast<queue_event_call<TEvent> *
>(
this)->
call(deque_, event);
589 template <
class TDeque,
class TEvent>
590 static auto push_impl(
void *deque,
const TEvent &event) {
591 static_cast<TDeque *
>(deque)->push_back(event);
599 struct unexpected {};
600 struct entry_exit {};
601 struct terminate_state {
602 static auto c_str() {
return "terminate"; }
604 struct internal_event {
605 static auto c_str() {
return "internal_event"; }
607 struct anonymous : internal_event {
608 static auto c_str() {
return "anonymous"; }
610 template <
class T,
class TEvent = T>
611 struct on_entry : internal_event, entry_exit {
612 static auto c_str() {
return "on_entry"; }
613 explicit on_entry(
const TEvent &event = {}) : event_(event) {}
614 const TEvent &event_;
616 template <
class T,
class TEvent = T>
617 struct on_exit : internal_event, entry_exit {
618 static auto c_str() {
return "on_exit"; }
619 explicit on_exit(
const TEvent &event = {}) : event_(event) {}
620 const TEvent &event_;
622 template <
class T,
class TException = T>
623 struct exception : internal_event {
624 using type = TException;
625 explicit exception(
const TException &exception = {}) : exception_(exception) {}
626 const TException &exception_;
628 template <
class T,
class TEvent = T>
629 struct unexpected_event : internal_event, unexpected {
630 explicit unexpected_event(
const TEvent &event = {}) : event_(event) {}
631 const TEvent &event_;
633 template <
class TEvent>
635 using event_t = TEvent;
636 using generic_t = TEvent;
637 using mapped_t = void;
639 template <
class TEvent>
640 struct event_type<exception<TEvent>> {
641 using event_t = TEvent;
642 using generic_t = exception<TEvent>;
643 using mapped_t = void;
645 template <
class TEvent,
class T>
646 struct event_type<unexpected_event<T, TEvent>> {
647 using event_t = TEvent;
648 using generic_t = unexpected_event<T>;
649 using mapped_t = void;
651 template <
class TEvent,
class T>
652 struct event_type<on_entry<T, TEvent>> {
653 using event_t = TEvent;
654 using generic_t = on_entry<T>;
655 using mapped_t = on_entry<T, TEvent>;
657 template <
class TEvent,
class T>
658 struct event_type<on_exit<T, TEvent>> {
659 using event_t = TEvent;
660 using generic_t = on_exit<T>;
661 using mapped_t = on_exit<T, TEvent>;
663 template <
class TEvent>
664 using get_event_t =
typename event_type<TEvent>::event_t;
665 template <
class TEvent>
666 using get_generic_t =
typename event_type<TEvent>::generic_t;
667 template <
class TEvent>
668 using get_mapped_t =
typename event_type<TEvent>::mapped_t;
669 template <
class... TEvents>
670 struct process : queue_handler<TEvents...> {
671 using queue_handler<TEvents...>::queue_handler;
673 template <
class... TEvents>
674 struct defer : deque_handler<TEvents...> {
675 using deque_handler<TEvents...>::deque_handler;
683 template <
class,
class...>
685 template <
class TEvent>
686 using get_event = aux::conditional_t<aux::is_base_of<internal_event, TEvent>::value, aux::type_list<>, aux::type_list<TEvent>>;
687 template <
class,
class,
class TEvent>
688 struct get_all_events_impl {
689 using type = get_event<TEvent>;
691 template <
class TSrc,
class TDst,
class TEvent>
692 struct get_all_events_impl<TSrc, TDst, unexpected_event<TEvent>> {
693 using type = aux::type_list<TEvent>;
695 template <
class TSrc,
class TDst,
class TEvent>
696 struct get_all_events_impl<sm<TSrc>, TDst, TEvent> {
697 using type = aux::join_t<get_event<TEvent>,
typename sm<TSrc>::events>;
699 template <
class TSrc,
class TDst,
class TEvent>
700 struct get_all_events_impl<TSrc, sm<TDst>, TEvent> {
701 using type = aux::join_t<get_event<TEvent>,
typename sm<TDst>::events>;
703 template <
class TSrc,
class TDst,
class TEvent>
704 struct get_all_events_impl<sm<TSrc>, sm<TDst>, TEvent> {
705 using type = aux::join_t<get_event<TEvent>,
typename sm<TSrc>::events,
typename sm<TDst>::events>;
707 template <
class,
class TEvent>
708 struct get_sub_internal_events_impl {
709 using type = aux::conditional_t<aux::is_base_of<internal_event, TEvent>::value, aux::type_list<TEvent>, aux::type_list<>>;
711 template <
class T,
class TEvent>
712 struct get_sub_internal_events_impl<sm<T>, TEvent> {
713 using type = aux::join_t<aux::type_list<TEvent>,
typename sm_impl<T>::sub_internal_events_t>;
715 template <
class... Ts>
716 using get_all_events =
717 aux::join_t<typename get_all_events_impl<typename Ts::src_state, typename Ts::dst_state, typename Ts::event>::type...>;
718 template <
class... Ts>
719 using get_sub_internal_events =
720 aux::join_t<typename get_sub_internal_events_impl<typename Ts::src_state, typename Ts::event>::type...,
721 typename get_sub_internal_events_impl<typename Ts::dst_state, typename Ts::event>::type...>;
722 template <
class... Ts>
723 using get_events = aux::type_list<
typename Ts::event...>;
725 struct get_exception : aux::type_list<> {};
727 struct get_exception<exception<T>> : aux::type_list<exception<T>> {};
728 template <
class... Ts>
729 using get_exceptions = aux::join_t<typename get_exception<Ts>::type...>;
730 template <
class... Ts>
731 using get_states = aux::join_t<aux::type_list<typename Ts::src_state, typename Ts::dst_state>...>;
732 template <
class... Ts>
733 using get_initial_states =
734 aux::join_t<typename aux::conditional<Ts::initial, aux::type_list<typename Ts::src_state>, aux::type_list<>>::type...>;
735 template <
class... Ts>
736 using get_history_states = aux::join_t<
737 typename aux::conditional<!Ts::history && Ts::initial, aux::type_list<typename Ts::src_state>, aux::type_list<>>::type...>;
739 struct get_sub_sm : aux::type_list<> {};
741 struct get_sub_sm<sm<T>> : aux::join_t<aux::type_list<T>, typename sm<T>::state_machines> {};
742 template <
class... Ts>
743 using get_sub_sms = aux::join_t<typename get_sub_sm<Ts>::type...>;
744 template <
class... Ts>
745 using get_sm_t = aux::type_list<
typename Ts::sm...>;
746 template <
class... Ts>
747 using get_non_empty_t =
748 aux::join_t<typename aux::conditional<aux::is_empty<Ts>::value, aux::type_list<>, aux::type_list<Ts>>::type...>;
749 template <
class... Ts>
750 using merge_deps = aux::join_t<
typename Ts::deps...>;
754 struct sub_sm<sm_impl<sm_policy<T>>> {
755 template <
class U,
class... TPolicies>
756 static sm_impl<sm_policy<T, aux::identity<U>, TPolicies...>> &
get(
757 aux::pool_type<sm_impl<sm_policy<T, aux::identity<U>, TPolicies...>>> *object) {
758 return static_cast<aux::pool_type<sm_impl<sm_policy<T, aux::identity<U>, TPolicies...
>>> &>(*object).value;
760 template <
class... TPolicies>
761 static sm_impl<sm_policy<T, TPolicies...>> &
get(aux::pool_type<sm_impl<sm_policy<T, TPolicies...>>> *object) {
762 return static_cast<aux::pool_type<sm_impl<sm_policy<T, TPolicies...
>>> &>(*object).value;
764 template <
class... TPolicies>
765 static const sm_impl<sm_policy<T, TPolicies...>> &cget(
const aux::pool_type<sm_impl<sm_policy<T, TPolicies...>>> *
object) {
766 return static_cast<const aux::pool_type<sm_impl<sm_policy<T, TPolicies...
>>> &>(*object).value;
769 template <
class T,
class U>
770 struct sub_sm<sm_impl<sm_policy<T, aux::identity<U>>>> {
771 template <
class... TPolicies>
772 static sm_impl<sm_policy<T, aux::identity<U>, TPolicies...>> &
get(
773 aux::pool_type<sm_impl<sm_policy<T, aux::identity<U>, TPolicies...>>> *object) {
774 return static_cast<aux::pool_type<sm_impl<sm_policy<T, aux::identity<U>, TPolicies...
>>> &>(*object).value;
776 template <
class... TPolicies>
777 static const sm_impl<sm_policy<T, aux::identity<U>, TPolicies...>> &cget(
778 const aux::pool_type<sm_impl<sm_policy<T, aux::identity<U>, TPolicies...>>> *
object) {
779 return static_cast<const aux::pool_type<sm_impl<sm_policy<T, aux::identity<U>, TPolicies...
>>> &>(*object).value;
782 template <
class T,
class... TPolicies>
784 using type = sm_policy<T, TPolicies...>;
786 template <
class T,
class... TDetails,
class... TPolicies>
787 struct rebind_impl<sm_policy<T, TDetails...>, TPolicies...> {
788 using type = sm_policy<T, TDetails..., TPolicies...>;
790 template <
class T,
class... TDetails,
class... TPolicies>
791 struct rebind_impl<sm<sm_policy<T, TDetails...>>, TPolicies...> {
792 using type = sm_policy<T, TDetails..., TPolicies...>;
794 template <
class,
class>
795 struct convert_to_sm;
796 template <
class T,
class... Ts>
797 struct convert_to_sm<T, aux::type_list<Ts...>> {
798 using type = aux::type_list<sm_impl<T>, sm_impl<typename T::template rebind<Ts>>...>;
809 struct transitions_sub;
810 template <
class T,
class... Ts>
811 struct transitions<T, Ts...> {
812 template <
class TEvent,
class SM,
class TDeps,
class TSubs>
813 static bool execute(
const TEvent &event, SM &sm, TDeps &deps, TSubs &subs,
typename SM::state_t ¤t_state) {
814 if (aux::get<T>(sm.transitions_).execute(event, sm, deps, subs, current_state,
typename SM::has_entry_exits{})) {
817 return transitions<Ts...>::execute(event, sm, deps, subs, current_state);
821 struct transitions<T> {
822 template <
class TEvent,
class SM,
class TDeps,
class TSubs>
823 static bool execute(
const TEvent &event, SM &sm, TDeps &deps, TSubs &subs,
typename SM::state_t ¤t_state) {
824 return execute_impl(event, sm, deps, subs, current_state);
826 template <
class TEvent,
class SM,
class TDeps,
class TSubs>
827 static bool execute_impl(
const TEvent &event, SM &sm, TDeps &deps, TSubs &subs,
typename SM::state_t ¤t_state) {
828 return aux::get<T>(sm.transitions_).
execute(event, sm, deps, subs, current_state,
typename SM::has_entry_exits{});
830 template <
class _,
class TEvent,
class SM,
class TDeps,
class TSubs>
831 static bool execute_impl(
const on_exit<_, TEvent> &event, SM &sm, TDeps &deps, TSubs &subs,
832 typename SM::state_t ¤t_state) {
833 aux::get<T>(sm.transitions_).
execute(event, sm, deps, subs, current_state,
typename SM::has_entry_exits{});
838 struct transitions<aux::true_type> {
839 template <
class TEvent,
class SM,
class TDeps,
class TSubs>
840 static bool execute(
const TEvent &event, SM &sm, TDeps &deps, TSubs &subs,
typename SM::state_t ¤t_state) {
841 sm.process_internal_event(unexpected_event<TEvent>{
event}, deps, subs, current_state);
846 struct transitions<aux::false_type> {
847 template <
class TEvent,
class SM,
class TDeps,
class TSubs>
848 static bool execute(
const TEvent &, SM &, TDeps &, TSubs &,
typename SM::state_t &) {
852 template <
class TSM,
class T,
class... Ts>
853 struct transitions_sub<sm<TSM>, T, Ts...> {
854 template <
class TEvent,
class SM,
class TDeps,
class TSubs>
855 static bool execute(
const TEvent &event, SM &sm, TDeps &deps, TSubs &subs,
typename SM::state_t ¤t_state) {
856 return execute_impl(event, sm, deps, subs, current_state);
858 template <
class,
class SM,
class TDeps,
class TSubs>
859 static bool execute(
const anonymous &event, SM &sm, TDeps &deps, TSubs &subs,
typename SM::state_t ¤t_state) {
860 if (sub_sm<sm_impl<TSM>>::cget(&subs).is_terminated()) {
861 const auto handled = sub_sm<sm_impl<TSM>>::get(&subs).process_event(event, deps, subs);
862 return handled ? handled : transitions<T, Ts...>::execute(event, sm, deps, subs, current_state);
866 template <
class TEvent,
class SM,
class TDeps,
class TSubs>
867 static bool execute_impl(
const TEvent &event, SM &sm, TDeps &deps, TSubs &subs,
typename SM::state_t ¤t_state) {
868 const auto handled = sub_sm<sm_impl<TSM>>::get(&subs).process_event(event, deps, subs);
869 return handled ? handled : transitions<T, Ts...>::execute(event, sm, deps, subs, current_state);
871 template <
class _,
class TEvent,
class SM,
class TDeps,
class TSubs>
872 static bool execute_impl(
const back::on_entry<_, TEvent> &event, SM &sm, TDeps &deps, TSubs &subs,
873 typename SM::state_t ¤t_state) {
874 transitions<T, Ts...>::execute(event, sm, deps, subs, current_state);
875 sub_sm<sm_impl<TSM>>::get(&subs).process_event(event, deps, subs);
880 struct transitions_sub<sm<TSM>> {
881 template <
class TEvent,
class SM,
class TDeps,
class TSubs>
882 static bool execute(
const TEvent &event, SM &, TDeps &deps, TSubs &subs,
typename SM::state_t &) {
883 return sub_sm<sm_impl<TSM>>::get(&subs).template process_event<TEvent>(event, deps, subs);
897 struct transitions_sub;
898 template <
class,
class>
899 struct state_mappings;
900 template <
class S,
class... Ts>
901 struct state_mappings<S, aux::type_list<Ts...>> {
902 using element_type = state<S>;
903 using types = aux::type_list<Ts...>;
905 template <
class,
class>
906 struct event_mappings;
907 template <
class E,
class... Ts>
908 struct event_mappings<E, aux::inherit<Ts...>> {
909 using element_type = event<E>;
910 using types = aux::type_list<Ts...>;
913 struct unique_mappings;
914 template <
class,
class...>
915 struct unique_mappings_impl;
916 template <
class... Ts>
917 using unique_mappings_t =
typename unique_mappings<Ts...>::type;
918 template <
class,
class,
class,
class R>
919 struct get_mapping : aux::type_list<R> {};
920 template <
class E,
class T,
class R>
921 struct get_mapping<event<E>, event<E>, T, R>
922 : aux::type_list<event_mappings<E, aux::apply_t<unique_mappings_t, aux::join_t<typename R::types, typename T::types>>>> {};
923 template <
class S,
class T,
class R>
924 struct get_mapping<state<S>, state<S>, T, R>
925 : aux::type_list<state_mappings<S, aux::join_t<typename R::types, typename T::types>>> {};
926 template <
class T,
class... Ts>
927 struct extend_mapping : aux::join_t<typename get_mapping<typename T::element_type, typename Ts::element_type, T, Ts>::type...> {
929 template <
class T,
class... Ts>
930 using extend_mapping_t = aux::apply_t<aux::inherit,
typename extend_mapping<T, Ts...>::type>;
931 template <bool,
class,
class...>
932 struct conditional_mapping;
933 template <
class T1,
class T2,
class... Rs,
class... Ts>
934 struct conditional_mapping<true, aux::type<T1, aux::inherit<Rs...>>, T2, Ts...> {
935 using type = unique_mappings_impl<aux::type<aux::inherit<T1>, extend_mapping_t<T2, Rs...>>, Ts...>;
937 template <
class T1,
class T2,
class... Rs,
class... Ts>
938 struct conditional_mapping<false, aux::type<T1, aux::inherit<Rs...>>, T2, Ts...> {
940 unique_mappings_impl<aux::type<aux::inherit<T1, aux::type<typename T2::element_type>>, aux::inherit<T2, Rs...>>, Ts...>;
942 template <
class T1,
class T2,
class... Rs,
class... Ts>
943 struct unique_mappings_impl<aux::type<T1, aux::inherit<Rs...>>, T2, Ts...>
944 : conditional_mapping<aux::is_base_of<aux::type<typename T2::element_type>, T1>::value, aux::type<T1, aux::inherit<Rs...>>,
946 template <
class T1,
class Rs>
947 struct unique_mappings_impl<aux::type<T1, Rs>> : aux::apply_t<aux::inherit, Rs> {};
948 template <
class... Ts>
949 struct unique_mappings : unique_mappings_impl<aux::type<aux::none_type, aux::inherit<>>, Ts...> {};
951 struct unique_mappings<T> : aux::inherit<T> {};
952 template <
class,
class...>
954 template <
class... Ts>
955 struct mappings<aux::pool<Ts...>>
957 event_mappings<typename Ts::event, aux::inherit<state_mappings<typename Ts::src_state, aux::type_list<Ts>>>>...> {};
959 using mappings_t =
typename mappings<T>::type;
960 template <
class,
class TUnexpected>
961 transitions<TUnexpected> get_state_mapping_impl(...);
962 template <
class T,
class,
class... Ts>
963 transitions<Ts...> get_state_mapping_impl(state_mappings<T, aux::type_list<Ts...>> *);
964 template <
class T,
class TMappings,
class TUnexpected>
965 struct get_state_mapping {
966 using type = decltype(get_state_mapping_impl<T, TUnexpected>((TMappings *)0));
969 transitions_sub<S> get_sub_state_mapping_impl(...);
970 template <
class T,
class... Ts>
971 transitions_sub<T, Ts...> get_sub_state_mapping_impl(state_mappings<T, aux::type_list<Ts...>> *);
972 template <
class T,
class TMappings,
class TUnexpected>
973 struct get_state_mapping<sm<T>, TMappings, TUnexpected> {
974 using type = decltype(get_sub_state_mapping_impl<sm<T>>((TMappings *)0));
976 template <
class T,
class TMappings,
class TUnexpected>
977 using get_state_mapping_t =
typename get_state_mapping<T, TMappings, TUnexpected>::type;
979 transitions<aux::true_type> get_event_mapping_impl(...);
980 template <
class T,
class TMappings>
981 TMappings get_event_mapping_impl(event_mappings<T, TMappings> *);
982 template <
class T,
class... T1Mappings,
class... T2Mappings>
983 unique_mappings_t<T1Mappings..., T2Mappings...> get_event_mapping_impl(event_mappings<T, aux::inherit<T1Mappings...>> *,
984 event_mappings<_, aux::inherit<T2Mappings...>> *);
985 template <
class T,
class TMappings>
986 struct get_event_mapping_impl_helper
987 : aux::conditional<aux::is_same<transitions<aux::true_type>, decltype(get_event_mapping_impl<_>((TMappings *)0))>::value,
988 decltype(get_event_mapping_impl<T>((TMappings *)0)),
989 decltype(get_event_mapping_impl<T>((TMappings *)0, (TMappings *)0))>::type {};
990 template <
class T,
class TMappings>
991 struct get_event_mapping_impl_helper<exception<T>, TMappings> : decltype(get_event_mapping_impl<exception<T>>((TMappings *)0)) {
993 template <
class T1,
class T2,
class TMappings>
994 struct get_event_mapping_impl_helper<unexpected_event<T1, T2>, TMappings>
995 : decltype(get_event_mapping_impl<unexpected_event<T1, T2>>((TMappings *)0)) {};
996 template <
class T1,
class T2,
class TMappings>
997 struct get_event_mapping_impl_helper<on_entry<T1, T2>, TMappings>
998 : decltype(get_event_mapping_impl<on_entry<T1, T2>>((TMappings *)0)) {};
999 template <
class T1,
class T2,
class TMappings>
1000 struct get_event_mapping_impl_helper<on_exit<T1, T2>, TMappings>
1001 : decltype(get_event_mapping_impl<on_exit<T1, T2>>((TMappings *)0)) {};
1002 template <
class T,
class TMappings>
1003 using get_event_mapping_t = get_event_mapping_impl_helper<T, TMappings>;
1006 namespace policies {
1007 struct dispatch_policy__ {};
1009 struct dispatch : aux::pair<dispatch_policy__, T> {
1013 template <
int,
class TMappings,
class sm_impl,
class State,
class TEvent,
class TDeps,
class TSubs>
1014 static bool dispatch(sm_impl &, State &,
const TEvent &, TDeps &, TSubs &,
const aux::type_list<> &) {
1017 template <int,
class TMappings,
class sm_impl,
class State,
class TEvent,
class TDeps,
class TSubs,
class... TStates>
1018 static bool dispatch(sm_impl &
self, State ¤t_state,
const TEvent &event, TDeps &deps, TSubs &subs,
1019 const aux::type_list<TStates...> &) {
1020 using dispatch_table_t = bool (*)(
const TEvent &, sm_impl &, TDeps &, TSubs &, State &);
1021 constexpr
static dispatch_table_t dispatch_table[__BOOST_SML_ZERO_SIZE_ARRAY_CREATE(
sizeof...(TStates))] = {
1022 &get_state_mapping_t<TStates, TMappings, typename sm_impl::has_unexpected_events>::template
execute<TEvent, sm_impl,
1024 return dispatch_table[current_state](event,
self, deps, subs, current_state);
1028 template <
int,
class TMappings,
class sm_impl,
class State,
class TEvent,
class TDeps,
class TSubs>
1029 static bool dispatch(sm_impl &, State &,
const TEvent &, TDeps &, TSubs &,
const aux::type_list<> &) {
1032 template <
int N,
class TMappings,
class sm_impl,
class State,
class TEvent,
class TDeps,
class TSubs,
class TState,
1034 static bool dispatch(sm_impl &
self, State ¤t_state,
const TEvent &event, TDeps &deps, TSubs &subs,
1035 const aux::type_list<TState, TStates...> &) {
1036 return current_state == N
1037 ? get_state_mapping_t<TState, TMappings, typename sm_impl::has_unexpected_events>::template
execute<
1038 TEvent, sm_impl, TDeps, TSubs>(event,
self, deps, subs, current_state)
1039 : dispatch<N + 1, TMappings>(
self, current_state, event, deps, subs, aux::type_list<TStates...>{});
1043 template <
int,
class TMappings,
class sm_impl,
class State,
class TEvent,
class TDeps,
class TSubs>
1044 static bool dispatch(sm_impl &, State &,
const TEvent &, TDeps &, TSubs &,
const aux::type_list<> &) {
1047 template <
int N,
class TMappings,
class sm_impl,
class State,
class TEvent,
class TDeps,
class TSubs,
class TState,
1049 static bool dispatch(sm_impl &
self, State ¤t_state,
const TEvent &event, TDeps &deps, TSubs &subs,
1050 const aux::type_list<TState, TStates...> &) {
1051 switch (current_state) {
1053 return get_state_mapping_t<TState, TMappings, typename sm_impl::has_unexpected_events>::template
execute<
1054 TEvent, sm_impl, TDeps, TSubs>(event,
self, deps, subs, current_state);
1056 return dispatch<N + 1, TMappings>(
self, current_state, event, deps, subs, aux::type_list<TStates...>{});
1060 #if defined(__cpp_fold_expressions) 1062 template <
class TMappings,
int... Ns,
class sm_impl,
class State,
class TEvent,
class TDeps,
class TSubs,
class... TStates>
1063 static bool dispatch_impl(sm_impl &
self, State ¤t_state, aux::index_sequence<Ns...>,
const TEvent &event, TDeps &deps,
1064 TSubs &subs,
const aux::type_list<TStates...> &) {
1065 return ((current_state == Ns
1066 ? get_state_mapping_t<TStates, TMappings, typename sm_impl::has_unexpected_events>::template execute<
1067 TEvent, sm_impl, TDeps, TSubs>(event,
self, deps, subs, current_state)
1071 template <
int N,
class TMappings,
class sm_impl,
class State,
class TEvent,
class TDeps,
class TSubs,
class... TStates>
1072 static bool dispatch(sm_impl &
self, State ¤t_state,
const TEvent &event, TDeps &deps, TSubs &subs,
1073 const aux::type_list<TStates...> &states) {
1074 return dispatch_impl<TMappings>(
self, current_state, aux::make_index_sequence<
sizeof...(TStates)>{}, event, deps, subs,
1084 template <
class,
class...>
1087 namespace policies {
1088 struct logger_policy__ {};
1090 struct logger : aux::pair<logger_policy__, logger<T>> {
1094 struct get_state_name;
1096 struct get_state_name<aux::string<T>> {
1097 using type = aux::string<T>;
1099 template <
class T,
class... Ts>
1100 struct get_state_name<aux::string<sm<sm_policy<T, Ts...>>>> {
1101 using type =
typename get_state_name<aux::string<sm_policy<T, Ts...>>>::type;
1104 struct get_state_name<aux::string<sm_policy<T>>> {
1105 using type = aux::string<T>;
1107 template <
class T,
class TName>
1108 struct get_state_name<aux::string<sm_policy<T, TName>>> {
1109 using type = aux::string<T(typename TName::type)>;
1112 using get_state_name_t =
typename get_state_name<T>::type;
1113 template <
class,
class TDeps,
class TEvent>
1114 void log_process_event(
const aux::type<no_policy> &, TDeps &,
const TEvent &) {}
1115 template <
class SM,
class TLogger,
class TDeps,
class TEvent>
1116 void log_process_event(
const aux::type<TLogger> &, TDeps &deps,
const TEvent &event) {
1117 return static_cast<aux::pool_type<TLogger &> &
>(deps).value.template log_process_event<SM>(event);
1119 template <
class,
class TDeps,
class TSrcState,
class TDstState>
1120 void log_state_change(
const aux::type<no_policy> &, TDeps &,
const TSrcState &,
const TDstState &) {}
1121 template <
class SM,
class TLogger,
class TDeps,
class TSrcState,
class TDstState>
1122 void log_state_change(
const aux::type<TLogger> &, TDeps &deps,
const TSrcState &,
const TDstState &) {
1123 return static_cast<aux::pool_type<TLogger &> &
>(deps).value.template log_state_change<SM>(get_state_name_t<TSrcState>{},
1124 get_state_name_t<TDstState>{});
1126 template <
class,
class TDeps,
class TAction,
class TEvent>
1127 void log_action(
const aux::type<no_policy> &, TDeps &,
const TAction &,
const TEvent &) {}
1128 template <
class SM,
class TLogger,
class TDeps,
class TAction,
class TEvent>
1129 void log_action(
const aux::type<TLogger> &, TDeps &deps,
const TAction &action,
const TEvent &event) {
1130 return static_cast<aux::pool_type<TLogger &> &
>(deps).value.template log_action<SM>(action, event);
1132 template <
class SM,
class TLogger,
class TDeps,
class TAction,
class TEvent>
1133 void log_action(
const aux::type<TLogger> &, TDeps &deps,
const aux::zero_wrapper<TAction> &action,
const TEvent &event) {
1134 return static_cast<aux::pool_type<TLogger &> &
>(deps).value.template log_action<SM>(action.get(), event);
1136 template <
class,
class TDeps,
class TGuard,
class TEvent>
1137 void log_guard(
const aux::type<no_policy> &, TDeps &,
const TGuard &,
const TEvent &,
bool) {}
1138 template <
class SM,
class TLogger,
class TDeps,
class TGuard,
class TEvent>
1139 void log_guard(
const aux::type<TLogger> &, TDeps &deps,
const TGuard &guard,
const TEvent &event,
bool result) {
1140 return static_cast<aux::pool_type<TLogger &> &
>(deps).value.template log_guard<SM>(guard, event, result);
1142 template <
class SM,
class TLogger,
class TDeps,
class TGuard,
class TEvent>
1143 void log_guard(
const aux::type<TLogger> &, TDeps &deps,
const aux::zero_wrapper<TGuard> &guard,
const TEvent &event,
1145 return static_cast<aux::pool_type<TLogger &> &
>(deps).value.template log_guard<SM>(guard.get(), event, result);
1150 namespace policies {
1151 struct process_queue_policy__ {};
1152 template <
template <
class...>
class T>
1153 struct process_queue : aux::pair<back::policies::process_queue_policy__, process_queue<T>> {
1155 using rebind = T<U>;
1160 namespace policies {
1161 struct testing_policy__ {};
1162 struct testing : aux::pair<testing_policy__, testing> {};
1166 namespace policies {
1167 struct thread_safety_policy__ {
1168 auto create_lock() {
return *
this; }
1169 __BOOST_SML_ZERO_SIZE_ARRAY(aux::byte);
1171 template <
class TLock>
1172 struct thread_safe : aux::pair<thread_safety_policy__, thread_safe<TLock>> {
1173 using type = thread_safe;
1174 auto create_lock() {
1176 explicit lock_guard(TLock &lock) : lock_{lock} { lock_.lock(); }
1177 ~lock_guard() { lock_.unlock(); }
1180 return lock_guard{lock};
1187 struct no_policy : policies::thread_safety_policy__ {
1188 using type = no_policy;
1190 using rebind = no_policy;
1192 using defer = no_policy;
1193 using const_iterator = no_policy;
1194 using flag = no_policy;
1195 __BOOST_SML_ZERO_SIZE_ARRAY(aux::byte);
1197 template <
class TDefault,
class>
1198 TDefault get_policy(...);
1199 template <
class,
class T,
class TPolicy>
1200 TPolicy get_policy(aux::pair<T, TPolicy> *);
1201 template <
class SM,
class... TPolicies>
1203 static_assert(aux::is_same<aux::remove_reference_t<SM>, SM>::value,
"SM type can't have qualifiers");
1204 #if defined(COMPILING_WITH_MSVC) 1205 using default_dispatch_policy = policies::jump_table;
1206 #elif defined(__clang__) 1207 using default_dispatch_policy = policies::jump_table;
1208 #elif defined(__GNUC__) 1209 using default_dispatch_policy = policies::branch_stm;
1212 using thread_safety_policy =
1213 decltype(get_policy<no_policy, policies::thread_safety_policy__>((aux::inherit<TPolicies...> *)0));
1214 using defer_queue_policy = decltype(get_policy<no_policy, policies::defer_queue_policy__>((aux::inherit<TPolicies...> *)0));
1215 using process_queue_policy =
1216 decltype(get_policy<no_policy, policies::process_queue_policy__>((aux::inherit<TPolicies...> *)0));
1217 using logger_policy = decltype(get_policy<no_policy, policies::logger_policy__>((aux::inherit<TPolicies...> *)0));
1218 using testing_policy = decltype(get_policy<no_policy, policies::testing_policy__>((aux::inherit<TPolicies...> *)0));
1219 using dispatch_policy =
1220 decltype(get_policy<default_dispatch_policy, policies::dispatch_policy__>((aux::inherit<TPolicies...> *)0));
1222 using rebind =
typename rebind_impl<T, TPolicies...>::type;
1225 namespace concepts {
1226 struct callable_fallback {
1230 aux::false_type test_callable(aux::non_type<
void (callable_fallback::*)(), &T::operator()> *);
1232 aux::true_type test_callable(...);
1233 template <
class,
class T>
1235 : decltype(test_callable<aux::inherit<aux::conditional_t<__is_class(T), T, aux::none_type>, callable_fallback>>(0)) {};
1237 namespace concepts {
1239 decltype(aux::declval<T>().
operator()()) composable_impl(
int);
1241 void composable_impl(...);
1243 struct composable : aux::is<aux::pool, decltype(composable_impl<T>(0))> {};
1245 #if !defined(BOOST_SML_DISABLE_EXCEPTIONS) 1246 #if !(defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) 1247 #define BOOST_SML_DISABLE_EXCEPTIONS true 1249 #define BOOST_SML_DISABLE_EXCEPTIONS false 1253 template <
class TSM>
1254 struct sm_impl : aux::conditional_t<aux::is_empty<typename TSM::sm>::value, aux::none_type, typename TSM::sm> {
1255 using sm_t =
typename TSM::sm;
1256 using thread_safety_t =
typename TSM::thread_safety_policy::type;
1258 using defer_queue_t =
typename TSM::defer_queue_policy::template rebind<T>;
1259 using defer_flag_t =
typename TSM::defer_queue_policy::flag;
1261 using process_queue_t =
typename TSM::process_queue_policy::template rebind<T>;
1262 using logger_t =
typename TSM::logger_policy::type;
1263 using dispatch_t =
typename TSM::dispatch_policy;
1264 using transitions_t = decltype(aux::declval<sm_t>().
operator()());
1265 using states_t = aux::apply_t<aux::unique_t, aux::apply_t<get_states, transitions_t>>;
1266 using states_ids_t = aux::apply_t<aux::type_id, states_t>;
1267 using initial_states_t = aux::apply_t<aux::unique_t, aux::apply_t<get_initial_states, transitions_t>>;
1268 using initial_states_ids_t = aux::apply_t<aux::type_id, initial_states_t>;
1269 using history_states_t = aux::apply_t<get_history_states, transitions_t>;
1270 using has_history_states =
1271 aux::integral_constant<bool, aux::size<initial_states_t>::value != aux::size<history_states_t>::value>;
1272 using sub_internal_events_t = aux::apply_t<get_sub_internal_events, transitions_t>;
1273 using events_t = aux::apply_t<aux::unique_t, aux::join_t<sub_internal_events_t, aux::apply_t<get_all_events, transitions_t>>>;
1274 using events_ids_t = aux::apply_t<aux::inherit, events_t>;
1275 using has_unexpected_events =
typename aux::is_base_of<unexpected, aux::apply_t<aux::inherit, events_t>>::type;
1276 using has_entry_exits =
typename aux::is_base_of<entry_exit, aux::apply_t<aux::inherit, events_t>>::type;
1277 using defer_t = defer_queue_t<aux::apply_t<queue_event, events_t>>;
1278 using process_t = process_queue_t<aux::apply_t<queue_event, events_t>>;
1279 using deps = aux::apply_t<merge_deps, transitions_t>;
1280 using state_t = aux::conditional_t<(aux::size<states_t>::value > 0xFF),
unsigned short, aux::byte>;
1281 static constexpr
auto regions = aux::size<initial_states_t>::value;
1282 static_assert(regions > 0,
"At least one initial state is required");
1283 #if !BOOST_SML_DISABLE_EXCEPTIONS 1284 using exceptions = aux::apply_t<aux::unique_t, aux::apply_t<get_exceptions, events_t>>;
1285 using has_exceptions = aux::integral_constant<bool, (aux::size<exceptions>::value > 0)>;
1287 struct mappings : mappings_t<transitions_t> {};
1288 template <
class TPool>
1289 sm_impl(aux::init,
const TPool &p) : sm_impl{p, aux::is_empty<sm_t>{}} {}
1290 template <
class TPool>
1291 sm_impl(
const TPool &p, aux::false_type) : sm_t{aux::try_get<sm_t>(&p)}, transitions_{(*this)()} {
1292 initialize(
typename sm_impl<TSM>::initial_states_t{});
1294 template <
class TPool>
1295 sm_impl(
const TPool &p, aux::true_type) : transitions_{aux::try_get<sm_t>(&p)()} {
1296 initialize(
typename sm_impl<TSM>::initial_states_t{});
1298 template <
class TEvent,
class TDeps,
class TSubs>
1299 bool process_event(
const TEvent &event, TDeps &deps, TSubs &subs) {
1300 policies::log_process_event<sm_t>(aux::type<logger_t>{}, deps, event);
1301 #if BOOST_SML_DISABLE_EXCEPTIONS 1302 const auto handled = process_event_impl<get_event_mapping_t<get_generic_t<TEvent>, mappings>>(
1303 event, deps, subs, states_t{}, aux::make_index_sequence<regions>{});
1305 const auto handled =
1306 process_event_noexcept<get_event_mapping_t<get_generic_t<TEvent>, mappings>>(event, deps, subs, has_exceptions{});
1309 while (process_internal_events(anonymous{}, deps, subs)) {
1311 process_defer_events(deps, subs, handled, aux::type<defer_queue_t<TEvent>>{}, events_t{});
1312 }
while (process_queued_events(deps, subs, aux::type<process_queue_t<TEvent>>{}, events_t{}) ||
1313 process_internal_events(anonymous{}, deps, subs));
1317 template <
class TState>
1318 void initialize(
const aux::type_list<TState> &) {
1319 current_state_[0] = aux::get_id<state_t, TState>((states_ids_t *)0);
1321 template <
class... TStates>
1322 void initialize(
const aux::type_list<TStates...> &) {
1324 #if defined(__cpp_fold_expressions) 1325 ((current_state_[region++] = aux::get_id<state_t, TStates>((states_ids_t *)0)), ...);
1327 (void)aux::swallow{0, (current_state_[region++] = aux::get_id<state_t, TStates>((states_ids_t *)0), 0)...};
1330 template <
class TDeps,
class TSubs>
1331 void start(TDeps &deps, TSubs &subs) {
1332 process_internal_events(on_entry<_, initial>{}, deps, subs);
1334 while (process_internal_events(anonymous{}, deps, subs)) {
1336 process_defer_events(deps, subs,
true, aux::type<defer_queue_t<initial>>{}, events_t{});
1337 }
while (process_queued_events(deps, subs, aux::type<process_queue_t<initial>>{}, events_t{}) ||
1338 process_internal_events(anonymous{}, deps, subs));
1340 template <
class TEvent,
class TDeps,
class TSubs,
class... Ts,
1341 __BOOST_SML_REQUIRES(!aux::is_base_of<get_generic_t<TEvent>, events_ids_t>::value &&
1342 !aux::is_base_of<get_mapped_t<TEvent>, events_ids_t>::value)>
1343 bool process_internal_events(
const TEvent &, TDeps &, TSubs &, Ts &&...) {
1346 template <
class TEvent,
class TDeps,
class TSubs,
1347 __BOOST_SML_REQUIRES(aux::is_base_of<get_generic_t<TEvent>, events_ids_t>::value &&
1348 !aux::is_base_of<get_mapped_t<TEvent>, events_ids_t>::value)>
1349 bool process_internal_events(
const TEvent &event, TDeps &deps, TSubs &subs) {
1350 policies::log_process_event<sm_t>(aux::type<logger_t>{}, deps, event);
1351 #if BOOST_SML_DISABLE_EXCEPTIONS 1352 return process_event_impl<get_event_mapping_t<get_generic_t<TEvent>, mappings>>(event, deps, subs, states_t{},
1353 aux::make_index_sequence<regions>{});
1355 return process_event_noexcept<get_event_mapping_t<get_generic_t<TEvent>, mappings>>(event, deps, subs, has_exceptions{});
1358 template <
class TEvent,
class TDeps,
class TSubs,
1359 __BOOST_SML_REQUIRES(aux::is_base_of<get_mapped_t<TEvent>, events_ids_t>::value)>
1360 bool process_internal_events(
const TEvent &event, TDeps &deps, TSubs &subs) {
1361 policies::log_process_event<sm_t>(aux::type<logger_t>{}, deps, event);
1362 #if BOOST_SML_DISABLE_EXCEPTIONS 1363 return process_event_impl<get_event_mapping_t<get_mapped_t<TEvent>, mappings>>(event, deps, subs, states_t{},
1364 aux::make_index_sequence<regions>{});
1366 return process_event_noexcept<get_event_mapping_t<get_mapped_t<TEvent>, mappings>>(event, deps, subs, has_exceptions{});
1369 template <
class TEvent,
class TDeps,
class TSubs,
class... Ts,
1370 __BOOST_SML_REQUIRES(!aux::is_base_of<get_generic_t<TEvent>, events_ids_t>::value &&
1371 !aux::is_base_of<get_mapped_t<TEvent>, events_ids_t>::value)>
1372 bool process_internal_event(
const TEvent &, TDeps &, TSubs &, Ts &&...) {
1375 template <
class TEvent,
class TDeps,
class TSubs,
1376 __BOOST_SML_REQUIRES(!aux::is_base_of<get_generic_t<TEvent>, events_ids_t>::value)>
1377 bool process_internal_generic_event(
const TEvent &, TDeps &, TSubs &, state_t &) {
1380 template <
class TEvent,
class TDeps,
class TSubs,
1381 __BOOST_SML_REQUIRES(aux::is_base_of<get_generic_t<TEvent>, events_ids_t>::value)>
1382 bool process_internal_generic_event(
const TEvent &event, TDeps &deps, TSubs &subs, state_t ¤t_state) {
1383 policies::log_process_event<sm_t>(aux::type<logger_t>{}, deps, event);
1384 #if BOOST_SML_DISABLE_EXCEPTIONS 1385 return process_event_impl<get_event_mapping_t<get_generic_t<TEvent>, mappings>>(event, deps, subs, states_t{},
1388 return process_event_noexcept<get_event_mapping_t<get_generic_t<TEvent>, mappings>>(event, deps, subs, current_state,
1392 template <
class TEvent,
class TDeps,
class TSubs,
1393 __BOOST_SML_REQUIRES(aux::is_base_of<get_generic_t<TEvent>, events_ids_t>::value &&
1394 !aux::is_base_of<get_mapped_t<TEvent>, events_ids_t>::value)>
1395 bool process_internal_event(
const TEvent &event, TDeps &deps, TSubs &subs, state_t ¤t_state) {
1396 return process_internal_generic_event(event, deps, subs, current_state);
1398 template <
class TEvent,
class TDeps,
class TSubs,
1399 __BOOST_SML_REQUIRES(aux::is_base_of<get_mapped_t<TEvent>, events_ids_t>::value)>
1400 bool process_internal_event(
const TEvent &event, TDeps &deps, TSubs &subs, state_t ¤t_state) {
1401 policies::log_process_event<sm_t>(aux::type<logger_t>{}, deps, event);
1402 #if BOOST_SML_DISABLE_EXCEPTIONS 1403 return process_event_impl<get_event_mapping_t<get_mapped_t<TEvent>, mappings>>(event, deps, subs, states_t{}, current_state)
1405 return process_event_noexcept<get_event_mapping_t<get_mapped_t<TEvent>, mappings>>(event, deps, subs, current_state,
1408 || process_internal_generic_event(event, deps, subs, current_state);
1410 template <
class TMappings,
class TEvent,
class TDeps,
class TSubs,
class... TStates>
1411 bool process_event_impl(
const TEvent &event, TDeps &deps, TSubs &subs,
const aux::type_list<TStates...> &states,
1412 aux::index_sequence<0>) {
1413 const auto lock = thread_safety_.create_lock();
1415 return dispatch_t::template dispatch<0, TMappings>(*
this, current_state_[0], event, deps, subs, states);
1417 template <
class TMappings,
class TEvent,
class TDeps,
class TSubs,
class... TStates,
int... Ns>
1418 bool process_event_impl(
const TEvent &event, TDeps &deps, TSubs &subs,
const aux::type_list<TStates...> &states,
1419 aux::index_sequence<Ns...>) {
1420 const auto lock = thread_safety_.create_lock();
1422 #if defined(__cpp_fold_expressions) 1423 return ((dispatch_t::template dispatch<0, TMappings>(*
this, current_state_[Ns], event, deps, subs, states)), ...);
1425 auto handled =
false;
1428 (handled |= dispatch_t::template dispatch<0, TMappings>(*
this, current_state_[Ns], event, deps, subs, states), 0)...};
1432 template <
class TMappings,
class TEvent,
class TDeps,
class TSubs,
class... TStates>
1433 bool process_event_impl(
const TEvent &event, TDeps &deps, TSubs &subs,
const aux::type_list<TStates...> &states,
1434 state_t ¤t_state) {
1435 const auto lock = thread_safety_.create_lock();
1437 return dispatch_t::template dispatch<0, TMappings>(*
this, current_state, event, deps, subs, states);
1439 #if !BOOST_SML_DISABLE_EXCEPTIONS 1440 template <
class TMappings,
class TEvent,
class TDeps,
class TSubs>
1441 bool process_event_noexcept(
const TEvent &event, TDeps &deps, TSubs &subs, aux::false_type) noexcept {
1442 return process_event_impl<TMappings>(event, deps, subs, states_t{}, aux::make_index_sequence<regions>{});
1444 template <
class TMappings,
class TEvent,
class TDeps,
class TSubs>
1445 bool process_event_noexcept(
const TEvent &event, TDeps &deps, TSubs &subs, state_t ¤t_state, aux::false_type) noexcept {
1446 return process_event_impl<TMappings>(event, deps, subs, states_t{}, current_state);
1448 template <
class TMappings,
class TEvent,
class TDeps,
class TSubs>
1449 bool process_event_noexcept(
const TEvent &event, TDeps &deps, TSubs &subs, state_t ¤t_state, aux::true_type) noexcept {
1451 return process_event_impl<TMappings>(event, deps, subs, states_t{}, current_state);
1453 return process_exception(deps, subs, exceptions{});
1456 template <
class TMappings,
class TEvent,
class TDeps,
class TSubs>
1457 bool process_event_noexcept(
const TEvent &event, TDeps &deps, TSubs &subs, aux::true_type) {
1459 return process_event_impl<TMappings>(event, deps, subs, states_t{}, aux::make_index_sequence<regions>{});
1461 return process_exception(deps, subs, exceptions{});
1464 template <
class TDeps,
class TSubs>
1465 bool process_exception(TDeps &deps, TSubs &subs,
const aux::type_list<> &) {
1466 return process_internal_events(exception<_>{}, deps, subs);
1468 template <
class TDeps,
class TSubs,
class E,
class... Es>
1469 bool process_exception(TDeps &deps, TSubs &subs,
const aux::type_list<E, Es...> &) {
1472 }
catch (
const typename E::type &e) {
1473 return process_internal_events(E{e}, deps, subs);
1475 return process_exception(deps, subs, aux::type_list<Es...>{});
1479 template <
class TDeps,
class TSubs,
class... TEvents>
1480 bool process_defer_events(TDeps &, TSubs &,
const bool,
const aux::type<no_policy> &,
const aux::type_list<TEvents...> &) {
1483 template <
class TDeps,
class TSubs,
class TEvent>
1484 bool process_event_no_defer(TDeps &deps, TSubs &subs,
const void *data) {
1485 const auto &
event = *
static_cast<const TEvent *
>(data);
1486 policies::log_process_event<sm_t>(aux::type<logger_t>{}, deps, event);
1487 #if BOOST_SML_DISABLE_EXCEPTIONS 1488 const auto handled = process_event_impl<get_event_mapping_t<TEvent, mappings>>(event, deps, subs, states_t{},
1489 aux::make_index_sequence<regions>{});
1491 const auto handled = process_event_noexcept<get_event_mapping_t<TEvent, mappings>>(event, deps, subs, has_exceptions{});
1493 if (handled && defer_again_) {
1496 defer_.erase(defer_it_);
1497 defer_it_ = defer_.begin();
1498 defer_end_ = defer_.end();
1502 template <
class TDeps,
class TSubs,
class TDeferQueue,
class... TEvents>
1503 bool process_defer_events(TDeps &deps, TSubs &subs,
const bool handled,
const aux::type<TDeferQueue> &,
1504 const aux::type_list<TEvents...> &) {
1505 bool processed_events =
false;
1507 using dispatch_table_t = bool (sm_impl::*)(TDeps &, TSubs &,
const void *);
1508 const static dispatch_table_t dispatch_table[__BOOST_SML_ZERO_SIZE_ARRAY_CREATE(
sizeof...(TEvents))] = {
1509 &sm_impl::process_event_no_defer<TDeps, TSubs, TEvents>...};
1510 defer_processing_ =
true;
1511 defer_again_ =
false;
1512 defer_it_ = defer_.begin();
1513 defer_end_ = defer_.end();
1514 processed_events = defer_it_ != defer_end_;
1515 while (defer_it_ != defer_end_) {
1516 (this->*dispatch_table[defer_it_->id])(deps, subs, defer_it_->data);
1517 defer_again_ =
false;
1519 defer_processing_ =
false;
1521 return processed_events;
1523 template <
class TDeps,
class TSubs,
class... TEvents>
1524 bool process_queued_events(TDeps &, TSubs &,
const aux::type<no_policy> &,
const aux::type_list<TEvents...> &) {
1527 template <
class TDeps,
class TSubs,
class TEvent>
1528 bool process_event_no_queue(TDeps &deps, TSubs &subs,
const void *data) {
1529 const auto &
event = *
static_cast<const TEvent *
>(data);
1530 policies::log_process_event<sm_t>(aux::type<logger_t>{}, deps, event);
1531 #if BOOST_SML_DISABLE_EXCEPTIONS 1532 return process_event_impl<get_event_mapping_t<TEvent, mappings>>(event, deps, subs, states_t{},
1533 aux::make_index_sequence<regions>{});
1535 return process_event_noexcept<get_event_mapping_t<TEvent, mappings>>(event, deps, subs, has_exceptions{});
1538 template <
class TDeps,
class TSubs,
class TDeferQueue,
class... TEvents>
1539 bool process_queued_events(TDeps &deps, TSubs &subs,
const aux::type<TDeferQueue> &,
const aux::type_list<TEvents...> &) {
1540 using dispatch_table_t = bool (sm_impl::*)(TDeps &, TSubs &,
const void *);
1541 const static dispatch_table_t dispatch_table[__BOOST_SML_ZERO_SIZE_ARRAY_CREATE(
sizeof...(TEvents))] = {
1542 &sm_impl::process_event_no_queue<TDeps, TSubs, TEvents>...};
1543 bool wasnt_empty = !process_.empty();
1544 while (!process_.empty()) {
1545 (this->*dispatch_table[process_.front().id])(deps, subs, process_.front().data);
1550 template <
class TVisitor,
class... TStates>
1551 void visit_current_states(
const TVisitor &visitor,
const aux::type_list<TStates...> &, aux::index_sequence<0>)
const {
1552 using dispatch_table_t = void (*)(
const TVisitor &);
1553 const static dispatch_table_t dispatch_table[__BOOST_SML_ZERO_SIZE_ARRAY_CREATE(
sizeof...(TStates))] = {
1554 &sm_impl::visit_state<TVisitor, TStates>...};
1555 dispatch_table[current_state_[0]](visitor);
1557 template <
class TVisitor,
class... TStates,
int... Ns>
1558 void visit_current_states(
const TVisitor &visitor,
const aux::type_list<TStates...> &, aux::index_sequence<Ns...>)
const {
1559 using dispatch_table_t = void (*)(
const TVisitor &);
1560 const static dispatch_table_t dispatch_table[__BOOST_SML_ZERO_SIZE_ARRAY_CREATE(
sizeof...(TStates))] = {
1561 &sm_impl::visit_state<TVisitor, TStates>...};
1562 #if defined(__cpp_fold_expressions) 1563 (dispatch_table[current_state_[Ns]](visitor), ...);
1565 (void)aux::swallow{0, (dispatch_table[current_state_[Ns]](visitor), 0)...};
1568 template <
class TVisitor,
class TState>
1569 static void visit_state(
const TVisitor &visitor) {
1570 visitor(aux::string<TState>{});
1572 bool is_terminated()
const {
return is_terminated_impl(aux::make_index_sequence<regions>{}); }
1573 bool is_terminated_impl(aux::index_sequence<0>)
const {
1574 return current_state_[0] == aux::get_id<state_t, terminate_state>((states_ids_t *)0);
1576 template <
int... Ns>
1577 bool is_terminated_impl(aux::index_sequence<Ns...>)
const {
1578 #if defined(__cpp_fold_expressions) 1579 return ((current_state_[Ns] == aux::get_id<state_t, terminate_state>((states_ids_t *)0)) && ...);
1583 0, (current_state_[Ns] == aux::get_id<state_t, terminate_state>((states_ids_t *)0) ? result : (result =
false))...};
1587 transitions_t transitions_;
1588 state_t current_state_[regions];
1589 thread_safety_t thread_safety_;
1592 defer_flag_t defer_processing_ = defer_flag_t{};
1593 defer_flag_t defer_again_ = defer_flag_t{};
1594 typename defer_t::const_iterator defer_it_;
1595 typename defer_t::const_iterator defer_end_;
1597 template <
class TSM>
1599 using sm_t =
typename TSM::sm;
1600 using logger_t =
typename TSM::logger_policy::type;
1601 using logger_dep_t =
1602 aux::conditional_t<aux::is_same<no_policy, logger_t>::value, aux::type_list<>, aux::type_list<logger_t &>>;
1603 using transitions_t = decltype(aux::declval<sm_t>().
operator()());
1604 static_assert(concepts::composable<sm_t>::value,
"Composable constraint is not satisfied!");
1607 using states = aux::apply_t<aux::unique_t, aux::apply_t<get_states, transitions_t>>;
1608 using state_machines = aux::apply_t<get_sub_sms, states>;
1609 using events = aux::apply_t<aux::unique_t, aux::apply_t<get_all_events, transitions_t>>;
1610 using transitions = aux::apply_t<aux::type_list, transitions_t>;
1613 using sm_all_t = aux::apply_t<get_non_empty_t, aux::join_t<aux::type_list<sm_t>, aux::apply_t<get_sm_t, state_machines>>>;
1615 aux::apply_t<aux::pool,
1616 typename convert_to_sm<TSM, aux::apply_t<aux::unique_t, aux::apply_t<get_sub_sms, states>>>::type>;
1617 using deps = aux::apply_t<merge_deps, transitions_t>;
1619 aux::apply_t<aux::pool,
1620 aux::apply_t<aux::unique_t, aux::join_t<deps, sm_all_t, logger_dep_t, aux::apply_t<merge_deps, sub_sms_t>>>>;
1621 struct events_ids : aux::apply_t<aux::inherit, events> {};
1624 sm() : deps_{aux::init{}, aux::pool<>{}}, sub_sms_{aux::pool<>{}} { aux::get<sm_impl<TSM>>(sub_sms_).
start(deps_, sub_sms_); }
1625 template <
class TDeps, __BOOST_SML_REQUIRES(!aux::is_same<aux::remove_reference_t<TDeps>, sm>::value)>
1626 explicit sm(TDeps &&deps) : deps_{aux::init{}, aux::pool<TDeps>{deps}}, sub_sms_{aux::pool<TDeps>{deps}} {
1627 aux::get<sm_impl<TSM>>(sub_sms_).
start(deps_, sub_sms_);
1629 template <
class... TDeps, __BOOST_SML_REQUIRES((
sizeof...(TDeps) > 1) && aux::is_unique_t<TDeps...>::value)>
1630 explicit sm(TDeps &&... deps) : deps_{aux::init{}, aux::pool<TDeps...>{deps...}}, sub_sms_{aux::pool<TDeps...>{deps...}} {
1631 aux::get<sm_impl<TSM>>(sub_sms_).
start(deps_, sub_sms_);
1633 sm(aux::init, deps_t &deps) : deps_{deps}, sub_sms_{deps} { aux::get<sm_impl<TSM>>(sub_sms_).
start(deps_, sub_sms_); }
1634 sm(
const sm &) =
default;
1635 sm(sm &&) =
default;
1636 sm &operator=(
const sm &) =
default;
1637 sm &operator=(sm &&) =
default;
1638 template <class TEvent, __BOOST_SML_REQUIRES(aux::is_base_of<TEvent, events_ids>::value)>
1639 bool process_event(
const TEvent &event) {
1640 return aux::get<sm_impl<TSM>>(sub_sms_).process_event(event, deps_, sub_sms_);
1642 template <class TEvent, __BOOST_SML_REQUIRES(!aux::is_base_of<TEvent, events_ids>::value)>
1643 bool process_event(
const TEvent &event) {
1644 return aux::get<sm_impl<TSM>>(sub_sms_).process_event(unexpected_event<_, TEvent>{
event}, deps_, sub_sms_);
1646 template <
class T = aux::
identity<sm_t>,
class TVisitor, __BOOST_SML_REQUIRES(concepts::callable<
void, TVisitor>::value)>
1647 void visit_current_states(
const TVisitor &visitor)
const {
1648 using type =
typename T::type;
1649 using sm_impl_t = sm_impl<typename TSM::template rebind<type>>;
1650 using states_t =
typename sm_impl_t::states_t;
1651 constexpr
auto regions = sm_impl_t::regions;
1652 aux::cget<sm_impl_t>(sub_sms_).visit_current_states(visitor, states_t{}, aux::make_index_sequence<regions>{});
1654 template <
class T = aux::
identity<sm_t>,
class TState>
1655 bool is(
const TState &)
const {
1656 using type =
typename T::type;
1657 using sm_impl_t = sm_impl<typename TSM::template rebind<type>>;
1658 using state_t =
typename sm_impl_t::state_t;
1659 using states_ids_t =
typename sm_impl_t::states_ids_t;
1660 return aux::get_id<state_t, typename TState::type>((states_ids_t *)0) == aux::cget<sm_impl_t>(sub_sms_).current_state_[0];
1662 template <
class T = aux::
identity<sm_t>,
template <
class...>
class TState>
1663 bool is(
const TState<terminate_state> &)
const {
1664 using type =
typename T::type;
1665 using sm_impl_t = sm_impl<typename TSM::template rebind<type>>;
1666 using state_t =
typename sm_impl_t::state_t;
1667 using states_ids_t =
typename sm_impl_t::states_ids_t;
1668 auto result =
false;
1669 visit_current_states<T>([&](
auto state) {
1671 result |= (aux::get_id<state_t, terminate_state>((states_ids_t *)0) ==
1672 aux::get_id<state_t, typename decltype(state)::type>((states_ids_t *)0));
1676 template <
class T = aux::
identity<sm_t>,
class... TStates,
1677 __BOOST_SML_REQUIRES(sizeof...(TStates) == sm_impl<
typename TSM::
template rebind<
typename T::type>>::regions)>
1678 bool is(
const TStates &...)
const {
1679 using type =
typename T::type;
1680 using sm_impl_t = sm_impl<typename TSM::template rebind<type>>;
1681 using states_ids_t =
typename sm_impl_t::states_ids_t;
1682 using state_t =
typename sm_impl_t::state_t;
1685 state_t state_ids[] = {aux::get_id<state_t, typename TStates::type>((states_ids_t *)0)...};
1686 visit_current_states<T>([&](
auto state) {
1688 result &= (aux::get_id<state_t, typename decltype(state)::type>((states_ids_t *)0) == state_ids[i++]);
1692 template <
class T = aux::
identity<sm_t>,
class... TStates,
1693 __BOOST_SML_REQUIRES(!aux::is_same<no_policy,
typename TSM::testing_policy>::value && aux::always<T>::value)>
1694 void set_current_states(
const TStates &...) {
1695 using type =
typename T::type;
1696 using sm_impl_t = sm_impl<typename TSM::template rebind<type>>;
1697 using states_ids_t =
typename sm_impl_t::states_ids_t;
1698 using state_t =
typename sm_impl_t::state_t;
1699 auto &sm = aux::get<sm_impl_t>(sub_sms_);
1701 #if defined(__cpp_fold_expressions) 1702 ((sm.current_state_[region++] = aux::get_id<state_t, typename TStates::type>((states_ids_t *)0)), ...);
1704 (void)aux::swallow{0,
1705 (sm.current_state_[region++] = aux::get_id<state_t, typename TStates::type>((states_ids_t *)0), 0)...};
1710 return aux::get<sm_impl<typename TSM::template rebind<T>>>(sub_sms_);
1713 operator const T &() {
1714 return aux::cget<sm_impl<typename TSM::template rebind<T>>>(sub_sms_);
1723 struct operator_base {};
1724 struct action_base {};
1725 template <
class TRootSM,
class... TSubSMs>
1726 TRootSM get_root_sm_impl(aux::pool<TRootSM, TSubSMs...> *);
1727 template <
class TSubs>
1728 using get_root_sm_t = decltype(get_root_sm_impl((TSubs *)0));
1729 template <
class,
class>
1730 aux::type_list<action_base> args1__(...);
1731 template <
class T,
class E>
1732 auto args1__(
int) -> aux::function_traits_t<decltype(&T::operator())>;
1733 template <
class T,
class E>
1734 auto args__(
int) -> aux::function_traits_t<decltype(&T::__BOOST_SML_TEMPLATE_KEYWORD operator()<back::get_event_t<E>>)>;
1735 template <
class T,
class E>
1736 auto args__(...) -> decltype(args1__<T, E>(0));
1737 template <
class T,
class E>
1738 using args_t = decltype(args__<T, E>(0));
1739 template <
class T,
class TEvent,
class TSM,
class TDeps>
1740 decltype(
auto) get_arg(const aux::type<T> &, const TEvent &, TSM &, TDeps &deps) {
1741 return aux::get<T>(deps);
1743 template <
class TEvent,
class TSM,
class TDeps>
1744 decltype(
auto) get_arg(const aux::type<TEvent> &, const TEvent &event, TSM &, TDeps &) {
1747 template <
class TEvent,
class TSM,
class TDeps>
1748 decltype(
auto) get_arg(const aux::type<const TEvent &> &, const TEvent &event, TSM &, TDeps &) {
1751 template <
class T,
class TEvent,
class TSM,
class TDeps>
1752 decltype(
auto) get_arg(const aux::type<const TEvent &> &, const back::unexpected_event<T, TEvent> &event, TSM &, TDeps &) {
1753 return event.event_;
1755 template <
class T,
class TEvent,
class TSM,
class TDeps>
1756 decltype(
auto) get_arg(const aux::type<const TEvent &> &, const back::on_entry<T, TEvent> &event, TSM &, TDeps &) {
1757 return event.event_;
1759 template <
class T,
class TEvent,
class TSM,
class TDeps>
1760 decltype(
auto) get_arg(const aux::type<const TEvent &> &, const back::on_exit<T, TEvent> &event, TSM &, TDeps &) {
1761 return event.event_;
1763 template <
class T,
class TEvent,
class TSM,
class TDeps>
1764 decltype(
auto) get_arg(const aux::type<const TEvent &> &, const back::exception<T, TEvent> &event, TSM &, TDeps &) {
1765 return event.exception_;
1767 template <
class... TEvents,
class TEvent,
class TSM,
class TDeps>
1768 decltype(
auto) get_arg(const aux::type<back::defer<TEvents...>> &, const TEvent, TSM &sm, TDeps &) {
1769 return back::defer<TEvents...>{sm.defer_};
1771 template <
class... TEvents,
class TEvent,
class TSM,
class TDeps>
1772 decltype(
auto) get_arg(const aux::type<back::process<TEvents...>> &, const TEvent, TSM &sm, TDeps &) {
1773 return back::process<TEvents...>{sm.process_};
1775 template <
class,
class,
class>
1777 template <
class TEvent>
1778 struct call<TEvent, aux::type_list<>, back::no_policy> {
1779 template <
class T,
class TSM,
class TDeps,
class TSubs>
1780 static auto execute(T
object,
const TEvent &, TSM &, TDeps &, TSubs &) {
1784 template <
class TEvent,
class TLogger>
1785 struct call<TEvent, aux::type_list<>, TLogger> {
1786 template <
class T,
class TSM,
class TDeps,
class TSubs>
1787 static auto execute(T
object,
const TEvent &event, TSM &, TDeps &deps, TSubs &) {
1788 using result_type = decltype(
object());
1789 return execute_impl<typename TSM::sm_t>(aux::type<result_type>{}, object, event, deps);
1791 template <
class TSM,
class T,
class TDeps>
1792 static auto execute_impl(
const aux::type<bool> &, T
object,
const TEvent &event, TDeps &deps) {
1793 const auto result = object();
1794 back::policies::log_guard<TSM>(aux::type<TLogger>{}, deps, object, event, result);
1797 template <
class TSM,
class T,
class TDeps>
1798 static auto execute_impl(
const aux::type<void> &, T
object,
const TEvent &event, TDeps &deps) {
1799 back::policies::log_action<TSM>(aux::type<TLogger>{}, deps, object, event);
1803 template <
class TEvent>
1804 struct call<TEvent, aux::type_list<TEvent>, back::no_policy> {
1805 template <
class T,
class TSM,
class TDeps,
class TSubs>
1806 static auto execute(T
object,
const TEvent &event, TSM &, TDeps &, TSubs &) {
1807 return object(event);
1810 template <
class TEvent,
class TLogger>
1811 struct call<TEvent, aux::type_list<TEvent>, TLogger> {
1812 template <
class T,
class TSM,
class TDeps,
class TSubs>
1813 static auto execute(T
object,
const TEvent &event, TSM &, TDeps &deps, TSubs &) {
1814 using result_type = decltype(
object(event));
1815 return execute_impl<typename TSM::sm_t>(aux::type<result_type>{}, object, event, deps);
1817 template <
class TSM,
class T,
class TDeps>
1818 static auto execute_impl(
const aux::type<bool> &, T
object,
const TEvent &event, TDeps &deps) {
1819 const auto result = object(event);
1820 back::policies::log_guard<TSM>(aux::type<TLogger>{}, deps, object, event, result);
1823 template <
class TSM,
class T,
class TDeps>
1824 static auto execute_impl(
const aux::type<void> &, T
object,
const TEvent &event, TDeps &deps) {
1825 back::policies::log_action<TSM>(aux::type<TLogger>{}, deps, object, event);
1829 template <
class TEvent>
1830 struct call<TEvent, aux::type_list<action_base>, back::no_policy> {
1831 template <
class T,
class TSM,
class TDeps,
class TSubs>
1832 static auto execute(T
object,
const TEvent &event, TSM &sm, TDeps &deps, TSubs &subs) {
1833 return object(event, sm, deps, subs);
1836 template <
class TEvent,
class TLogger>
1837 struct call<TEvent, aux::type_list<action_base>, TLogger> {
1838 template <
class T,
class TSM,
class TDeps,
class TSubs>
1839 static auto execute(T
object,
const TEvent &event, TSM &sm, TDeps &deps, TSubs &subs) {
1840 return object(event, sm, deps, subs);
1843 template <
class TEvent,
class... Ts>
1844 struct call<TEvent, aux::type_list<Ts...>, back::no_policy> {
1845 template <
class T,
class TSM,
class TDeps,
class TSubs>
1846 static auto execute(T
object,
const TEvent &event, TSM &sm, TDeps &deps, TSubs &) {
1847 return object(get_arg(aux::type<Ts>{}, event, sm, deps)...);
1850 template <
class TEvent,
class... Ts,
class TLogger>
1851 struct call<TEvent, aux::type_list<Ts...>, TLogger> {
1852 template <
class T,
class TSM,
class TDeps,
class TSubs>
1853 static auto execute(T
object,
const TEvent &event, TSM &sm, TDeps &deps, TSubs &) {
1854 using result_type = decltype(
object(get_arg(aux::type<Ts>{}, event, sm, deps)...));
1855 return execute_impl<typename TSM::sm_t>(aux::type<result_type>{}, object, event, sm, deps);
1857 template <
class TSM,
class T,
class SM,
class TDeps>
1858 static auto execute_impl(
const aux::type<bool> &, T
object,
const TEvent &event, SM &sm, TDeps &deps) {
1859 const auto result = object(get_arg(aux::type<Ts>{}, event, sm, deps)...);
1860 back::policies::log_guard<TSM>(aux::type<TLogger>{}, deps, object, event, result);
1863 template <
class TSM,
class T,
class SM,
class TDeps>
1864 static auto execute_impl(
const aux::type<void> &, T
object,
const TEvent &event, SM &sm, TDeps &deps) {
1865 back::policies::log_action<TSM>(aux::type<TLogger>{}, deps, object, event);
1866 object(get_arg(aux::type<Ts>{}, event, sm, deps)...);
1869 template <
class... Ts>
1870 class seq_ : operator_base {
1872 explicit seq_(Ts... ts) : a(ts...) {}
1873 template <
class TEvent,
class TSM,
class TDeps,
class TSubs>
1874 void operator()(
const TEvent &event, TSM &sm, TDeps &deps, TSubs &subs) {
1875 for_all(aux::make_index_sequence<
sizeof...(Ts)>{}, event, sm, deps, subs);
1879 template <
int... Ns,
class TEvent,
class TSM,
class TDeps,
class TSubs>
1880 void for_all(
const aux::index_sequence<Ns...> &,
const TEvent &event, TSM &sm, TDeps &deps, TSubs &subs) {
1881 #if defined(__cpp_fold_expressions) 1882 (call<TEvent, args_t<Ts, TEvent>,
typename TSM::logger_t>::execute(aux::get_by_id<Ns>(&a), event, sm, deps, subs), ...);
1885 0, (call<TEvent, args_t<Ts, TEvent>,
typename TSM::logger_t>::execute(aux::get_by_id<Ns>(&a), event, sm, deps, subs),
1889 aux::tuple<Ts...> a;
1891 template <
class... Ts>
1892 class and_ : operator_base {
1894 explicit and_(Ts... ts) : g(ts...) {}
1895 template <
class TEvent,
class TSM,
class TDeps,
class TSubs>
1896 auto operator()(
const TEvent &event, TSM &sm, TDeps &deps, TSubs &subs) {
1897 return for_all(aux::make_index_sequence<
sizeof...(Ts)>{}, event, sm, deps, subs);
1901 template <
int... Ns,
class TEvent,
class TSM,
class TDeps,
class TSubs>
1902 auto for_all(
const aux::index_sequence<Ns...> &,
const TEvent &event, TSM &sm, TDeps &deps, TSubs &subs) {
1903 #if defined(__cpp_fold_expressions) 1904 return (call<TEvent, args_t<Ts, TEvent>,
typename TSM::logger_t>::
execute(aux::get_by_id<Ns>(&g), event, sm, deps, subs) &&
1908 (void)aux::swallow{0, (result && call<TEvent, args_t<Ts, TEvent>,
typename TSM::logger_t>::execute(aux::get_by_id<Ns>(&g),
1909 event, sm, deps, subs)
1911 : (result =
false))...};
1915 aux::tuple<Ts...> g;
1917 template <
class... Ts>
1918 class or_ : operator_base {
1920 explicit or_(Ts... ts) : g(ts...) {}
1921 template <
class TEvent,
class TSM,
class TDeps,
class TSubs>
1922 auto operator()(
const TEvent &event, TSM &sm, TDeps &deps, TSubs &subs) {
1923 return for_all(aux::make_index_sequence<
sizeof...(Ts)>{}, event, sm, deps, subs);
1927 template <
int... Ns,
class TEvent,
class TSM,
class TDeps,
class TSubs>
1928 auto for_all(
const aux::index_sequence<Ns...> &,
const TEvent &event, TSM &sm, TDeps &deps, TSubs &subs) {
1929 #if defined(__cpp_fold_expressions) 1930 return (call<TEvent, args_t<Ts, TEvent>,
typename TSM::logger_t>::
execute(aux::get_by_id<Ns>(&g), event, sm, deps, subs) ||
1933 auto result =
false;
1934 (void)aux::swallow{0, (result || call<TEvent, args_t<Ts, TEvent>,
typename TSM::logger_t>::execute(aux::get_by_id<Ns>(&g),
1935 event, sm, deps, subs)
1941 aux::tuple<Ts...> g;
1944 class not_ : operator_base {
1946 explicit not_(T t) : g(t) {}
1947 template <
class TEvent,
class TSM,
class TDeps,
class TSubs>
1948 auto operator()(
const TEvent &event, TSM &sm, TDeps &deps, TSubs &subs) {
1949 return !call<TEvent, args_t<T, TEvent>,
typename TSM::logger_t>::execute(g, event, sm, deps, subs);
1956 template <class T, __BOOST_SML_REQUIRES(concepts::callable<bool, T>::value)>
1957 auto operator!(
const T &t) {
1958 return front::not_<aux::zero_wrapper<T>>(aux::zero_wrapper<T>{t});
1960 template <class T1, class T2, __BOOST_SML_REQUIRES(concepts::callable<bool, T1>::value &&concepts::callable<bool, T2>::value)>
1961 auto operator&&(
const T1 &t1,
const T2 &t2) {
1962 return front::and_<aux::zero_wrapper<T1>, aux::zero_wrapper<T2>>(aux::zero_wrapper<T1>{t1}, aux::zero_wrapper<T2>{t2});
1964 template <class T1, class T2, __BOOST_SML_REQUIRES(concepts::callable<bool, T1>::value &&concepts::callable<bool, T2>::value)>
1965 auto operator||(
const T1 &t1,
const T2 &t2) {
1966 return front::or_<aux::zero_wrapper<T1>, aux::zero_wrapper<T2>>(aux::zero_wrapper<T1>{t1}, aux::zero_wrapper<T2>{t2});
1968 template <class T1, class T2, __BOOST_SML_REQUIRES(concepts::callable<void, T1>::value &&concepts::callable<void, T2>::value)>
1969 auto operator,(
const T1 &t1,
const T2 &t2) {
1970 return front::seq_<aux::zero_wrapper<T1>, aux::zero_wrapper<T2>>(aux::zero_wrapper<T1>{t1}, aux::zero_wrapper<T2>{t2});
1974 struct defer : action_base {
1975 template <
class TEvent,
class TSM,
class TDeps,
class TSubs>
1976 void operator()(
const TEvent &event, TSM &sm, TDeps &, TSubs &) {
1977 if (sm.defer_processing_) {
1978 sm.defer_again_ =
true;
1980 sm.defer_.push_back(event);
1986 using testing = back::policies::testing;
1988 using logger = back::policies::logger<T>;
1990 using thread_safe = back::policies::thread_safe<T>;
1992 using dispatch = back::policies::dispatch<T>;
1993 template <
template <
class...>
class T>
1994 using defer_queue = back::policies::defer_queue<T>;
1995 template <
template <
class...>
class T>
1996 using process_queue = back::policies::process_queue<T>;
1997 #if defined(COMPILING_WITH_MSVC) 1998 template <
class T,
class... TPolicies,
class T__ = aux::remove_reference_t<decltype(aux::declval<T>())>>
1999 using sm = back::sm<back::sm_policy<T__, TPolicies...>>;
2001 template <
class T,
class... TPolicies>
2002 using sm = back::sm<back::sm_policy<T, TPolicies...>>;
2004 namespace concepts {
2005 aux::false_type transitional_impl(...);
2007 auto transitional_impl(T &&t) -> aux::always<
typename T::dst_state,
typename T::src_state,
typename T::event,
typename T::deps,
2008 decltype(T::initial), decltype(T::history)>;
2010 struct transitional : decltype(transitional_impl(aux::declval<T>())) {};
2015 template <
class TEvent>
2016 class process_impl :
public action_base {
2018 explicit process_impl(
const TEvent &event) : event(event) {}
2019 template <
class T,
class TSM,
class TDeps,
class TSubs>
2020 void operator()(
const T &, TSM &, TDeps &, TSubs &subs) {
2021 aux::get<get_root_sm_t<TSubs>>(subs).process_.push(event);
2027 template <
class TEvent>
2028 auto operator()(
const TEvent &event) {
2029 return process_impl<TEvent>{
event};
2035 template <
class,
class>
2036 struct transition_eg;
2037 template <
class,
class>
2038 struct transition_ea;
2039 template <
class TEvent>
2041 template <class T, __BOOST_SML_REQUIRES(concepts::callable<bool, T>::value)>
2042 auto operator[](
const T &t)
const {
2043 return transition_eg<event, aux::zero_wrapper<T>>{*
this, aux::zero_wrapper<T>{t}};
2045 template <class T, __BOOST_SML_REQUIRES(concepts::callable<void, T>::value)>
2046 auto operator/(
const T &t)
const {
2047 return transition_ea<event, aux::zero_wrapper<T>>{*
this, aux::zero_wrapper<T>{t}};
2049 auto operator()()
const {
return TEvent{}; }
2053 struct initial_state {};
2054 struct history_state {};
2057 template <
class,
class>
2058 struct transition_sa;
2059 template <
class,
class>
2060 struct transition_sg;
2061 template <
class,
class>
2062 struct transition_eg;
2065 template <
class TState>
2068 auto operator<=(
const T &t)
const {
2069 return transition<TState, T>{
static_cast<const TState &
>(*this), t};
2072 auto operator+(
const T &t)
const {
2073 return transition<TState, T>{
static_cast<const TState &
>(*this), t};
2075 template <class T, __BOOST_SML_REQUIRES(concepts::callable<bool, T>::value)>
2076 auto operator[](
const T &t)
const {
2077 return transition_sg<TState, aux::zero_wrapper<T>>{
static_cast<const TState &
>(*this), aux::zero_wrapper<T>{t}};
2079 template <class T, __BOOST_SML_REQUIRES(concepts::callable<void, T>::value)>
2080 auto operator/(
const T &t)
const {
2081 return transition_sa<TState, aux::zero_wrapper<T>>{
static_cast<const TState &
>(*this), aux::zero_wrapper<T>{t}};
2084 template <
class TState>
2085 struct state : state_impl<state<TState>> {
2086 using type = TState;
2087 static constexpr
auto initial =
false;
2088 static constexpr
auto history =
false;
2089 auto operator*()
const {
return state<TState(initial_state)>{}; }
2090 auto operator()(
const initial_state &)
const {
return state<TState(initial_state)>{}; }
2091 auto operator()(
const history_state &)
const {
return state<TState(history_state)>{}; }
2092 template <
class... Ts>
2093 auto operator()(
const state<Ts> &...)
const {
2094 return state<TState(Ts...)>{};
2097 auto operator=(
const T &t)
const {
2098 return transition<T, state>{t, *
this};
2102 return state<back::sm<back::sm_policy<T, aux::identity<TState>>>>{};
2105 template <
class TState>
2106 struct state<TState(initial_state)> : state_impl<state<TState(initial_state)>> {
2107 using type = TState;
2108 static constexpr
auto initial =
true;
2109 static constexpr
auto history =
false;
2111 auto operator=(
const T &t)
const {
2112 return transition<T, state>{t, *
this};
2115 template <
class TState>
2116 struct state<TState(history_state)> : state_impl<state<TState(history_state)>> {
2117 using type = TState;
2118 static constexpr
auto initial =
true;
2119 static constexpr
auto history =
true;
2121 auto operator=(
const T &t)
const {
2122 return transition<T, state>{t, *
this};
2125 #if defined(COMPILING_WITH_MSVC) 2126 template <
class T,
class T__ = aux::remove_reference_t<decltype(aux::declval<T>())>,
class =
void>
2128 using type = state<T>;
2130 template <
class T,
class T__>
2131 struct state_sm<T, T__, aux::enable_if_t<concepts::composable<T__>::value>> {
2132 using type = state<back::sm<back::sm_policy<T__>>>;
2135 template <
class T,
class =
void>
2137 using type = state<T>;
2140 struct state_sm<T, aux::enable_if_t<concepts::composable<T>::value>> {
2141 using type = state<back::sm<back::sm_policy<T>>>;
2147 template <
class,
class>
2149 template <
class E,
class... Ts>
2150 struct ignore<E, aux::type_list<Ts...>> {
2154 aux::conditional_t<aux::is_same<back::get_event_t<E>, aux::remove_const_t<aux::remove_reference_t<T>>>::value ||
2155 aux::is_same<T, action_base>::value,
2156 aux::type_list<>, aux::type_list<T>>;
2158 using type = aux::join_t<typename non_events<Ts>::type...>;
2160 template <
class T,
class E,
class =
void>
2162 using type =
typename ignore<E, args_t<T, E>>::type;
2164 template <
class T,
class E>
2165 using get_deps_t =
typename get_deps<T, E>::type;
2166 template <
template <
class...>
class T,
class... Ts,
class E>
2167 struct get_deps<T<Ts...>, E, aux::enable_if_t<aux::is_base_of<operator_base, T<Ts...>>::value>> {
2168 using type = aux::join_t<get_deps_t<Ts, E>...>;
2171 using type = always;
2172 bool operator()()
const {
return true; }
2173 __BOOST_SML_ZERO_SIZE_ARRAY(aux::byte);
2177 void operator()() {}
2178 __BOOST_SML_ZERO_SIZE_ARRAY(aux::byte);
2182 template <
class E,
class G>
2183 struct transition<front::event<E>, G> {
2185 auto operator/(
const T &t)
const {
2186 return transition<front::event<E>, G, aux::zero_wrapper<T>>{e, g, aux::zero_wrapper<T>{t}};
2191 template <
class E,
class G,
class A>
2192 struct transition<front::event<E>, G, A> {
2197 template <
class S2,
class G,
class A>
2198 struct transition<state<S2>, G, A> : transition<state<internal>, state<S2>, front::event<back::anonymous>, G, A> {
2199 using transition<state<internal>, state<S2>, front::event<back::anonymous>, G, A>::g;
2200 using transition<state<internal>, state<S2>, front::event<back::anonymous>, G, A>::a;
2201 transition(
const G &g,
const A &a) : transition<state<internal>, state<S2>, front::event<back::anonymous>, G, A>{g, a} {}
2203 auto operator=(
const T &)
const {
2204 return transition<T, state<S2>, front::event<back::anonymous>, G, A>{g, a};
2207 template <
class S1,
class S2>
2208 struct transition<state<S1>, state<S2>> : transition<state<S1>, state<S2>, front::event<back::anonymous>, always, none> {
2209 transition(
const state<S1> &,
const state<S2> &)
2210 : transition<state<S1>, state<S2>, front::event<back::anonymous>, always, none>{always{}, none{}} {}
2212 template <
class S2,
class G>
2213 struct transition_sg<state<S2>, G> : transition<state<internal>, state<S2>, front::event<back::anonymous>, G, none> {
2214 using transition<state<internal>, state<S2>, front::event<back::anonymous>, G, none>::g;
2215 transition_sg(
const state<S2> &,
const G &g)
2216 : transition<state<internal>, state<S2>, front::event<back::anonymous>, G, none>{g, none{}} {}
2218 auto operator/(
const T &t)
const {
2219 return transition<state<S2>, G, aux::zero_wrapper<T>>{g, aux::zero_wrapper<T>{t}};
2222 auto operator=(
const T &)
const {
2223 return transition<T, state<S2>, front::event<back::anonymous>, G, none>{g, none{}};
2226 template <
class S2,
class A>
2227 struct transition_sa<state<S2>, A> : transition<state<internal>, state<S2>, front::event<back::anonymous>, always, A> {
2228 using transition<state<internal>, state<S2>, front::event<back::anonymous>, always, A>::a;
2229 transition_sa(
const state<S2> &,
const A &a)
2230 : transition<state<internal>, state<S2>, front::event<back::anonymous>, always, A>{always{}, a} {}
2232 auto operator=(
const T &)
const {
2233 return transition<T, state<S2>, front::event<back::anonymous>, always, A>{always{}, a};
2236 template <
class S2,
class E>
2237 struct transition<state<S2>, front::event<E>> {
2239 auto operator=(
const T &)
const {
2240 return transition<T, state<S2>, front::event<E>, always, none>{always{}, none{}};
2242 const state<S2> &s2;
2245 template <
class E,
class G>
2246 struct transition_eg<front::event<E>, G> {
2248 auto operator/(
const T &t)
const {
2249 return transition<front::event<E>, G, aux::zero_wrapper<T>>{e, g, aux::zero_wrapper<T>{t}};
2254 template <
class E,
class A>
2255 struct transition_ea<front::event<E>, A> {
2259 template <
class S1,
class S2,
class G,
class A>
2260 struct transition<state<S1>, transition<state<S2>, G, A>>
2261 : transition<state<S1>, state<S2>, front::event<back::anonymous>, G, A> {
2262 transition(
const state<S1> &,
const transition<state<S2>, G, A> &t)
2263 : transition<state<S1>, state<S2>, front::event<back::anonymous>, G, A>{t.g, t.a} {}
2265 template <
class S1,
class E,
class G,
class A>
2266 struct transition<state<S1>, transition<front::event<E>, G, A>>
2267 : transition<state<internal>, state<S1>, front::event<E>, G, A> {
2268 using transition<state<internal>, state<S1>, front::event<E>, G, A>::g;
2269 using transition<state<internal>, state<S1>, front::event<E>, G, A>::a;
2270 transition(
const state<S1> &,
const transition<front::event<E>, G, A> &t)
2271 : transition<state<internal>, state<S1>, front::event<E>, G, A>{t.g, t.a} {}
2273 auto operator=(
const T &)
const {
2274 return transition<T, state<S1>, front::event<E>, G, A>{g, a};
2277 template <
class S1,
class S2,
class E>
2278 struct transition<state<S1>, transition<state<S2>, front::event<E>>>
2279 : transition<state<S1>, state<S2>, front::event<E>, always, none> {
2280 transition(
const state<S1> &,
const transition<state<S2>, front::event<E>> &)
2281 : transition<state<S1>, state<S2>, front::event<E>, always, none>{always{}, none{}} {}
2283 template <
class S1,
class S2,
class G>
2284 struct transition<state<S1>, transition_sg<state<S2>, G>>
2285 : transition<state<S1>, state<S2>, front::event<back::anonymous>, G, none> {
2286 transition(
const state<S1> &,
const transition_sg<state<S2>, G> &t)
2287 : transition<state<S1>, state<S2>, front::event<back::anonymous>, G, none>{t.g, none{}} {}
2289 template <
class S1,
class S2,
class A>
2290 struct transition<state<S1>, transition_sa<state<S2>, A>>
2291 : transition<state<S1>, state<S2>, front::event<back::anonymous>, always, A> {
2292 transition(
const state<S1> &,
const transition_sa<state<S2>, A> &t)
2293 : transition<state<S1>, state<S2>, front::event<back::anonymous>, always, A>{always{}, t.a} {}
2295 template <
class S2,
class E,
class G>
2296 struct transition<state<S2>, transition_eg<front::event<E>, G>>
2297 : transition<state<internal>, state<S2>, front::event<E>, G, none> {
2298 using transition<state<internal>, state<S2>, front::event<E>, G, none>::g;
2299 transition(
const state<S2> &,
const transition_eg<front::event<E>, G> &t)
2300 : transition<state<internal>, state<S2>, front::event<E>, G, none>{t.g, none{}} {}
2302 auto operator=(
const T &)
const {
2303 return transition<T, state<S2>, front::event<E>, G, none>{g, none{}};
2306 template <
class S1,
class S2,
class E,
class G>
2307 struct transition<state<S1>, transition<state<S2>, transition_eg<front::event<E>, G>>>
2308 : transition<state<S1>, state<S2>, front::event<E>, G, none> {
2309 transition(
const state<S1> &,
const transition<state<S2>, transition_eg<front::event<E>, G>> &t)
2310 : transition<state<S1>, state<S2>, front::event<E>, G, none>{t.g, none{}} {}
2312 template <
class S2,
class E,
class A>
2313 struct transition<state<S2>, transition_ea<front::event<E>, A>>
2314 : transition<state<internal>, state<S2>, front::event<E>, always, A> {
2315 using transition<state<internal>, state<S2>, front::event<E>, always, A>::a;
2316 transition(
const state<S2> &,
const transition_ea<front::event<E>, A> &t)
2317 : transition<state<internal>, state<S2>, front::event<E>, always, A>{always{}, t.a} {}
2319 auto operator=(
const T &)
const {
2320 return transition<T, state<S2>, front::event<E>, always, A>{always{}, a};
2323 template <
class S1,
class S2,
class E,
class A>
2324 struct transition<state<S1>, transition<state<S2>, transition_ea<front::event<E>, A>>>
2325 : transition<state<S1>, state<S2>, front::event<E>, always, A> {
2326 transition(
const state<S1> &,
const transition<state<S2>, transition_ea<front::event<E>, A>> &t)
2327 : transition<state<S1>, state<S2>, front::event<E>, always, A>{always{}, t.a} {}
2329 template <
class S1,
class S2,
class E,
class G,
class A>
2330 struct transition<state<S1>, transition<state<S2>, transition<front::event<E>, G, A>>>
2331 : transition<state<S1>, state<S2>, front::event<E>, G, A> {
2332 transition(
const state<S1> &,
const transition<state<S2>, transition<front::event<E>, G, A>> &t)
2333 : transition<state<S1>, state<S2>, front::event<E>, G, A>{t.g, t.a} {}
2335 template <
class T,
class TSubs,
class... Ts,
class... THs>
2336 void update_composite_states(TSubs &subs, aux::true_type,
const aux::type_list<THs...> &) {
2337 using state_t =
typename T::state_t;
2338 auto &sm = back::sub_sm<T>::get(&subs);
2340 #if defined(__cpp_fold_expressions) 2341 ((sm.current_state_[aux::get_id<state_t, THs>((
typename T::initial_states_ids_t *)0)] =
2342 aux::get_id<state_t, THs>((
typename T::states_ids_t *)0)),
2345 (void)aux::swallow{0, (sm.current_state_[aux::get_id<state_t, THs>((
typename T::initial_states_ids_t *)0)] =
2346 aux::get_id<state_t, THs>((
typename T::states_ids_t *)0),
2350 template <
class T,
class TSubs,
class... Ts>
2351 void update_composite_states(TSubs &subs, aux::false_type, Ts &&...) {
2352 back::sub_sm<T>::get(&subs).initialize(
typename T::initial_states_t{});
2354 template <
class SM,
class TDeps,
class TSubs,
class TSrcState,
class TDstState>
2355 void update_current_state(SM &, TDeps &deps, TSubs &,
typename SM::state_t ¤t_state,
2356 const typename SM::state_t &new_state,
const TSrcState &,
const TDstState &) {
2357 back::policies::log_state_change<typename SM::sm_t>(aux::type<typename SM::logger_t>{}, deps,
2358 aux::string<typename TSrcState::type>{},
2359 aux::string<typename TDstState::type>{});
2360 current_state = new_state;
2362 template <
class SM,
class TDeps,
class TSubs,
class TSrcState,
class T>
2363 void update_current_state(SM &, TDeps &deps, TSubs &subs,
typename SM::state_t ¤t_state,
2364 const typename SM::state_t &new_state,
const TSrcState &,
const state<back::sm<T>> &) {
2365 back::policies::log_state_change<typename SM::sm_t>(aux::type<typename SM::logger_t>{}, deps,
2366 aux::string<typename TSrcState::type>{}, aux::string<T>{});
2367 current_state = new_state;
2368 update_composite_states<back::sm_impl<T>>(subs,
typename back::sm_impl<T>::has_history_states{},
2369 typename back::sm_impl<T>::history_states_t{});
2371 template <
class TDeps,
class TSubs,
class TDstState>
2372 void process_internal_transitions(TDeps &, TSubs &,
const TDstState &) {}
2373 template <
class TDeps,
class TSubs,
class T>
2374 void process_internal_transitions(TDeps &deps, TSubs &subs,
const state<back::sm<T>> &) {
2375 auto &sm = back::sub_sm<back::sm_impl<T>>::get(&subs);
2376 while (sm.process_internal_events(back::anonymous{}, deps, subs)) {
2379 template <
class S1,
class S2,
class E,
class G,
class A>
2380 struct transition<state<S1>, state<S2>, front::event<E>, G, A> {
2381 static constexpr
auto initial = state<S2>::initial;
2382 static constexpr
auto history = state<S2>::history;
2383 using src_state =
typename state<S2>::type;
2384 using dst_state =
typename state<S1>::type;
2388 using deps = aux::apply_t<aux::unique_t, aux::join_t<get_deps_t<G, E>, get_deps_t<A, E>>>;
2389 transition(
const G &g,
const A &a) : g(g), a(a) {}
2390 template <
class TEvent,
class SM,
class TDeps,
class TSubs>
2391 bool execute(
const TEvent &event, SM &sm, TDeps &deps, TSubs &subs,
typename SM::state_t ¤t_state, aux::true_type) {
2392 if (call<TEvent, args_t<G, TEvent>,
typename SM::logger_t>::
execute(g, event, sm, deps, subs)) {
2393 sm.process_internal_event(back::on_exit<back::_, TEvent>{
event}, deps, subs, current_state);
2394 update_current_state(sm, deps, subs, current_state,
2395 aux::get_id<typename SM::state_t, dst_state>((
typename SM::states_ids_t *)0), state<src_state>{},
2396 state<dst_state>{});
2397 call<TEvent, args_t<A, TEvent>,
typename SM::logger_t>::execute(a, event, sm, deps, subs);
2398 sm.process_internal_event(back::on_entry<back::_, TEvent>{
event}, deps, subs, current_state);
2399 process_internal_transitions(deps, subs, state<dst_state>{});
2404 template <
class TEvent,
class SM,
class TDeps,
class TSubs>
2405 bool execute(
const TEvent &event, SM &sm, TDeps &deps, TSubs &subs,
typename SM::state_t ¤t_state, aux::false_type) {
2406 if (call<TEvent, args_t<G, TEvent>,
typename SM::logger_t>::
execute(g, event, sm, deps, subs)) {
2407 update_current_state(sm, deps, subs, current_state,
2408 aux::get_id<typename SM::state_t, dst_state>((
typename SM::states_ids_t *)0), state<src_state>{},
2409 state<dst_state>{});
2410 call<TEvent, args_t<A, TEvent>,
typename SM::logger_t>::execute(a, event, sm, deps, subs);
2411 process_internal_transitions(deps, subs, state<dst_state>{});
2419 template <
class S2,
class E,
class G,
class A>
2420 struct transition<state<internal>, state<S2>, front::event<E>, G, A> {
2421 static constexpr
auto initial = state<S2>::initial;
2422 static constexpr
auto history = state<S2>::history;
2423 using src_state =
typename state<S2>::type;
2424 using dst_state =
internal;
2428 using deps = aux::apply_t<aux::unique_t, aux::join_t<get_deps_t<G, E>, get_deps_t<A, E>>>;
2429 transition(
const G &g,
const A &a) : g(g), a(a) {}
2430 template <
class TEvent,
class SM,
class TDeps,
class TSubs,
class... Ts>
2431 bool execute(
const TEvent &event, SM &sm, TDeps &deps, TSubs &subs,
typename SM::state_t &, Ts &&...) {
2432 if (call<TEvent, args_t<G, TEvent>,
typename SM::logger_t>::
execute(g, event, sm, deps, subs)) {
2433 call<TEvent, args_t<A, TEvent>,
typename SM::logger_t>::execute(a, event, sm, deps, subs);
2441 template <
class S1,
class S2,
class E,
class A>
2442 struct transition<state<S1>, state<S2>, front::event<E>, always, A> {
2443 static constexpr
auto initial = state<S2>::initial;
2444 static constexpr
auto history = state<S2>::history;
2445 using src_state =
typename state<S2>::type;
2446 using dst_state =
typename state<S1>::type;
2448 using guard = always;
2450 using deps = aux::apply_t<aux::unique_t, get_deps_t<A, E>>;
2451 transition(
const always &,
const A &a) : a(a) {}
2452 template <
class TEvent,
class SM,
class TDeps,
class TSubs>
2453 bool execute(
const TEvent &event, SM &sm, TDeps &deps, TSubs &subs,
typename SM::state_t ¤t_state, aux::true_type) {
2454 sm.process_internal_event(back::on_exit<back::_, TEvent>{
event}, deps, subs, current_state);
2455 update_current_state(sm, deps, subs, current_state,
2456 aux::get_id<typename SM::state_t, dst_state>((
typename SM::states_ids_t *)0), state<src_state>{},
2457 state<dst_state>{});
2458 call<TEvent, args_t<A, TEvent>,
typename SM::logger_t>::execute(a, event, sm, deps, subs);
2459 sm.process_internal_event(back::on_entry<back::_, TEvent>{
event}, deps, subs, current_state);
2460 process_internal_transitions(deps, subs, state<dst_state>{});
2463 template <
class TEvent,
class SM,
class TDeps,
class TSubs>
2464 bool execute(
const TEvent &event, SM &sm, TDeps &deps, TSubs &subs,
typename SM::state_t ¤t_state, aux::false_type) {
2465 update_current_state(sm, deps, subs, current_state,
2466 aux::get_id<typename SM::state_t, dst_state>((
typename SM::states_ids_t *)0), state<src_state>{},
2467 state<dst_state>{});
2468 call<TEvent, args_t<A, TEvent>,
typename SM::logger_t>::execute(a, event, sm, deps, subs);
2469 process_internal_transitions(deps, subs, state<dst_state>{});
2474 template <
class S2,
class E,
class A>
2475 struct transition<state<internal>, state<S2>, front::event<E>, always, A> {
2476 static constexpr
auto initial = state<S2>::initial;
2477 static constexpr
auto history = state<S2>::history;
2478 using src_state =
typename state<S2>::type;
2479 using dst_state =
internal;
2481 using guard = always;
2483 using deps = aux::apply_t<aux::unique_t, get_deps_t<A, E>>;
2484 transition(
const always &,
const A &a) : a(a) {}
2485 template <
class TEvent,
class SM,
class TDeps,
class TSubs,
class... Ts>
2486 bool execute(
const TEvent &event, SM &sm, TDeps &deps, TSubs &subs,
typename SM::state_t &, Ts &&...) {
2487 call<TEvent, args_t<A, TEvent>,
typename SM::logger_t>::execute(a, event, sm, deps, subs);
2492 template <
class S1,
class S2,
class E,
class G>
2493 struct transition<state<S1>, state<S2>, front::event<E>, G, none> {
2494 static constexpr
auto initial = state<S2>::initial;
2495 static constexpr
auto history = state<S2>::history;
2496 using src_state =
typename state<S2>::type;
2497 using dst_state =
typename state<S1>::type;
2500 using action = none;
2501 using deps = aux::apply_t<aux::unique_t, get_deps_t<G, E>>;
2502 transition(
const G &g,
const none &) : g(g) {}
2503 template <
class TEvent,
class SM,
class TDeps,
class TSubs>
2504 bool execute(
const TEvent &event, SM &sm, TDeps &deps, TSubs &subs,
typename SM::state_t ¤t_state, aux::true_type) {
2505 if (call<TEvent, args_t<G, TEvent>,
typename SM::logger_t>::
execute(g, event, sm, deps, subs)) {
2506 sm.process_internal_event(back::on_exit<back::_, TEvent>{
event}, deps, subs, current_state);
2507 update_current_state(sm, deps, subs, current_state,
2508 aux::get_id<typename SM::state_t, dst_state>((
typename SM::states_ids_t *)0), state<src_state>{},
2509 state<dst_state>{});
2510 sm.process_internal_event(back::on_entry<back::_, TEvent>{
event}, deps, subs, current_state);
2511 process_internal_transitions(deps, subs, state<dst_state>{});
2516 template <
class TEvent,
class SM,
class TDeps,
class TSubs>
2517 bool execute(
const TEvent &event, SM &sm, TDeps &deps, TSubs &subs,
typename SM::state_t ¤t_state, aux::false_type) {
2518 if (call<TEvent, args_t<G, TEvent>,
typename SM::logger_t>::
execute(g, event, sm, deps, subs)) {
2519 update_current_state(sm, deps, subs, current_state,
2520 aux::get_id<typename SM::state_t, dst_state>((
typename SM::states_ids_t *)0), state<src_state>{},
2521 state<dst_state>{});
2522 process_internal_transitions(deps, subs, state<dst_state>{});
2529 template <
class S2,
class E,
class G>
2530 struct transition<state<internal>, state<S2>, front::event<E>, G, none> {
2531 static constexpr
auto initial = state<S2>::initial;
2532 static constexpr
auto history = state<S2>::history;
2533 using src_state =
typename state<S2>::type;
2534 using dst_state =
internal;
2537 using action = none;
2538 using deps = aux::apply_t<aux::unique_t, get_deps_t<G, E>>;
2539 transition(
const G &g,
const none &) : g(g) {}
2540 template <
class TEvent,
class SM,
class TDeps,
class TSubs,
class... Ts>
2541 bool execute(
const TEvent &event, SM &sm, TDeps &deps, TSubs &subs,
typename SM::state_t &, Ts &&...) {
2542 return call<TEvent, args_t<G, TEvent>,
typename SM::logger_t>::execute(g, event, sm, deps, subs);
2546 template <
class S1,
class S2,
class E>
2547 struct transition<state<S1>, state<S2>, front::event<E>, always, none> {
2548 static constexpr
auto initial = state<S2>::initial;
2549 static constexpr
auto history = state<S2>::history;
2550 using src_state =
typename state<S2>::type;
2551 using dst_state =
typename state<S1>::type;
2553 using guard = always;
2554 using action = none;
2555 using deps = aux::type_list<>;
2556 transition(
const always &,
const none &) {}
2557 template <
class TEvent,
class SM,
class TDeps,
class TSubs>
2558 bool execute(
const TEvent &event, SM &sm, TDeps &deps, TSubs &subs,
typename SM::state_t ¤t_state, aux::true_type) {
2559 sm.process_internal_event(back::on_exit<back::_, TEvent>{
event}, deps, subs, current_state);
2560 update_current_state(sm, deps, subs, current_state,
2561 aux::get_id<typename SM::state_t, dst_state>((
typename SM::states_ids_t *)0), state<src_state>{},
2562 state<dst_state>{});
2563 sm.process_internal_event(back::on_entry<back::_, TEvent>{
event}, deps, subs, current_state);
2564 process_internal_transitions(deps, subs, state<dst_state>{});
2567 template <
class TEvent,
class SM,
class TDeps,
class TSubs>
2568 bool execute(
const TEvent &, SM &sm, TDeps &deps, TSubs &subs,
typename SM::state_t ¤t_state, aux::false_type) {
2569 update_current_state(sm, deps, subs, current_state,
2570 aux::get_id<typename SM::state_t, dst_state>((
typename SM::states_ids_t *)0), state<src_state>{},
2571 state<dst_state>{});
2572 process_internal_transitions(deps, subs, state<dst_state>{});
2575 __BOOST_SML_ZERO_SIZE_ARRAY(aux::byte);
2577 template <
class S2,
class E>
2578 struct transition<state<internal>, state<S2>, front::event<E>, always, none> {
2579 static constexpr
auto initial = state<S2>::initial;
2580 static constexpr
auto history = state<S2>::history;
2581 using src_state =
typename state<S2>::type;
2582 using dst_state =
internal;
2584 using guard = always;
2585 using action = none;
2586 using deps = aux::type_list<>;
2587 transition(
const always &,
const none &) {}
2588 template <
class TEvent,
class SM,
class TDeps,
class TSubs,
class... Ts>
2589 bool execute(
const TEvent &, SM &, TDeps &, TSubs &,
typename SM::state_t &, Ts &&...) {
2592 __BOOST_SML_ZERO_SIZE_ARRAY(aux::byte);
2596 #if !defined(COMPILING_WITH_MSVC) 2597 template <
class TEvent>
2598 constexpr front::event<TEvent>
event{};
2600 template <
class TEvent>
2601 front::event<TEvent>
event __BOOST_SML_VT_INIT;
2603 template <
class TEvent>
2604 __BOOST_SML_UNUSED front::event<back::on_entry<_, TEvent>> on_entry __BOOST_SML_VT_INIT;
2605 template <
class TEvent>
2606 __BOOST_SML_UNUSED front::event<back::on_exit<_, TEvent>> on_exit __BOOST_SML_VT_INIT;
2607 template <
class TEvent>
2608 front::event<back::unexpected_event<TEvent>> unexpected_event __BOOST_SML_VT_INIT;
2610 front::event<back::exception<T>> exception __BOOST_SML_VT_INIT;
2611 using anonymous = back::anonymous;
2612 using initial = back::initial;
2613 #if !defined(COMPILING_WITH_MSVC) 2615 constexpr
typename front::state_sm<T>::type state{};
2618 typename front::state_sm<T>::type state __BOOST_SML_VT_INIT;
2620 inline namespace literals {
2621 #if !defined(COMPILING_WITH_MSVC) 2622 template <
class T, T... Chrs>
2623 constexpr
auto operator""_s() {
2624 return front::state<aux::string<T, Chrs...>>{};
2626 template <
class T, T... Chrs>
2627 constexpr
auto operator""_e() {
2628 return event<aux::string<T, Chrs...>>;
2632 __BOOST_SML_UNUSED
static front::state<back::terminate_state> X;
2633 __BOOST_SML_UNUSED
static front::history_state H;
2634 __BOOST_SML_UNUSED
static front::actions::defer defer;
2635 __BOOST_SML_UNUSED
static front::actions::process process;
2636 template <
class... Ts, __BOOST_SML_REQUIRES(aux::is_same<aux::bool_list<aux::always<Ts>::value...>,
2637 aux::bool_list<concepts::transitional<Ts>::value...>>::value)>
2638 auto make_transition_table(Ts... ts) {
2639 return aux::pool<Ts...>{ts...};
2641 BOOST_SML_NAMESPACE_END
2642 #undef __BOOST_SML_UNUSED 2643 #undef __BOOST_SML_VT_INIT 2644 #undef __BOOST_SML_ZERO_SIZE_ARRAY 2645 #undef __BOOST_SML_ZERO_SIZE_ARRAY_CREATE 2646 #undef __BOOST_SML_TEMPLATE_KEYWORD 2647 #if defined(__clang__) 2648 #pragma clang diagnostic pop 2649 #elif defined(__GNUC__) && defined(__BOOST_SML_DEFINED_HAS_BUILTIN) 2650 #undef __has_builtin 2651 #pragma GCC diagnostic pop 2652 #elif defined(COMPILING_WITH_MSVC) && defined(__BOOST_SML_DEFINED_HAS_BUILTIN) 2653 #undef __has_builtin 2654 #undef __has_builtin__make_integer_seq 2656 #undef COMPILING_WITH_MSVC
ROSCONSOLE_DECL void initialize()
void init(const M_string &remappings)
bool call(const std::string &service_name, MReq &req, MRes &res)
ROSCPP_DECL bool execute(const std::string &method, const XmlRpc::XmlRpcValue &request, XmlRpc::XmlRpcValue &response, XmlRpc::XmlRpcValue &payload, bool wait_for_master)