[libc++] Enable the optimized _IsSame on GCC as well as Clang.
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 for GCC's benefit we need to avoid using raw `_IsSame` in the return type of `swap(tuple&, tuple&)`. Therefore, make `__all` into a named type instead of an alias. If we ever need to support a compiler without the __is_same builtin, we can make this an alias template for `is_same<T,U>::type`. Differential Revision: https://reviews.llvm.org/D115100
This commit is contained in:
parent
50187d2dd5
commit
5c0ea7488b
|
@ -387,7 +387,7 @@ template <bool ..._Preds>
|
|||
struct __all_dummy;
|
||||
|
||||
template <bool ..._Pred>
|
||||
using __all = _IsSame<__all_dummy<_Pred...>, __all_dummy<((void)_Pred, true)...>>;
|
||||
struct __all : _IsSame<__all_dummy<_Pred...>, __all_dummy<((void)_Pred, true)...>> {};
|
||||
|
||||
struct __tuple_sfinae_base {
|
||||
template <template <class, class...> class _Trait,
|
||||
|
|
|
@ -550,8 +550,6 @@ template <bool _Bp, class _If, class _Then> using conditional_t = typename condi
|
|||
|
||||
// is_same
|
||||
|
||||
#if __has_keyword(__is_same)
|
||||
|
||||
template <class _Tp, class _Up>
|
||||
struct _LIBCPP_TEMPLATE_VIS is_same : _BoolConstant<__is_same(_Tp, _Up)> { };
|
||||
|
||||
|
@ -560,36 +558,18 @@ template <class _Tp, class _Up>
|
|||
inline constexpr bool is_same_v = __is_same(_Tp, _Up);
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
template <class _Tp, class _Up> struct _LIBCPP_TEMPLATE_VIS is_same : public false_type {};
|
||||
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_same<_Tp, _Tp> : public true_type {};
|
||||
|
||||
#if _LIBCPP_STD_VER > 14
|
||||
template <class _Tp, class _Up>
|
||||
inline constexpr bool is_same_v = is_same<_Tp, _Up>::value;
|
||||
#endif
|
||||
|
||||
#endif // __is_same
|
||||
// _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
|
||||
// _IsSame<A,B> and _IsSame<C,D> are the same type (namely, false_type).
|
||||
// Neither GCC nor Clang can mangle the __is_same builtin, so _IsSame
|
||||
// mustn't be directly used anywhere that contributes to name-mangling
|
||||
// (such as in a dependent return type).
|
||||
|
||||
template <class _Tp, class _Up>
|
||||
using _IsSame = _BoolConstant<
|
||||
#ifdef __clang__
|
||||
__is_same(_Tp, _Up)
|
||||
#else
|
||||
is_same<_Tp, _Up>::value
|
||||
#endif
|
||||
>;
|
||||
using _IsSame = _BoolConstant<__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)>;
|
||||
|
||||
template <class _Tp>
|
||||
using __test_for_primary_template = __enable_if_t<
|
||||
|
|
Loading…
Reference in New Issue