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

Feat/release readiness preparation (#6)

* adapt tests
* use alternative dispatch table initialization if C++20 is not available
* restructure test Jamfile and adapt build Jamfile
This commit is contained in:
Christian Granzin
2025-08-03 17:31:34 +02:00
committed by GitHub
parent b7c4cc5178
commit 50cfdf0fd7
17 changed files with 92 additions and 90 deletions

View File

@@ -6,12 +6,6 @@
cmake_minimum_required(VERSION 3.5...3.16)
project(boost_msm VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX)
# Temporary settings for development, need to be cleaned up later.
# Required for testing puml frontend
# set(CMAKE_CXX_STANDARD 20)
# Required due to bug in clang19
# add_compile_options("-Wno-missing-template-arg-list-after-template-kw")
# add_compile_options("-ftime-trace")
add_library(boost_msm INTERFACE)
add_library(Boost::msm ALIAS boost_msm)
@@ -28,6 +22,7 @@ target_link_libraries(boost_msm
Boost::core
Boost::function
Boost::fusion
Boost::mp11
Boost::mpl
Boost::parameter
Boost::phoenix

View File

@@ -14,6 +14,7 @@ constant boost_dependencies :
/boost/core//boost_core
/boost/function//boost_function
/boost/fusion//boost_fusion
/boost/mp11//boost_mp11
/boost/mpl//boost_mpl
/boost/parameter//boost_parameter
/boost/phoenix//boost_phoenix

View File

@@ -30,7 +30,6 @@ When using the `favor_compile_time` policy, a different macro to generate missin
Summary:
- Optimized cell initialization with initializer arrays (to reduce template instantiations)
- TODO: double-check optimization
- Default-initialized everything and afterwards only defer transition cells
@@ -56,8 +55,3 @@ Summary:
- If only a subset needs to be processed, prefer copy_if & transform over fold
- Selecting a template-based function overload in Mp11 seems more efficient than using enable_if/disable_if
## TODOs:
- Consider trying out the tuple impl from SML

View File

@@ -163,6 +163,34 @@ private:
}
private:
// A function object for use with mp11::mp_for_each that stuffs transitions into cells.
// Only used when C++20 is not available.
class row_init_helper
{
public:
row_init_helper(event_cell* entries)
: m_entries(entries) {}
template<typename Row>
typename ::boost::disable_if<typename is_kleene_event<typename Row::transition_event>::type, void>::type
operator()(Row)
{
m_entries[get_table_index<Fsm, typename Row::current_state_type>::value] =
&Row::execute;
}
template<typename Row>
typename ::boost::enable_if<typename is_kleene_event<typename Row::transition_event>::type, void>::type
operator()(Row)
{
m_entries[get_table_index<Fsm, typename Row::current_state_type>::value] =
&convert_event_and_forward<Row>::execute;
}
private:
event_cell* m_entries;
};
// initialize the dispatch table for a given Event and Fsm
event_dispatch_table()
{
@@ -202,18 +230,23 @@ private:
row_chainer,
map_of_row_seq
> chained_rows;
// Go back and fill in cells for matching transitions.
#if __cplusplus >= 202002L
typedef mp11::mp_transform<
preprocess_row,
chained_rows
> chained_and_preprocessed_rows;
// Go back and fill in cells for matching transitions.
event_cell_initializer::init(
reinterpret_cast<generic_cell*>(entries),
get_init_cells<event_cell, chained_and_preprocessed_rows>(),
mp11::mp_size<chained_and_preprocessed_rows>::value
);
#else
mp11::mp_for_each<chained_rows>(row_init_helper{entries});
#endif
}
// class used to build a chain (or sequence) of transitions for a given event and start state
// (like an UML diamond). Allows transition conflicts.
template< typename Seq,typename AnEvent,typename State >
@@ -315,13 +348,13 @@ private:
>::type type;
};
template <class Transition>
template <class Row>
struct convert_event_and_forward
{
static HandledEnum execute(Fsm& fsm, int region_index, int state, Event const& evt)
{
typename Transition::transition_event forwarded(evt);
return Transition::execute(fsm,region_index,state,forwarded);
typename Row::transition_event forwarded(evt);
return Row::execute(fsm,region_index,state,forwarded);
}
};
@@ -386,25 +419,25 @@ private:
// just one row, no chaining, we rebuild the row like it was before
mp11::mp_front<mp11::mp_second<T>>
>;
template<typename Transition>
using preprocess_row_helper = cell_constant<&Transition::execute>;
template<typename Transition>
template<typename Row>
using preprocess_row_helper = cell_constant<&Row::execute>;
template<typename Row>
using preprocess_row = init_cell_constant<
// Offset into the entries array
get_table_index<Fsm, typename Transition::current_state_type>::value,
get_table_index<Fsm, typename Row::current_state_type>::value,
// Address of the execute function
mp11::mp_eval_if_c<
is_kleene_event<typename Transition::transition_event>::type::value,
is_kleene_event<typename Row::transition_event>::type::value,
cell_constant<
&convert_event_and_forward<Transition>::execute
&convert_event_and_forward<Row>::execute
>,
preprocess_row_helper,
Transition
Row
>::value
>;
// data members
public:
public:
// max_state+1, because 0 is reserved for this fsm (internal transitions)
event_cell entries[max_state+1];
};

