__tuple revision 276792
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#ifdef _LIBCPP_HAS_NO_VARIADICS 23227825Stheraven 24227825Stheraven#include <__tuple_03> 25227825Stheraven 26227825Stheraven#else // _LIBCPP_HAS_NO_VARIADICS 27227825Stheraven 28227825Stheraven_LIBCPP_BEGIN_NAMESPACE_STD 29227825Stheraven 30276792Sdim// __lazy_and 31276792Sdim 32276792Sdimtemplate <bool _Last, class ..._Preds> 33276792Sdimstruct __lazy_and_impl; 34276792Sdim 35276792Sdimtemplate <class ..._Preds> 36276792Sdimstruct __lazy_and_impl<false, _Preds...> : false_type {}; 37276792Sdim 38276792Sdimtemplate <> 39276792Sdimstruct __lazy_and_impl<true> : true_type {}; 40276792Sdim 41276792Sdimtemplate <class _Pred> 42276792Sdimstruct __lazy_and_impl<true, _Pred> : integral_constant<bool, _Pred::type::value> {}; 43276792Sdim 44276792Sdimtemplate <class _Hp, class ..._Tp> 45276792Sdimstruct __lazy_and_impl<true, _Hp, _Tp...> : __lazy_and_impl<_Hp::type::value, _Tp...> {}; 46276792Sdim 47276792Sdimtemplate <class _P1, class ..._Pr> 48276792Sdimstruct __lazy_and : __lazy_and_impl<_P1::type::value, _Pr...> {}; 49276792Sdim 50276792Sdim// __lazy_not 51276792Sdim 52276792Sdimtemplate <class _Pred> 53276792Sdimstruct __lazy_not : integral_constant<bool, !_Pred::type::value> {}; 54276792Sdim 55276792Sdim 56261272Sdimtemplate <class _Tp> class _LIBCPP_TYPE_VIS_ONLY tuple_size; 57227825Stheraven 58227825Stheraventemplate <class _Tp> 59261272Sdimclass _LIBCPP_TYPE_VIS_ONLY tuple_size<const _Tp> 60227825Stheraven : public tuple_size<_Tp> {}; 61227825Stheraven 62227825Stheraventemplate <class _Tp> 63261272Sdimclass _LIBCPP_TYPE_VIS_ONLY tuple_size<volatile _Tp> 64227825Stheraven : public tuple_size<_Tp> {}; 65227825Stheraven 66227825Stheraventemplate <class _Tp> 67261272Sdimclass _LIBCPP_TYPE_VIS_ONLY tuple_size<const volatile _Tp> 68227825Stheraven : public tuple_size<_Tp> {}; 69227825Stheraven 70261272Sdimtemplate <size_t _Ip, class _Tp> class _LIBCPP_TYPE_VIS_ONLY tuple_element; 71227825Stheraven 72227825Stheraventemplate <size_t _Ip, class _Tp> 73261272Sdimclass _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, const _Tp> 74227825Stheraven{ 75227825Stheravenpublic: 76227825Stheraven typedef typename add_const<typename tuple_element<_Ip, _Tp>::type>::type type; 77227825Stheraven}; 78227825Stheraven 79227825Stheraventemplate <size_t _Ip, class _Tp> 80261272Sdimclass _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, volatile _Tp> 81227825Stheraven{ 82227825Stheravenpublic: 83227825Stheraven typedef typename add_volatile<typename tuple_element<_Ip, _Tp>::type>::type type; 84227825Stheraven}; 85227825Stheraven 86227825Stheraventemplate <size_t _Ip, class _Tp> 87261272Sdimclass _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, const volatile _Tp> 88227825Stheraven{ 89227825Stheravenpublic: 90227825Stheraven typedef typename add_cv<typename tuple_element<_Ip, _Tp>::type>::type type; 91227825Stheraven}; 92227825Stheraven 93261272Sdimtemplate <class ..._Tp> class _LIBCPP_TYPE_VIS_ONLY tuple; 94261272Sdimtemplate <class _T1, class _T2> struct _LIBCPP_TYPE_VIS_ONLY pair; 95261272Sdimtemplate <class _Tp, size_t _Size> struct _LIBCPP_TYPE_VIS_ONLY array; 96227825Stheraven 97227825Stheraventemplate <class _Tp> struct __tuple_like : false_type {}; 98227825Stheraven 99227825Stheraventemplate <class _Tp> struct __tuple_like<const _Tp> : public __tuple_like<_Tp> {}; 100227825Stheraventemplate <class _Tp> struct __tuple_like<volatile _Tp> : public __tuple_like<_Tp> {}; 101227825Stheraventemplate <class _Tp> struct __tuple_like<const volatile _Tp> : public __tuple_like<_Tp> {}; 102227825Stheraven 103227825Stheraventemplate <class... _Tp> struct __tuple_like<tuple<_Tp...> > : true_type {}; 104227825Stheraventemplate <class _T1, class _T2> struct __tuple_like<pair<_T1, _T2> > : true_type {}; 105227825Stheraventemplate <class _Tp, size_t _Size> struct __tuple_like<array<_Tp, _Size> > : true_type {}; 106227825Stheraven 107227825Stheraventemplate <size_t _Ip, class ..._Tp> 108261272Sdim_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 109227825Stheraventypename tuple_element<_Ip, tuple<_Tp...> >::type& 110227825Stheravenget(tuple<_Tp...>&) _NOEXCEPT; 111227825Stheraven 112227825Stheraventemplate <size_t _Ip, class ..._Tp> 113261272Sdim_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 114227825Stheravenconst typename tuple_element<_Ip, tuple<_Tp...> >::type& 115227825Stheravenget(const tuple<_Tp...>&) _NOEXCEPT; 116227825Stheraven 117227825Stheraventemplate <size_t _Ip, class ..._Tp> 118261272Sdim_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 119227825Stheraventypename tuple_element<_Ip, tuple<_Tp...> >::type&& 120227825Stheravenget(tuple<_Tp...>&&) _NOEXCEPT; 121227825Stheraven 122227825Stheraventemplate <size_t _Ip, class _T1, class _T2> 123261272Sdim_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 124227825Stheraventypename tuple_element<_Ip, pair<_T1, _T2> >::type& 125227825Stheravenget(pair<_T1, _T2>&) _NOEXCEPT; 126227825Stheraven 127227825Stheraventemplate <size_t _Ip, class _T1, class _T2> 128261272Sdim_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 129227825Stheravenconst typename tuple_element<_Ip, pair<_T1, _T2> >::type& 130227825Stheravenget(const pair<_T1, _T2>&) _NOEXCEPT; 131227825Stheraven 132227825Stheraventemplate <size_t _Ip, class _T1, class _T2> 133261272Sdim_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 134227825Stheraventypename tuple_element<_Ip, pair<_T1, _T2> >::type&& 135227825Stheravenget(pair<_T1, _T2>&&) _NOEXCEPT; 136227825Stheraven 137227825Stheraventemplate <size_t _Ip, class _Tp, size_t _Size> 138261272Sdim_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 139227825Stheraven_Tp& 140227825Stheravenget(array<_Tp, _Size>&) _NOEXCEPT; 141227825Stheraven 142227825Stheraventemplate <size_t _Ip, class _Tp, size_t _Size> 143261272Sdim_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 144227825Stheravenconst _Tp& 145227825Stheravenget(const array<_Tp, _Size>&) _NOEXCEPT; 146227825Stheraven 147227825Stheraventemplate <size_t _Ip, class _Tp, size_t _Size> 148261272Sdim_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 149227825Stheraven_Tp&& 150227825Stheravenget(array<_Tp, _Size>&&) _NOEXCEPT; 151227825Stheraven 152227825Stheraven// __make_tuple_indices 153227825Stheraven 154227825Stheraventemplate <size_t...> struct __tuple_indices {}; 155227825Stheraven 156227825Stheraventemplate <size_t _Sp, class _IntTuple, size_t _Ep> 157227825Stheravenstruct __make_indices_imp; 158227825Stheraven 159227825Stheraventemplate <size_t _Sp, size_t ..._Indices, size_t _Ep> 160227825Stheravenstruct __make_indices_imp<_Sp, __tuple_indices<_Indices...>, _Ep> 161227825Stheraven{ 162227825Stheraven typedef typename __make_indices_imp<_Sp+1, __tuple_indices<_Indices..., _Sp>, _Ep>::type type; 163227825Stheraven}; 164227825Stheraven 165227825Stheraventemplate <size_t _Ep, size_t ..._Indices> 166227825Stheravenstruct __make_indices_imp<_Ep, __tuple_indices<_Indices...>, _Ep> 167227825Stheraven{ 168227825Stheraven typedef __tuple_indices<_Indices...> type; 169227825Stheraven}; 170227825Stheraven 171227825Stheraventemplate <size_t _Ep, size_t _Sp = 0> 172227825Stheravenstruct __make_tuple_indices 173227825Stheraven{ 174227825Stheraven static_assert(_Sp <= _Ep, "__make_tuple_indices input error"); 175227825Stheraven typedef typename __make_indices_imp<_Sp, __tuple_indices<>, _Ep>::type type; 176227825Stheraven}; 177227825Stheraven 178227825Stheraven// __tuple_types 179227825Stheraven 180227825Stheraventemplate <class ..._Tp> struct __tuple_types {}; 181227825Stheraven 182227825Stheraventemplate <size_t _Ip> 183261272Sdimclass _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, __tuple_types<> > 184227825Stheraven{ 185227825Stheravenpublic: 186227825Stheraven static_assert(_Ip == 0, "tuple_element index out of range"); 187227825Stheraven static_assert(_Ip != 0, "tuple_element index out of range"); 188227825Stheraven}; 189227825Stheraven 190227825Stheraventemplate <class _Hp, class ..._Tp> 191261272Sdimclass _LIBCPP_TYPE_VIS_ONLY tuple_element<0, __tuple_types<_Hp, _Tp...> > 192227825Stheraven{ 193227825Stheravenpublic: 194227825Stheraven typedef _Hp type; 195227825Stheraven}; 196227825Stheraven 197227825Stheraventemplate <size_t _Ip, class _Hp, class ..._Tp> 198261272Sdimclass _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, __tuple_types<_Hp, _Tp...> > 199227825Stheraven{ 200227825Stheravenpublic: 201227825Stheraven typedef typename tuple_element<_Ip-1, __tuple_types<_Tp...> >::type type; 202227825Stheraven}; 203227825Stheraven 204227825Stheraventemplate <class ..._Tp> 205261272Sdimclass _LIBCPP_TYPE_VIS_ONLY tuple_size<__tuple_types<_Tp...> > 206227825Stheraven : public integral_constant<size_t, sizeof...(_Tp)> 207227825Stheraven{ 208227825Stheraven}; 209227825Stheraven 210227825Stheraventemplate <class... _Tp> struct __tuple_like<__tuple_types<_Tp...> > : true_type {}; 211227825Stheraven 212227825Stheraven// __make_tuple_types 213227825Stheraven 214227825Stheraven// __make_tuple_types<_Tuple<_Types...>, _Ep, _Sp>::type is a 215227825Stheraven// __tuple_types<_Types...> using only those _Types in the range [_Sp, _Ep). 216227825Stheraven// _Sp defaults to 0 and _Ep defaults to tuple_size<_Tuple>. If _Tuple is a 217227825Stheraven// lvalue_reference type, then __tuple_types<_Types&...> is the result. 218227825Stheraven 219227825Stheraventemplate <class _TupleTypes, class _Tp, size_t _Sp, size_t _Ep> 220227825Stheravenstruct __make_tuple_types_imp; 221227825Stheraven 222227825Stheraventemplate <class ..._Types, class _Tp, size_t _Sp, size_t _Ep> 223227825Stheravenstruct __make_tuple_types_imp<__tuple_types<_Types...>, _Tp, _Sp, _Ep> 224227825Stheraven{ 225227825Stheraven typedef typename remove_reference<_Tp>::type _Tpr; 226227825Stheraven typedef typename __make_tuple_types_imp<__tuple_types<_Types..., 227227825Stheraven typename conditional<is_lvalue_reference<_Tp>::value, 228227825Stheraven typename tuple_element<_Sp, _Tpr>::type&, 229227825Stheraven typename tuple_element<_Sp, _Tpr>::type>::type>, 230227825Stheraven _Tp, _Sp+1, _Ep>::type type; 231227825Stheraven}; 232227825Stheraven 233227825Stheraventemplate <class ..._Types, class _Tp, size_t _Ep> 234227825Stheravenstruct __make_tuple_types_imp<__tuple_types<_Types...>, _Tp, _Ep, _Ep> 235227825Stheraven{ 236227825Stheraven typedef __tuple_types<_Types...> type; 237227825Stheraven}; 238227825Stheraven 239227825Stheraventemplate <class _Tp, size_t _Ep = tuple_size<typename remove_reference<_Tp>::type>::value, size_t _Sp = 0> 240227825Stheravenstruct __make_tuple_types 241227825Stheraven{ 242227825Stheraven static_assert(_Sp <= _Ep, "__make_tuple_types input error"); 243227825Stheraven typedef typename __make_tuple_types_imp<__tuple_types<>, _Tp, _Sp, _Ep>::type type; 244227825Stheraven}; 245227825Stheraven 246227825Stheraven// __tuple_convertible 247227825Stheraven 248276792Sdimtemplate <class, class> 249227825Stheravenstruct __tuple_convertible_imp : public false_type {}; 250227825Stheraven 251227825Stheraventemplate <class _Tp0, class ..._Tp, class _Up0, class ..._Up> 252276792Sdimstruct __tuple_convertible_imp<__tuple_types<_Tp0, _Tp...>, __tuple_types<_Up0, _Up...> > 253227825Stheraven : public integral_constant<bool, 254234959Stheraven is_convertible<_Tp0, _Up0>::value && 255276792Sdim __tuple_convertible_imp<__tuple_types<_Tp...>, __tuple_types<_Up...> >::value> {}; 256227825Stheraven 257227825Stheraventemplate <> 258276792Sdimstruct __tuple_convertible_imp<__tuple_types<>, __tuple_types<> > 259227825Stheraven : public true_type {}; 260227825Stheraven 261276792Sdimtemplate <bool, class, class> 262276792Sdimstruct __tuple_convertible_apply : public false_type {}; 263276792Sdim 264276792Sdimtemplate <class _Tp, class _Up> 265276792Sdimstruct __tuple_convertible_apply<true, _Tp, _Up> 266276792Sdim : public __tuple_convertible_imp< 267276792Sdim typename __make_tuple_types<_Tp>::type 268276792Sdim , typename __make_tuple_types<_Up>::type 269276792Sdim > 270276792Sdim{}; 271276792Sdim 272227825Stheraventemplate <class _Tp, class _Up, bool = __tuple_like<typename remove_reference<_Tp>::type>::value, 273227825Stheraven bool = __tuple_like<_Up>::value> 274227825Stheravenstruct __tuple_convertible 275227825Stheraven : public false_type {}; 276227825Stheraven 277227825Stheraventemplate <class _Tp, class _Up> 278227825Stheravenstruct __tuple_convertible<_Tp, _Up, true, true> 279276792Sdim : public __tuple_convertible_apply<tuple_size<typename remove_reference<_Tp>::type>::value == 280276792Sdim tuple_size<_Up>::value, _Tp, _Up> 281227825Stheraven{}; 282227825Stheraven 283234959Stheraven// __tuple_constructible 284234959Stheraven 285276792Sdimtemplate <class, class> 286234959Stheravenstruct __tuple_constructible_imp : public false_type {}; 287234959Stheraven 288234959Stheraventemplate <class _Tp0, class ..._Tp, class _Up0, class ..._Up> 289276792Sdimstruct __tuple_constructible_imp<__tuple_types<_Tp0, _Tp...>, __tuple_types<_Up0, _Up...> > 290234959Stheraven : public integral_constant<bool, 291234959Stheraven is_constructible<_Up0, _Tp0>::value && 292276792Sdim __tuple_constructible_imp<__tuple_types<_Tp...>, __tuple_types<_Up...> >::value> {}; 293234959Stheraven 294234959Stheraventemplate <> 295276792Sdimstruct __tuple_constructible_imp<__tuple_types<>, __tuple_types<> > 296234959Stheraven : public true_type {}; 297234959Stheraven 298276792Sdimtemplate <bool _SameSize, class, class> 299276792Sdimstruct __tuple_constructible_apply : public false_type {}; 300276792Sdim 301276792Sdimtemplate <class _Tp, class _Up> 302276792Sdimstruct __tuple_constructible_apply<true, _Tp, _Up> 303276792Sdim : public __tuple_constructible_imp< 304276792Sdim typename __make_tuple_types<_Tp>::type 305276792Sdim , typename __make_tuple_types<_Up>::type 306276792Sdim > 307276792Sdim{}; 308276792Sdim 309234959Stheraventemplate <class _Tp, class _Up, bool = __tuple_like<typename remove_reference<_Tp>::type>::value, 310234959Stheraven bool = __tuple_like<_Up>::value> 311234959Stheravenstruct __tuple_constructible 312234959Stheraven : public false_type {}; 313234959Stheraven 314234959Stheraventemplate <class _Tp, class _Up> 315234959Stheravenstruct __tuple_constructible<_Tp, _Up, true, true> 316276792Sdim : public __tuple_constructible_apply<tuple_size<typename remove_reference<_Tp>::type>::value == 317276792Sdim tuple_size<_Up>::value, _Tp, _Up> 318234959Stheraven{}; 319234959Stheraven 320227825Stheraven// __tuple_assignable 321227825Stheraven 322276792Sdimtemplate <class, class> 323227825Stheravenstruct __tuple_assignable_imp : public false_type {}; 324227825Stheraven 325227825Stheraventemplate <class _Tp0, class ..._Tp, class _Up0, class ..._Up> 326276792Sdimstruct __tuple_assignable_imp<__tuple_types<_Tp0, _Tp...>, __tuple_types<_Up0, _Up...> > 327227825Stheraven : public integral_constant<bool, 328227825Stheraven is_assignable<_Up0&, _Tp0>::value && 329276792Sdim __tuple_assignable_imp<__tuple_types<_Tp...>, __tuple_types<_Up...> >::value> {}; 330227825Stheraven 331227825Stheraventemplate <> 332276792Sdimstruct __tuple_assignable_imp<__tuple_types<>, __tuple_types<> > 333227825Stheraven : public true_type {}; 334227825Stheraven 335276792Sdimtemplate <bool, class, class> 336276792Sdimstruct __tuple_assignable_apply : public false_type {}; 337276792Sdim 338276792Sdimtemplate <class _Tp, class _Up> 339276792Sdimstruct __tuple_assignable_apply<true, _Tp, _Up> 340276792Sdim : __tuple_assignable_imp< 341276792Sdim typename __make_tuple_types<_Tp>::type 342276792Sdim , typename __make_tuple_types<_Up>::type 343276792Sdim > 344276792Sdim{}; 345276792Sdim 346227825Stheraventemplate <class _Tp, class _Up, bool = __tuple_like<typename remove_reference<_Tp>::type>::value, 347227825Stheraven bool = __tuple_like<_Up>::value> 348227825Stheravenstruct __tuple_assignable 349227825Stheraven : public false_type {}; 350227825Stheraven 351227825Stheraventemplate <class _Tp, class _Up> 352227825Stheravenstruct __tuple_assignable<_Tp, _Up, true, true> 353276792Sdim : public __tuple_assignable_apply<tuple_size<typename remove_reference<_Tp>::type>::value == 354276792Sdim tuple_size<_Up>::value, _Tp, _Up> 355227825Stheraven{}; 356227825Stheraven 357227825Stheraven_LIBCPP_END_NAMESPACE_STD 358227825Stheraven 359227825Stheraven#endif // _LIBCPP_HAS_NO_VARIADICS 360227825Stheraven 361227825Stheraven#endif // _LIBCPP___TUPLE 362