2
0
mirror of https://github.com/boostorg/msm.git synced 2026-01-19 04:22:11 +00:00

backmp11: Add Kleene tests and fix any_cast with boost::any

This commit is contained in:
Christian Granzin
2025-10-12 23:41:26 -04:00
parent aeb6c6b7fa
commit fe09c93d44
6 changed files with 123 additions and 2 deletions

View File

@@ -25,4 +25,14 @@ struct is_kleene_event<std::any> : std::true_type {};
} // boost::msm
namespace boost::msm::backmp11
{
// Import std::any_cast for overload resolution:
// In case boost::any is used as Kleene event,
// overload resolution will pick boost::any_cast for us.
using std::any_cast;
} // boost::msm::backmp11
#endif //BOOST_MSM_EVENT_TRAITS_H

View File

@@ -162,7 +162,7 @@ private:
template<typename Event, typename Row>
static HandledEnum convert_and_execute(Fsm& fsm, int region_id, int state_id, const any_event& event)
{
return Row::execute(fsm, region_id, state_id, *std::any_cast<Event>(&event));
return Row::execute(fsm, region_id, state_id, *any_cast<Event>(&event));
}
// Dispatch table for one state.

View File

@@ -1089,7 +1089,7 @@ public:
using KnownEvent = typename decltype(event_identity)::type;
if (event.type() == typeid(KnownEvent))
{
do_defer_event(event);
this->do_defer_event(*any_cast<KnownEvent>(&event));
return true;
}
return false;

View File

@@ -37,6 +37,7 @@ add_executable(boost_msm_tests
SetStates.cpp
SimpleInternal.cpp
SimpleInternalFunctors.cpp
SimpleKleene.cpp
SimpleMachine.cpp
SimpleWithFunctors.cpp
Test2RegionsAnonymous.cpp

View File

@@ -98,6 +98,9 @@ namespace
};
// Pick a back-end
typedef mpl::vector<
#ifndef BOOST_MSM_TEST_SKIP_BACKMP11
boost::msm::backmp11::state_machine_adapter<fsm_>,
#endif // BOOST_MSM_TEST_SKIP_BACKMP11
boost::msm::back::state_machine<fsm_>,
boost::msm::back11::state_machine<fsm_>
> Fsms;

107
test/SimpleKleene.cpp Normal file
View File

@@ -0,0 +1,107 @@
// Copyright 2025 Christian Granzin
// Copyright 2010 Christophe Henry
// henry UNDERSCORE christophe AT hotmail DOT com
// This is an extended version of the state machine available in the boost::mpl library
// Distributed under the same license as the original.
// Copyright for the original version:
// Copyright 2005 David Abrahams and Aleksey Gurtovoy. Distributed
// under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// back-end
#include "BackCommon.hpp"
// front-end
#include <boost/msm/front/state_machine_def.hpp>
#include <boost/msm/front/functor_row.hpp>
#ifndef BOOST_MSM_NONSTANDALONE_TEST
#define BOOST_TEST_MODULE simple_kleene_test
#endif
#include <boost/test/unit_test.hpp>
namespace msm = boost::msm;
namespace front = msm::front;
using front::Row;
using front::state_machine_def;
namespace mp11 = boost::mp11;
namespace {
template <bool Value>
struct Guard
{
template <typename Event, typename Fsm, typename SourceState, typename TargetState>
bool operator()(const Event&, Fsm&, SourceState&, TargetState&)
{
return Value;
}
};
template <int E>
struct Event {};
template <int I>
struct Action
{
template <typename Event, typename Fsm, typename SourceState, typename TargetState>
void operator()(const Event&, Fsm&, SourceState&, TargetState&)
{
return;
}
};
template <int I>
struct State : front::state<>
{
template <class Event,class Fsm>
void on_entry(Event const&, Fsm&)
{
active = true;
}
template <class Event,class Fsm>
void on_exit(Event const&, Fsm&)
{
active = false;
}
static constexpr int value = I;
bool active = false;
};
struct Simple_ : front::state_machine_def<Simple_>
{
using transition_table = mp11::mp_list<
Row<State<0>, Event<0>, State<1>, Action<0>, Guard<false>>,
Row<State<0>, boost::any, State<1>, Action<1>, Guard<true>>
>;
using initial_state = State<0>;
};
// Pick a back-end
using Fsms = mp11::mp_list<
#ifndef BOOST_MSM_TEST_SKIP_BACKMP11
msm::backmp11::state_machine_adapter<Simple_>,
#endif // BOOST_MSM_TEST_SKIP_BACKMP11
msm::back::state_machine<Simple_>
// back11 requires a const boost::any overload to identify the Kleene event.
// Leave it out of this test to ensure backwards compatibility.
// msm::back11::state_machine<Front>
>;
BOOST_AUTO_TEST_CASE_TEMPLATE(simple_kleene_test, Fsm, Fsms)
{
Fsm fsm;
fsm.start();
BOOST_CHECK_MESSAGE(fsm.template get_state<State<0>&>().active == true, "State<0> entry not called correctly");
fsm.process_event(Event<0>{});
BOOST_CHECK_MESSAGE(fsm.template get_state<State<0>&>().active == false, "State<0> exit not called correctly");
BOOST_CHECK_MESSAGE(fsm.template get_state<State<1>&>().active == true, "State<1> entry not called correctly");
}
} // namespace