View File

@@ -1,12 +1,17 @@
file(GLOB SOURCES "*.cpp")
# list(FILTER SOURCES EXCLUDE REGEX "xyz")
# list(FILTER SOURCES INCLUDE REGEX "xyz")
if(CMAKE_CXX_STANDARD LESS 20)
message(STATUS "MSM: CXX standard is below 20, excluding puml tests")
list(FILTER SOURCES EXCLUDE REGEX "puml|Puml")
endif()
add_executable(msm_test
add_executable(boost_msm_tests
EXCLUDE_FROM_ALL
${SOURCES}
main.cpp
)
target_include_directories(msm_test PRIVATE ../include)
target_include_directories(boost_msm_tests PRIVATE ../include)
find_package(boost_serialization)
target_link_libraries(msm_test Boost::serialization)
target_compile_definitions(msm_test PRIVATE "BOOST_MSM_NONSTANDALONE_TEST")
target_link_libraries(boost_msm_tests Boost::serialization)
target_compile_definitions(boost_msm_tests PRIVATE "BOOST_MSM_NONSTANDALONE_TEST")
add_test(boost_msm_tests boost_msm_tests)

View File

@@ -158,7 +158,6 @@ namespace
BOOST_AUTO_TEST_CASE_TEMPLATE( composite_euml_test, test_machine, test_machines )
{
typename test_machine::player p;
typedef typename test_machine::player_ player_;
typedef typename test_machine::Playing_type Playing_type;
p.start();
@@ -289,7 +288,6 @@ namespace
using back0 = hierarchical_state_machine<boost::msm::back::state_machine, boost::msm::back::favor_compile_time>::player;
using back1 = hierarchical_state_machine<boost::msm::back::state_machine, boost::msm::back::favor_compile_time>::Playing_type;
BOOST_MSM_BACK_GENERATE_PROCESS_EVENT(back0);
BOOST_MSM_BACK_GENERATE_PROCESS_EVENT(back1);
using backmp11_0 = hierarchical_state_machine<boost::msm::backmp11::state_machine, boost::msm::backmp11::favor_compile_time>::player;

View File

@@ -353,7 +353,6 @@ namespace
using back0 = hierarchical_state_machine<boost::msm::back::state_machine, boost::msm::back::favor_compile_time>::player;
using back1 = hierarchical_state_machine<boost::msm::back::state_machine, boost::msm::back::favor_compile_time>::player_::Playing;
BOOST_MSM_BACK_GENERATE_PROCESS_EVENT(back0);
BOOST_MSM_BACK_GENERATE_PROCESS_EVENT(back1);
using backmp11_0 = hierarchical_state_machine<boost::msm::backmp11::state_machine, boost::msm::backmp11::favor_compile_time>::player;

View File

@@ -207,5 +207,4 @@ namespace
}
}
using backmp11_fsm = boost::msm::backmp11::state_machine<player_, boost::msm::backmp11::favor_compile_time>;
BOOST_MSM_BACKMP11_GENERATE_DISPATCH_TABLE(backmp11_fsm);
using backmp11_fsm = boost::msm::backmp11::state_machine<player_, boost::msm::backmp11::favor_compile_time>;

