diff --git a/include/boost/sml.hpp b/include/boost/sml.hpp index ef2339e4..bbeb365d 100644 --- a/include/boost/sml.hpp +++ b/include/boost/sml.hpp @@ -807,8 +807,9 @@ template struct pool_type_impl::value && aux::is_constructible::value>> : pool_type_base { constexpr explicit pool_type_impl(T &val) : value{val} {} // bind ref directly + constexpr explicit pool_type_impl(missing_ctor_parameter) : value_{}, value{value_} {} // default-construct backing store template - constexpr explicit pool_type_impl(TObject val) : value_{val}, value{value_} {}// default-construct backing store + constexpr explicit pool_type_impl(TObject val) : value_{val}, value{value_} {} // #504: cross-pool copy — extract T into the local backing store first, then // bind value to it. The naive ': value(i, object)' was a comma-expression // that bound value directly to the pool parameter (dangling after return). diff --git a/test/ft/CMakeLists.txt b/test/ft/CMakeLists.txt index 4bbe9ec3..28c92cdf 100644 --- a/test/ft/CMakeLists.txt +++ b/test/ft/CMakeLists.txt @@ -155,6 +155,11 @@ if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/issue_552_sub_sm_dep_identity.cpp) add_test(test_issue_552_sub_sm_dep_identity test_issue_552_sub_sm_dep_identity) endif() +if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/issue_718_expected_member.cpp) + add_executable(test_issue_718_expected_member issue_718_expected_member.cpp) + add_test(test_issue_718_expected_member test_issue_718_expected_member) +endif() + if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/issue_317_bare_internal_transition.cpp) add_executable(test_issue_317_bare_internal_transition issue_317_bare_internal_transition.cpp) add_test(test_issue_317_bare_internal_transition test_issue_317_bare_internal_transition) diff --git a/test/ft/issue_718_expected_member.cpp b/test/ft/issue_718_expected_member.cpp new file mode 100644 index 00000000..a287a7b9 --- /dev/null +++ b/test/ft/issue_718_expected_member.cpp @@ -0,0 +1,98 @@ +#define BOOST_SML_CREATE_DEFAULT_CONSTRUCTIBLE_DEPS +// cppcheck-suppress missingIncludeSystem +#include +// cppcheck-suppress missingIncludeSystem +#include +// cppcheck-suppress missingIncludeSystem +#include +#if defined(__has_include) +#if __has_include() +// cppcheck-suppress missingIncludeSystem +#include +#endif +#endif +#if defined(__cpp_lib_expected) +// cppcheck-suppress missingIncludeSystem +#include +#endif + +namespace sml = boost::sml; + +struct e718 {}; + +struct greedy718 { + int value{}; + greedy718() = default; + template + // cppcheck-suppress noExplicitConstructor + greedy718(U&&) : value{-1} {} +}; + +struct greedy_first_member718 { + greedy718 member; +}; + +test default_dep_with_greedy_first_member_is_value_initialized_and_shared = [] { + static int value_on_entry = -2; + static int value_on_event = -2; + + struct c { + auto operator()() const noexcept { + using namespace sml; + return make_transition_table( + *state + event / [](greedy_first_member718& s) { value_on_event = s.member.value; } = X, + state + on_entry<_> / + [](greedy_first_member718& s) { + value_on_entry = s.member.value; + s.member.value = 7; + }); + } + }; + + sml::sm sm; + expect(value_on_entry == 0); + sm.process_event(e718{}); + expect(value_on_event == 7); + expect(sm.is(sml::X)); +}; + +test default_dep_with_initializer_list_ctor_is_empty = [] { + static std::size_t size_on_event = 1; + + struct c { + auto operator()() const noexcept { + using namespace sml; + return make_transition_table(*state + event / [](std::vector& v) { size_on_event = v.size(); } = + X); + } + }; + + sml::sm sm; + sm.process_event(e718{}); + expect(size_on_event == 0u); + expect(sm.is(sml::X)); +}; + +#if defined(__cpp_lib_expected) +struct expected_first_member718 { + std::expected member; +}; + +test default_dep_with_std_expected_first_member_is_shared = [] { + static int value_on_event = 0; + + struct c { + auto operator()() const noexcept { + using namespace sml; + return make_transition_table( + *state + event / [](expected_first_member718& s) { value_on_event = *s.member; } = X, + state + on_entry<_> / [](expected_first_member718& s) { s.member = 1; }); + } + }; + + sml::sm sm; + sm.process_event(e718{}); + expect(value_on_event == 1); + expect(sm.is(sml::X)); +}; +#endif