[libcxx-commits] [libcxx] 4e0876e - [libc++] Use __underlying_type directly in underyling_type_t (#135423)

via libcxx-commits libcxx-commits at lists.llvm.org
Sun Apr 13 02:01:22 PDT 2025


Author: Nikolas Klauser
Date: 2025-04-13T11:01:17+02:00
New Revision: 4e0876ee43d00c5fc28ed30bcb7c1aac2b18674f

URL: https://github.com/llvm/llvm-project/commit/4e0876ee43d00c5fc28ed30bcb7c1aac2b18674f
DIFF: https://github.com/llvm/llvm-project/commit/4e0876ee43d00c5fc28ed30bcb7c1aac2b18674f.diff

LOG: [libc++] Use __underlying_type directly in underyling_type_t (#135423)

This avoids instantiating multiple classes, reducing compile times. This
patch also introduces `__underyling_type_t` for internal use, similar to
other type traits.

Added: 
    

Modified: 
    libcxx/include/__atomic/memory_order.h
    libcxx/include/__functional/hash.h
    libcxx/include/__type_traits/underlying_type.h
    libcxx/include/__utility/convert_to_integral.h
    libcxx/include/__utility/to_underlying.h
    libcxx/include/future

Removed: 
    


################################################################################
diff  --git a/libcxx/include/__atomic/memory_order.h b/libcxx/include/__atomic/memory_order.h
index 44790fe888b36..355804312b2ec 100644
--- a/libcxx/include/__atomic/memory_order.h
+++ b/libcxx/include/__atomic/memory_order.h
@@ -24,7 +24,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 // to pin the underlying type in C++20.
 enum __legacy_memory_order { __mo_relaxed, __mo_consume, __mo_acquire, __mo_release, __mo_acq_rel, __mo_seq_cst };
 
-using __memory_order_underlying_t _LIBCPP_NODEBUG = underlying_type<__legacy_memory_order>::type;
+using __memory_order_underlying_t _LIBCPP_NODEBUG = __underlying_type_t<__legacy_memory_order>;
 
 #if _LIBCPP_STD_VER >= 20
 
@@ -37,7 +37,7 @@ enum class memory_order : __memory_order_underlying_t {
   seq_cst = __mo_seq_cst
 };
 
-static_assert(is_same<underlying_type<memory_order>::type, __memory_order_underlying_t>::value,
+static_assert(is_same<__underlying_type_t<memory_order>, __memory_order_underlying_t>::value,
               "unexpected underlying type for std::memory_order");
 
 inline constexpr auto memory_order_relaxed = memory_order::relaxed;

diff  --git a/libcxx/include/__functional/hash.h b/libcxx/include/__functional/hash.h
index 3b50eccdad387..f9f7d2c767caa 100644
--- a/libcxx/include/__functional/hash.h
+++ b/libcxx/include/__functional/hash.h
@@ -504,7 +504,7 @@ struct hash<long double> : public __scalar_hash<long double> {
 template <class _Tp, bool = is_enum<_Tp>::value>
 struct __enum_hash : public __unary_function<_Tp, size_t> {
   _LIBCPP_HIDE_FROM_ABI size_t operator()(_Tp __v) const _NOEXCEPT {
-    typedef typename underlying_type<_Tp>::type type;
+    using type = __underlying_type_t<_Tp>;
     return hash<type>()(static_cast<type>(__v));
   }
 };

diff  --git a/libcxx/include/__type_traits/underlying_type.h b/libcxx/include/__type_traits/underlying_type.h
index 45a9b40e3e4c9..100734ccf15d6 100644
--- a/libcxx/include/__type_traits/underlying_type.h
+++ b/libcxx/include/__type_traits/underlying_type.h
@@ -18,7 +18,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-template <class _Tp, bool = is_enum<_Tp>::value>
+template <class _Tp, bool>
 struct __underlying_type_impl;
 
 template <class _Tp>
@@ -32,9 +32,18 @@ struct __underlying_type_impl<_Tp, true> {
 template <class _Tp>
 struct _LIBCPP_NO_SPECIALIZATIONS underlying_type : __underlying_type_impl<_Tp, is_enum<_Tp>::value> {};
 
+// GCC doesn't SFINAE away when using __underlying_type directly
+#if !defined(_LIBCPP_COMPILER_GCC)
+template <class _Tp>
+using __underlying_type_t _LIBCPP_NODEBUG = __underlying_type(_Tp);
+#else
+template <class _Tp>
+using __underlying_type_t _LIBCPP_NODEBUG = typename underlying_type<_Tp>::type;
+#endif
+
 #if _LIBCPP_STD_VER >= 14
 template <class _Tp>
-using underlying_type_t = typename underlying_type<_Tp>::type;
+using underlying_type_t = __underlying_type_t<_Tp>;
 #endif
 
 _LIBCPP_END_NAMESPACE_STD

diff  --git a/libcxx/include/__utility/convert_to_integral.h b/libcxx/include/__utility/convert_to_integral.h
index 8947c349d8302..c8149b7744984 100644
--- a/libcxx/include/__utility/convert_to_integral.h
+++ b/libcxx/include/__utility/convert_to_integral.h
@@ -50,7 +50,7 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __uint128_t __convert_to_integral
 
 template <class _Tp, bool = is_enum<_Tp>::value>
 struct __sfinae_underlying_type {
-  typedef typename underlying_type<_Tp>::type type;
+  using type = __underlying_type_t<_Tp>;
   typedef decltype(((type)1) + 0) __promoted_type;
 };
 

diff  --git a/libcxx/include/__utility/to_underlying.h b/libcxx/include/__utility/to_underlying.h
index 77587108f20dc..3e9d405a5f666 100644
--- a/libcxx/include/__utility/to_underlying.h
+++ b/libcxx/include/__utility/to_underlying.h
@@ -21,8 +21,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 #ifndef _LIBCPP_CXX03_LANG
 template <class _Tp>
-_LIBCPP_HIDE_FROM_ABI constexpr typename underlying_type<_Tp>::type __to_underlying(_Tp __val) noexcept {
-  return static_cast<typename underlying_type<_Tp>::type>(__val);
+[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI constexpr __underlying_type_t<_Tp> __to_underlying(_Tp __val) noexcept {
+  return static_cast<__underlying_type_t<_Tp>>(__val);
 }
 #endif // !_LIBCPP_CXX03_LANG
 

diff  --git a/libcxx/include/future b/libcxx/include/future
index 28850ad618dfb..3dfcce80a977d 100644
--- a/libcxx/include/future
+++ b/libcxx/include/future
@@ -440,7 +440,7 @@ _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(launch)
 
 #    ifndef _LIBCPP_CXX03_LANG
 
-typedef underlying_type<launch>::type __launch_underlying_type;
+using __launch_underlying_type _LIBCPP_NODEBUG = __underlying_type_t<launch>;
 
 inline _LIBCPP_HIDE_FROM_ABI constexpr launch operator&(launch __x, launch __y) {
   return static_cast<launch>(static_cast<__launch_underlying_type>(__x) & static_cast<__launch_underlying_type>(__y));


        


More information about the libcxx-commits mailing list