public inbox for libstdc++@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] libstdc++: Define std::__is_constant_evaluated() for internal use
@ 2021-11-26 12:29 Jonathan Wakely
  2021-11-26 12:38 ` Ville Voutilainen
  2021-11-26 12:39 ` Jakub Jelinek
  0 siblings, 2 replies; 6+ messages in thread
From: Jonathan Wakely @ 2021-11-26 12:29 UTC (permalink / raw)
  To: libstdc++, gcc-patches

I've bored of having to do preprocessor checks before using
is_constant_evaluated, so I've come up with this approach. Anybody got a
better idea, or objections to this?

An alternative to __is_constant_evaluated would be to define a function
called __builtin_is_constant_evaluated when it isn't supported by the
compiler, but that feels a bit icky. We shouldn't be using the
compiler's "__builtin_" prefix for an ordinary function defined in the
library.

...

This adds std::__is_constant_evaluated() as a C++11 wrapper for
__builtin_is_constant_evaluated, but just returning false if the
built-in isn't supported by the compiler. This allows us to use it
throughout the library without checking __has_builtin every time.

The remaining checks of the __cpp_lib_is_constant_evaluated macro could
now be replaced by checking __cplusplus >= 202002 instead, but there's
no practical difference. We still need a preprocessor check in those
cases.

libstdc++-v3/ChangeLog:

	* include/bits/allocator.h (allocate, deallocate): Use
	std::__is_constant_evaluated() unconditionally, instead of
	checking whether std::is_constant_evaluated() (or the built-in)
	can be used.
	* include/bits/char_traits.h (char_traits): Likewise.
	* include/bits/ranges_algobase.h (__copy_or_move): Likewise.
	(__copy_or_move_backward, __fill_n_fn): Likewise.
	* include/bits/ranges_cmp.h (ranges::less): Likewise.
	* include/bits/stl_algobase.h (lexicographical_compare_three_way):
	Likewise.
	* include/bits/stl_construct.h (_Construct, _Destroy, _Destroy_n):
	Likewise.
	* include/bits/stl_function.h (greater, less, greater_equal)
	(less_equal): Likewise.
	* include/std/array (operator<=>): Likewise.
	* include/std/bit (__bit_ceil): Likewise.
	* include/std/type_traits (__is_constant_evaluated): Define new
	function for internal use.
	* testsuite/23_containers/array/tuple_interface/get_neg.cc:
	Adjust dg-error lines.
---
 libstdc++-v3/include/bits/allocator.h         |   8 +-
 libstdc++-v3/include/bits/char_traits.h       | 127 +++++++++---------
 libstdc++-v3/include/bits/ranges_algobase.h   |  12 +-
 libstdc++-v3/include/bits/ranges_cmp.h        |   5 +-
 libstdc++-v3/include/bits/stl_algobase.h      |   5 +-
 libstdc++-v3/include/bits/stl_construct.h     |  12 +-
 libstdc++-v3/include/bits/stl_function.h      |  24 +---
 libstdc++-v3/include/std/array                |   4 +-
 libstdc++-v3/include/std/bit                  |   5 +-
 libstdc++-v3/include/std/type_traits          |  12 ++
 .../array/tuple_interface/get_neg.cc          |   6 +-
 11 files changed, 102 insertions(+), 118 deletions(-)

diff --git a/libstdc++-v3/include/bits/allocator.h b/libstdc++-v3/include/bits/allocator.h
index f83e6b87666..1c099514e18 100644
--- a/libstdc++-v3/include/bits/allocator.h
+++ b/libstdc++-v3/include/bits/allocator.h
@@ -178,10 +178,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       constexpr _Tp*
       allocate(size_t __n)
       {
-#ifdef __cpp_lib_is_constant_evaluated
-	if (std::is_constant_evaluated())
+	if (std::__is_constant_evaluated())
 	  return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp)));
-#endif
 	return __allocator_base<_Tp>::allocate(__n, 0);
       }
 
@@ -189,13 +187,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       constexpr void
       deallocate(_Tp* __p, size_t __n)
       {
-#ifdef __cpp_lib_is_constant_evaluated
-	if (std::is_constant_evaluated())
+	if (std::__is_constant_evaluated())
 	  {
 	    ::operator delete(__p);
 	    return;
 	  }
-#endif
 	__allocator_base<_Tp>::deallocate(__p, __n);
       }
 #endif // C++20
diff --git a/libstdc++-v3/include/bits/char_traits.h b/libstdc++-v3/include/bits/char_traits.h
index b1cdc55ea61..e6afcc72860 100644
--- a/libstdc++-v3/include/bits/char_traits.h
+++ b/libstdc++-v3/include/bits/char_traits.h
@@ -38,6 +38,9 @@
 
 #include <bits/postypes.h>      // For streampos
 #include <cwchar>               // For WEOF, wmemmove, wmemset, etc.
+#if __cplusplus >= 201103L
+# include <type_traits>
+#endif
 #if __cplusplus >= 202002L
 # include <compare>
 # include <bits/stl_construct.h>
