Fix more constexpr

This commit is contained in:
Krystian Stasiowski
2020-02-02 11:43:17 -05:00
parent 00d6d174fb
commit 497c84b5a1
2 changed files with 22 additions and 13 deletions

View File

@ -35,12 +35,10 @@
// Can we use is_constant_evaluated? // Can we use is_constant_evaluated?
// Standard version // Standard version
#if __cpp_lib_is_constant_evaluated >= 201811L #if __cpp_lib_is_constant_evaluated >= 201811L
#define BOOST_STATIC_STRING_USE_IS_CONST_EVAL
#define BOOST_STATIC_STRING_IS_CONST_EVAL std::is_constant_evaluated() #define BOOST_STATIC_STRING_IS_CONST_EVAL std::is_constant_evaluated()
#elif defined(__clang__) && (__clang_major__ > 8) #elif defined(__clang__) && __has_builtin(__builtin_is_constant_evaluated)
// If we have clang version 9+, we can use the intrinsic // If we have clang version 9+, we can use the intrinsic
// While gcc also has this, we don't need it // While gcc also has this, we don't need it
#define BOOST_STATIC_STRING_USE_IS_CONST_EVAL
#define BOOST_STATIC_STRING_IS_CONST_EVAL __builtin_is_constant_evaluated() #define BOOST_STATIC_STRING_IS_CONST_EVAL __builtin_is_constant_evaluated()
#endif #endif
@ -158,12 +156,13 @@ defined(__clang__) && \
#define BOOST_STATIC_STRING_CPP14_CONSTEXPR #define BOOST_STATIC_STRING_CPP14_CONSTEXPR
#endif #endif
// These are for compiler/library configurations // This is for compiler/library configurations
// that cannot use the library comparison function // that cannot use the library comparison function
// objects at all in constant expresssions. In these // objects at all in constant expresssions. In these
// cases, we use whatever will make more constexpr work. // cases, we use whatever will make more constexpr work.
#if defined(__clang__) && defined(__GLIBCXX__) && \ #if defined(__clang__) && defined(__GLIBCXX__) && ((__GLIBCXX__ > 20181206 && __GLIBCXX__ <= 20190812))
((__GLIBCXX__ > 20181206) && (__GLIBCXX__ < 20190812)) #define BOOST_STATIC_STRING_NO_PTR_COMP_FUNCTIONS
#elif __has_builtin(__builtin_constant_p) || defined(BOOST_STATIC_STRING_IS_CONST_EVAL)
#define BOOST_STATIC_STRING_NO_PTR_COMP_FUNCTIONS #define BOOST_STATIC_STRING_NO_PTR_COMP_FUNCTIONS
#endif #endif

View File

@ -596,8 +596,9 @@ find_first_of(
return last; return last;
} }
// Check if a pointer lies within a range (inclusive) without unspecified behavior, // Check if a pointer lies within the range [src_first, src_last)
// allowing it to be used in a constant evaluation // without unspecified behavior, allowing it to be used
// in a constant evaluation.
template<typename T> template<typename T>
BOOST_STATIC_STRING_CPP14_CONSTEXPR BOOST_STATIC_STRING_CPP14_CONSTEXPR
inline inline
@ -615,7 +616,7 @@ is_inside(
// no applications in constant expressions. // no applications in constant expressions.
#ifdef BOOST_STATIC_STRING_CPP14 #ifdef BOOST_STATIC_STRING_CPP14
#ifdef BOOST_STATIC_STRING_NO_PTR_COMP_FUNCTIONS #ifdef BOOST_STATIC_STRING_NO_PTR_COMP_FUNCTIONS
#ifdef BOOST_STATIC_STRING_USE_IS_CONST_EVAL #ifdef BOOST_STATIC_STRING_IS_CONST_EVAL
// Our second best option is to use is_constant_evaluated // Our second best option is to use is_constant_evaluated
// and a loop that checks for equality, since equality for // and a loop that checks for equality, since equality for
// pointer to object types is never unspecified in this case. // pointer to object types is never unspecified in this case.
@ -626,18 +627,27 @@ is_inside(
return true; return true;
return false; return false;
} }
#elif defined(__clang__) && __has_builtin(__builtin_constant_p)
// We can also try using __builtin_constant_p
if (__builtin_constant_p((ptr, src_first, src_last)))
{
for (; src_first != src_last; ++src_first)
if (src_first == ptr)
return true;
return false;
}
#else #else
// If library comparison functions don't work, and // If library comparison functions don't work, and
// we cannot use is_constant_evaluated, we can use // we cannot use any of the above, we can use
// the builtin comparison operators instead. // try builtin comparison operators instead.
return ptr >= src_first && ptr <= src_last; return ptr >= src_first && ptr < src_last;
#endif #endif
#endif #endif
#endif #endif
// Use the library comparison functions if we can't use // Use the library comparison functions if we can't use
// is_constant_evaluated or if we don't need to. // is_constant_evaluated or if we don't need to.
return std::greater_equal<const T*>()(ptr, src_first) && return std::greater_equal<const T*>()(ptr, src_first) &&
std::less_equal<const T*>()(ptr, src_last); std::less<const T*>()(ptr, src_last);
} }
} // detail } // detail
#endif #endif