diff --git a/include/boost/static_string/config.hpp b/include/boost/static_string/config.hpp index 7789e34..ba0044c 100644 --- a/include/boost/static_string/config.hpp +++ b/include/boost/static_string/config.hpp @@ -25,6 +25,16 @@ #define BOOST_STATIC_STRING_USE_DEDUCT #endif +// Include if we can +#if __has_include() +#include +#endif + +// Can we use is_constant_evaluated? +#if __cpp_lib_is_constant_evaluated >= 201811L +#define BOOST_STATIC_STRING_USE_IS_CONST_EVAL +#endif + // Can we use [[nodiscard]]? #ifdef __has_attribute #if __has_attribute(nodiscard) diff --git a/include/boost/static_string/impl/static_string.hpp b/include/boost/static_string/impl/static_string.hpp index dddd924..155fee3 100644 --- a/include/boost/static_string/impl/static_string.hpp +++ b/include/boost/static_string/impl/static_string.hpp @@ -363,7 +363,15 @@ insert( const auto s = &*first; BOOST_STATIC_STRING_THROW_IF( count > max_size() - curr_size, std::length_error{"count > max_size() - size()"}); - const bool inside = s <= &curr_data[curr_size] && s >= curr_data; + // Makes this more constexpr friendly if we can use is_constant_evaluated + const bool inside = +#ifdef BOOST_STATIC_STRING_USE_IS_CONST_EVAL + std::is_constant_evaluated() ? + detail::is_inside(curr_data, curr_data + curr_size, s) : + s <= &curr_data[curr_size] && s >= curr_data; +#else + s <= &curr_data[curr_size] && s >= curr_data; +#endif if (!inside || (inside && ((s - curr_data) + count <= index))) { Traits::move(&curr_data[index + count], &curr_data[index], curr_size - index + 1); @@ -683,7 +691,15 @@ replace( curr_size - (std::min)(n1, curr_size - pos) >= max_size() - n2, std::length_error{"replaced string exceeds max_size()"}); n1 = (std::min)(n1, curr_size - pos); - const bool inside = s <= &curr_data[curr_size] && s >= curr_data; + // Makes this more constexpr friendly if we can use is_constant_evaluated + const bool inside = +#ifdef BOOST_STATIC_STRING_USE_IS_CONST_EVAL + std::is_constant_evaluated() ? + detail::is_inside(curr_data, curr_data + curr_size, s) : + s <= &curr_data[curr_size] && s >= curr_data; +#else + s <= &curr_data[curr_size] && s >= curr_data; +#endif if (inside && size_type(s - curr_data) == pos && n1 == n2) return *this; if (!inside || (inside && ((s - curr_data) + n2 <= pos))) diff --git a/test/constexpr_tests.hpp b/test/constexpr_tests.hpp index 1df0ba9..77a7acf 100644 --- a/test/constexpr_tests.hpp +++ b/test/constexpr_tests.hpp @@ -191,6 +191,11 @@ testConstantEvaluation() a.replace(a.begin(), a.end(), a.begin(), a.end()); a.replace(a.begin(), a.end(), {'a'}); +#ifdef BOOST_STATIC_STRING_USE_IS_CONST_EVAL + a.replace(a.begin(), a.end(), "a"); + a.replace(a.begin(), a.end(), "a", 1); +#endif + // find a.find(a); a.find("a", 0, 1);