diff --git a/include/boost/sml.hpp b/include/boost/sml.hpp index c46b9b41..5603b4f2 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 { @@ -451,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}; @@ -458,13 +468,23 @@ 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 +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 @@ -472,20 +492,37 @@ 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 + constexpr operator std::basic_string_view() const { + return {str, sizeof(str) - 1}; + } }; 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(); } + + 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 { @@ -597,23 +634,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_; };