diff --git a/include/boost/static_string/detail/static_string.hpp b/include/boost/static_string/detail/static_string.hpp index 8beb0a4..b5f1b26 100644 --- a/include/boost/static_string/detail/static_string.hpp +++ b/include/boost/static_string/detail/static_string.hpp @@ -39,6 +39,28 @@ using smallest_width = typename std::conditional<(N <= (std::numeric_limits::max)()), unsigned long long, void>::type>::type>::type>::type>::type; +// std::is_nothrow_convertible is C++20 +template +void is_nothrow_convertible_helper(To) noexcept; + +// MSVC is unable to parse this inline, so a helper is needed +template(std::declval()))> +struct is_nothrow_convertible_msvc_helper +{ + static const bool value = + noexcept(is_nothrow_convertible_helper(std::declval())); +}; + +template +struct is_nothrow_convertible + : std::false_type { }; + +template +struct is_nothrow_convertible::value>::type> + : std::true_type { }; + // Optimization for using the smallest possible type template class static_string_base_zero @@ -208,7 +230,7 @@ inline int lexicographical_compare( CharT const* s1, std::size_t n1, - CharT const* s2, std::size_t n2) + CharT const* s2, std::size_t n2) noexcept { if(n1 < n2) return Traits::compare( @@ -224,7 +246,7 @@ inline int lexicographical_compare( basic_string_view s1, - CharT const* s2, std::size_t n2) + CharT const* s2, std::size_t n2) noexcept { return detail::lexicographical_compare< CharT, Traits>(s1.data(), s1.size(), s2, n2); @@ -235,7 +257,7 @@ inline int lexicographical_compare( const basic_static_string& s1, - CharT const* s2, std::size_t n2) + CharT const* s2, std::size_t n2) noexcept { return detail::lexicographical_compare< CharT, Traits>(s1.data(), s1.size(), s2, n2); @@ -246,7 +268,7 @@ inline int lexicographical_compare( basic_string_view s1, - basic_string_view s2) + basic_string_view s2) noexcept { return detail::lexicographical_compare( s1.data(), s1.size(), s2.data(), s2.size()); @@ -257,7 +279,7 @@ inline int lexicographical_compare( const basic_static_string& s1, - const basic_static_string& s2) + const basic_static_string& s2) noexcept { return detail::lexicographical_compare( s1.data(), s1.size(), s2.data(), s2.size()); diff --git a/include/boost/static_string/static_string.hpp b/include/boost/static_string/static_string.hpp index cbe1166..cd37c60 100644 --- a/include/boost/static_string/static_string.hpp +++ b/include/boost/static_string/static_string.hpp @@ -1895,7 +1895,8 @@ public: #endif find( const T& t, - size_type pos = 0) const + size_type pos = 0) const noexcept(detail::is_nothrow_convertible::value) { string_view_type sv = t; return find(sv.data(), pos, sv.size()); @@ -1974,7 +1975,8 @@ public: #endif rfind( const T& t, - size_type pos = npos) const + size_type pos = npos) const noexcept(detail::is_nothrow_convertible::value) { string_view_type sv = t; return rfind(sv.data(), pos, sv.size()); @@ -2052,7 +2054,8 @@ public: #endif find_first_of( const T& t, - size_type pos = 0) const + size_type pos = 0) const noexcept(detail::is_nothrow_convertible::value) { string_view_type sv = t; return find_first_of(sv.data(), pos, sv.size()); @@ -2130,7 +2133,8 @@ public: #endif find_last_of( const T& t, - size_type pos = npos) const + size_type pos = npos) const noexcept(detail::is_nothrow_convertible::value) { string_view_type sv = t; return find_last_of(sv.data(), pos, sv.size()); @@ -2208,7 +2212,8 @@ public: #endif find_first_not_of( const T& t, - size_type pos = 0) const + size_type pos = 0) const noexcept(detail::is_nothrow_convertible::value) { string_view_type sv = t; return find_first_not_of(sv.data(), pos, sv.size()); @@ -2286,7 +2291,8 @@ public: #endif find_last_not_of( const T& t, - size_type pos = npos) const + size_type pos = npos) const noexcept(detail::is_nothrow_convertible::value) { string_view_type sv = t; return find_last_not_of(sv.data(), pos, sv.size());