[libcxx-commits] [PATCH] D115100: [libc++] Enable the optimized _IsSame on GCC as well as Clang.

Arthur O'Dwyer via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Sat Dec 4 09:14:15 PST 2021


Quuxplusone created this revision.
Quuxplusone added reviewers: ldionne, EricWF, libc++.
Quuxplusone added a project: libc++.
Quuxplusone requested review of this revision.
Herald added a subscriber: libcxx-commits.
Herald added 1 blocking reviewer(s): libc++.

This involves shuffling some code from `#ifdef __clang__` into `#if __has_keyword(__is_same)`... and then noticing that `__has_keyword` is nerfed to false on all non-Clang compilers(!!) and what we really should be using throughout the codebase is `__has_builtin`.

There are two obvious followup directions, which I can submit if this is accepted:

- Consistently use `__has_builtin` in many places, instead of `__has_keyword`, to enable more builtin-related optimizations on GCC as well as Clang.
- Consistently use `_IsSame` in many places, instead of `is_same`, to somewhat improve compile times.

As it now says on the tin, the advantage of `_IsSame` is that `_IsSame<A,B> == false_type == _IsSame<C,D>` and `_IsSame<A,A> == true_type == _IsSame<C,C>`, whereas with `is_same` those //types// are all //different// — thy just happen to have boolean `value` members whose //values// are equal. So `_IsSame` is much cheaper.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D115100

Files:
  libcxx/include/type_traits


Index: libcxx/include/type_traits
===================================================================
--- libcxx/include/type_traits
+++ libcxx/include/type_traits
@@ -550,7 +550,7 @@
 
 // is_same
 
-#if __has_keyword(__is_same)
+#if __has_builtin(__is_same)
 
 template <class _Tp, class _Up>
 struct _LIBCPP_TEMPLATE_VIS is_same : _BoolConstant<__is_same(_Tp, _Up)> { };
@@ -560,6 +560,16 @@
 inline constexpr bool is_same_v = __is_same(_Tp, _Up);
 #endif
 
+// _IsSame<T,U> has the same effect as is_same<T,U> but instantiates fewer types:
+// is_same<A,B> and is_same<C,D> are guaranteed to be different types, but on supported
+// compilers _IsSame<A,B> and _IsSame<C,D> may be the same type (namely, false_type).
+
+template <class _Tp, class _Up>
+using _IsSame = _BoolConstant<__is_same(_Tp, _Up)>;
+
+template <class _Tp, class _Up>
+using _IsNotSame = _BoolConstant<!__is_same(_Tp, _Up)>;
+
 #else
 
 template <class _Tp, class _Up> struct _LIBCPP_TEMPLATE_VIS is_same           : public false_type {};
@@ -570,26 +580,13 @@
 inline constexpr bool is_same_v = is_same<_Tp, _Up>::value;
 #endif
 
-#endif // __is_same
-
 template <class _Tp, class _Up>
-using _IsSame = _BoolConstant<
-#ifdef __clang__
-    __is_same(_Tp, _Up)
-#else
-    is_same<_Tp, _Up>::value
-#endif
->;
+using _IsSame = is_same<_Tp, _Up>;
 
 template <class _Tp, class _Up>
-using _IsNotSame = _BoolConstant<
-#ifdef __clang__
-    !__is_same(_Tp, _Up)
-#else
-    !is_same<_Tp, _Up>::value
-#endif
->;
+using _IsNotSame = _BoolConstant<!is_same<_Tp, _Up>::value>;
 
+#endif // __has_builtin(__is_same)
 
 template <class _Tp>
 using __test_for_primary_template = __enable_if_t<
@@ -602,8 +599,6 @@
 
 struct __two {char __lx[2];};
 
-// helper class:
-
 // is_const
 
 #if __has_keyword(__is_const)


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D115100.391842.patch
Type: text/x-patch
Size: 1784 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libcxx-commits/attachments/20211204/725d329f/attachment.bin>


More information about the libcxx-commits mailing list