Reduced copying cost of tuple_cat from quadratic to linear.
git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@121655 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
0e1493ec5e
commit
e48e36623b
103
include/tuple
103
include/tuple
@ -804,46 +804,83 @@ tuple_cat()
|
|||||||
return tuple<>();
|
return tuple<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _Tuple>
|
template <class _R, class _Indices, class _Tuple0, class ..._Tuples>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
struct __tuple_cat_return_ref_imp;
|
||||||
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 <class _Tuple0, size_t ..._I0, class _Tuple1, size_t ..._I1>
|
template <class ..._Types, size_t ..._I0, class _Tuple0>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
struct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>, _Tuple0>
|
||||||
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 <class _Tuple0, class _Tuple1>
|
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
|
||||||
typename __tuple_cat_return<_Tuple0, _Tuple1>::type
|
|
||||||
tuple_cat(_Tuple0&& __t0, _Tuple1&& __t1)
|
|
||||||
{
|
{
|
||||||
typedef typename remove_reference<_Tuple0>::type _T0;
|
typedef typename remove_reference<_Tuple0>::type _T0;
|
||||||
typedef typename remove_reference<_Tuple1>::type _T1;
|
typedef tuple<_Types..., typename __apply_cv<_Tuple0,
|
||||||
return __tuple_cat(_STD::forward<_Tuple0>(__t0),
|
typename tuple_element<_I0, _T0>::type>::type&&...> type;
|
||||||
typename __make_tuple_indices<tuple_size<_T0>::value>::type(),
|
};
|
||||||
_STD::forward<_Tuple1>(__t1),
|
|
||||||
typename __make_tuple_indices<tuple_size<_T1>::value>::type());
|
template <class ..._Types, size_t ..._I0, class _Tuple0, class _Tuple1, class ..._Tuples>
|
||||||
|
struct __tuple_cat_return_ref_imp<tuple<_Types...>, __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<tuple_size<typename
|
||||||
|
remove_reference<_Tuple1>::type>::value>::type,
|
||||||
|
_Tuple1, _Tuples...>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class _Tuple0, class ..._Tuples>
|
||||||
|
struct __tuple_cat_return_ref
|
||||||
|
: public __tuple_cat_return_ref_imp<tuple<>,
|
||||||
|
typename __make_tuple_indices<
|
||||||
|
tuple_size<typename remove_reference<_Tuple0>::type>::value
|
||||||
|
>::type, _Tuple0, _Tuples...>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class _Types, class _I0, class _J0>
|
||||||
|
struct __tuple_cat;
|
||||||
|
|
||||||
|
template <class ..._Types, size_t ..._I0, size_t ..._J0>
|
||||||
|
struct __tuple_cat<tuple<_Types...>, __tuple_indices<_I0...>, __tuple_indices<_J0...>>
|
||||||
|
{
|
||||||
|
template <class _Tuple0>
|
||||||
|
_LIBCPP_INLINE_VISIBILITY
|
||||||
|
typename __tuple_cat_return_ref<tuple<_Types...>&&, _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 <class _Tuple0, class _Tuple1, class ..._Tuples>
|
template <class _Tuple0, class _Tuple1, class ..._Tuples>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_INLINE_VISIBILITY
|
||||||
typename __tuple_cat_return<_Tuple0, _Tuple1, _Tuples...>::type
|
typename __tuple_cat_return_ref<tuple<_Types...>&&, _Tuple0&&, _Tuple1&&, _Tuples&&...>::type
|
||||||
tuple_cat(_Tuple0&& __t0, _Tuple1&& __t1, _Tuples&&... __tpls)
|
operator()(tuple<_Types...> __t, _Tuple0&& __t0, _Tuple1&& __t1, _Tuples&& ...__tpls)
|
||||||
{
|
{
|
||||||
return tuple_cat(tuple_cat(_STD::forward<_Tuple0>(__t0),
|
typedef typename remove_reference<_Tuple0>::type _T0;
|
||||||
_STD::forward<_Tuple1>(__t1)),
|
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<sizeof ...(_Types) + tuple_size<_T0>::value>::type,
|
||||||
|
typename __make_tuple_indices<tuple_size<_T1>::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 <class _Tuple0, class... _Tuples>
|
||||||
|
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<>, __tuple_indices<>,
|
||||||
|
typename __make_tuple_indices<tuple_size<_T0>::value>::type>()
|
||||||
|
(tuple<>(), _STD::forward<_Tuple0>(__t0),
|
||||||
_STD::forward<_Tuples>(__tpls)...);
|
_STD::forward<_Tuples>(__tpls)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user