View File

@@ -306,7 +306,6 @@ namespace
using back0 = hierarchical_state_machine<boost::msm::back::state_machine, boost::msm::back::favor_compile_time>::Fsm;
using back1 = hierarchical_state_machine<boost::msm::back::state_machine, boost::msm::back::favor_compile_time>::Fsm_::SubFsm2;
BOOST_MSM_BACK_GENERATE_PROCESS_EVENT(back0);
BOOST_MSM_BACK_GENERATE_PROCESS_EVENT(back1);
using backmp11_0 = hierarchical_state_machine<boost::msm::backmp11::state_machine, boost::msm::backmp11::favor_compile_time>::Fsm;

View File

@@ -364,7 +364,6 @@ namespace
using back0 = hierarchical_state_machine<boost::msm::back::state_machine, boost::msm::back::favor_compile_time>::player;
using back1 = hierarchical_state_machine<boost::msm::back::state_machine, boost::msm::back::favor_compile_time>::player_::Playing;
BOOST_MSM_BACK_GENERATE_PROCESS_EVENT(back0);
BOOST_MSM_BACK_GENERATE_PROCESS_EVENT(back1);
using backmp11_0 = hierarchical_state_machine<boost::msm::backmp11::state_machine, boost::msm::backmp11::favor_compile_time>::player;

View File

