__tuple revision 300770
1227825Stheraven// -*- C++ -*- 2227825Stheraven//===----------------------------------------------------------------------===// 3227825Stheraven// 4227825Stheraven// The LLVM Compiler Infrastructure 5227825Stheraven// 6227825Stheraven// This file is dual licensed under the MIT and the University of Illinois Open 7227825Stheraven// Source Licenses. See LICENSE.TXT for details. 8227825Stheraven// 9227825Stheraven//===----------------------------------------------------------------------===// 10227825Stheraven 11227825Stheraven#ifndef _LIBCPP___TUPLE 12227825Stheraven#define _LIBCPP___TUPLE 13227825Stheraven 14227825Stheraven#include <__config> 15227825Stheraven#include <cstddef> 16227825Stheraven#include <type_traits> 17227825Stheraven 18227825Stheraven#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 19227825Stheraven#pragma GCC system_header 20227825Stheraven#endif 21227825Stheraven 22227825Stheraven 23227825Stheraven_LIBCPP_BEGIN_NAMESPACE_STD 24227825Stheraven 25261272Sdimtemplate <class _Tp> class _LIBCPP_TYPE_VIS_ONLY tuple_size; 26227825Stheraven 27227825Stheraventemplate <class _Tp> 28261272Sdimclass _LIBCPP_TYPE_VIS_ONLY tuple_size<const _Tp> 29227825Stheraven : public tuple_size<_Tp> {}; 30227825Stheraven 31227825Stheraventemplate <class _Tp> 32261272Sdimclass _LIBCPP_TYPE_VIS_ONLY tuple_size<volatile _Tp> 33227825Stheraven : public tuple_size<_Tp> {}; 34227825Stheraven 35227825Stheraventemplate <class _Tp> 36261272Sdimclass _LIBCPP_TYPE_VIS_ONLY tuple_size<const volatile _Tp> 37227825Stheraven : public tuple_size<_Tp> {}; 38227825Stheraven 39261272Sdimtemplate <size_t _Ip, class _Tp> class _LIBCPP_TYPE_VIS_ONLY tuple_element; 40227825Stheraven 41227825Stheraventemplate <size_t _Ip, class _Tp> 42261272Sdimclass _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, const _Tp> 43227825Stheraven{ 44227825Stheravenpublic: 45227825Stheraven typedef typename add_const<typename tuple_element<_Ip, _Tp>::type>::type type; 46227825Stheraven}; 47227825Stheraven 48227825Stheraventemplate <size_t _Ip, class _Tp> 49261272Sdimclass _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, volatile _Tp> 50227825Stheraven{ 51227825Stheravenpublic: 52227825Stheraven typedef typename add_volatile<typename tuple_element<_Ip, _Tp>::type>::type type; 53227825Stheraven}; 54227825Stheraven 55227825Stheraventemplate <size_t _Ip, class _Tp> 56261272Sdimclass _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, const volatile _Tp> 57227825Stheraven{ 58227825Stheravenpublic: 59227825Stheraven typedef typename add_cv<typename tuple_element<_Ip, _Tp>::type>::type type; 60227825Stheraven}; 61227825Stheraven 62227825Stheraventemplate <class _Tp> struct __tuple_like : false_type {}; 63227825Stheraven 64227825Stheraventemplate <class _Tp> struct __tuple_like<const _Tp> : public __tuple_like<_Tp> {}; 65227825Stheraventemplate <class _Tp> struct __tuple_like<volatile _Tp> : public __tuple_like<_Tp> {}; 66227825Stheraventemplate <class _Tp> struct __tuple_like<const volatile _Tp> : public __tuple_like<_Tp> {}; 67227825Stheraven 68288943Sdim// tuple specializations 69288943Sdim 70288943Sdim#if !defined(_LIBCPP_HAS_NO_VARIADICS) 71288943Sdimtemplate <class ..._Tp> class _LIBCPP_TYPE_VIS_ONLY tuple; 72288943Sdim 73227825Stheraventemplate <class... _Tp> struct __tuple_like<tuple<_Tp...> > : true_type {}; 74227825Stheraven 75227825Stheraventemplate <size_t _Ip, class ..._Tp> 76261272Sdim_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 77227825Stheraventypename tuple_element<_Ip, tuple<_Tp...> >::type& 78227825Stheravenget(tuple<_Tp...>&) _NOEXCEPT; 79227825Stheraven 80227825Stheraventemplate <size_t _Ip, class ..._Tp> 81261272Sdim_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 82227825Stheravenconst typename tuple_element<_Ip, tuple<_Tp...> >::type& 83227825Stheravenget(const tuple<_Tp...>&) _NOEXCEPT; 84227825Stheraven 85227825Stheraventemplate <size_t _Ip, class ..._Tp> 86261272Sdim_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 87227825Stheraventypename tuple_element<_Ip, tuple<_Tp...> >::type&& 88227825Stheravenget(tuple<_Tp...>&&) _NOEXCEPT; 89300770Sdim 90300770Sdimtemplate <size_t _Ip, class ..._Tp> 91300770Sdim_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 92300770Sdimconst typename tuple_element<_Ip, tuple<_Tp...> >::type&& 93300770Sdimget(const tuple<_Tp...>&&) _NOEXCEPT; 94288943Sdim#endif 95227825Stheraven 96288943Sdim// pair specializations 97288943Sdim 98288943Sdimtemplate <class _T1, class _T2> struct _LIBCPP_TYPE_VIS_ONLY pair; 99288943Sdim 100288943Sdimtemplate <class _T1, class _T2> struct __tuple_like<pair<_T1, _T2> > : true_type {}; 101288943Sdim 102227825Stheraventemplate <size_t _Ip, class _T1, class _T2> 103261272Sdim_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 104227825Stheraventypename tuple_element<_Ip, pair<_T1, _T2> >::type& 105227825Stheravenget(pair<_T1, _T2>&) _NOEXCEPT; 106227825Stheraven 107227825Stheraventemplate <size_t _Ip, class _T1, class _T2> 108261272Sdim_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 109227825Stheravenconst typename tuple_element<_Ip, pair<_T1, _T2> >::type& 110227825Stheravenget(const pair<_T1, _T2>&) _NOEXCEPT; 111227825Stheraven 112288943Sdim#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) 113227825Stheraventemplate <size_t _Ip, class _T1, class _T2> 114261272Sdim_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 115227825Stheraventypename tuple_element<_Ip, pair<_T1, _T2> >::type&& 116227825Stheravenget(pair<_T1, _T2>&&) _NOEXCEPT; 117300770Sdim 118300770Sdimtemplate <size_t _Ip, class _T1, class _T2> 119300770Sdim_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 120300770Sdimconst typename tuple_element<_Ip, pair<_T1, _T2> >::type&& 121300770Sdimget(const pair<_T1, _T2>&&) _NOEXCEPT; 122288943Sdim#endif 123227825Stheraven 124288943Sdim// array specializations 125288943Sdim 126288943Sdimtemplate <class _Tp, size_t _Size> struct _LIBCPP_TYPE_VIS_ONLY array; 127288943Sdim 128288943Sdimtemplate <class _Tp, size_t _Size> struct __tuple_like<array<_Tp, _Size> > : true_type {}; 129288943Sdim 130227825Stheraventemplate <size_t _Ip, class _Tp, size_t _Size> 131261272Sdim_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 132227825Stheraven_Tp& 133227825Stheravenget(array<_Tp, _Size>&) _NOEXCEPT; 134227825Stheraven 135227825Stheraventemplate <size_t _Ip, class _Tp, size_t _Size> 136261272Sdim_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 137227825Stheravenconst _Tp& 138227825Stheravenget(const array<_Tp, _Size>&) _NOEXCEPT; 139227825Stheraven 140288943Sdim#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) 141227825Stheraventemplate <size_t _Ip, class _Tp, size_t _Size> 142261272Sdim_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 143227825Stheraven_Tp&& 144227825Stheravenget(array<_Tp, _Size>&&) _NOEXCEPT; 145300770Sdim 146300770Sdimtemplate <size_t _Ip, class _Tp, size_t _Size> 147300770Sdim_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 148300770Sdimconst _Tp&& 149300770Sdimget(const array<_Tp, _Size>&&) _NOEXCEPT; 150288943Sdim#endif 151227825Stheraven 152288943Sdim#if !defined(_LIBCPP_HAS_NO_VARIADICS) 153288943Sdim 154227825Stheraven// __make_tuple_indices 155227825Stheraven 156227825Stheraventemplate <size_t...> struct __tuple_indices {}; 157227825Stheraven 158227825Stheraventemplate <size_t _Sp, class _IntTuple, size_t _Ep> 159227825Stheravenstruct __make_indices_imp; 160227825Stheraven 161227825Stheraventemplate <size_t _Sp, size_t ..._Indices, size_t _Ep> 162227825Stheravenstruct __make_indices_imp<_Sp, __tuple_indices<_Indices...>, _Ep> 163227825Stheraven{ 164227825Stheraven typedef typename __make_indices_imp<_Sp+1, __tuple_indices<_Indices..., _Sp>, _Ep>::type type; 165227825Stheraven}; 166227825Stheraven 167227825Stheraventemplate <size_t _Ep, size_t ..._Indices> 168227825Stheravenstruct __make_indices_imp<_Ep, __tuple_indices<_Indices...>, _Ep> 169227825Stheraven{ 170227825Stheraven typedef __tuple_indices<_Indices...> type; 171227825Stheraven}; 172227825Stheraven 173227825Stheraventemplate <size_t _Ep, size_t _Sp = 0> 174227825Stheravenstruct __make_tuple_indices 175227825Stheraven{ 176227825Stheraven static_assert(_Sp <= _Ep, "__make_tuple_indices input error"); 177227825Stheraven typedef typename __make_indices_imp<_Sp, __tuple_indices<>, _Ep>::type type; 178227825Stheraven}; 179227825Stheraven 180227825Stheraven// __tuple_types 181227825Stheraven 182227825Stheraventemplate <class ..._Tp> struct __tuple_types {}; 183227825Stheraven 184227825Stheraventemplate <size_t _Ip> 185261272Sdimclass _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, __tuple_types<> > 186227825Stheraven{ 187227825Stheravenpublic: 188227825Stheraven static_assert(_Ip == 0, "tuple_element index out of range"); 189227825Stheraven static_assert(_Ip != 0, "tuple_element index out of range"); 190227825Stheraven}; 191227825Stheraven 192227825Stheraventemplate <class _Hp, class ..._Tp> 193261272Sdimclass _LIBCPP_TYPE_VIS_ONLY tuple_element<0, __tuple_types<_Hp, _Tp...> > 194227825Stheraven{ 195227825Stheravenpublic: 196227825Stheraven typedef _Hp type; 197227825Stheraven}; 198227825Stheraven 199227825Stheraventemplate <size_t _Ip, class _Hp, class ..._Tp> 200261272Sdimclass _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, __tuple_types<_Hp, _Tp...> > 201227825Stheraven{ 202227825Stheravenpublic: 203227825Stheraven typedef typename tuple_element<_Ip-1, __tuple_types<_Tp...> >::type type; 204227825Stheraven}; 205227825Stheraven 206227825Stheraventemplate <class ..._Tp> 207261272Sdimclass _LIBCPP_TYPE_VIS_ONLY tuple_size<__tuple_types<_Tp...> > 208227825Stheraven : public integral_constant<size_t, sizeof...(_Tp)> 209227825Stheraven{ 210227825Stheraven}; 211227825Stheraven 212227825Stheraventemplate <class... _Tp> struct __tuple_like<__tuple_types<_Tp...> > : true_type {}; 213227825Stheraven 214227825Stheraven// __make_tuple_types 215227825Stheraven 216227825Stheraven// __make_tuple_types<_Tuple<_Types...>, _Ep, _Sp>::type is a 217227825Stheraven// __tuple_types<_Types...> using only those _Types in the range [_Sp, _Ep). 218227825Stheraven// _Sp defaults to 0 and _Ep defaults to tuple_size<_Tuple>. If _Tuple is a 219227825Stheraven// lvalue_reference type, then __tuple_types<_Types&...> is the result. 220227825Stheraven 221227825Stheraventemplate <class _TupleTypes, class _Tp, size_t _Sp, size_t _Ep> 222227825Stheravenstruct __make_tuple_types_imp; 223227825Stheraven 224227825Stheraventemplate <class ..._Types, class _Tp, size_t _Sp, size_t _Ep> 225227825Stheravenstruct __make_tuple_types_imp<__tuple_types<_Types...>, _Tp, _Sp, _Ep> 226227825Stheraven{ 227227825Stheraven typedef typename remove_reference<_Tp>::type _Tpr; 228227825Stheraven typedef typename __make_tuple_types_imp<__tuple_types<_Types..., 229227825Stheraven typename conditional<is_lvalue_reference<_Tp>::value, 230227825Stheraven typename tuple_element<_Sp, _Tpr>::type&, 231227825Stheraven typename tuple_element<_Sp, _Tpr>::type>::type>, 232227825Stheraven _Tp, _Sp+1, _Ep>::type type; 233227825Stheraven}; 234227825Stheraven 235227825Stheraventemplate <class ..._Types, class _Tp, size_t _Ep> 236227825Stheravenstruct __make_tuple_types_imp<__tuple_types<_Types...>, _Tp, _Ep, _Ep> 237227825Stheraven{ 238227825Stheraven typedef __tuple_types<_Types...> type; 239227825Stheraven}; 240227825Stheraven 241227825Stheraventemplate <class _Tp, size_t _Ep = tuple_size<typename remove_reference<_Tp>::type>::value, size_t _Sp = 0> 242227825Stheravenstruct __make_tuple_types 243227825Stheraven{ 244227825Stheraven static_assert(_Sp <= _Ep, "__make_tuple_types input error"); 245227825Stheraven typedef typename __make_tuple_types_imp<__tuple_types<>, _Tp, _Sp, _Ep>::type type; 246227825Stheraven}; 247227825Stheraven 248227825Stheraven// __tuple_convertible 249227825Stheraven 250276792Sdimtemplate <class, class> 251227825Stheravenstruct __tuple_convertible_imp : public false_type {}; 252227825Stheraven 253227825Stheraventemplate <class _Tp0, class ..._Tp, class _Up0, class ..._Up> 254276792Sdimstruct __tuple_convertible_imp<__tuple_types<_Tp0, _Tp...>, __tuple_types<_Up0, _Up...> > 255227825Stheraven : public integral_constant<bool, 256234959Stheraven is_convertible<_Tp0, _Up0>::value && 257276792Sdim __tuple_convertible_imp<__tuple_types<_Tp...>, __tuple_types<_Up...> >::value> {}; 258227825Stheraven 259227825Stheraventemplate <> 260276792Sdimstruct __tuple_convertible_imp<__tuple_types<>, __tuple_types<> > 261227825Stheraven : public true_type {}; 262227825Stheraven 263276792Sdimtemplate <bool, class, class> 264276792Sdimstruct __tuple_convertible_apply : public false_type {}; 265276792Sdim 266276792Sdimtemplate <class _Tp, class _Up> 267276792Sdimstruct __tuple_convertible_apply<true, _Tp, _Up> 268276792Sdim : public __tuple_convertible_imp< 269276792Sdim typename __make_tuple_types<_Tp>::type 270276792Sdim , typename __make_tuple_types<_Up>::type 271276792Sdim > 272276792Sdim{}; 273276792Sdim 274227825Stheraventemplate <class _Tp, class _Up, bool = __tuple_like<typename remove_reference<_Tp>::type>::value, 275227825Stheraven bool = __tuple_like<_Up>::value> 276227825Stheravenstruct __tuple_convertible 277227825Stheraven : public false_type {}; 278227825Stheraven 279227825Stheraventemplate <class _Tp, class _Up> 280227825Stheravenstruct __tuple_convertible<_Tp, _Up, true, true> 281276792Sdim : public __tuple_convertible_apply<tuple_size<typename remove_reference<_Tp>::type>::value == 282276792Sdim tuple_size<_Up>::value, _Tp, _Up> 283227825Stheraven{}; 284227825Stheraven 285234959Stheraven// __tuple_constructible 286234959Stheraven 287276792Sdimtemplate <class, class> 288234959Stheravenstruct __tuple_constructible_imp : public false_type {}; 289234959Stheraven 290234959Stheraventemplate <class _Tp0, class ..._Tp, class _Up0, class ..._Up> 291276792Sdimstruct __tuple_constructible_imp<__tuple_types<_Tp0, _Tp...>, __tuple_types<_Up0, _Up...> > 292234959Stheraven : public integral_constant<bool, 293234959Stheraven is_constructible<_Up0, _Tp0>::value && 294276792Sdim __tuple_constructible_imp<__tuple_types<_Tp...>, __tuple_types<_Up...> >::value> {}; 295234959Stheraven 296234959Stheraventemplate <> 297276792Sdimstruct __tuple_constructible_imp<__tuple_types<>, __tuple_types<> > 298234959Stheraven : public true_type {}; 299234959Stheraven 300276792Sdimtemplate <bool _SameSize, class, class> 301276792Sdimstruct __tuple_constructible_apply : public false_type {}; 302276792Sdim 303276792Sdimtemplate <class _Tp, class _Up> 304276792Sdimstruct __tuple_constructible_apply<true, _Tp, _Up> 305276792Sdim : public __tuple_constructible_imp< 306276792Sdim typename __make_tuple_types<_Tp>::type 307276792Sdim , typename __make_tuple_types<_Up>::type 308276792Sdim > 309276792Sdim{}; 310276792Sdim 311234959Stheraventemplate <class _Tp, class _Up, bool = __tuple_like<typename remove_reference<_Tp>::type>::value, 312234959Stheraven bool = __tuple_like<_Up>::value> 313234959Stheravenstruct __tuple_constructible 314234959Stheraven : public false_type {}; 315234959Stheraven 316234959Stheraventemplate <class _Tp, class _Up> 317234959Stheravenstruct __tuple_constructible<_Tp, _Up, true, true> 318276792Sdim : public __tuple_constructible_apply<tuple_size<typename remove_reference<_Tp>::type>::value == 319276792Sdim tuple_size<_Up>::value, _Tp, _Up> 320234959Stheraven{}; 321234959Stheraven 322227825Stheraven// __tuple_assignable 323227825Stheraven 324276792Sdimtemplate <class, class> 325227825Stheravenstruct __tuple_assignable_imp : public false_type {}; 326227825Stheraven 327227825Stheraventemplate <class _Tp0, class ..._Tp, class _Up0, class ..._Up> 328276792Sdimstruct __tuple_assignable_imp<__tuple_types<_Tp0, _Tp...>, __tuple_types<_Up0, _Up...> > 329227825Stheraven : public integral_constant<bool, 330227825Stheraven is_assignable<_Up0&, _Tp0>::value && 331276792Sdim __tuple_assignable_imp<__tuple_types<_Tp...>, __tuple_types<_Up...> >::value> {}; 332227825Stheraven 333227825Stheraventemplate <> 334276792Sdimstruct __tuple_assignable_imp<__tuple_types<>, __tuple_types<> > 335227825Stheraven : public true_type {}; 336227825Stheraven 337276792Sdimtemplate <bool, class, class> 338276792Sdimstruct __tuple_assignable_apply : public false_type {}; 339276792Sdim 340276792Sdimtemplate <class _Tp, class _Up> 341276792Sdimstruct __tuple_assignable_apply<true, _Tp, _Up> 342276792Sdim : __tuple_assignable_imp< 343276792Sdim typename __make_tuple_types<_Tp>::type 344276792Sdim , typename __make_tuple_types<_Up>::type 345276792Sdim > 346276792Sdim{}; 347276792Sdim 348227825Stheraventemplate <class _Tp, class _Up, bool = __tuple_like<typename remove_reference<_Tp>::type>::value, 349227825Stheraven bool = __tuple_like<_Up>::value> 350227825Stheravenstruct __tuple_assignable 351227825Stheraven : public false_type {}; 352227825Stheraven 353227825Stheraventemplate <class _Tp, class _Up> 354227825Stheravenstruct __tuple_assignable<_Tp, _Up, true, true> 355276792Sdim : public __tuple_assignable_apply<tuple_size<typename remove_reference<_Tp>::type>::value == 356276792Sdim tuple_size<_Up>::value, _Tp, _Up> 357227825Stheraven{}; 358227825Stheraven 359288943Sdim#endif // _LIBCPP_HAS_NO_VARIADICS 360288943Sdim 361227825Stheraven_LIBCPP_END_NAMESPACE_STD 362227825Stheraven 363227825Stheraven#endif // _LIBCPP___TUPLE 364