// -*- C++ -*- //===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #ifndef _LIBCPP___TUPLE #define _LIBCPP___TUPLE #include <__config> #include #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD template class _LIBCPP_TEMPLATE_VIS tuple_size; #if !defined(_LIBCPP_CXX03_LANG) template using __enable_if_tuple_size_imp = _Tp; template class _LIBCPP_TEMPLATE_VIS tuple_size<__enable_if_tuple_size_imp< const _Tp, typename enable_if::value>::type, integral_constant)>>> : public integral_constant::value> {}; template class _LIBCPP_TEMPLATE_VIS tuple_size<__enable_if_tuple_size_imp< volatile _Tp, typename enable_if::value>::type, integral_constant)>>> : public integral_constant::value> {}; template class _LIBCPP_TEMPLATE_VIS tuple_size<__enable_if_tuple_size_imp< const volatile _Tp, integral_constant)>>> : public integral_constant::value> {}; #else template class _LIBCPP_TEMPLATE_VIS tuple_size : public tuple_size<_Tp> {}; template class _LIBCPP_TEMPLATE_VIS tuple_size : public tuple_size<_Tp> {}; template class _LIBCPP_TEMPLATE_VIS tuple_size : public tuple_size<_Tp> {}; #endif template struct _LIBCPP_TEMPLATE_VIS tuple_element; template struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, const _Tp> { typedef _LIBCPP_NODEBUG typename add_const::type>::type type; }; template struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, volatile _Tp> { typedef _LIBCPP_NODEBUG typename add_volatile::type>::type type; }; template struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, const volatile _Tp> { typedef _LIBCPP_NODEBUG typename add_cv::type>::type type; }; template struct __tuple_like : false_type {}; template struct __tuple_like : public __tuple_like<_Tp> {}; template struct __tuple_like : public __tuple_like<_Tp> {}; template struct __tuple_like : public __tuple_like<_Tp> {}; // tuple specializations #ifndef _LIBCPP_CXX03_LANG template struct __tuple_indices {}; template struct __integer_sequence { template using __to_tuple_indices = __tuple_indices<(_Values + _Sp)...>; }; #if defined(__CUDACC__) || !__has_builtin(__make_integer_seq) || defined(_LIBCPP_TESTING_FALLBACK_MAKE_INTEGER_SEQUENCE) namespace __detail { template struct __repeat; template struct __repeat<__integer_sequence<_Tp, _Np...>, _Extra...> { typedef _LIBCPP_NODEBUG __integer_sequence<_Tp, _Np..., sizeof...(_Np) + _Np..., 2 * sizeof...(_Np) + _Np..., 3 * sizeof...(_Np) + _Np..., 4 * sizeof...(_Np) + _Np..., 5 * sizeof...(_Np) + _Np..., 6 * sizeof...(_Np) + _Np..., 7 * sizeof...(_Np) + _Np..., _Extra...> type; }; template struct __parity; template struct __make : __parity<_Np % 8>::template __pmake<_Np> {}; template<> struct __make<0> { typedef __integer_sequence type; }; template<> struct __make<1> { typedef __integer_sequence type; }; template<> struct __make<2> { typedef __integer_sequence type; }; template<> struct __make<3> { typedef __integer_sequence type; }; template<> struct __make<4> { typedef __integer_sequence type; }; template<> struct __make<5> { typedef __integer_sequence type; }; template<> struct __make<6> { typedef __integer_sequence type; }; template<> struct __make<7> { typedef __integer_sequence type; }; template<> struct __parity<0> { template struct __pmake : __repeat::type> {}; }; template<> struct __parity<1> { template struct __pmake : __repeat::type, _Np - 1> {}; }; template<> struct __parity<2> { template struct __pmake : __repeat::type, _Np - 2, _Np - 1> {}; }; template<> struct __parity<3> { template struct __pmake : __repeat::type, _Np - 3, _Np - 2, _Np - 1> {}; }; template<> struct __parity<4> { template struct __pmake : __repeat::type, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; }; template<> struct __parity<5> { template struct __pmake : __repeat::type, _Np - 5, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; }; template<> struct __parity<6> { template struct __pmake : __repeat::type, _Np - 6, _Np - 5, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; }; template<> struct __parity<7> { template struct __pmake : __repeat::type, _Np - 7, _Np - 6, _Np - 5, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; }; } // namespace detail #endif // !__has_builtin(__make_integer_seq) || defined(_LIBCPP_TESTING_FALLBACK_MAKE_INTEGER_SEQUENCE) #if __has_builtin(__make_integer_seq) && !defined(__CUDACC__) template using __make_indices_imp = typename __make_integer_seq<__integer_sequence, size_t, _Ep - _Sp>::template __to_tuple_indices<_Sp>; #else template using __make_indices_imp = typename __detail::__make<_Ep - _Sp>::type::template __to_tuple_indices<_Sp>; #endif template struct __make_tuple_indices { static_assert(_Sp <= _Ep, "__make_tuple_indices input error"); typedef __make_indices_imp<_Ep, _Sp> type; }; template class _LIBCPP_TEMPLATE_VIS tuple; template struct __tuple_like > : true_type {}; template class _LIBCPP_TEMPLATE_VIS tuple_size > : public integral_constant { }; template _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 typename tuple_element<_Ip, tuple<_Tp...> >::type& get(tuple<_Tp...>&) _NOEXCEPT; template _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const typename tuple_element<_Ip, tuple<_Tp...> >::type& get(const tuple<_Tp...>&) _NOEXCEPT; template _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 typename tuple_element<_Ip, tuple<_Tp...> >::type&& get(tuple<_Tp...>&&) _NOEXCEPT; template _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const typename tuple_element<_Ip, tuple<_Tp...> >::type&& get(const tuple<_Tp...>&&) _NOEXCEPT; #endif // !defined(_LIBCPP_CXX03_LANG) // pair specializations template struct __tuple_like > : true_type {}; template _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 typename tuple_element<_Ip, pair<_T1, _T2> >::type& get(pair<_T1, _T2>&) _NOEXCEPT; template _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const typename tuple_element<_Ip, pair<_T1, _T2> >::type& get(const pair<_T1, _T2>&) _NOEXCEPT; #ifndef _LIBCPP_CXX03_LANG template _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 typename tuple_element<_Ip, pair<_T1, _T2> >::type&& get(pair<_T1, _T2>&&) _NOEXCEPT; template _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const typename tuple_element<_Ip, pair<_T1, _T2> >::type&& get(const pair<_T1, _T2>&&) _NOEXCEPT; #endif // array specializations template struct _LIBCPP_TEMPLATE_VIS array; template struct __tuple_like > : true_type {}; template _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 _Tp& get(array<_Tp, _Size>&) _NOEXCEPT; template _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const _Tp& get(const array<_Tp, _Size>&) _NOEXCEPT; #ifndef _LIBCPP_CXX03_LANG template _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 _Tp&& get(array<_Tp, _Size>&&) _NOEXCEPT; template _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const _Tp&& get(const array<_Tp, _Size>&&) _NOEXCEPT; #endif #ifndef _LIBCPP_CXX03_LANG // __tuple_types template struct __tuple_types {}; #if !__has_builtin(__type_pack_element) namespace __indexer_detail { template struct __indexed { using type _LIBCPP_NODEBUG = _Tp; }; template struct __indexer; template struct __indexer<__tuple_types<_Types...>, __tuple_indices<_Idx...>> : __indexed<_Idx, _Types>... {}; template __indexed<_Idx, _Tp> __at_index(__indexed<_Idx, _Tp> const&); } // namespace __indexer_detail #if !defined(__CUDACC__) || !defined(_MSC_VER) template using __type_pack_element _LIBCPP_NODEBUG = typename decltype( __indexer_detail::__at_index<_Idx>( __indexer_detail::__indexer< __tuple_types<_Types...>, typename __make_tuple_indices::type >{}) )::type; #else // !defined(__CUDACC__) || !defined(_MSC_VER) template struct __y_type_pack_element { using __t1 = typename __make_tuple_indices::type; using __t2 = __indexer_detail::__indexer<__tuple_types<_Types...>, __t1>; using __t3 = decltype(__indexer_detail::__at_index<_Idx>(__t2{})); using __t4 = typename __t3::type; }; template using __type_pack_element = typename __y_type_pack_element<_Idx, _Types...>::__t4; #endif // !defined(__CUDACC__) || !defined(_MSC_VER) #endif // __has_builtin(__type_pack_element) template struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, __tuple_types<_Types...> > { static_assert(_Ip < sizeof...(_Types), "tuple_element index out of range"); typedef _LIBCPP_NODEBUG __type_pack_element<_Ip, _Types...> type; }; template class _LIBCPP_TEMPLATE_VIS tuple_size<__tuple_types<_Tp...> > : public integral_constant { }; 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 _LIBCPP_NODEBUG = const _Tp; }; template <> struct __apply_cv_mf { template using __apply _LIBCPP_NODEBUG = volatile _Tp; }; template <> struct __apply_cv_mf { template using __apply _LIBCPP_NODEBUG = const volatile _Tp; }; template <> struct __apply_cv_mf { template using __apply _LIBCPP_NODEBUG = _Tp&; }; template <> struct __apply_cv_mf { template using __apply _LIBCPP_NODEBUG = const _Tp&; }; template <> struct __apply_cv_mf { template using __apply _LIBCPP_NODEBUG = volatile _Tp&; }; template <> struct __apply_cv_mf { template using __apply _LIBCPP_NODEBUG = const volatile _Tp&; }; template ::type> using __apply_cv_t _LIBCPP_NODEBUG = __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 // __tuple_types<_Types...> using only those _Types in the range [_Sp, _Ep). // _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. #ifdef _LIBCPP_COMPILER_MSVC template struct __make_tuple_types_append_front; template struct __make_tuple_types_append_front<__tuple_types<_Types...>, _Tp> { using type = __tuple_types<_Tp, _Types...>; }; template struct __make_tuple_types_flat; template struct __make_tuple_types_flat<_Tuple, _Apply, 0, 0, void> { using type = __tuple_types<>; }; template class _Tuple, class _Tp, class ..._Types, class _Apply, size_t _Ep> struct __make_tuple_types_flat<_Tuple<_Tp, _Types...>, _Apply, _Ep, 0, enable_if_t<(_Ep > 0)>> { using type = typename __make_tuple_types_append_front< typename __make_tuple_types_flat<__tuple_types<_Types...>, _Apply, _Ep - 1, 0>::type, typename _Apply::template __apply<_Tp>>::type; }; template