@@ -32,68 +32,53 @@ project
test-suite msm-unit-tests
:
[ run Anonymous.cpp ]
[ run AnonymousAndGuard.cpp ]
[ run AnonymousEuml.cpp ]
[ run Back11CompositeMachine.cpp ]
[ run BigWithFunctors.cpp ]
[ run CompositeEuml.cpp ]
[ run CompositeMachine.cpp ]
[ run Constructor.cpp ]
[ run Entries.cpp ]
[ run EventQueue.cpp ]
[ run History.cpp ]
[ run KleeneDeferred.cpp ]
[ run ManyDeferTransitions.cpp ]
[ run OrthogonalDeferred.cpp ]
[ run OrthogonalDeferred2.cpp ]
[ run OrthogonalDeferred3.cpp ]
[ run OrthogonalDeferredEuml.cpp ]
[ run Serialize.cpp ]
[ run SerializeSimpleEuml.cpp ]
[ run SerializeWithHistory.cpp ]
[ run SetStates.cpp ]
[ run SimpleEuml.cpp ]
[ run SimpleEuml2.cpp ]
[ run SimpleInternal.cpp ]
[ run SimpleInternalEuml.cpp ]
[ run SimpleInternalFunctors.cpp ]
[ run SimpleMachine.cpp ]
[ run KleeneDeferred.cpp ]
[ run SimpleWithFunctors.cpp ]
[ run Serialize.cpp ]
[ run SerializeWithHistory.cpp ]
[ run SerializeSimpleEuml.cpp ]
[ run Test2RegionsAnonymous.cpp ]
[ run TestConstructor.cpp ]
[ run ManyDeferTransitions.cpp ]
[ run Back11AnonymousAndGuard.cpp ]
[ run Back11Throwing.cpp ]
[ run Back11KleeneDeferred.cpp : :
: [ requires cxx11_variadic_templates ] ]
[ run Back11Anonymous.cpp : :
: [ requires cxx11_variadic_templates ] ]
[ run Back11BigWithFunctors.cpp : :
: [ requires cxx11_variadic_templates ] ]
[ run Back11CompositeMachine.cpp : :
: [ requires cxx11_variadic_templates ] ]
[ run Back11Entries.cpp : :
: [ requires cxx11_variadic_templates ] ]
[ run Back11OrthogonalDeferred3.cpp : :
: [ requires cxx11_variadic_templates ] ]
[ run Back11SimpleInternalEuml.cpp : :
: [ requires cxx11_variadic_templates ] ]
[ run Back11SimpleInternalFunctors.cpp : :
: [ requires cxx11_variadic_templates ] ]
[ run Back11SimpleMachine.cpp : :
: [ requires cxx11_variadic_templates ] ]
[ run Back11SimpleWithFunctors.cpp : :
: [ requires cxx11_variadic_templates ] ]
[ run Back11TestDeferIn2Regions.cpp : :
: [ requires cxx11_variadic_templates ] ]
[ run Back11ManyDeferTransitions.cpp : :
: [ requires cxx11_variadic_templates ] ]
[ run Back11TransitionSkipping.cpp : :
: [ requires cxx11_variadic_templates ] ]
[ run Back11SimpleWithPuml.cpp : :
: [ requires cxx20_hdr_version cxx20_hdr_barrier cxx20_hdr_compare cxx20_hdr_format cxx20_hdr_ranges cxx20_hdr_numbers ] ]
[ run Back11OnlyStringPuml.cpp : :
: [ requires cxx20_hdr_version cxx20_hdr_barrier cxx20_hdr_compare cxx20_hdr_format cxx20_hdr_ranges cxx20_hdr_numbers ] ]
[ run Back11SimpleInternalWithPuml.cpp : :
: [ requires cxx20_hdr_version cxx20_hdr_barrier cxx20_hdr_compare cxx20_hdr_format cxx20_hdr_ranges cxx20_hdr_numbers ] ]
[ run Back11OrthogonalDeferred3WithPuml.cpp : :
: [ requires cxx20_hdr_version cxx20_hdr_barrier cxx20_hdr_compare cxx20_hdr_format cxx20_hdr_ranges cxx20_hdr_numbers ] ]
[ run puml_syntax.cpp : :
: [ requires cxx20_hdr_version cxx20_hdr_barrier cxx20_hdr_compare cxx20_hdr_format cxx20_hdr_ranges cxx20_hdr_numbers ] ]
[ run puml_syntax_2.cpp : :
: [ requires cxx20_hdr_version cxx20_hdr_barrier cxx20_hdr_compare cxx20_hdr_format cxx20_hdr_ranges cxx20_hdr_numbers ] ]
[ run TestConstructorMovableOnlyTypes.cpp ]
[ run TestDeferAndMessageQueue.cpp ]
[ run TestDeferAndMessageQueue2.cpp ]
[ run TestDeferAndMessageQueue3.cpp ]
[ run TestDeferIn2Regions.cpp ]
[ run Throwing.cpp ]
[ run TransitionSkipping.cpp ]
;
test-suite msm-unit-tests-cxxstd20
:
[ run Back11OrthogonalDeferred3WithPuml.cpp ]
[ run OnlyStringPuml.cpp ]
[ run puml_syntax.cpp ]
[ run puml_syntax_2.cpp ]
[ run SimpleWithPuml.cpp ]
[ run StringTerminatePuml.cpp ]
:
<cxxstd>20
;

View File

@@ -498,7 +498,6 @@ namespace
using back0 = hierarchical_state_machine<boost::msm::back::state_machine, boost::msm::back::favor_compile_time>::player;
using back1 = hierarchical_state_machine<boost::msm::back::state_machine, boost::msm::back::favor_compile_time>::player_::Playing;
BOOST_MSM_BACK_GENERATE_PROCESS_EVENT(back0);
BOOST_MSM_BACK_GENERATE_PROCESS_EVENT(back1);
using backmp11_0 = hierarchical_state_machine<boost::msm::backmp11::state_machine, boost::msm::backmp11::favor_compile_time>::player;

