Index: include/__tuple =================================================================== --- include/__tuple +++ include/__tuple @@ -228,28 +228,46 @@ template struct __tuple_types {}; -template -class _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, __tuple_types<> > -{ -public: - static_assert(_Ip == 0, "tuple_element index out of range"); - static_assert(_Ip != 0, "tuple_element index out of range"); -}; +#if !__has_builtin(__type_pack_element) +namespace __indexer_detail { + +template +struct __indexed { using type = _Tp; }; + +template struct __indexer; -template -class _LIBCPP_TYPE_VIS_ONLY tuple_element<0, __tuple_types<_Hp, _Tp...> > +template +struct __indexer<__tuple_types<_Types...>, __tuple_indices<_Idx...>> + : __indexed<_Idx, _Types>... { -public: - typedef _Hp type; }; -template -class _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, __tuple_types<_Hp, _Tp...> > +template +using __make_indexer = __indexer<__tuple_types<_Types...>, + typename __make_tuple_indices::type>; + +__nat __at_index(...); + +template + __indexed<_Idx, _Tp> __at_index(__indexed<_Idx, _Tp> const&); + +} // namespace __indexer_detail + +template +using __type_pack_element = typename decltype( + __indexer_detail::__at_index<_Idx>( + __indexer_detail::__make_indexer<_Types...>{}))::type; + +#endif + +template +class _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, __tuple_types<_Types...>> { public: - typedef typename tuple_element<_Ip-1, __tuple_types<_Tp...> >::type type; + typedef __type_pack_element<_Ip, _Types...> type; }; + template class _LIBCPP_TYPE_VIS_ONLY tuple_size<__tuple_types<_Tp...> > : public integral_constant @@ -258,6 +276,46 @@ template struct __tuple_like<__tuple_types<_Tp...> > : true_type {}; +template +struct __apply_cv_mf; +template <> +struct __apply_cv_mf { + template using __apply = _Tp; +}; +template <> +struct __apply_cv_mf { + template using __apply = const _Tp; +}; +template <> +struct __apply_cv_mf { + template using __apply = volatile _Tp; +}; +template <> +struct __apply_cv_mf { + template using __apply = const volatile _Tp; +}; +template <> +struct __apply_cv_mf { + template using __apply = _Tp&; +}; +template <> +struct __apply_cv_mf { + template using __apply = const _Tp&; +}; +template <> +struct __apply_cv_mf { + template using __apply = volatile _Tp&; +}; +template <> +struct __apply_cv_mf { + template using __apply = const volatile _Tp&; +}; +template ::type> +using __apply_cv_t = __apply_cv_mf< + is_lvalue_reference<_Tp>::value, + is_const<_RawTp>::value, + is_volatile<_RawTp>::value>; + // __make_tuple_types // __make_tuple_types<_Tuple<_Types...>, _Ep, _Sp>::type is a @@ -265,31 +323,46 @@ // _Sp defaults to 0 and _Ep defaults to tuple_size<_Tuple>. If _Tuple is a // lvalue_reference type, then __tuple_types<_Types&...> is the result. -template -struct __make_tuple_types_imp; +template +struct __make_tuple_types_flat; -template -struct __make_tuple_types_imp<__tuple_types<_Types...>, _Tp, _Sp, _Ep> -{ - typedef typename remove_reference<_Tp>::type _Tpr; - typedef typename __make_tuple_types_imp<__tuple_types<_Types..., - typename conditional::value, - typename tuple_element<_Sp, _Tpr>::type&, - typename tuple_element<_Sp, _Tpr>::type>::type>, - _Tp, _Sp+1, _Ep>::type type; +template