diff --git a/include/tuple b/include/tuple index 97d21139..5bdf6902 100644 --- a/include/tuple +++ b/include/tuple @@ -804,47 +804,84 @@ tuple_cat() return tuple<>(); } -template -inline _LIBCPP_INLINE_VISIBILITY -typename __tuple_cat_return<_Tuple>::type -tuple_cat(_Tuple&& __tpl) -{ - typedef typename __tuple_cat_return<_Tuple>::type _R; - return _R(_STD::forward<_Tuple>(__tpl)); -} +template +struct __tuple_cat_return_ref_imp; -template -inline _LIBCPP_INLINE_VISIBILITY -typename __tuple_cat_return<_Tuple0, _Tuple1>::type -__tuple_cat(_Tuple0&& __t0, __tuple_indices<_I0...>, - _Tuple1&& __t1, __tuple_indices<_I1...>) -{ - typedef typename __tuple_cat_return<_Tuple0, _Tuple1>::type _R; - return _R(get<_I0>(_STD::forward<_Tuple0>(__t0))..., - get<_I1>(_STD::forward<_Tuple1>(__t1))...); -} - -template -inline _LIBCPP_INLINE_VISIBILITY -typename __tuple_cat_return<_Tuple0, _Tuple1>::type -tuple_cat(_Tuple0&& __t0, _Tuple1&& __t1) +template +struct __tuple_cat_return_ref_imp, __tuple_indices<_I0...>, _Tuple0> { typedef typename remove_reference<_Tuple0>::type _T0; - typedef typename remove_reference<_Tuple1>::type _T1; - return __tuple_cat(_STD::forward<_Tuple0>(__t0), - typename __make_tuple_indices::value>::type(), - _STD::forward<_Tuple1>(__t1), - typename __make_tuple_indices::value>::type()); -} + typedef tuple<_Types..., typename __apply_cv<_Tuple0, + typename tuple_element<_I0, _T0>::type>::type&&...> type; +}; -template -inline _LIBCPP_INLINE_VISIBILITY -typename __tuple_cat_return<_Tuple0, _Tuple1, _Tuples...>::type -tuple_cat(_Tuple0&& __t0, _Tuple1&& __t1, _Tuples&&... __tpls) +template +struct __tuple_cat_return_ref_imp, __tuple_indices<_I0...>, + _Tuple0, _Tuple1, _Tuples...> + : public __tuple_cat_return_ref_imp< + tuple<_Types..., typename __apply_cv<_Tuple0, + typename tuple_element<_I0, + typename remove_reference<_Tuple0>::type>::type>::type&&...>, + typename __make_tuple_indices::type>::value>::type, + _Tuple1, _Tuples...> { - return tuple_cat(tuple_cat(_STD::forward<_Tuple0>(__t0), - _STD::forward<_Tuple1>(__t1)), - _STD::forward<_Tuples>(__tpls)...); +}; + +template +struct __tuple_cat_return_ref + : public __tuple_cat_return_ref_imp, + typename __make_tuple_indices< + tuple_size::type>::value + >::type, _Tuple0, _Tuples...> +{ +}; + +template +struct __tuple_cat; + +template +struct __tuple_cat, __tuple_indices<_I0...>, __tuple_indices<_J0...>> +{ + template + _LIBCPP_INLINE_VISIBILITY + typename __tuple_cat_return_ref&&, _Tuple0&&>::type + operator()(tuple<_Types...> __t, _Tuple0&& __t0) + { + return _STD::forward_as_tuple(_STD::forward<_Types>(get<_I0>(__t))..., + get<_J0>(_STD::forward<_Tuple0>(__t0))...); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __tuple_cat_return_ref&&, _Tuple0&&, _Tuple1&&, _Tuples&&...>::type + operator()(tuple<_Types...> __t, _Tuple0&& __t0, _Tuple1&& __t1, _Tuples&& ...__tpls) + { + typedef typename remove_reference<_Tuple0>::type _T0; + typedef typename remove_reference<_Tuple1>::type _T1; + return __tuple_cat< + tuple<_Types..., typename __apply_cv<_Tuple0, typename tuple_element<_J0, _T0>::type>::type&&...>, + typename __make_tuple_indices::value>::type, + typename __make_tuple_indices::value>::type>() + (_STD::forward_as_tuple( + _STD::forward<_Types>(get<_I0>(__t))..., + get<_J0>(_STD::forward<_Tuple0>(__t0))... + ), + _STD::forward<_Tuple1>(__t1), + _STD::forward<_Tuples>(__tpls)...); + } +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +typename __tuple_cat_return<_Tuple0, _Tuples...>::type +tuple_cat(_Tuple0&& __t0, _Tuples&&... __tpls) +{ + typedef typename remove_reference<_Tuple0>::type _T0; + return __tuple_cat, __tuple_indices<>, + typename __make_tuple_indices::value>::type>() + (tuple<>(), _STD::forward<_Tuple0>(__t0), + _STD::forward<_Tuples>(__tpls)...); } template