View File

@@ -505,7 +505,6 @@ namespace
using back0 = hierarchical_state_machine<boost::msm::back::state_machine, boost::msm::back::favor_compile_time>::player;
using back1 = hierarchical_state_machine<boost::msm::back::state_machine, boost::msm::back::favor_compile_time>::player_::Playing;
BOOST_MSM_BACK_GENERATE_PROCESS_EVENT(back0);
BOOST_MSM_BACK_GENERATE_PROCESS_EVENT(back1);
using backmp11_0 = hierarchical_state_machine<boost::msm::backmp11::state_machine, boost::msm::backmp11::favor_compile_time>::player;

View File

@@ -168,7 +168,6 @@ namespace
BOOST_AUTO_TEST_CASE_TEMPLATE(orthogonal_deferred_euml_test, test_machine, test_machines)
{
typename test_machine::player p;
typedef typename test_machine::player_ player_;
typedef typename test_machine::Playing_type Playing_type;
// needed to start the highest-level SM. This will call on_entry and mark the start of the SM
@@ -375,7 +374,6 @@ namespace
using back0 = hierarchical_state_machine<boost::msm::back::state_machine, boost::msm::back::favor_compile_time>::player;
using back1 = hierarchical_state_machine<boost::msm::back::state_machine, boost::msm::back::favor_compile_time>::Playing_type;
BOOST_MSM_BACK_GENERATE_PROCESS_EVENT(back0);
BOOST_MSM_BACK_GENERATE_PROCESS_EVENT(back1);
using backmp11_0 = hierarchical_state_machine<boost::msm::backmp11::state_machine, boost::msm::backmp11::favor_compile_time>::player;

View File

@@ -376,7 +376,6 @@ namespace
using back0 = hierarchical_state_machine<boost::msm::back::state_machine, boost::msm::back::favor_compile_time>::player;
using back1 = hierarchical_state_machine<boost::msm::back::state_machine, boost::msm::back::favor_compile_time>::player_::Playing;
BOOST_MSM_BACK_GENERATE_PROCESS_EVENT(back0);
BOOST_MSM_BACK_GENERATE_PROCESS_EVENT(back1);
using backmp11_0 = hierarchical_state_machine<boost::msm::backmp11::state_machine, boost::msm::backmp11::favor_compile_time>::player;

View File

@@ -159,7 +159,6 @@ namespace
using back0 = hierarchical_state_machine<boost::msm::back::state_machine, boost::msm::back::favor_compile_time>::Fsm;
using back1 = hierarchical_state_machine<boost::msm::back::state_machine, boost::msm::back::favor_compile_time>::SubFsm;
BOOST_MSM_BACK_GENERATE_PROCESS_EVENT(back0);
BOOST_MSM_BACK_GENERATE_PROCESS_EVENT(back1);
using backmp11_0 = hierarchical_state_machine<boost::msm::backmp11::state_machine, boost::msm::backmp11::favor_compile_time>::Fsm;

View File

@@ -22,6 +22,7 @@
#define BOOST_TEST_MODULE test_constructor_movable_only_types
#endif
#include <boost/test/unit_test.hpp>
#include <boost/make_unique.hpp>
namespace msm = boost::msm;
namespace mpl = boost::mpl;
@@ -98,7 +99,7 @@ namespace
BOOST_AUTO_TEST_CASE_TEMPLATE(test_constructor_movable_only_types, bistable_switch, bistable_switches)
{
auto bulp = std::make_unique<Lightbulp>(3);
auto bulp = boost::make_unique<Lightbulp>(3);
bistable_switch bs(std::move(bulp), 5);
BOOST_CHECK_MESSAGE(bs.bulp_->current == 10, "Wrong returned current value");