diff --git a/include/boost/sml.hpp b/include/boost/sml.hpp index 118e319c..637fc8b5 100644 --- a/include/boost/sml.hpp +++ b/include/boost/sml.hpp @@ -230,6 +230,17 @@ struct remove_reference { }; template using remove_reference_t = typename remove_reference::type; + +template +struct remove_pointer { + using type = T; +}; +template +struct remove_pointer { + using type = T; +}; +template +using remove_pointer_t = typename remove_pointer::type; } // namespace aux namespace aux { using swallow = int[]; @@ -401,6 +412,14 @@ template T &try_get(const pool_type *object) { return object->value; } +template +const T *try_get(const pool_type *object) { + return object->value; +} +template +T *try_get(const pool_type *object) { + return object->value; +} template T &get(TPool &p) { return static_cast &>(p).value; @@ -409,13 +428,22 @@ template const T &cget(const TPool &p) { return static_cast &>(p).value; } +template +T *get(TPool *p) { + return static_cast &>(p).value; +} +template +const T *cget(const TPool *p) { + return static_cast &>(p).value; +} template struct pool : pool_type... { using boost_di_inject__ = type_list; pool() = default; explicit pool(Ts... ts) : pool_type(ts)... {} template - pool(init, const pool &p) : pool_type(try_get>>(&p))... {} + pool(init, const pool &p) + : pool_type(try_get>>>(&p))... {} template pool(const pool &p) : pool_type(init{}, p)... {} }; @@ -580,6 +608,7 @@ struct string { static auto c_str_impl(...) { return get_type_name(); } }; } // namespace aux + template constexpr auto wrap(T callback) { return aux::zero_wrapper{callback}; diff --git a/include/boost/sml/aux_/type_traits.hpp b/include/boost/sml/aux_/type_traits.hpp index b6567689..23475e7a 100644 --- a/include/boost/sml/aux_/type_traits.hpp +++ b/include/boost/sml/aux_/type_traits.hpp @@ -186,6 +186,16 @@ struct remove_reference { template using remove_reference_t = typename remove_reference::type; +template +struct remove_pointer { + using type = T; +}; +template +struct remove_pointer { + using type = T; +}; +template +using remove_pointer_t = typename remove_pointer::type; } // namespace aux #endif diff --git a/include/boost/sml/aux_/utility.hpp b/include/boost/sml/aux_/utility.hpp index 993081ae..7af77b52 100644 --- a/include/boost/sml/aux_/utility.hpp +++ b/include/boost/sml/aux_/utility.hpp @@ -209,6 +209,15 @@ T &try_get(const pool_type *object) { return object->value; } +template +const T *try_get(const pool_type *object) { + return object->value; +} +template +T *try_get(const pool_type *object) { + return object->value; +} + template T &get(TPool &p) { return static_cast &>(p).value; @@ -219,6 +228,15 @@ const T &cget(const TPool &p) { return static_cast &>(p).value; } +template +T *get(TPool *p) { + return static_cast &>(p).value; +} +template +const T *cget(const TPool *p) { + return static_cast &>(p).value; +} + template struct pool : pool_type... { using boost_di_inject__ = type_list; @@ -228,7 +246,7 @@ struct pool : pool_type... { explicit pool(Ts... ts) : pool_type(ts)... {} template - pool(init, const pool &p) : pool_type(try_get>>(&p))... {} + pool(init, const pool &p) : pool_type(try_get>>>(&p))... {} template pool(const pool &p) : pool_type(init{}, p)... {} diff --git a/test/ft/dependencies.cpp b/test/ft/dependencies.cpp index f74bf96d..ae8f7131 100644 --- a/test/ft/dependencies.cpp +++ b/test/ft/dependencies.cpp @@ -179,6 +179,90 @@ test dependencies_smart_ptrs = [] { expect(sm.is(sml::X)); }; +test dependencies_with_reference = [] { + struct Data { + int m_member { 42 }; + }; + + struct c { + auto operator()() noexcept { + const auto action = [](Data& data) { expect(data.m_member == 42); }; + + using namespace sml; + return make_transition_table(*idle + event / action = X); + } + }; + + Data data; + sml::sm sm{data}; + sm.process_event(e1{}); + expect(sm.is(sml::X)); +}; + +test dependencies_with_const_reference = [] { + struct Data { + int m_member { 42 }; + }; + + struct c { + auto operator()() noexcept { + const auto action = [](const Data& data) { + expect(data.m_member == 42); + }; + + using namespace sml; + return make_transition_table(*idle + event / action = X); + } + }; + + Data data; + sml::sm sm{data}; + sm.process_event(e1{}); + expect(sm.is(sml::X)); +}; + +test dependencies_with_pointer = [] { + struct Data { + int m_member { 42 }; + }; + + struct c { + auto operator()() noexcept { + const auto action = [](Data* data) { expect(data->m_member == 42); }; + + using namespace sml; + return make_transition_table(*idle + event / action = X); + } + }; + + Data data; + sml::sm sm{&data}; + sm.process_event(e1{}); + expect(sm.is(sml::X)); +}; + +test dependencies_with_const_pointer = [] { + struct Data { + int m_member { 42 }; + }; + + struct c { + auto operator()() noexcept { + const auto action = [](const Data* data) { + expect(data->m_member == 42); + }; + + using namespace sml; + return make_transition_table(*idle + event / action = X); + } + }; + + Data data; + sml::sm sm{&data}; + sm.process_event(e1{}); + expect(sm.is(sml::X)); +}; + #if (_MSC_VER >= 1910) // MSVC 2017 test dependencies_multiple_subs = [] { struct update {