@@ -101,8 +104,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       static _GLIBCXX14_CONSTEXPR void
       assign(char_type& __c1, const char_type& __c2)
       {
-#if __cpp_constexpr_dynamic_alloc && __cpp_lib_is_constant_evaluated
-	if (std::is_constant_evaluated())
+#if __cpp_constexpr_dynamic_alloc
+	if (std::__is_constant_evaluated())
 	  std::construct_at(__builtin_addressof(__c1), __c2);
 	else
 #endif
@@ -199,8 +202,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     {
       if (__n == 0)
 	return __s1;
-#if __cpp_lib_is_constant_evaluated
-      if (std::is_constant_evaluated())
+#if __cplusplus >= 202002L
+      if (std::__is_constant_evaluated())
 	{
 	  if (__s1 == __s2) // unlikely, but saves a lot of work
 	    return __s1;
@@ -247,8 +250,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     char_traits<_CharT>::
     copy(char_type* __s1, const char_type* __s2, std::size_t __n)
     {
-#if __cpp_lib_is_constant_evaluated
-      if (std::is_constant_evaluated())
+#if __cplusplus >= 202002L
+      if (std::__is_constant_evaluated())
 	{
 	  for (std::size_t __i = 0; __i < __n; ++__i)
 	    std::construct_at(__s1 + __i, __s2[__i]);
@@ -266,8 +269,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     char_traits<_CharT>::
     assign(char_type* __s, std::size_t __n, char_type __a)
     {
-#if __cpp_lib_is_constant_evaluated
-      if (std::is_constant_evaluated())
+#if __cplusplus >= 202002L
+      if (std::__is_constant_evaluated())
 	{
 	  for (std::size_t __i = 0; __i < __n; ++__i)
 	    std::construct_at(__s + __i, __a);
@@ -338,8 +341,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       static _GLIBCXX17_CONSTEXPR void
       assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
       {
-#if __cpp_constexpr_dynamic_alloc && __cpp_lib_is_constant_evaluated
-	if (std::is_constant_evaluated())
+#if __cpp_constexpr_dynamic_alloc
+	if (std::__is_constant_evaluated())
 	  std::construct_at(__builtin_addressof(__c1), __c2);
 	else
 #endif
@@ -363,8 +366,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       {
 	if (__n == 0)
 	  return 0;
-#if __cplusplus >= 201703L && _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED
-	if (__builtin_is_constant_evaluated())
+#if __cplusplus >= 201703L
+	if (std::__is_constant_evaluated())
 	  {
 	    for (size_t __i = 0; __i < __n; ++__i)
 	      if (lt(__s1[__i], __s2[__i]))
@@ -380,8 +383,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       static _GLIBCXX17_CONSTEXPR size_t
       length(const char_type* __s)
       {
-#if __cplusplus >= 201703L && _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED
-	if (__builtin_is_constant_evaluated())
+#if __cplusplus >= 201703L
+	if (std::__is_constant_evaluated())
 	  return __gnu_cxx::char_traits<char_type>::length(__s);
 #endif
 	return __builtin_strlen(__s);
@@ -392,8 +395,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       {
 	if (__n == 0)
 	  return 0;
-#if __cplusplus >= 201703L && _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED
-	if (__builtin_is_constant_evaluated())
+#if __cplusplus >= 201703L
+	if (std::__is_constant_evaluated())
 	  return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a);
 #endif
 	return static_cast<const char_type*>(__builtin_memchr(__s, __a, __n));
@@ -404,8 +407,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       {
 	if (__n == 0)
 	  return __s1;
-#ifdef __cpp_lib_is_constant_evaluated
-	if (std::is_constant_evaluated())
+#if __cplusplus >= 202002L
+	if (std::__is_constant_evaluated())
 	  return __gnu_cxx::char_traits<char_type>::move(__s1, __s2, __n);
 #endif
 	return static_cast<char_type*>(__builtin_memmove(__s1, __s2, __n));
@@ -416,8 +419,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       {
 	if (__n == 0)
 	  return __s1;
-#ifdef __cpp_lib_is_constant_evaluated
-	if (std::is_constant_evaluated())
+#if __cplusplus >= 202002L
+	if (std::__is_constant_evaluated())
 	  return __gnu_cxx::char_traits<char_type>::copy(__s1, __s2, __n);
 #endif
 	return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n));
@@ -428,8 +431,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       {
 	if (__n == 0)
 	  return __s;
-#ifdef __cpp_lib_is_constant_evaluated
-	if (std::is_constant_evaluated())
+#if __cplusplus >= 202002L
+	if (std::__is_constant_evaluated())
 	  return __gnu_cxx::char_traits<char_type>::assign(__s, __n, __a);
 #endif
 	return static_cast<char_type*>(__builtin_memset(__s, __a, __n));
@@ -476,8 +479,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       static _GLIBCXX17_CONSTEXPR void
       assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
       {
-#if __cpp_constexpr_dynamic_alloc && __cpp_lib_is_constant_evaluated
-	if (std::is_constant_evaluated())
+#if __cpp_constexpr_dynamic_alloc
+	if (std::__is_constant_evaluated())
 	  std::construct_at(__builtin_addressof(__c1), __c2);
 	else
 #endif
@@ -497,8 +500,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       {
 	if (__n == 0)
 	  return 0;
-#if __cplusplus >= 201703L && _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED
-	if (__builtin_is_constant_evaluated())
+#if __cplusplus >= 201703L
+	if (std::__is_constant_evaluated())
 	  return __gnu_cxx::char_traits<char_type>::compare(__s1, __s2, __n);
 #endif
 	return wmemcmp(__s1, __s2, __n);
@@ -507,8 +510,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       static _GLIBCXX17_CONSTEXPR size_t
       length(const char_type* __s)
       {
-#if __cplusplus >= 201703L && _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED
-	if (__builtin_is_constant_evaluated())
+#if __cplusplus >= 201703L
+	if (std::__is_constant_evaluated())
 	  return __gnu_cxx::char_traits<char_type>::length(__s);
 #endif
 	return wcslen(__s);
@@ -519,8 +522,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       {
 	if (__n == 0)
 	  return 0;
-#if __cplusplus >= 201703L && _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED
-	if (__builtin_is_constant_evaluated())
+#if __cplusplus >= 201703L
+	if (std::__is_constant_evaluated())
 	  return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a);
 #endif
 	return wmemchr(__s, __a, __n);
@@ -531,8 +534,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       {
 	if (__n == 0)
 	  return __s1;
-#ifdef __cpp_lib_is_constant_evaluated
-	if (std::is_constant_evaluated())
+#if __cplusplus >= 202002L
+	if (std::__is_constant_evaluated())
 	  return __gnu_cxx::char_traits<char_type>::move(__s1, __s2, __n);
 #endif
 	return wmemmove(__s1, __s2, __n);
@@ -543,8 +546,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       {
 	if (__n == 0)
 	  return __s1;
-#ifdef __cpp_lib_is_constant_evaluated
-	if (std::is_constant_evaluated())
+#if __cplusplus >= 202002L
+	if (std::__is_constant_evaluated())
 	  return __gnu_cxx::char_traits<char_type>::copy(__s1, __s2, __n);
 #endif
 	return wmemcpy(__s1, __s2, __n);
@@ -555,8 +558,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       {
 	if (__n == 0)
 	  return __s;
-#ifdef __cpp_lib_is_constant_evaluated
-	if (std::is_constant_evaluated())
+#if __cplusplus >= 202002L
+	if (std::__is_constant_evaluated())
 	  return __gnu_cxx::char_traits<char_type>::assign(__s, __n, __a);
 #endif
 	return wmemset(__s, __a, __n);
@@ -604,8 +607,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       static _GLIBCXX17_CONSTEXPR void
       assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
       {
-#if __cpp_constexpr_dynamic_alloc && __cpp_lib_is_constant_evaluated
-	if (std::is_constant_evaluated())
+#if __cpp_constexpr_dynamic_alloc
+	if (std::__is_constant_evaluated())
 	  std::construct_at(__builtin_addressof(__c1), __c2);
 	else
 #endif
@@ -625,8 +628,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       {
 	if (__n == 0)
 	  return 0;
-#if __cplusplus >= 201703L && _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED
-	if (__builtin_is_constant_evaluated())
+#if __cplusplus >= 201703L
+	if (std::__is_constant_evaluated())
 	  return __gnu_cxx::char_traits<char_type>::compare(__s1, __s2, __n);
 #endif
 	return __builtin_memcmp(__s1, __s2, __n);
@@ -635,8 +638,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       static _GLIBCXX17_CONSTEXPR size_t
       length(const char_type* __s)
       {
-#if __cplusplus >= 201703L && _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED
-	if (__builtin_is_constant_evaluated())
+#if __cplusplus >= 201703L
+	if (std::__is_constant_evaluated())
 	  return __gnu_cxx::char_traits<char_type>::length(__s);
 #endif
 	size_t __i = 0;
@@ -650,8 +653,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       {
 	if (__n == 0)
 	  return 0;
-#if __cplusplus >= 201703L && _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED
-	if (__builtin_is_constant_evaluated())
+#if __cplusplus >= 201703L
+	if (std::__is_constant_evaluated())
 	  return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a);
 #endif
 	return static_cast<const char_type*>(__builtin_memchr(__s, __a, __n));
@@ -662,8 +665,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       {
 	if (__n == 0)
 	  return __s1;
-#ifdef __cpp_lib_is_constant_evaluated
-	if (std::is_constant_evaluated())
+#if __cplusplus >= 202002L
+	if (std::__is_constant_evaluated())
 	  return __gnu_cxx::char_traits<char_type>::move(__s1, __s2, __n);
 #endif
 	return static_cast<char_type*>(__builtin_memmove(__s1, __s2, __n));
@@ -674,8 +677,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       {
 	if (__n == 0)
 	  return __s1;
-#ifdef __cpp_lib_is_constant_evaluated
-	if (std::is_constant_evaluated())
+#if __cplusplus >= 202002L
+	if (std::__is_constant_evaluated())
 	  return __gnu_cxx::char_traits<char_type>::copy(__s1, __s2, __n);
 #endif
 	return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n));
@@ -686,8 +689,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       {
 	if (__n == 0)
 	  return __s;
-#ifdef __cpp_lib_is_constant_evaluated
-	if (std::is_constant_evaluated())
+#if __cplusplus >= 202002L
+	if (std::__is_constant_evaluated())
 	  return __gnu_cxx::char_traits<char_type>::assign(__s, __n, __a);
 #endif
 	return static_cast<char_type*>(__builtin_memset(__s, __a, __n));
@@ -747,8 +750,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       static _GLIBCXX17_CONSTEXPR void
       assign(char_type& __c1, const char_type& __c2) noexcept
       {
-#if __cpp_constexpr_dynamic_alloc && __cpp_lib_is_constant_evaluated
-	if (std::is_constant_evaluated())
+#if __cpp_constexpr_dynamic_alloc
+	if (std::__is_constant_evaluated())
 	  std::construct_at(__builtin_addressof(__c1), __c2);
 	else
 #endif
@@ -797,8 +800,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       {
 	if (__n == 0)
 	  return __s1;
-#ifdef __cpp_lib_is_constant_evaluated
-	if (std::is_constant_evaluated())
+#if __cplusplus >= 202002L
+	if (std::__is_constant_evaluated())
 	  return __gnu_cxx::char_traits<char_type>::move(__s1, __s2, __n);
 #endif
 	return (static_cast<char_type*>
@@ -810,8 +813,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       {
 	if (__n == 0)
 	  return __s1;
-#ifdef __cpp_lib_is_constant_evaluated
-	if (std::is_constant_evaluated())
+#if __cplusplus >= 202002L
+	if (std::__is_constant_evaluated())
 	  return __gnu_cxx::char_traits<char_type>::copy(__s1, __s2, __n);
 #endif
 	return (static_cast<char_type*>
@@ -868,8 +871,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       static _GLIBCXX17_CONSTEXPR void
       assign(char_type& __c1, const char_type& __c2) noexcept
       {
-#if __cpp_constexpr_dynamic_alloc && __cpp_lib_is_constant_evaluated
-	if (std::is_constant_evaluated())
+#if __cpp_constexpr_dynamic_alloc
+	if (std::__is_constant_evaluated())
 	  std::construct_at(__builtin_addressof(__c1), __c2);
 	else
 #endif
@@ -918,8 +921,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       {
 	if (__n == 0)
 	  return __s1;
-#ifdef __cpp_lib_is_constant_evaluated
-	if (std::is_constant_evaluated())
+#if __cplusplus >= 202002L
+	if (std::__is_constant_evaluated())
 	  return __gnu_cxx::char_traits<char_type>::move(__s1, __s2, __n);
 #endif
 	return (static_cast<char_type*>
@@ -931,8 +934,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       { 
 	if (__n == 0)
 	  return __s1;
-#ifdef __cpp_lib_is_constant_evaluated
-	if (std::is_constant_evaluated())
+#if __cplusplus >= 202002L
+	if (std::__is_constant_evaluated())
 	  return __gnu_cxx::char_traits<char_type>::copy(__s1, __s2, __n);
 #endif
 	return (static_cast<char_type*>
diff --git a/libstdc++-v3/include/bits/ranges_algobase.h b/libstdc++-v3/include/bits/ranges_algobase.h
index 9929e5e828b..74b8e9c4d59 100644
--- a/libstdc++-v3/include/bits/ranges_algobase.h
+++ b/libstdc++-v3/include/bits/ranges_algobase.h
@@ -251,9 +251,7 @@ namespace ranges
 	}
       else if constexpr (sized_sentinel_for<_Sent, _Iter>)
 	{
-#ifdef __cpp_lib_is_constant_evaluated
-	  if (!std::is_constant_evaluated())
-#endif
+	  if (!std::__is_constant_evaluated())
 	    {
 	      if constexpr (__memcpyable<_Iter, _Out>::__value)
 		{
@@ -388,9 +386,7 @@ namespace ranges
 	}
       else if constexpr (sized_sentinel_for<_Sent, _Iter>)
 	{
-#ifdef __cpp_lib_is_constant_evaluated
-	  if (!std::is_constant_evaluated())
-#endif
+	  if (!std::__is_constant_evaluated())
 	    {
 	      if constexpr (__memcpyable<_Out, _Iter>::__value)
 		{
@@ -535,9 +531,7 @@ namespace ranges
 			  && __is_byte<remove_pointer_t<_Out>>::__value
 			  && integral<_Tp>)
 	      {
-#ifdef __cpp_lib_is_constant_evaluated
-		if (!std::is_constant_evaluated())
-#endif
+		if (!std::__is_constant_evaluated())
 		  {
 		    __builtin_memset(__first,
 				     static_cast<unsigned char>(__value),
diff --git a/libstdc++-v3/include/bits/ranges_cmp.h b/libstdc++-v3/include/bits/ranges_cmp.h
index 1d7da30dddf..098022e63a2 100644
--- a/libstdc++-v3/include/bits/ranges_cmp.h
+++ b/libstdc++-v3/include/bits/ranges_cmp.h
@@ -119,10 +119,9 @@ namespace ranges
       {
 	if constexpr (__detail::__less_builtin_ptr_cmp<_Tp, _Up>)
 	  {
-#ifdef __cpp_lib_is_constant_evaluated
-	    if (std::is_constant_evaluated())
+	    if (std::__is_constant_evaluated())
 	      return __t < __u;
-#endif
+
 	    auto __x = reinterpret_cast<__UINTPTR_TYPE__>(
 	      static_cast<const volatile void*>(std::forward<_Tp>(__t)));
 	    auto __y = reinterpret_cast<__UINTPTR_TYPE__>(
diff --git a/libstdc++-v3/include/bits/stl_algobase.h b/libstdc++-v3/include/bits/stl_algobase.h
index f441165714b..984a5bf94b9 100644
--- a/libstdc++-v3/include/bits/stl_algobase.h
+++ b/libstdc++-v3/include/bits/stl_algobase.h
@@ -1826,11 +1826,10 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
       __glibcxx_requires_valid_range(__first1, __last1);
       __glibcxx_requires_valid_range(__first2, __last2);
 
-#if __cpp_lib_is_constant_evaluated
       using _Cat = decltype(__comp(*__first1, *__first2));
       static_assert(same_as<common_comparison_category_t<_Cat>, _Cat>);
 
-      if (!std::is_constant_evaluated())
+      if (!std::__is_constant_evaluated())
 	if constexpr (same_as<_Comp, __detail::_Synth3way>
 		      || same_as<_Comp, compare_three_way>)
 	  if constexpr (__is_byte_iter<_InputIter1>)
@@ -1847,7 +1846,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
 		  }
 		return __lencmp;
 	      }
-#endif // is_constant_evaluated
+
       while (__first1 != __last1)
 	{
 	  if (__first2 == __last2)
diff --git a/libstdc++-v3/include/bits/stl_construct.h b/libstdc++-v3/include/bits/stl_construct.h
index e53ed0d9f91..dd621f24bc2 100644
--- a/libstdc++-v3/include/bits/stl_construct.h
+++ b/libstdc++-v3/include/bits/stl_construct.h
@@ -108,8 +108,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     inline void
     _Construct(_Tp* __p, _Args&&... __args)
     {
-#if __cplusplus >= 202002L && __has_builtin(__builtin_is_constant_evaluated)
-      if (__builtin_is_constant_evaluated())
+#if __cplusplus >= 202002L
+      if (std::__is_constant_evaluated())
 	{
 	  // Allow std::_Construct to be used in constant expressions.
 	  std::construct_at(__p, std::forward<_Args>(__args)...);
@@ -188,8 +188,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       static_assert(is_destructible<_Value_type>::value,
 		    "value type is destructible");
 #endif
-#if __cplusplus > 201703L && defined __cpp_lib_is_constant_evaluated
-      if (std::is_constant_evaluated())
+#if __cplusplus >= 202002L
+      if (std::__is_constant_evaluated())
 	return _Destroy_aux<false>::__destroy(__first, __last);
 #endif
       std::_Destroy_aux<__has_trivial_destructor(_Value_type)>::
@@ -237,8 +237,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       static_assert(is_destructible<_Value_type>::value,
 		    "value type is destructible");
 #endif
-#if __cplusplus > 201703L && defined __cpp_lib_is_constant_evaluated
-      if (std::is_constant_evaluated())
+#if __cplusplus >= 202002L
+      if (std::__is_constant_evaluated())
 	return _Destroy_n_aux<false>::__destroy_n(__first, __count);
 #endif
       return std::_Destroy_n_aux<__has_trivial_destructor(_Value_type)>::
diff --git a/libstdc++-v3/include/bits/stl_function.h b/libstdc++-v3/include/bits/stl_function.h
index 5de8c3234f7..92e9dc75a80 100644
--- a/libstdc++-v3/include/bits/stl_function.h
+++ b/libstdc++-v3/include/bits/stl_function.h
@@ -428,11 +428,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       operator()(_Tp* __x, _Tp* __y) const _GLIBCXX_NOTHROW
       {
 #if __cplusplus >= 201402L
-#ifdef _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED
-	if (__builtin_is_constant_evaluated())
-#else
-	if (__builtin_constant_p(__x > __y))
-#endif
+	if (std::__is_constant_evaluated())
 	  return __x > __y;
 #endif
 	return (__UINTPTR_TYPE__)__x > (__UINTPTR_TYPE__)__y;
@@ -447,11 +443,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       operator()(_Tp* __x, _Tp* __y) const _GLIBCXX_NOTHROW
       {
 #if __cplusplus >= 201402L
-#ifdef _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED
-	if (__builtin_is_constant_evaluated())
-#else
-	if (__builtin_constant_p(__x < __y))
-#endif
+	if (std::__is_constant_evaluated())
 	  return __x < __y;
 #endif
 	return (__UINTPTR_TYPE__)__x < (__UINTPTR_TYPE__)__y;
@@ -466,11 +458,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       operator()(_Tp* __x, _Tp* __y) const _GLIBCXX_NOTHROW
       {
 #if __cplusplus >= 201402L
-#ifdef _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED
-	if (__builtin_is_constant_evaluated())
-#else
-	if (__builtin_constant_p(__x >= __y))
-#endif
+	if (std::__is_constant_evaluated())
 	  return __x >= __y;
 #endif
 	return (__UINTPTR_TYPE__)__x >= (__UINTPTR_TYPE__)__y;
@@ -485,11 +473,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       operator()(_Tp* __x, _Tp* __y) const _GLIBCXX_NOTHROW
       {
 #if __cplusplus >= 201402L
-#ifdef _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED
-	if (__builtin_is_constant_evaluated())
-#else
-	if (__builtin_constant_p(__x <= __y))
-#endif
+	if (std::__is_constant_evaluated())
 	  return __x <= __y;
 #endif
 	return (__UINTPTR_TYPE__)__x <= (__UINTPTR_TYPE__)__y;
diff --git a/libstdc++-v3/include/std/array b/libstdc++-v3/include/std/array
index 413f8e2be01..e632de15aff 100644
--- a/libstdc++-v3/include/std/array
+++ b/libstdc++-v3/include/std/array
@@ -310,14 +310,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     constexpr __detail::__synth3way_t<_Tp>
     operator<=>(const array<_Tp, _Nm>& __a, const array<_Tp, _Nm>& __b)
     {
-#ifdef __cpp_lib_is_constant_evaluated
       if constexpr (_Nm && __is_memcmp_ordered<_Tp>::__value)
-	if (!std::is_constant_evaluated())
+	if (!std::__is_constant_evaluated())
 	  {
 	    constexpr size_t __n = _Nm * sizeof(_Tp);
 	    return __builtin_memcmp(__a.data(), __b.data(), __n) <=> 0;
 	  }
-#endif
 
       for (size_t __i = 0; __i < _Nm; ++__i)
 	{
diff --git a/libstdc++-v3/include/std/bit b/libstdc++-v3/include/std/bit
index c5aae8bab03..cc73bcfec6b 100644
--- a/libstdc++-v3/include/std/bit
+++ b/libstdc++-v3/include/std/bit
@@ -265,12 +265,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       // representable as a value of _Tp, and so the result is undefined.
       // Want that undefined behaviour to be detected in constant expressions,
       // by UBSan, and by debug assertions.
-#ifdef _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED
-      if (!__builtin_is_constant_evaluated())
+      if (!std::__is_constant_evaluated())
 	{
 	  __glibcxx_assert( __shift_exponent != __int_traits<_Tp>::__digits );
 	}
-#endif
+
       using __promoted_type = decltype(__x << 1);
       if _GLIBCXX17_CONSTEXPR (!is_same<__promoted_type, _Tp>::value)
 	{
diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits
index d3693b1069e..cf4abe58e90 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -3693,6 +3693,18 @@ template<typename _Ret, typename _Fn, typename... _Args>
 
 #endif // C++2a
 
+  // Internal version of std::is_constant_evaluated() for C++11.
+  // This can be used without checking if the compiler supports the built-in.
+  constexpr inline bool
+  __is_constant_evaluated() noexcept
+  {
+#if __has_builtin(__builtin_is_constant_evaluated)
+    return __builtin_is_constant_evaluated();
+#else
+    return false;
+#endif
+  }
+
   /// @} group metaprogramming
 
 _GLIBCXX_END_NAMESPACE_VERSION
diff --git a/libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_neg.cc b/libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_neg.cc
index 70742c14a7d..776ff5f771f 100644
--- a/libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_neg.cc
@@ -26,6 +26,6 @@ int n1 = std::get<1>(a);
 int n2 = std::get<1>(std::move(a));
 int n3 = std::get<1>(ca);
 
-// { dg-error "static assertion failed" "" { target *-*-* } 398 }
-// { dg-error "static assertion failed" "" { target *-*-* } 407 }
-// { dg-error "static assertion failed" "" { target *-*-* } 416 }
+// { dg-error "static assertion failed" "" { target *-*-* } 396 }
+// { dg-error "static assertion failed" "" { target *-*-* } 405 }
+// { dg-error "static assertion failed" "" { target *-*-* } 414 }
-- 
2.31.1


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] libstdc++: Define std::__is_constant_evaluated() for internal use
  2021-11-26 12:29 [PATCH] libstdc++: Define std::__is_constant_evaluated() for internal use Jonathan Wakely
@ 2021-11-26 12:38 ` Ville Voutilainen
  2021-11-26 12:39 ` Jakub Jelinek
  1 sibling, 0 replies; 6+ messages in thread
From: Ville Voutilainen @ 2021-11-26 12:38 UTC (permalink / raw)
  To: Jonathan Wakely; +Cc: libstdc++, gcc-patches List

On Fri, 26 Nov 2021 at 14:29, Jonathan Wakely via Libstdc++
<libstdc++@gcc.gnu.org> wrote:
>
> I've bored of having to do preprocessor checks before using
> is_constant_evaluated, so I've come up with this approach. Anybody got a
> better idea, or objections to this?

None here, I like this improvement.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] libstdc++: Define std::__is_constant_evaluated() for internal use
  2021-11-26 12:29 [PATCH] libstdc++: Define std::__is_constant_evaluated() for internal use Jonathan Wakely
  2021-11-26 12:38 ` Ville Voutilainen
@ 2021-11-26 12:39 ` Jakub Jelinek
  2021-11-26 12:43   ` Jonathan Wakely
  1 sibling, 1 reply; 6+ messages in thread
From: Jakub Jelinek @ 2021-11-26 12:39 UTC (permalink / raw)
  To: Jonathan Wakely; +Cc: libstdc++, gcc-patches

On Fri, Nov 26, 2021 at 12:29:25PM +0000, Jonathan Wakely via Gcc-patches wrote:
> +  // Internal version of std::is_constant_evaluated() for C++11.
> +  // This can be used without checking if the compiler supports the built-in.
> +  constexpr inline bool
> +  __is_constant_evaluated() noexcept
> +  {

When you have such a nice one spot, shouldn't it:
#if __cpp_if_consteval >= 202106L 
  if consteval
    {
      return true;
    }
  else
    {
      return false;
    }
#elif __has_builtin(__builtin_is_constant_evaluated)
...

Theoretically not all compilers need to support the builtin and in C++23
mode if consteval should be slightly more efficient.

One disadvantage of std::__is_constant_evaluated() is that Marek's
warning for if constexpr (std::is_constant_evaluated()) will not trigger
if __is_constant_evaluated() is used instead.  But I'd hope testsuite
coverage would discover it quickly if such bug would appear...

	Jakub


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] libstdc++: Define std::__is_constant_evaluated() for internal use
  2021-11-26 12:39 ` Jakub Jelinek
@ 2021-11-26 12:43   ` Jonathan Wakely
  2021-11-26 12:49     ` Jakub Jelinek
  2021-11-26 23:26     ` [PATCH v2] " Jonathan Wakely
  0 siblings, 2 replies; 6+ messages in thread
From: Jonathan Wakely @ 2021-11-26 12:43 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: libstdc++, gcc Patches

On Fri, 26 Nov 2021 at 12:39, Jakub Jelinek wrote:
>
> On Fri, Nov 26, 2021 at 12:29:25PM +0000, Jonathan Wakely via Gcc-patches wrote:
> > +  // Internal version of std::is_constant_evaluated() for C++11.
> > +  // This can be used without checking if the compiler supports the built-in.
> > +  constexpr inline bool
> > +  __is_constant_evaluated() noexcept
> > +  {
>
> When you have such a nice one spot, shouldn't it:
> #if __cpp_if_consteval >= 202106L
>   if consteval
>     {
>       return true;
>     }
>   else
>     {
>       return false;
>     }
> #elif __has_builtin(__builtin_is_constant_evaluated)
> ...
>
> Theoretically not all compilers need to support the builtin and in C++23
> mode if consteval should be slightly more efficient.

Yes, good idea. We actually still have two spots, because we still
have std::is_constant_evaluated as well, which is only defined if it
actually works. But we can use the same implementation in there (or
make it call std::__is_constant_evaluated()). I'll prepare a new patch
soon.

> One disadvantage of std::__is_constant_evaluated() is that Marek's
> warning for if constexpr (std::is_constant_evaluated()) will not trigger
> if __is_constant_evaluated() is used instead.  But I'd hope testsuite
> coverage would discover it quickly if such bug would appear...

Yes, and I hope I won't make that mistake anyway, or miss it in reviews.

It's a good warning for users, but I like to think I don't need it
(and now we start the sweepstake on how many days until I push a patch
making exactly that mistake ;-)


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] libstdc++: Define std::__is_constant_evaluated() for internal use
  2021-11-26 12:43   ` Jonathan Wakely
@ 2021-11-26 12:49     ` Jakub Jelinek
  2021-11-26 23:26     ` [PATCH v2] " Jonathan Wakely
  1 sibling, 0 replies; 6+ messages in thread
From: Jakub Jelinek @ 2021-11-26 12:49 UTC (permalink / raw)
  To: Jonathan Wakely; +Cc: libstdc++, gcc Patches

On Fri, Nov 26, 2021 at 12:43:44PM +0000, Jonathan Wakely wrote:
> > On Fri, Nov 26, 2021 at 12:29:25PM +0000, Jonathan Wakely via Gcc-patches wrote:
> > > +  // Internal version of std::is_constant_evaluated() for C++11.
> > > +  // This can be used without checking if the compiler supports the built-in.
> > > +  constexpr inline bool
> > > +  __is_constant_evaluated() noexcept
> > > +  {
> >
> > When you have such a nice one spot, shouldn't it:
> > #if __cpp_if_consteval >= 202106L
> >   if consteval
> >     {
> >       return true;
> >     }
> >   else
> >     {
> >       return false;
> >     }
> > #elif __has_builtin(__builtin_is_constant_evaluated)
> > ...
> >
> > Theoretically not all compilers need to support the builtin and in C++23
> > mode if consteval should be slightly more efficient.
> 
> Yes, good idea. We actually still have two spots, because we still
> have std::is_constant_evaluated as well, which is only defined if it
> actually works. But we can use the same implementation in there (or
> make it call std::__is_constant_evaluated()). I'll prepare a new patch
> soon.

While calling the latter might be more maintainable, I think having it
implemented twice would be better, so that std::is_constant_evaluated()
doesn't need to hop through another inline call.
I'd expect people to use std::is_constant_evaluated() in their code quite a
lot, it will take time until they start to use if consteval instead.

	Jakub


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH v2] libstdc++: Define std::__is_constant_evaluated() for internal use
  2021-11-26 12:43   ` Jonathan Wakely
  2021-11-26 12:49     ` Jakub Jelinek
@ 2021-11-26 23:26     ` Jonathan Wakely
  1 sibling, 0 replies; 6+ messages in thread
From: Jonathan Wakely @ 2021-11-26 23:26 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: libstdc++, gcc Patches

[-- Attachment #1: Type: text/plain, Size: 1821 bytes --]

On Fri, 26 Nov 2021 at 12:43, Jonathan Wakely wrote:
>
> On Fri, 26 Nov 2021 at 12:39, Jakub Jelinek wrote:
> >
> > On Fri, Nov 26, 2021 at 12:29:25PM +0000, Jonathan Wakely via Gcc-patches wrote:
> > > +  // Internal version of std::is_constant_evaluated() for C++11.
> > > +  // This can be used without checking if the compiler supports the built-in.
> > > +  constexpr inline bool
> > > +  __is_constant_evaluated() noexcept
> > > +  {
> >
> > When you have such a nice one spot, shouldn't it:
> > #if __cpp_if_consteval >= 202106L
> >   if consteval
> >     {
> >       return true;
> >     }
> >   else
> >     {
> >       return false;
> >     }
> > #elif __has_builtin(__builtin_is_constant_evaluated)
> > ...
> >
> > Theoretically not all compilers need to support the builtin and in C++23
> > mode if consteval should be slightly more efficient.
>
> Yes, good idea. We actually still have two spots, because we still
> have std::is_constant_evaluated as well, which is only defined if it
> actually works. But we can use the same implementation in there (or
> make it call std::__is_constant_evaluated()). I'll prepare a new patch
> soon.
>
> > One disadvantage of std::__is_constant_evaluated() is that Marek's
> > warning for if constexpr (std::is_constant_evaluated()) will not trigger
> > if __is_constant_evaluated() is used instead.  But I'd hope testsuite
> > coverage would discover it quickly if such bug would appear...
>
> Yes, and I hope I won't make that mistake anyway, or miss it in reviews.
>
> It's a good warning for users, but I like to think I don't need it
> (and now we start the sweepstake on how many days until I push a patch
> making exactly that mistake ;-)

Who had -15 days in the sweepstake? r12-5187 did it. Fixed in r12-5552.

Here's a new WIP patch for __is_constant_evaluated.

[-- Attachment #2: patch.txt --]
[-- Type: text/plain, Size: 37470 bytes --]

commit 3569c5f76ad9fc91b327a97e9cb6d5dd0f38358a
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Fri Nov 26 23:25:03 2021

    libstdc++: Define std::__is_constant_evaluated() for internal use
    
    This adds std::__is_constant_evaluated() as a C++11 wrapper for
    __builtin_is_constant_evaluated, but just returning false if the
    built-in isn't supported by the compiler. This allows us to use it
    throughout the library without checking __has_builtin every time.
    
    Some uses in std::vector and std::string can only be constexpr when the
    std::is_constant_evaluated() function actually works, so we might as
    well guard them with a relevant macro and call that function directly,
    rather than the built-in or std::__is_constant_evaluated().
    
    The remaining checks of the __cpp_lib_is_constant_evaluated macro could
    now be replaced by checking __cplusplus >= 202002 instead, but there's
    no practical difference. We still need some kind of preprocessor check
    there anyway.
    
    libstdc++-v3/ChangeLog:
    
            * doc/doxygen/user.cfg.in (PREDEFINED): Change macro name.
            * include/bits/allocator.h (allocate, deallocate): Use
            std::__is_constant_evaluated() unconditionally, instead of
            checking whether std::is_constant_evaluated() (or the built-in)
            can be used.
            * include/bits/basic_string.h: Check new macro. call
            std::is_constant_evaluated() directly in C++20-only code that is
            guarded by a suitable macro.
            * include/bits/basic_string.tcc: Likewise.
            * include/bits/c++config (__is_constant_evaluated): Define.
            (_GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED): Replace with ...
            (_GLIBCXX_HAVE_IS_CONSTANT_EVALUATED): New macro.
            * include/bits/char_traits.h (char_traits): Replace conditional
            calls to std::is_constant_evaluated with unconditional calls to
            std::__is_constant_evaluated.
            * include/bits/cow_string.h: Use new macro.
            * include/bits/ranges_algobase.h (__copy_or_move): Replace
            conditional calls to std::is_constant_evaluated with unconditional
            calls to std::__is_constant_evaluated.
            (__copy_or_move_backward, __fill_n_fn): Likewise.
            * include/bits/ranges_cmp.h (ranges::less): Likewise.
            * include/bits/stl_algobase.h (lexicographical_compare_three_way):
            Likewise.
            * include/bits/stl_bvector.h: Call std::is_constant_evaluated
            directly in C++20-only code that is guarded by a suitable macro.
            * include/bits/stl_construct.h (_Construct, _Destroy, _Destroy_n):
            Replace is_constant_evaluated with __is_constant_evaluated.
            * include/bits/stl_function.h (greater, less, greater_equal)
            (less_equal): Replace __builtin_is_constant_evaluated and
            __builtin_constant_p with __is_constant_evaluated.
            * include/bits/stl_vector.h: Call std::is_constant_evaluated()
            in C++20-only code.
            * include/debug/helper_functions.h (__check_singular): Use
            __is_constant_evaluated instead of built-in, or remove check
            entirely.
            * include/std/array (operator<=>): Use __is_constant_evaluated
            unconditionally.
            * include/std/bit (__bit_ceil): Likewise.
            * include/std/type_traits (is_constant_evaluated): Define using
            'if consteval' if possible.
            * include/std/version: Use new macro.
            * libsupc++/compare: Use __is_constant_evaluated instead of
            __builtin_is_constant_evaluated.
            * testsuite/23_containers/array/tuple_interface/get_neg.cc:
            Adjust dg-error lines.

diff --git a/libstdc++-v3/doc/doxygen/user.cfg.in b/libstdc++-v3/doc/doxygen/user.cfg.in
index 17cd6fc1c0e..2f15f2c1b82 100644
--- a/libstdc++-v3/doc/doxygen/user.cfg.in
+++ b/libstdc++-v3/doc/doxygen/user.cfg.in
@@ -2399,7 +2399,7 @@ PREDEFINED             = __cplusplus=202002L \
                          "__has_builtin(x)=1" \
                          _GLIBCXX_HAVE_BUILTIN_HAS_UNIQ_OBJ_REP \
                          _GLIBCXX_HAVE_BUILTIN_IS_AGGREGATE \
-                         _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED \
+                         _GLIBCXX_HAVE_IS_CONSTANT_EVALUATED \
                          _GLIBCXX_HAVE_BUILTIN_LAUNDER \
 
 # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
diff --git a/libstdc++-v3/include/bits/allocator.h b/libstdc++-v3/include/bits/allocator.h
index f83e6b87666..1c099514e18 100644
--- a/libstdc++-v3/include/bits/allocator.h
+++ b/libstdc++-v3/include/bits/allocator.h
@@ -178,10 +178,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       constexpr _Tp*
       allocate(size_t __n)
       {
-#ifdef __cpp_lib_is_constant_evaluated
-	if (std::is_constant_evaluated())
+	if (std::__is_constant_evaluated())
 	  return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp)));
-#endif
 	return __allocator_base<_Tp>::allocate(__n, 0);
       }
 
@@ -189,13 +187,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       constexpr void
       deallocate(_Tp* __p, size_t __n)
       {
-#ifdef __cpp_lib_is_constant_evaluated
-	if (std::is_constant_evaluated())
+	if (std::__is_constant_evaluated())
 	  {
 	    ::operator delete(__p);
 	    return;
 	  }
-#endif
 	__allocator_base<_Tp>::deallocate(__p, __n);
       }
 #endif // C++20
diff --git a/libstdc++-v3/include/bits/basic_string.h b/libstdc++-v3/include/bits/basic_string.h
index 6e7de738308..4007a8d2d7c 100644
--- a/libstdc++-v3/include/bits/basic_string.h
+++ b/libstdc++-v3/include/bits/basic_string.h
@@ -59,7 +59,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
 #ifdef __cpp_lib_is_constant_evaluated
 // Support P0980R1 in C++20.
 # define __cpp_lib_constexpr_string 201907L
-#elif __cplusplus >= 201703L && _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED
+#elif __cplusplus >= 201703L && _GLIBCXX_HAVE_IS_CONSTANT_EVALUATED
 // Support P0426R1 changes to char_traits in C++17.
 # define __cpp_lib_constexpr_string 201611L
 #endif
@@ -101,7 +101,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
 	  allocate(_Char_alloc_type& __a, typename _Base::size_type __n)
 	  {
 	    pointer __p = _Base::allocate(__a, __n);
-	    if (__builtin_is_constant_evaluated())
+	    if (std::is_constant_evaluated())
 	      // Begin the lifetime of characters in allocated storage.
 	      for (size_type __i = 0; __i < __n; ++__i)
 		std::construct_at(__builtin_addressof(__p[__i]));
@@ -352,7 +352,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
       _M_use_local_data() _GLIBCXX_NOEXCEPT
       {
 #if __cpp_lib_is_constant_evaluated
-	if (__builtin_is_constant_evaluated())
+	if (std::is_constant_evaluated())
 	  _M_local_buf[0] = _CharT();
 #endif
 	return _M_local_data();
diff --git a/libstdc++-v3/include/bits/basic_string.tcc b/libstdc++-v3/include/bits/basic_string.tcc
index 6f619a08f70..4a2d48c48e8 100644
--- a/libstdc++-v3/include/bits/basic_string.tcc
+++ b/libstdc++-v3/include/bits/basic_string.tcc
@@ -488,7 +488,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 	  const size_type __how_much = __old_size - __pos - __len1;
 #if __cpp_lib_is_constant_evaluated
-	  if (__builtin_is_constant_evaluated())
+	  if (std::is_constant_evaluated())
 	    {
 	      auto __newp = _Alloc_traits::allocate(_M_get_allocator(),
 						    __new_size);
@@ -571,7 +571,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	  __p = _M_create(__n, __capacity);
 	  this->_S_copy(__p, _M_data(), length()); // exclude trailing null
 #if __cpp_lib_is_constant_evaluated
-	  if (__builtin_is_constant_evaluated())
+	  if (std::is_constant_evaluated())
 	    traits_type::assign(__p + length(), __n - length(), _CharT());
 #endif
 	  _M_dispose();
diff --git a/libstdc++-v3/include/bits/c++config b/libstdc++-v3/include/bits/c++config
index cbcdedb366f..ff23161e8d8 100644
--- a/libstdc++-v3/include/bits/c++config
+++ b/libstdc++-v3/include/bits/c++config
@@ -495,6 +495,25 @@ namespace std
 
 #endif // _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT && IEEE128
 
+namespace std
+{
+  // Internal version of std::is_constant_evaluated().
+  // This can be used without checking if the compiler supports the feature.
+  _GLIBCXX_CONSTEXPR inline bool
+  __is_constant_evaluated() _GLIBCXX_NOEXCEPT
+  {
+#if __cpp_if_consteval >= 202106L
+# define _GLIBCXX_HAVE_IS_CONSTANT_EVALUATED 1
+    if consteval { return true; } else { return false; }
+#elif __cplusplus >= 201103L && __has_builtin(__builtin_is_constant_evaluated)
+# define _GLIBCXX_HAVE_IS_CONSTANT_EVALUATED 1
+    return __builtin_is_constant_evaluated();
+#else
+    return false;
+#endif
+  }
+}
+
 // Debug Mode implies checking assertions.
 #if defined(_GLIBCXX_DEBUG) && !defined(_GLIBCXX_ASSERTIONS)
 # define _GLIBCXX_ASSERTIONS 1
@@ -507,9 +526,9 @@ namespace std
 #endif
 
 
-#if __has_builtin(__builtin_is_constant_evaluated)
+#if _GLIBCXX_HAVE_IS_CONSTANT_EVALUATED
 # define __glibcxx_constexpr_assert(cond) \
-  if (__builtin_is_constant_evaluated() && !bool(cond))	\
+  if (std::__is_constant_evaluated() && !bool(cond))	\
     __builtin_unreachable() /* precondition violation detected! */
 #else
 # define __glibcxx_constexpr_assert(unevaluated)
@@ -762,10 +781,6 @@ namespace std
 # define _GLIBCXX_HAVE_BUILTIN_IS_AGGREGATE 1
 #endif
 
-#if _GLIBCXX_HAS_BUILTIN(__builtin_is_constant_evaluated)
-#  define _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED 1
-#endif
-
 #if _GLIBCXX_HAS_BUILTIN(__is_same)
 #  define _GLIBCXX_HAVE_BUILTIN_IS_SAME 1
 #endif
@@ -776,7 +791,6 @@ namespace std
 
 #undef _GLIBCXX_HAS_BUILTIN
 
-
 // PSTL configuration
 
 #if __cplusplus >= 201703L
diff --git a/libstdc++-v3/include/bits/char_traits.h b/libstdc++-v3/include/bits/char_traits.h
index b1cdc55ea61..da3e0ffffaa 100644
--- a/libstdc++-v3/include/bits/char_traits.h
+++ b/libstdc++-v3/include/bits/char_traits.h
@@ -38,6 +38,9 @@
 
 #include <bits/postypes.h>      // For streampos
 #include <cwchar>               // For WEOF, wmemmove, wmemset, etc.
+#if __cplusplus >= 201103L
+# include <type_traits>
+#endif
 #if __cplusplus >= 202002L
 # include <compare>
 # include <bits/stl_construct.h>
@@ -101,8 +104,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       static _GLIBCXX14_CONSTEXPR void
       assign(char_type& __c1, const char_type& __c2)
       {
-#if __cpp_constexpr_dynamic_alloc && __cpp_lib_is_constant_evaluated
-	if (std::is_constant_evaluated())
+#if __cpp_constexpr_dynamic_alloc
+	if (std::__is_constant_evaluated())
 	  std::construct_at(__builtin_addressof(__c1), __c2);
 	else
 #endif
@@ -199,8 +202,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     {
       if (__n == 0)
 	return __s1;
-#if __cpp_lib_is_constant_evaluated
-      if (std::is_constant_evaluated())
+#if __cplusplus >= 202002L
+      if (std::__is_constant_evaluated())
 	{
 	  if (__s1 == __s2) // unlikely, but saves a lot of work
 	    return __s1;
@@ -247,8 +250,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     char_traits<_CharT>::
     copy(char_type* __s1, const char_type* __s2, std::size_t __n)
     {
-#if __cpp_lib_is_constant_evaluated
-      if (std::is_constant_evaluated())
+#if __cplusplus >= 202002L
+      if (std::__is_constant_evaluated())
 	{
 	  for (std::size_t __i = 0; __i < __n; ++__i)
 	    std::construct_at(__s1 + __i, __s2[__i]);
@@ -266,8 +269,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     char_traits<_CharT>::
     assign(char_type* __s, std::size_t __n, char_type __a)
     {
-#if __cpp_lib_is_constant_evaluated
-      if (std::is_constant_evaluated())
+#if __cplusplus >= 202002L
+      if (std::__is_constant_evaluated())
 	{
 	  for (std::size_t __i = 0; __i < __n; ++__i)
 	    std::construct_at(__s + __i, __a);
@@ -299,7 +302,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #ifdef __cpp_lib_is_constant_evaluated
 // Unofficial macro indicating P1032R1 support in C++20
 # define __cpp_lib_constexpr_char_traits 201811L
-#elif __cplusplus >= 201703L && _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED
+#elif __cplusplus >= 201703L && _GLIBCXX_HAVE_IS_CONSTANT_EVALUATED
 // Unofficial macro indicating P0426R1 support in C++17
 # define __cpp_lib_constexpr_char_traits 201611L
 #endif
@@ -338,8 +341,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       static _GLIBCXX17_CONSTEXPR void
       assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
       {
-#if __cpp_constexpr_dynamic_alloc && __cpp_lib_is_constant_evaluated
-	if (std::is_constant_evaluated())
+#if __cpp_constexpr_dynamic_alloc
+	if (std::__is_constant_evaluated())
 	  std::construct_at(__builtin_addressof(__c1), __c2);
 	else
 #endif
@@ -363,8 +366,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       {
 	if (__n == 0)
 	  return 0;
-#if __cplusplus >= 201703L && _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED
-	if (__builtin_is_constant_evaluated())
+#if __cplusplus >= 201703L
+	if (std::__is_constant_evaluated())
 	  {
 	    for (size_t __i = 0; __i < __n; ++__i)
 	      if (lt(__s1[__i], __s2[__i]))
@@ -380,8 +383,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       static _GLIBCXX17_CONSTEXPR size_t
       length(const char_type* __s)
       {
-#if __cplusplus >= 201703L && _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED
-	if (__builtin_is_constant_evaluated())
+#if __cplusplus >= 201703L
+	if (std::__is_constant_evaluated())
 	  return __gnu_cxx::char_traits<char_type>::length(__s);
 #endif
 	return __builtin_strlen(__s);
@@ -392,8 +395,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       {
 	if (__n == 0)
 	  return 0;
-#if __cplusplus >= 201703L && _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED
-	if (__builtin_is_constant_evaluated())
+#if __cplusplus >= 201703L
+	if (std::__is_constant_evaluated())
 	  return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a);
 #endif
 	return static_cast<const char_type*>(__builtin_memchr(__s, __a, __n));
@@ -404,8 +407,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       {
 	if (__n == 0)
 	  return __s1;
-#ifdef __cpp_lib_is_constant_evaluated
-	if (std::is_constant_evaluated())
+#if __cplusplus >= 202002L
+	if (std::__is_constant_evaluated())
 	  return __gnu_cxx::char_traits<char_type>::move(__s1, __s2, __n);
 #endif
 	return static_cast<char_type*>(__builtin_memmove(__s1, __s2, __n));
@@ -416,8 +419,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       {
 	if (__n == 0)
 	  return __s1;
-#ifdef __cpp_lib_is_constant_evaluated
-	if (std::is_constant_evaluated())
+#if __cplusplus >= 202002L
+	if (std::__is_constant_evaluated())
 	  return __gnu_cxx::char_traits<char_type>::copy(__s1, __s2, __n);
 #endif
 	return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n));
@@ -428,8 +431,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       {
 	if (__n == 0)
 	  return __s;
-#ifdef __cpp_lib_is_constant_evaluated
-	if (std::is_constant_evaluated())
+#if __cplusplus >= 202002L
+	if (std::__is_constant_evaluated())
 	  return __gnu_cxx::char_traits<char_type>::assign(__s, __n, __a);
 #endif
 	return static_cast<char_type*>(__builtin_memset(__s, __a, __n));
@@ -476,8 +479,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       static _GLIBCXX17_CONSTEXPR void
       assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
       {
-#if __cpp_constexpr_dynamic_alloc && __cpp_lib_is_constant_evaluated
-	if (std::is_constant_evaluated())
+#if __cpp_constexpr_dynamic_alloc
+	if (std::__is_constant_evaluated())
 	  std::construct_at(__builtin_addressof(__c1), __c2);
 	else
 #endif
@@ -497,8 +500,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       {
 	if (__n == 0)
 	  return 0;
-#if __cplusplus >= 201703L && _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED
-	if (__builtin_is_constant_evaluated())
+#if __cplusplus >= 201703L
+	if (std::__is_constant_evaluated())
 	  return __gnu_cxx::char_traits<char_type>::compare(__s1, __s2, __n);
 #endif
 	return wmemcmp(__s1, __s2, __n);
@@ -507,8 +510,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       static _GLIBCXX17_CONSTEXPR size_t
       length(const char_type* __s)
       {
-#if __cplusplus >= 201703L && _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED
-	if (__builtin_is_constant_evaluated())
+#if __cplusplus >= 201703L
+	if (std::__is_constant_evaluated())
 	  return __gnu_cxx::char_traits<char_type>::length(__s);
 #endif
 	return wcslen(__s);
@@ -519,8 +522,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       {
 	if (__n == 0)
 	  return 0;
-#if __cplusplus >= 201703L && _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED
-	if (__builtin_is_constant_evaluated())
+#if __cplusplus >= 201703L
+	if (std::__is_constant_evaluated())
 	  return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a);
 #endif
 	return wmemchr(__s, __a, __n);
@@ -531,8 +534,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       {
 	if (__n == 0)
 	  return __s1;
-#ifdef __cpp_lib_is_constant_evaluated
-	if (std::is_constant_evaluated())
+#if __cplusplus >= 202002L
+	if (std::__is_constant_evaluated())
 	  return __gnu_cxx::char_traits<char_type>::move(__s1, __s2, __n);
 #endif
 	return wmemmove(__s1, __s2, __n);
@@ -543,8 +546,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       {
 	if (__n == 0)
 	  return __s1;
-#ifdef __cpp_lib_is_constant_evaluated
-	if (std::is_constant_evaluated())
+#if __cplusplus >= 202002L
+	if (std::__is_constant_evaluated())
 	  return __gnu_cxx::char_traits<char_type>::copy(__s1, __s2, __n);
 #endif
 	return wmemcpy(__s1, __s2, __n);
@@ -555,8 +558,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       {
 	if (__n == 0)
 	  return __s;
-#ifdef __cpp_lib_is_constant_evaluated
-	if (std::is_constant_evaluated())
+#if __cplusplus >= 202002L
+	if (std::__is_constant_evaluated())
 	  return __gnu_cxx::char_traits<char_type>::assign(__s, __n, __a);
 #endif
 	return wmemset(__s, __a, __n);
@@ -604,8 +607,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       static _GLIBCXX17_CONSTEXPR void
       assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
       {
-#if __cpp_constexpr_dynamic_alloc && __cpp_lib_is_constant_evaluated
-	if (std::is_constant_evaluated())
+#if __cpp_constexpr_dynamic_alloc
+	if (std::__is_constant_evaluated())
 	  std::construct_at(__builtin_addressof(__c1), __c2);
 	else
 #endif
@@ -625,8 +628,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       {
 	if (__n == 0)
 	  return 0;
-#if __cplusplus >= 201703L && _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED
-	if (__builtin_is_constant_evaluated())
+#if __cplusplus >= 201703L
+	if (std::__is_constant_evaluated())
 	  return __gnu_cxx::char_traits<char_type>::compare(__s1, __s2, __n);
 #endif
 	return __builtin_memcmp(__s1, __s2, __n);
@@ -635,8 +638,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       static _GLIBCXX17_CONSTEXPR size_t
       length(const char_type* __s)
       {
-#if __cplusplus >= 201703L && _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED
-	if (__builtin_is_constant_evaluated())
+#if __cplusplus >= 201703L
+	if (std::__is_constant_evaluated())
 	  return __gnu_cxx::char_traits<char_type>::length(__s);
 #endif
 	size_t __i = 0;
@@ -650,8 +653,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       {
 	if (__n == 0)
 	  return 0;
-#if __cplusplus >= 201703L && _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED
-	if (__builtin_is_constant_evaluated())
+#if __cplusplus >= 201703L
+	if (std::__is_constant_evaluated())
 	  return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a);
 #endif
 	return static_cast<const char_type*>(__builtin_memchr(__s, __a, __n));
@@ -662,8 +665,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       {
 	if (__n == 0)
 	  return __s1;
-#ifdef __cpp_lib_is_constant_evaluated
-	if (std::is_constant_evaluated())
+#if __cplusplus >= 202002L
+	if (std::__is_constant_evaluated())
 	  return __gnu_cxx::char_traits<char_type>::move(__s1, __s2, __n);
 #endif
 	return static_cast<char_type*>(__builtin_memmove(__s1, __s2, __n));
@@ -674,8 +677,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       {
 	if (__n == 0)
 	  return __s1;
-#ifdef __cpp_lib_is_constant_evaluated
-	if (std::is_constant_evaluated())
+#if __cplusplus >= 202002L
+	if (std::__is_constant_evaluated())
 	  return __gnu_cxx::char_traits<char_type>::copy(__s1, __s2, __n);
 #endif
 	return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n));
@@ -686,8 +689,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       {
 	if (__n == 0)
 	  return __s;
-#ifdef __cpp_lib_is_constant_evaluated
-	if (std::is_constant_evaluated())
+#if __cplusplus >= 202002L
+	if (std::__is_constant_evaluated())
 	  return __gnu_cxx::char_traits<char_type>::assign(__s, __n, __a);
 #endif
 	return static_cast<char_type*>(__builtin_memset(__s, __a, __n));
@@ -747,8 +750,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       static _GLIBCXX17_CONSTEXPR void
       assign(char_type& __c1, const char_type& __c2) noexcept
       {
-#if __cpp_constexpr_dynamic_alloc && __cpp_lib_is_constant_evaluated
-	if (std::is_constant_evaluated())
+#if __cpp_constexpr_dynamic_alloc
+	if (std::__is_constant_evaluated())
 	  std::construct_at(__builtin_addressof(__c1), __c2);
 	else
 #endif
@@ -797,8 +800,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       {
 	if (__n == 0)
 	  return __s1;
-#ifdef __cpp_lib_is_constant_evaluated
-	if (std::is_constant_evaluated())
+#if __cplusplus >= 202002L
+	if (std::__is_constant_evaluated())
 	  return __gnu_cxx::char_traits<char_type>::move(__s1, __s2, __n);
 #endif
 	return (static_cast<char_type*>
@@ -810,8 +813,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       {
 	if (__n == 0)
 	  return __s1;
-#ifdef __cpp_lib_is_constant_evaluated
-	if (std::is_constant_evaluated())
+#if __cplusplus >= 202002L
+	if (std::__is_constant_evaluated())
 	  return __gnu_cxx::char_traits<char_type>::copy(__s1, __s2, __n);
 #endif
 	return (static_cast<char_type*>
@@ -868,8 +871,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       static _GLIBCXX17_CONSTEXPR void
       assign(char_type& __c1, const char_type& __c2) noexcept
       {
-#if __cpp_constexpr_dynamic_alloc && __cpp_lib_is_constant_evaluated
-	if (std::is_constant_evaluated())
+#if __cpp_constexpr_dynamic_alloc
+	if (std::__is_constant_evaluated())
 	  std::construct_at(__builtin_addressof(__c1), __c2);
 	else
 #endif
@@ -918,8 +921,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       {
 	if (__n == 0)
 	  return __s1;
-#ifdef __cpp_lib_is_constant_evaluated
-	if (std::is_constant_evaluated())
+#if __cplusplus >= 202002L
+	if (std::__is_constant_evaluated())
 	  return __gnu_cxx::char_traits<char_type>::move(__s1, __s2, __n);
 #endif
 	return (static_cast<char_type*>
@@ -931,8 +934,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       { 
 	if (__n == 0)
 	  return __s1;
-#ifdef __cpp_lib_is_constant_evaluated
-	if (std::is_constant_evaluated())
+#if __cplusplus >= 202002L
+	if (std::__is_constant_evaluated())
 	  return __gnu_cxx::char_traits<char_type>::copy(__s1, __s2, __n);
 #endif
 	return (static_cast<char_type*>
diff --git a/libstdc++-v3/include/bits/cow_string.h b/libstdc++-v3/include/bits/cow_string.h
index bafca7bb313..3d881a8a683 100644
--- a/libstdc++-v3/include/bits/cow_string.h
+++ b/libstdc++-v3/include/bits/cow_string.h
@@ -37,7 +37,7 @@
 #ifdef __cpp_lib_is_constant_evaluated
 // Support P1032R1 in C++20 (but not P0980R1 for COW strings).
 # define __cpp_lib_constexpr_string 201811L
-#elif __cplusplus >= 201703L && _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED
+#elif __cplusplus >= 201703L && _GLIBCXX_HAVE_IS_CONSTANT_EVALUATED
 // Support P0426R1 changes to char_traits in C++17.
 # define __cpp_lib_constexpr_string 201611L
 #endif
diff --git a/libstdc++-v3/include/bits/ranges_algobase.h b/libstdc++-v3/include/bits/ranges_algobase.h
index 9929e5e828b..74b8e9c4d59 100644
--- a/libstdc++-v3/include/bits/ranges_algobase.h
+++ b/libstdc++-v3/include/bits/ranges_algobase.h
@@ -251,9 +251,7 @@ namespace ranges
 	}
       else if constexpr (sized_sentinel_for<_Sent, _Iter>)
 	{
-#ifdef __cpp_lib_is_constant_evaluated
-	  if (!std::is_constant_evaluated())
-#endif
+	  if (!std::__is_constant_evaluated())
 	    {
 	      if constexpr (__memcpyable<_Iter, _Out>::__value)
 		{
@@ -388,9 +386,7 @@ namespace ranges
 	}
       else if constexpr (sized_sentinel_for<_Sent, _Iter>)
 	{
-#ifdef __cpp_lib_is_constant_evaluated
-	  if (!std::is_constant_evaluated())
-#endif
+	  if (!std::__is_constant_evaluated())
 	    {
 	      if constexpr (__memcpyable<_Out, _Iter>::__value)
 		{
@@ -535,9 +531,7 @@ namespace ranges
 			  && __is_byte<remove_pointer_t<_Out>>::__value
 			  && integral<_Tp>)
 	      {
-#ifdef __cpp_lib_is_constant_evaluated
-		if (!std::is_constant_evaluated())
-#endif
+		if (!std::__is_constant_evaluated())
 		  {
 		    __builtin_memset(__first,
 				     static_cast<unsigned char>(__value),
diff --git a/libstdc++-v3/include/bits/ranges_cmp.h b/libstdc++-v3/include/bits/ranges_cmp.h
index 1d7da30dddf..098022e63a2 100644
--- a/libstdc++-v3/include/bits/ranges_cmp.h
+++ b/libstdc++-v3/include/bits/ranges_cmp.h
@@ -119,10 +119,9 @@ namespace ranges
       {
 	if constexpr (__detail::__less_builtin_ptr_cmp<_Tp, _Up>)
 	  {
-#ifdef __cpp_lib_is_constant_evaluated
-	    if (std::is_constant_evaluated())
+	    if (std::__is_constant_evaluated())
 	      return __t < __u;
-#endif
+
 	    auto __x = reinterpret_cast<__UINTPTR_TYPE__>(
 	      static_cast<const volatile void*>(std::forward<_Tp>(__t)));
 	    auto __y = reinterpret_cast<__UINTPTR_TYPE__>(
diff --git a/libstdc++-v3/include/bits/stl_algobase.h b/libstdc++-v3/include/bits/stl_algobase.h
index f441165714b..984a5bf94b9 100644
--- a/libstdc++-v3/include/bits/stl_algobase.h
+++ b/libstdc++-v3/include/bits/stl_algobase.h
@@ -1826,11 +1826,10 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
       __glibcxx_requires_valid_range(__first1, __last1);
       __glibcxx_requires_valid_range(__first2, __last2);
 
-#if __cpp_lib_is_constant_evaluated
       using _Cat = decltype(__comp(*__first1, *__first2));
       static_assert(same_as<common_comparison_category_t<_Cat>, _Cat>);
 
-      if (!std::is_constant_evaluated())
+      if (!std::__is_constant_evaluated())
 	if constexpr (same_as<_Comp, __detail::_Synth3way>
 		      || same_as<_Comp, compare_three_way>)
 	  if constexpr (__is_byte_iter<_InputIter1>)
@@ -1847,7 +1846,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
 		  }
 		return __lencmp;
 	      }
-#endif // is_constant_evaluated
+
       while (__first1 != __last1)
 	{
 	  if (__first2 == __last2)
diff --git a/libstdc++-v3/include/bits/stl_bvector.h b/libstdc++-v3/include/bits/stl_bvector.h
index 68070685baf..7d93084fe37 100644
--- a/libstdc++-v3/include/bits/stl_bvector.h
+++ b/libstdc++-v3/include/bits/stl_bvector.h
@@ -625,8 +625,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       _M_allocate(size_t __n)
       {
 	_Bit_pointer __p = _Bit_alloc_traits::allocate(_M_impl, _S_nword(__n));
-#if __has_builtin(__builtin_is_constant_evaluated)
-	if (__builtin_is_constant_evaluated())
+#if __cpp_lib_is_constant_evaluated
+	if (std::is_constant_evaluated())
 	{
 	  __n = _S_nword(__n);
 	  for (size_t __i = 0; __i < __n; ++__i)
@@ -1524,8 +1524,8 @@ _GLIBCXX_END_NAMESPACE_CONTAINER
   inline void
   __fill_bvector_n(_Bit_type* __p, size_t __n, bool __x) _GLIBCXX_NOEXCEPT
   {
-#if __has_builtin(__builtin_is_constant_evaluated)
-    if (__builtin_is_constant_evaluated())
+#if __cpp_lib_is_constant_evaluated
+    if (std::is_constant_evaluated())
     {
       for (size_t __i = 0; __i < __n; ++__i)
 	__p[__i] = __x ? ~0ul : 0ul;
diff --git a/libstdc++-v3/include/bits/stl_construct.h b/libstdc++-v3/include/bits/stl_construct.h
index e53ed0d9f91..dd621f24bc2 100644
--- a/libstdc++-v3/include/bits/stl_construct.h
+++ b/libstdc++-v3/include/bits/stl_construct.h
@@ -108,8 +108,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     inline void
     _Construct(_Tp* __p, _Args&&... __args)
     {
-#if __cplusplus >= 202002L && __has_builtin(__builtin_is_constant_evaluated)
-      if (__builtin_is_constant_evaluated())
+#if __cplusplus >= 202002L
+      if (std::__is_constant_evaluated())
 	{
 	  // Allow std::_Construct to be used in constant expressions.
 	  std::construct_at(__p, std::forward<_Args>(__args)...);
@@ -188,8 +188,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       static_assert(is_destructible<_Value_type>::value,
 		    "value type is destructible");
 #endif
-#if __cplusplus > 201703L && defined __cpp_lib_is_constant_evaluated
-      if (std::is_constant_evaluated())
+#if __cplusplus >= 202002L
+      if (std::__is_constant_evaluated())
 	return _Destroy_aux<false>::__destroy(__first, __last);
 #endif
       std::_Destroy_aux<__has_trivial_destructor(_Value_type)>::
@@ -237,8 +237,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       static_assert(is_destructible<_Value_type>::value,
 		    "value type is destructible");
 #endif
-#if __cplusplus > 201703L && defined __cpp_lib_is_constant_evaluated
-      if (std::is_constant_evaluated())
+#if __cplusplus >= 202002L
+      if (std::__is_constant_evaluated())
 	return _Destroy_n_aux<false>::__destroy_n(__first, __count);
 #endif
       return std::_Destroy_n_aux<__has_trivial_destructor(_Value_type)>::
diff --git a/libstdc++-v3/include/bits/stl_function.h b/libstdc++-v3/include/bits/stl_function.h
index 5de8c3234f7..92e9dc75a80 100644
--- a/libstdc++-v3/include/bits/stl_function.h
+++ b/libstdc++-v3/include/bits/stl_function.h
@@ -428,11 +428,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       operator()(_Tp* __x, _Tp* __y) const _GLIBCXX_NOTHROW
       {
 #if __cplusplus >= 201402L
-#ifdef _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED
-	if (__builtin_is_constant_evaluated())
-#else
-	if (__builtin_constant_p(__x > __y))
-#endif
+	if (std::__is_constant_evaluated())
 	  return __x > __y;
 #endif
 	return (__UINTPTR_TYPE__)__x > (__UINTPTR_TYPE__)__y;
@@ -447,11 +443,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       operator()(_Tp* __x, _Tp* __y) const _GLIBCXX_NOTHROW
       {
 #if __cplusplus >= 201402L
-#ifdef _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED
-	if (__builtin_is_constant_evaluated())
-#else
-	if (__builtin_constant_p(__x < __y))
-#endif
+	if (std::__is_constant_evaluated())
 	  return __x < __y;
 #endif
 	return (__UINTPTR_TYPE__)__x < (__UINTPTR_TYPE__)__y;
@@ -466,11 +458,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       operator()(_Tp* __x, _Tp* __y) const _GLIBCXX_NOTHROW
       {
 #if __cplusplus >= 201402L
-#ifdef _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED
-	if (__builtin_is_constant_evaluated())
-#else
-	if (__builtin_constant_p(__x >= __y))
-#endif
+	if (std::__is_constant_evaluated())
 	  return __x >= __y;
 #endif
 	return (__UINTPTR_TYPE__)__x >= (__UINTPTR_TYPE__)__y;
@@ -485,11 +473,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       operator()(_Tp* __x, _Tp* __y) const _GLIBCXX_NOTHROW
       {
 #if __cplusplus >= 201402L
-#ifdef _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED
-	if (__builtin_is_constant_evaluated())
-#else
-	if (__builtin_constant_p(__x <= __y))
-#endif
+	if (std::__is_constant_evaluated())
 	  return __x <= __y;
 #endif
 	return (__UINTPTR_TYPE__)__x <= (__UINTPTR_TYPE__)__y;
diff --git a/libstdc++-v3/include/bits/stl_vector.h b/libstdc++-v3/include/bits/stl_vector.h
index 4587757637e..9015ba00dec 100644
--- a/libstdc++-v3/include/bits/stl_vector.h
+++ b/libstdc++-v3/include/bits/stl_vector.h
@@ -195,8 +195,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 	    static _GLIBCXX20_CONSTEXPR void
 	    _S_adjust(_Vector_impl& __impl, pointer __prev, pointer __curr)
 	    {
-#if __has_builtin(__builtin_is_constant_evaluated)
-	      if (!__builtin_is_constant_evaluated())
+#if __cpp_lib_is_constant_evaluated
+	      if (std::is_constant_evaluated())
+		return;
 #endif
 	      __sanitizer_annotate_contiguous_container(__impl._M_start,
 		  __impl._M_end_of_storage, __prev, __curr);
diff --git a/libstdc++-v3/include/debug/helper_functions.h b/libstdc++-v3/include/debug/helper_functions.h
index c0144ced979..1547154bca1 100644
--- a/libstdc++-v3/include/debug/helper_functions.h
+++ b/libstdc++-v3/include/debug/helper_functions.h
@@ -124,11 +124,8 @@ namespace __gnu_debug
     inline bool
     __check_singular(_Iterator const& __x)
     {
-      return
-#ifdef _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED
-	__builtin_is_constant_evaluated() ? false :
-#endif
-	__check_singular_aux(std::__addressof(__x));
+      return ! std::__is_constant_evaluated()
+	       && __check_singular_aux(std::__addressof(__x));
     }
 
   /** Non-NULL pointers are nonsingular. */
@@ -136,13 +133,7 @@ namespace __gnu_debug
     _GLIBCXX_CONSTEXPR
     inline bool
     __check_singular(_Tp* const& __ptr)
-    {
-      return
-#ifdef _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED
-	__builtin_is_constant_evaluated() ? false :
-#endif
-	__ptr == 0;
-    }
+    { return __ptr == 0; }
 
   /** We say that integral types for a valid range, and defer to other
    *  routines to realize what to do with integral types instead of
diff --git a/libstdc++-v3/include/std/array b/libstdc++-v3/include/std/array
index 413f8e2be01..e632de15aff 100644
--- a/libstdc++-v3/include/std/array
+++ b/libstdc++-v3/include/std/array
@@ -310,14 +310,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     constexpr __detail::__synth3way_t<_Tp>
     operator<=>(const array<_Tp, _Nm>& __a, const array<_Tp, _Nm>& __b)
     {
-#ifdef __cpp_lib_is_constant_evaluated
       if constexpr (_Nm && __is_memcmp_ordered<_Tp>::__value)
-	if (!std::is_constant_evaluated())
+	if (!std::__is_constant_evaluated())
 	  {
 	    constexpr size_t __n = _Nm * sizeof(_Tp);
 	    return __builtin_memcmp(__a.data(), __b.data(), __n) <=> 0;
 	  }
-#endif
 
       for (size_t __i = 0; __i < _Nm; ++__i)
 	{
diff --git a/libstdc++-v3/include/std/bit b/libstdc++-v3/include/std/bit
index c5aae8bab03..cc73bcfec6b 100644
--- a/libstdc++-v3/include/std/bit
+++ b/libstdc++-v3/include/std/bit
@@ -265,12 +265,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       // representable as a value of _Tp, and so the result is undefined.
       // Want that undefined behaviour to be detected in constant expressions,
       // by UBSan, and by debug assertions.
-#ifdef _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED
-      if (!__builtin_is_constant_evaluated())
+      if (!std::__is_constant_evaluated())
 	{
 	  __glibcxx_assert( __shift_exponent != __int_traits<_Tp>::__digits );
 	}
-#endif
+
       using __promoted_type = decltype(__x << 1);
       if _GLIBCXX17_CONSTEXPR (!is_same<__promoted_type, _Tp>::value)
 	{
diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits
index d3693b1069e..9866bf4cd96 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -32,9 +32,8 @@
 #pragma GCC system_header
 
 #if __cplusplus < 201103L
-# include <bits/c++0x_warning.h>
+#include <bits/c++0x_warning.h>
 #else
-
 #include <bits/c++config.h>
 
 namespace std _GLIBCXX_VISIBILITY(default)
@@ -3510,15 +3509,20 @@ template<typename _Ret, typename _Fn, typename... _Args>
 
 #endif // C++23
 
-#ifdef _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED
-
+#if _GLIBCXX_HAVE_IS_CONSTANT_EVALUATED
 #define __cpp_lib_is_constant_evaluated 201811L
 
   /// Returns true only when called during constant evaluation.
   /// @since C++20
   constexpr inline bool
   is_constant_evaluated() noexcept
-  { return __builtin_is_constant_evaluated(); }
+  {
+#if __cpp_if_consteval >= 202106L
+    if consteval { return true; } else { return false; }
+#else
+    return __builtin_is_constant_evaluated();
+#endif
+  }
 #endif
 
   /// @cond undocumented
diff --git a/libstdc++-v3/include/std/version b/libstdc++-v3/include/std/version
index fd7e1258543..e7e4d9fda82 100644
--- a/libstdc++-v3/include/std/version
+++ b/libstdc++-v3/include/std/version
@@ -130,7 +130,7 @@
 #define __cpp_lib_chrono 201611
 #define __cpp_lib_clamp 201603
 #if __cplusplus == 201703L // N.B. updated value in C++20
-# if _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED
+# if _GLIBCXX_HAVE_IS_CONSTANT_EVALUATED
 #  define __cpp_lib_constexpr_char_traits 201611L
 #  define __cpp_lib_constexpr_string 201611L
 # endif
@@ -195,7 +195,7 @@
 #endif
 #define __cpp_lib_endian 201907L
 #define __cpp_lib_int_pow2 202002L
-#ifdef _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED
+#ifdef _GLIBCXX_HAVE_IS_CONSTANT_EVALUATED
 # define __cpp_lib_is_constant_evaluated 201811L
 #endif
 #define __cpp_lib_is_nothrow_convertible 201806L
diff --git a/libstdc++-v3/libsupc++/compare b/libstdc++-v3/libsupc++/compare
index 5aee89e3a6e..f095de7935f 100644
--- a/libstdc++-v3/libsupc++/compare
+++ b/libstdc++-v3/libsupc++/compare
@@ -555,7 +555,7 @@ namespace std
 	  {
 	    auto __pt = static_cast<const volatile void*>(__t);
 	    auto __pu = static_cast<const volatile void*>(__u);
-	    if (__builtin_is_constant_evaluated())
+	    if (std::__is_constant_evaluated())
 	      return __pt <=> __pu;
 	    auto __it = reinterpret_cast<__UINTPTR_TYPE__>(__pt);
 	    auto __iu = reinterpret_cast<__UINTPTR_TYPE__>(__pu);
diff --git a/libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_neg.cc b/libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_neg.cc
index 70742c14a7d..776ff5f771f 100644
--- a/libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_neg.cc
@@ -26,6 +26,6 @@ int n1 = std::get<1>(a);
 int n2 = std::get<1>(std::move(a));
 int n3 = std::get<1>(ca);
 
-// { dg-error "static assertion failed" "" { target *-*-* } 398 }
-// { dg-error "static assertion failed" "" { target *-*-* } 407 }
-// { dg-error "static assertion failed" "" { target *-*-* } 416 }
+// { dg-error "static assertion failed" "" { target *-*-* } 396 }
+// { dg-error "static assertion failed" "" { target *-*-* } 405 }
+// { dg-error "static assertion failed" "" { target *-*-* } 414 }

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2021-11-26 23:26 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-11-26 12:29 [PATCH] libstdc++: Define std::__is_constant_evaluated() for internal use Jonathan Wakely
2021-11-26 12:38 ` Ville Voutilainen
2021-11-26 12:39 ` Jakub Jelinek
2021-11-26 12:43   ` Jonathan Wakely
2021-11-26 12:49     ` Jakub Jelinek
2021-11-26 23:26     ` [PATCH v2] " Jonathan Wakely

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).