106c3fb27SDimitry Andric //===----------------------------------------------------------------------===// 206c3fb27SDimitry Andric // 306c3fb27SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 406c3fb27SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 506c3fb27SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 606c3fb27SDimitry Andric // 706c3fb27SDimitry Andric //===----------------------------------------------------------------------===// 806c3fb27SDimitry Andric 906c3fb27SDimitry Andric #ifndef _LIBCPP___TUPLE_TUPLE_ELEMENT_H 1006c3fb27SDimitry Andric #define _LIBCPP___TUPLE_TUPLE_ELEMENT_H 1106c3fb27SDimitry Andric 1206c3fb27SDimitry Andric #include <__config> 1306c3fb27SDimitry Andric #include <__tuple/tuple_indices.h> 1406c3fb27SDimitry Andric #include <__tuple/tuple_types.h> 1506c3fb27SDimitry Andric #include <__type_traits/add_const.h> 1606c3fb27SDimitry Andric #include <__type_traits/add_cv.h> 1706c3fb27SDimitry Andric #include <__type_traits/add_volatile.h> 1806c3fb27SDimitry Andric #include <cstddef> 1906c3fb27SDimitry Andric 2006c3fb27SDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 2106c3fb27SDimitry Andric # pragma GCC system_header 2206c3fb27SDimitry Andric #endif 2306c3fb27SDimitry Andric 2406c3fb27SDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD 2506c3fb27SDimitry Andric 26*cb14a3feSDimitry Andric template <size_t _Ip, class _Tp> 27*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS tuple_element; 2806c3fb27SDimitry Andric 2906c3fb27SDimitry Andric template <size_t _Ip, class _Tp> 30*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, const _Tp> { 3106c3fb27SDimitry Andric typedef _LIBCPP_NODEBUG typename add_const<typename tuple_element<_Ip, _Tp>::type>::type type; 3206c3fb27SDimitry Andric }; 3306c3fb27SDimitry Andric 3406c3fb27SDimitry Andric template <size_t _Ip, class _Tp> 35*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, volatile _Tp> { 3606c3fb27SDimitry Andric typedef _LIBCPP_NODEBUG typename add_volatile<typename tuple_element<_Ip, _Tp>::type>::type type; 3706c3fb27SDimitry Andric }; 3806c3fb27SDimitry Andric 3906c3fb27SDimitry Andric template <size_t _Ip, class _Tp> 40*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, const volatile _Tp> { 4106c3fb27SDimitry Andric typedef _LIBCPP_NODEBUG typename add_cv<typename tuple_element<_Ip, _Tp>::type>::type type; 4206c3fb27SDimitry Andric }; 4306c3fb27SDimitry Andric 4406c3fb27SDimitry Andric #ifndef _LIBCPP_CXX03_LANG 4506c3fb27SDimitry Andric 4606c3fb27SDimitry Andric # if !__has_builtin(__type_pack_element) 4706c3fb27SDimitry Andric 4806c3fb27SDimitry Andric namespace __indexer_detail { 4906c3fb27SDimitry Andric 5006c3fb27SDimitry Andric template <size_t _Idx, class _Tp> 51*cb14a3feSDimitry Andric struct __indexed { 52*cb14a3feSDimitry Andric using type _LIBCPP_NODEBUG = _Tp; 53*cb14a3feSDimitry Andric }; 5406c3fb27SDimitry Andric 55*cb14a3feSDimitry Andric template <class _Types, class _Indexes> 56*cb14a3feSDimitry Andric struct __indexer; 5706c3fb27SDimitry Andric 5806c3fb27SDimitry Andric template <class... _Types, size_t... _Idx> 59*cb14a3feSDimitry Andric struct __indexer<__tuple_types<_Types...>, __tuple_indices<_Idx...>> : __indexed<_Idx, _Types>... {}; 6006c3fb27SDimitry Andric 6106c3fb27SDimitry Andric template <size_t _Idx, class _Tp> 6206c3fb27SDimitry Andric __indexed<_Idx, _Tp> __at_index(__indexed<_Idx, _Tp> const&); 6306c3fb27SDimitry Andric 6406c3fb27SDimitry Andric } // namespace __indexer_detail 6506c3fb27SDimitry Andric 6606c3fb27SDimitry Andric template <size_t _Idx, class... _Types> 67*cb14a3feSDimitry Andric using __type_pack_element _LIBCPP_NODEBUG = typename decltype(__indexer_detail::__at_index<_Idx>( 68*cb14a3feSDimitry Andric __indexer_detail::__indexer< __tuple_types<_Types...>, 69*cb14a3feSDimitry Andric typename __make_tuple_indices<sizeof...(_Types)>::type >{}))::type; 7006c3fb27SDimitry Andric # endif 7106c3fb27SDimitry Andric 7206c3fb27SDimitry Andric template <size_t _Ip, class... _Types> 73*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, __tuple_types<_Types...> > { 7406c3fb27SDimitry Andric static_assert(_Ip < sizeof...(_Types), "tuple_element index out of range"); 7506c3fb27SDimitry Andric typedef _LIBCPP_NODEBUG __type_pack_element<_Ip, _Types...> type; 7606c3fb27SDimitry Andric }; 7706c3fb27SDimitry Andric 7806c3fb27SDimitry Andric # if _LIBCPP_STD_VER >= 14 7906c3fb27SDimitry Andric template <size_t _Ip, class... _Tp> 8006c3fb27SDimitry Andric using tuple_element_t _LIBCPP_NODEBUG = typename tuple_element<_Ip, _Tp...>::type; 8106c3fb27SDimitry Andric # endif 8206c3fb27SDimitry Andric 8306c3fb27SDimitry Andric #endif // _LIBCPP_CXX03_LANG 8406c3fb27SDimitry Andric 8506c3fb27SDimitry Andric _LIBCPP_END_NAMESPACE_STD 8606c3fb27SDimitry Andric 8706c3fb27SDimitry Andric #endif // _LIBCPP___TUPLE_TUPLE_ELEMENT_H 88