[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 18:01:23 PST 2021
Quuxplusone updated this revision to Diff 391883.
Quuxplusone edited the summary of this revision.
Quuxplusone added a comment.
However, there's a problem on both GCC and Clang: they can't mangle
`__is_same(T,U)` if it appears anywhere that affects mangling. That's
a hard error. And it turns out that GCC puts dependent return types
into the mangling more aggressively than Clang, so we need to avoid
using raw `_IsSame` (or type aliases such as `__all` that expand into
`_IsSame`) in one return type, for GCC's benefit.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D115100/new/
https://reviews.llvm.org/D115100
Files:
libcxx/include/tuple
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)
Index: libcxx/include/tuple
===================================================================
--- libcxx/include/tuple
+++ libcxx/include/tuple
@@ -1116,13 +1116,12 @@
tuple(allocator_arg_t, _Alloc, tuple<_Tp...>) -> tuple<_Tp...>;
#endif
+template <class ..._Ts>
+struct __all_are_swappable : __all<__is_swappable<_Ts>::value...> {};
+
template <class ..._Tp>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
-typename enable_if
-<
- __all<__is_swappable<_Tp>::value...>::value,
- void
->::type
+typename enable_if<__all_are_swappable<_Tp...>::value>::type
swap(tuple<_Tp...>& __t, tuple<_Tp...>& __u)
_NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
{__t.swap(__u);}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D115100.391883.patch
Type: text/x-patch
Size: 2520 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libcxx-commits/attachments/20211205/a0fb716d/attachment.bin>
More information about the libcxx-commits
mailing list