Changeset View
Standalone View
libcxx/include/type_traits
Show First 20 Lines • Show All 523 Lines • ▼ Show 20 Lines | |||||
# pragma GCC system_header | # pragma GCC system_header | ||||
#endif | #endif | ||||
_LIBCPP_BEGIN_NAMESPACE_STD | _LIBCPP_BEGIN_NAMESPACE_STD | ||||
template <class _T1, class _T2> struct _LIBCPP_TEMPLATE_VIS pair; | template <class _T1, class _T2> struct _LIBCPP_TEMPLATE_VIS pair; | ||||
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS hash; | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS hash; | ||||
template <bool> struct _MetaBase; | template <bool> struct _MetaBase; | ||||
EricWF: `__nat` is an awful hack. Let's not user it more. | |||||
template <> | template <> | ||||
I EricWF: I | |||||
I'm still against this. That's not how these meta-functions are meant to work. Also EricWF: I'm still against this. That's not how these meta-functions are meant to work. Also | |||||
struct _MetaBase<true> { | struct _MetaBase<true> { | ||||
template <class _Tp, class _Up> | template <class _Tp, class _Up> | ||||
using _SelectImpl _LIBCPP_NODEBUG = _Tp; | using _SelectImpl _LIBCPP_NODEBUG = _Tp; | ||||
template <template <class...> class _FirstFn, template <class...> class, class ..._Args> | template <template <class...> class _FirstFn, template <class...> class, class ..._Args> | ||||
using _SelectApplyImpl _LIBCPP_NODEBUG = _FirstFn<_Args...>; | using _SelectApplyImpl _LIBCPP_NODEBUG = _FirstFn<_Args...>; | ||||
template <class _First, class...> | |||||
using _FirstImpl _LIBCPP_NODEBUG = _First; | |||||
template <class, class _Second, class...> | |||||
using _SecondImpl _LIBCPP_NODEBUG = _Second; | |||||
template <class _Result, class _First, class ..._Rest> | template <class _Result, class _First, class ..._Rest> | ||||
using _OrImpl _LIBCPP_NODEBUG = typename _MetaBase<_First::value != true && sizeof...(_Rest) != 0>::template _OrImpl<_First, _Rest...>; | using _OrImpl _LIBCPP_NODEBUG = typename _MetaBase<_First::value != true && sizeof...(_Rest) != 0>::template _OrImpl<_First, _Rest...>; | ||||
}; | }; | ||||
template <> | template <> | ||||
struct _MetaBase<false> { | struct _MetaBase<false> { | ||||
template <class _Tp, class _Up> | template <class _Tp, class _Up> | ||||
using _SelectImpl _LIBCPP_NODEBUG = _Up; | using _SelectImpl _LIBCPP_NODEBUG = _Up; | ||||
template <template <class...> class, template <class...> class _SecondFn, class ..._Args> | template <template <class...> class, template <class...> class _SecondFn, class ..._Args> | ||||
using _SelectApplyImpl _LIBCPP_NODEBUG = _SecondFn<_Args...>; | using _SelectApplyImpl _LIBCPP_NODEBUG = _SecondFn<_Args...>; | ||||
template <class _Result, class ...> | template <class _Result, class ...> | ||||
using _OrImpl _LIBCPP_NODEBUG = _Result; | using _OrImpl _LIBCPP_NODEBUG = _Result; | ||||
}; | }; | ||||
template <bool _Cond, class _IfRes, class _ElseRes> | template <bool _Cond, class _IfRes, class _ElseRes> | ||||
using _If _LIBCPP_NODEBUG = typename _MetaBase<_Cond>::template _SelectImpl<_IfRes, _ElseRes>; | using _If _LIBCPP_NODEBUG = typename _MetaBase<_Cond>::template _SelectImpl<_IfRes, _ElseRes>; | ||||
template <class ..._Rest> | template <class ..._Rest> | ||||
Uh...? This completely changes the meaning of e.g. _SecondType<int> from "ill-formed" to "well-formed __nat." There's no way that's safe. Quuxplusone: Uh...? This completely changes the meaning of e.g. `_SecondType<int>` from "ill-formed" to… | |||||
_FirstType and _SecondType are exclusively used in <tuple> and only in is_* contexts. If I'm not mistaken __nat should be false in every single case. philnik: `_FirstType` and `_SecondType` are exclusively used in `<tuple>` and only in `is_*` contexts. | |||||
I'm with Arthur, this should not succeed. This needs to be substitution failure. EricWF: I'm with Arthur, this should not succeed. This needs to be substitution failure. | |||||
In which case does it have to be a substitution failure? IIRC there are cases where I need it to not be a substitution failure. philnik: In which case does it have to be a substitution failure? IIRC there are cases where I need it… | |||||
It doesn't need to be substitution failure, but substitution failure is 1000x better than generating a bogus type and continuing on. In what cases are you trying to apply first/second type to a pack that doesn't have them? EricWF: It doesn't need to be substitution failure, but substitution failure is 1000x better than… | |||||
using _Or _LIBCPP_NODEBUG = typename _MetaBase< sizeof...(_Rest) != 0 >::template _OrImpl<false_type, _Rest...>; | using _Or _LIBCPP_NODEBUG = typename _MetaBase< sizeof...(_Rest) != 0 >::template _OrImpl<false_type, _Rest...>; | ||||
template <class ..._Args> | |||||
using _FirstType _LIBCPP_NODEBUG = typename _MetaBase<(sizeof...(_Args) >= 1)>::template _FirstImpl<_Args...>; | |||||
template <class ..._Args> | |||||
using _SecondType _LIBCPP_NODEBUG = typename _MetaBase<(sizeof...(_Args) >= 2)>::template _SecondImpl<_Args...>; | |||||
template <class ...> using __expand_to_true = true_type; | template <class ...> using __expand_to_true = true_type; | ||||
template <class ..._Pred> | template <class ..._Pred> | ||||
__expand_to_true<__enable_if_t<_Pred::value>...> __and_helper(int); | __expand_to_true<__enable_if_t<_Pred::value>...> __and_helper(int); | ||||
template <class ...> | template <class ...> | ||||
false_type __and_helper(...); | false_type __and_helper(...); | ||||
template <class ..._Pred> | template <class ..._Pred> | ||||
using _And _LIBCPP_NODEBUG = decltype(__and_helper<_Pred...>(0)); | using _And _LIBCPP_NODEBUG = decltype(__and_helper<_Pred...>(0)); | ||||
▲ Show 20 Lines • Show All 577 Lines • ▼ Show 20 Lines | : __common_type_impl< | ||||
__common_types<_Tp, _Up, _Vp _LIBCPP_OPTIONAL_PACK(_Rest...)> > {}; | __common_types<_Tp, _Up, _Vp _LIBCPP_OPTIONAL_PACK(_Rest...)> > {}; | ||||
#undef _LIBCPP_OPTIONAL_PACK | #undef _LIBCPP_OPTIONAL_PACK | ||||
#if _LIBCPP_STD_VER > 11 | #if _LIBCPP_STD_VER > 11 | ||||
template <class ..._Tp> using common_type_t = typename common_type<_Tp...>::type; | template <class ..._Tp> using common_type_t = typename common_type<_Tp...>::type; | ||||
#endif | #endif | ||||
#if _LIBCPP_STD_VER > 11 | |||||
// Let COPYCV(FROM, TO) be an alias for type TO with the addition of FROM's | // Let COPYCV(FROM, TO) be an alias for type TO with the addition of FROM's | ||||
// top-level cv-qualifiers. | // top-level cv-qualifiers. | ||||
template <class _From, class _To> | template <class _From, class _To> | ||||
struct __copy_cv | struct __copy_cv | ||||
{ | { | ||||
using type = _To; | using type = _To; | ||||
}; | }; | ||||
template <class _From, class _To> | template <class _From, class _To> | ||||
struct __copy_cv<const _From, _To> | struct __copy_cv<const _From, _To> | ||||
{ | { | ||||
using type = add_const_t<_To>; | using type = typename add_const<_To>::type; | ||||
}; | }; | ||||
template <class _From, class _To> | template <class _From, class _To> | ||||
struct __copy_cv<volatile _From, _To> | struct __copy_cv<volatile _From, _To> | ||||
{ | { | ||||
using type = add_volatile_t<_To>; | using type = typename add_volatile<_To>::type; | ||||
}; | }; | ||||
template <class _From, class _To> | template <class _From, class _To> | ||||
struct __copy_cv<const volatile _From, _To> | struct __copy_cv<const volatile _From, _To> | ||||
{ | { | ||||
using type = add_cv_t<_To>; | using type = typename add_cv<_To>::type; | ||||
}; | }; | ||||
template <class _From, class _To> | template <class _From, class _To> | ||||
using __copy_cv_t = typename __copy_cv<_From, _To>::type; | using __copy_cv_t = typename __copy_cv<_From, _To>::type; | ||||
template <class _From, class _To> | template <class _From, class _To> | ||||
struct __copy_cvref | struct __copy_cvref | ||||
{ | { | ||||
using type = __copy_cv_t<_From, _To>; | using type = __copy_cv_t<_From, _To>; | ||||
}; | }; | ||||
template <class _From, class _To> | template <class _From, class _To> | ||||
struct __copy_cvref<_From&, _To> | struct __copy_cvref<_From&, _To> | ||||
{ | { | ||||
using type = add_lvalue_reference_t<__copy_cv_t<_From, _To>>; | using type = typename add_lvalue_reference<__copy_cv_t<_From, _To> >::type; | ||||
}; | }; | ||||
template <class _From, class _To> | template <class _From, class _To> | ||||
struct __copy_cvref<_From&&, _To> | struct __copy_cvref<_From&&, _To> | ||||
{ | { | ||||
using type = add_rvalue_reference_t<__copy_cv_t<_From, _To>>; | using type = typename add_rvalue_reference<__copy_cv_t<_From, _To> >::type; | ||||
}; | }; | ||||
template <class _From, class _To> | template <class _From, class _To> | ||||
using __copy_cvref_t = typename __copy_cvref<_From, _To>::type; | using __copy_cvref_t = typename __copy_cvref<_From, _To>::type; | ||||
#endif // _LIBCPP_STD_VER > 11 | |||||
// common_reference | // common_reference | ||||
#if _LIBCPP_STD_VER > 17 | #if _LIBCPP_STD_VER > 17 | ||||
// Let COND_RES(X, Y) be: | // Let COND_RES(X, Y) be: | ||||
template <class _Xp, class _Yp> | template <class _Xp, class _Yp> | ||||
using __cond_res = | using __cond_res = | ||||
decltype(false ? declval<_Xp(&)()>()() : declval<_Yp(&)()>()()); | decltype(false ? declval<_Xp(&)()>()() : declval<_Yp(&)()>()()); | ||||
▲ Show 20 Lines • Show All 475 Lines • ▼ Show 20 Lines | struct __can_extract_map_key<_ValTy, _Key, _Key, _RawValTy> | ||||
: false_type {}; | : false_type {}; | ||||
template <class _CharT> | template <class _CharT> | ||||
using _IsCharLikeType = _And<is_standard_layout<_CharT>, is_trivial<_CharT> >; | using _IsCharLikeType = _And<is_standard_layout<_CharT>, is_trivial<_CharT> >; | ||||
template<class _Tp> | template<class _Tp> | ||||
using __make_const_lvalue_ref = const typename remove_reference<_Tp>::type&; | using __make_const_lvalue_ref = const typename remove_reference<_Tp>::type&; | ||||
#if _LIBCPP_STD_VER > 17 | |||||
template<bool _Const, class _Tp> | template<bool _Const, class _Tp> | ||||
using __maybe_const = conditional_t<_Const, const _Tp, _Tp>; | using __maybe_const = typename conditional<_Const, const _Tp, _Tp>::type; | ||||
Use _If here to avoid adding more template instantiations. EricWF: Use `_If` here to avoid adding more template instantiations. | |||||
#endif // _LIBCPP_STD_VER > 17 | |||||
_LIBCPP_END_NAMESPACE_STD | _LIBCPP_END_NAMESPACE_STD | ||||
#endif // _LIBCPP_TYPE_TRAITS | #endif // _LIBCPP_TYPE_TRAITS |
__nat is an awful hack. Let's not user it more.