From fab49d3ff945dcd93d1e48c7a102bc32951338bd Mon Sep 17 00:00:00 2001 From: Norbert Lange Date: Wed, 22 Apr 2020 23:32:24 +0200 Subject: [PATCH 1/3] make the c_str() functions constexpr With this change, its now possible to consteval the c_str() function of states during a visit_current_states. The detail::get_type_name function is not constexpr however, and types falling back to this, wont be consteval. --- include/boost/sml.hpp | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/include/boost/sml.hpp b/include/boost/sml.hpp index c46b9b41..325bc446 100644 --- a/include/boost/sml.hpp +++ b/include/boost/sml.hpp @@ -458,13 +458,13 @@ auto get_type_name(const char *ptr, index_sequence) { } } template -const char *get_type_name() { +constexpr auto get_type_name() { #if defined(COMPILING_WITH_MSVC) - return detail::get_type_name(__FUNCSIG__, make_index_sequence{}); + return detail::get_type_name(__FUNCSIG__, make_index_sequence{}); #elif defined(__clang__) - return detail::get_type_name(__PRETTY_FUNCTION__, make_index_sequence{}); + return detail::get_type_name(__PRETTY_FUNCTION__, make_index_sequence{}); #elif defined(__GNUC__) - return detail::get_type_name(__PRETTY_FUNCTION__, make_index_sequence{}); + return detail::get_type_name(__PRETTY_FUNCTION__, make_index_sequence{}); #endif } template @@ -472,20 +472,20 @@ struct string; template struct string { using type = string; - static auto c_str() { - static constexpr char str[] = {Chrs..., 0}; + static constexpr const char str[] = {Chrs..., 0}; + static constexpr auto c_str() { return str; } }; template struct string { using type = T; - static auto c_str() { return c_str_impl((T *)0); } + static constexpr auto c_str() { return c_str_impl((T *)0); } template - static decltype(U::c_str()) c_str_impl(U *) { + static constexpr decltype(U::c_str()) c_str_impl(U *) { return U::c_str(); } - static auto c_str_impl(...) { return get_type_name(); } + static constexpr auto c_str_impl(...) { return get_type_name(); } }; } namespace back { @@ -597,23 +597,23 @@ struct initial {}; struct unexpected {}; struct entry_exit {}; struct terminate_state { - static auto c_str() { return "terminate"; } + static constexpr auto c_str() { return "terminate"; } }; struct internal_event { - static auto c_str() { return "internal_event"; } + static constexpr auto c_str() { return "internal_event"; } }; struct anonymous : internal_event { - static auto c_str() { return "anonymous"; } + static constexpr auto c_str() { return "anonymous"; } }; template struct on_entry : internal_event, entry_exit { - static auto c_str() { return "on_entry"; } + static constexpr auto c_str() { return "on_entry"; } explicit on_entry(const TEvent &event = {}) : event_(event) {} const TEvent &event_; }; template struct on_exit : internal_event, entry_exit { - static auto c_str() { return "on_exit"; } + static constexpr auto c_str() { return "on_exit"; } explicit on_exit(const TEvent &event = {}) : event_(event) {} const TEvent &event_; }; From cd5fa65a1edf996c1309cf3fdca81a3c063f47e1 Mon Sep 17 00:00:00 2001 From: Norbert Lange Date: Thu, 23 Apr 2020 00:34:35 +0200 Subject: [PATCH 2/3] basic string_view support add string_view support, using the existing functions. note that this does not pull in any headers. --- include/boost/sml.hpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/include/boost/sml.hpp b/include/boost/sml.hpp index 325bc446..48cbf8f7 100644 --- a/include/boost/sml.hpp +++ b/include/boost/sml.hpp @@ -58,6 +58,10 @@ #pragma warning(disable : 4503) #pragma warning(disable : 4200) #endif +namespace std { +template +class basic_string_view; +} BOOST_SML_NAMESPACE_BEGIN #define __BOOST_SML_REQUIRES(...) typename aux::enable_if<__VA_ARGS__, int>::type = 0 namespace aux { @@ -476,6 +480,10 @@ struct string { static constexpr auto c_str() { return str; } + template + constexpr operator std::basic_string_view() const { + return {str, sizeof(str) - 1}; + } }; template struct string { @@ -486,6 +494,11 @@ struct string { return U::c_str(); } static constexpr auto c_str_impl(...) { return get_type_name(); } + + template + constexpr operator std::basic_string_view() const { + return {c_str()}; + } }; } namespace back { From 2ffb7cd28cc632d0808f337115bfde2e5c251238 Mon Sep 17 00:00:00 2001 From: Norbert Lange Date: Thu, 23 Apr 2020 00:40:33 +0200 Subject: [PATCH 3/3] add get_type_name_sv for string_views this change unfortunately duplicates get_type_name, but as string_views dont require a zero delimted string, its now always possible to consteval a state instance. --- include/boost/sml.hpp | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/include/boost/sml.hpp b/include/boost/sml.hpp index 48cbf8f7..5603b4f2 100644 --- a/include/boost/sml.hpp +++ b/include/boost/sml.hpp @@ -455,6 +455,12 @@ struct zero_wrapper())>> const TExpr &get() const { return reinterpret_cast(*this); } }; namespace detail { +struct stview { + const char *str; + unsigned usize; + constexpr const char *data() const { return str; } + constexpr unsigned size() const { return usize; } +}; template auto get_type_name(const char *ptr, index_sequence) { static const char str[] = {ptr[N + Ns]..., 0}; @@ -471,6 +477,16 @@ constexpr auto get_type_name() { return detail::get_type_name(__PRETTY_FUNCTION__, make_index_sequence{}); #endif } +template +constexpr auto get_type_name_sv() { +#if defined(COMPILING_WITH_MSVC) + return detail::stview{__FUNCSIG__ + 40, sizeof(__FUNCSIG__) - 40 - 8}; +#elif defined(__clang__) + return detail::stview{__PRETTY_FUNCTION__ + 54, sizeof(__PRETTY_FUNCTION__) - 54 - 2}; +#elif defined(__GNUC__) + return detail::stview{__PRETTY_FUNCTION__ + 69, sizeof(__PRETTY_FUNCTION__) - 69 - 2}; +#endif +} template struct string; template @@ -480,8 +496,8 @@ struct string { static constexpr auto c_str() { return str; } - template - constexpr operator std::basic_string_view() const { + template + constexpr operator std::basic_string_view() const { return {str, sizeof(str) - 1}; } }; @@ -495,10 +511,18 @@ struct string { } static constexpr auto c_str_impl(...) { return get_type_name(); } - template - constexpr operator std::basic_string_view() const { - return {c_str()}; + template + constexpr operator std::basic_string_view() const { + auto s = strv_impl((T *)0, (const char *)0); + return {s.data(), s.size()}; + } + + template + static constexpr auto strv_impl(U *, decltype(U::c_str())) { + return std::basic_string_view{U::c_str()}; } + template + static constexpr auto strv_impl(...) { return get_type_name_sv(); } }; } namespace back {