1 1.1 mrg // class template tuple -*- C++ -*- 2 1.1 mrg 3 1.1.1.12 mrg // Copyright (C) 2004-2024 Free Software Foundation, Inc. 4 1.1 mrg // 5 1.1 mrg // This file is part of the GNU ISO C++ Library. This library is free 6 1.1 mrg // software; you can redistribute it and/or modify it under the 7 1.1 mrg // terms of the GNU General Public License as published by the 8 1.1 mrg // Free Software Foundation; either version 3, or (at your option) 9 1.1 mrg // any later version. 10 1.1 mrg 11 1.1 mrg // This library is distributed in the hope that it will be useful, 12 1.1 mrg // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 1.1 mrg // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 1.1 mrg // GNU General Public License for more details. 15 1.1 mrg 16 1.1 mrg // Under Section 7 of GPL version 3, you are granted additional 17 1.1 mrg // permissions described in the GCC Runtime Library Exception, version 18 1.1 mrg // 3.1, as published by the Free Software Foundation. 19 1.1 mrg 20 1.1 mrg // You should have received a copy of the GNU General Public License and 21 1.1 mrg // a copy of the GCC Runtime Library Exception along with this program; 22 1.1 mrg // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 1.1 mrg // <http://www.gnu.org/licenses/>. 24 1.1 mrg 25 1.1 mrg /** @file tr1/tuple 26 1.1 mrg * This is a TR1 C++ Library header. 27 1.1 mrg */ 28 1.1 mrg 29 1.1 mrg // Chris Jefferson <chris (a] bubblescope.net> 30 1.1 mrg // Variadic Templates support by Douglas Gregor <doug.gregor (a] gmail.com> 31 1.1 mrg 32 1.1 mrg #ifndef _GLIBCXX_TR1_TUPLE 33 1.1 mrg #define _GLIBCXX_TR1_TUPLE 1 34 1.1 mrg 35 1.1 mrg #pragma GCC system_header 36 1.1 mrg 37 1.1.1.12 mrg #include <bits/requires_hosted.h> // TR1 38 1.1.1.12 mrg 39 1.1 mrg #include <utility> 40 1.1 mrg 41 1.1.1.2 mrg namespace std _GLIBCXX_VISIBILITY(default) 42 1.1 mrg { 43 1.1.1.7 mrg _GLIBCXX_BEGIN_NAMESPACE_VERSION 44 1.1.1.7 mrg 45 1.1.1.8 mrg namespace tr1 46 1.1.1.8 mrg { 47 1.1 mrg // Adds a const reference to a non-reference type. 48 1.1 mrg template<typename _Tp> 49 1.1 mrg struct __add_c_ref 50 1.1 mrg { typedef const _Tp& type; }; 51 1.1 mrg 52 1.1 mrg template<typename _Tp> 53 1.1 mrg struct __add_c_ref<_Tp&> 54 1.1 mrg { typedef _Tp& type; }; 55 1.1 mrg 56 1.1 mrg // Adds a reference to a non-reference type. 57 1.1 mrg template<typename _Tp> 58 1.1 mrg struct __add_ref 59 1.1 mrg { typedef _Tp& type; }; 60 1.1 mrg 61 1.1 mrg template<typename _Tp> 62 1.1 mrg struct __add_ref<_Tp&> 63 1.1 mrg { typedef _Tp& type; }; 64 1.1 mrg 65 1.1 mrg /** 66 1.1 mrg * Contains the actual implementation of the @c tuple template, stored 67 1.1 mrg * as a recursive inheritance hierarchy from the first element (most 68 1.1 mrg * derived class) to the last (least derived class). The @c Idx 69 1.1 mrg * parameter gives the 0-based index of the element stored at this 70 1.1 mrg * point in the hierarchy; we use it to implement a constant-time 71 1.1 mrg * get() operation. 72 1.1 mrg */ 73 1.1 mrg template<int _Idx, typename... _Elements> 74 1.1 mrg struct _Tuple_impl; 75 1.1 mrg 76 1.1 mrg /** 77 1.1 mrg * Zero-element tuple implementation. This is the basis case for the 78 1.1 mrg * inheritance recursion. 79 1.1 mrg */ 80 1.1 mrg template<int _Idx> 81 1.1 mrg struct _Tuple_impl<_Idx> { }; 82 1.1 mrg 83 1.1 mrg /** 84 1.1 mrg * Recursive tuple implementation. Here we store the @c Head element 85 1.1 mrg * and derive from a @c Tuple_impl containing the remaining elements 86 1.1 mrg * (which contains the @c Tail). 87 1.1 mrg */ 88 1.1 mrg template<int _Idx, typename _Head, typename... _Tail> 89 1.1 mrg struct _Tuple_impl<_Idx, _Head, _Tail...> 90 1.1 mrg : public _Tuple_impl<_Idx + 1, _Tail...> 91 1.1 mrg { 92 1.1 mrg typedef _Tuple_impl<_Idx + 1, _Tail...> _Inherited; 93 1.1 mrg 94 1.1 mrg _Head _M_head; 95 1.1 mrg 96 1.1 mrg _Inherited& _M_tail() { return *this; } 97 1.1 mrg const _Inherited& _M_tail() const { return *this; } 98 1.1 mrg 99 1.1 mrg _Tuple_impl() : _Inherited(), _M_head() { } 100 1.1 mrg 101 1.1 mrg explicit 102 1.1 mrg _Tuple_impl(typename __add_c_ref<_Head>::type __head, 103 1.1 mrg typename __add_c_ref<_Tail>::type... __tail) 104 1.1 mrg : _Inherited(__tail...), _M_head(__head) { } 105 1.1 mrg 106 1.1 mrg template<typename... _UElements> 107 1.1 mrg _Tuple_impl(const _Tuple_impl<_Idx, _UElements...>& __in) 108 1.1 mrg : _Inherited(__in._M_tail()), _M_head(__in._M_head) { } 109 1.1 mrg 110 1.1 mrg _Tuple_impl(const _Tuple_impl& __in) 111 1.1 mrg : _Inherited(__in._M_tail()), _M_head(__in._M_head) { } 112 1.1 mrg 113 1.1 mrg template<typename... _UElements> 114 1.1 mrg _Tuple_impl& 115 1.1 mrg operator=(const _Tuple_impl<_Idx, _UElements...>& __in) 116 1.1 mrg { 117 1.1 mrg _M_head = __in._M_head; 118 1.1 mrg _M_tail() = __in._M_tail(); 119 1.1 mrg return *this; 120 1.1 mrg } 121 1.1 mrg 122 1.1 mrg _Tuple_impl& 123 1.1 mrg operator=(const _Tuple_impl& __in) 124 1.1 mrg { 125 1.1 mrg _M_head = __in._M_head; 126 1.1 mrg _M_tail() = __in._M_tail(); 127 1.1 mrg return *this; 128 1.1 mrg } 129 1.1 mrg }; 130 1.1 mrg 131 1.1 mrg template<typename... _Elements> 132 1.1 mrg class tuple : public _Tuple_impl<0, _Elements...> 133 1.1 mrg { 134 1.1 mrg typedef _Tuple_impl<0, _Elements...> _Inherited; 135 1.1 mrg 136 1.1 mrg public: 137 1.1 mrg tuple() : _Inherited() { } 138 1.1 mrg 139 1.1 mrg explicit 140 1.1 mrg tuple(typename __add_c_ref<_Elements>::type... __elements) 141 1.1 mrg : _Inherited(__elements...) { } 142 1.1 mrg 143 1.1 mrg template<typename... _UElements> 144 1.1 mrg tuple(const tuple<_UElements...>& __in) 145 1.1 mrg : _Inherited(__in) { } 146 1.1 mrg 147 1.1 mrg tuple(const tuple& __in) 148 1.1 mrg : _Inherited(__in) { } 149 1.1 mrg 150 1.1 mrg template<typename... _UElements> 151 1.1 mrg tuple& 152 1.1 mrg operator=(const tuple<_UElements...>& __in) 153 1.1 mrg { 154 1.1 mrg static_cast<_Inherited&>(*this) = __in; 155 1.1 mrg return *this; 156 1.1 mrg } 157 1.1 mrg 158 1.1 mrg tuple& 159 1.1 mrg operator=(const tuple& __in) 160 1.1 mrg { 161 1.1 mrg static_cast<_Inherited&>(*this) = __in; 162 1.1 mrg return *this; 163 1.1 mrg } 164 1.1 mrg }; 165 1.1 mrg 166 1.1 mrg template<> class tuple<> { }; 167 1.1 mrg 168 1.1 mrg // 2-element tuple, with construction and assignment from a pair. 169 1.1 mrg template<typename _T1, typename _T2> 170 1.1 mrg class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2> 171 1.1 mrg { 172 1.1 mrg typedef _Tuple_impl<0, _T1, _T2> _Inherited; 173 1.1 mrg 174 1.1 mrg public: 175 1.1 mrg tuple() : _Inherited() { } 176 1.1 mrg 177 1.1 mrg explicit 178 1.1 mrg tuple(typename __add_c_ref<_T1>::type __a1, 179 1.1 mrg typename __add_c_ref<_T2>::type __a2) 180 1.1 mrg : _Inherited(__a1, __a2) { } 181 1.1 mrg 182 1.1 mrg template<typename _U1, typename _U2> 183 1.1 mrg tuple(const tuple<_U1, _U2>& __in) 184 1.1 mrg : _Inherited(__in) { } 185 1.1 mrg 186 1.1 mrg tuple(const tuple& __in) 187 1.1 mrg : _Inherited(__in) { } 188 1.1 mrg 189 1.1 mrg template<typename _U1, typename _U2> 190 1.1 mrg tuple(const pair<_U1, _U2>& __in) 191 1.1 mrg : _Inherited(_Tuple_impl<0, 192 1.1 mrg typename __add_c_ref<_U1>::type, 193 1.1 mrg typename __add_c_ref<_U2>::type>(__in.first, 194 1.1 mrg __in.second)) 195 1.1 mrg { } 196 1.1 mrg 197 1.1 mrg template<typename _U1, typename _U2> 198 1.1 mrg tuple& 199 1.1 mrg operator=(const tuple<_U1, _U2>& __in) 200 1.1 mrg { 201 1.1 mrg static_cast<_Inherited&>(*this) = __in; 202 1.1 mrg return *this; 203 1.1 mrg } 204 1.1 mrg 205 1.1 mrg tuple& 206 1.1 mrg operator=(const tuple& __in) 207 1.1 mrg { 208 1.1 mrg static_cast<_Inherited&>(*this) = __in; 209 1.1 mrg return *this; 210 1.1 mrg } 211 1.1 mrg 212 1.1 mrg template<typename _U1, typename _U2> 213 1.1 mrg tuple& 214 1.1 mrg operator=(const pair<_U1, _U2>& __in) 215 1.1 mrg { 216 1.1 mrg this->_M_head = __in.first; 217 1.1 mrg this->_M_tail()._M_head = __in.second; 218 1.1 mrg return *this; 219 1.1 mrg } 220 1.1 mrg }; 221 1.1 mrg 222 1.1 mrg 223 1.1 mrg /// Gives the type of the ith element of a given tuple type. 224 1.1 mrg template<int __i, typename _Tp> 225 1.1 mrg struct tuple_element; 226 1.1 mrg 227 1.1 mrg /** 228 1.1 mrg * Recursive case for tuple_element: strip off the first element in 229 1.1 mrg * the tuple and retrieve the (i-1)th element of the remaining tuple. 230 1.1 mrg */ 231 1.1 mrg template<int __i, typename _Head, typename... _Tail> 232 1.1 mrg struct tuple_element<__i, tuple<_Head, _Tail...> > 233 1.1 mrg : tuple_element<__i - 1, tuple<_Tail...> > { }; 234 1.1 mrg 235 1.1 mrg /** 236 1.1 mrg * Basis case for tuple_element: The first element is the one we're seeking. 237 1.1 mrg */ 238 1.1 mrg template<typename _Head, typename... _Tail> 239 1.1 mrg struct tuple_element<0, tuple<_Head, _Tail...> > 240 1.1 mrg { 241 1.1 mrg typedef _Head type; 242 1.1 mrg }; 243 1.1 mrg 244 1.1 mrg /// Finds the size of a given tuple type. 245 1.1 mrg template<typename _Tp> 246 1.1 mrg struct tuple_size; 247 1.1 mrg 248 1.1 mrg /// class tuple_size 249 1.1 mrg template<typename... _Elements> 250 1.1 mrg struct tuple_size<tuple<_Elements...> > 251 1.1 mrg { 252 1.1 mrg static const int value = sizeof...(_Elements); 253 1.1 mrg }; 254 1.1 mrg 255 1.1 mrg template<typename... _Elements> 256 1.1 mrg const int tuple_size<tuple<_Elements...> >::value; 257 1.1 mrg 258 1.1 mrg template<int __i, typename _Head, typename... _Tail> 259 1.1 mrg inline typename __add_ref<_Head>::type 260 1.1 mrg __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) 261 1.1 mrg { 262 1.1 mrg return __t._M_head; 263 1.1 mrg } 264 1.1 mrg 265 1.1 mrg template<int __i, typename _Head, typename... _Tail> 266 1.1 mrg inline typename __add_c_ref<_Head>::type 267 1.1 mrg __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) 268 1.1 mrg { 269 1.1 mrg return __t._M_head; 270 1.1 mrg } 271 1.1 mrg 272 1.1 mrg // Return a reference (const reference) to the ith element of a tuple. 273 1.1 mrg // Any const or non-const ref elements are returned with their original type. 274 1.1 mrg template<int __i, typename... _Elements> 275 1.1 mrg inline typename __add_ref< 276 1.1 mrg typename tuple_element<__i, tuple<_Elements...> >::type 277 1.1 mrg >::type 278 1.1 mrg get(tuple<_Elements...>& __t) 279 1.1 mrg { 280 1.1 mrg return __get_helper<__i>(__t); 281 1.1 mrg } 282 1.1 mrg 283 1.1 mrg template<int __i, typename... _Elements> 284 1.1 mrg inline typename __add_c_ref< 285 1.1 mrg typename tuple_element<__i, tuple<_Elements...> >::type 286 1.1 mrg >::type 287 1.1 mrg get(const tuple<_Elements...>& __t) 288 1.1 mrg { 289 1.1 mrg return __get_helper<__i>(__t); 290 1.1 mrg } 291 1.1 mrg 292 1.1 mrg // This class helps construct the various comparison operations on tuples 293 1.1 mrg template<int __check_equal_size, int __i, int __j, 294 1.1 mrg typename _Tp, typename _Up> 295 1.1 mrg struct __tuple_compare; 296 1.1 mrg 297 1.1 mrg template<int __i, int __j, typename _Tp, typename _Up> 298 1.1 mrg struct __tuple_compare<0, __i, __j, _Tp, _Up> 299 1.1 mrg { 300 1.1 mrg static bool __eq(const _Tp& __t, const _Up& __u) 301 1.1 mrg { 302 1.1 mrg return (get<__i>(__t) == get<__i>(__u) && 303 1.1 mrg __tuple_compare<0, __i+1, __j, _Tp, _Up>::__eq(__t, __u)); 304 1.1 mrg } 305 1.1 mrg 306 1.1 mrg static bool __less(const _Tp& __t, const _Up& __u) 307 1.1 mrg { 308 1.1 mrg return ((get<__i>(__t) < get<__i>(__u)) 309 1.1 mrg || !(get<__i>(__u) < get<__i>(__t)) && 310 1.1 mrg __tuple_compare<0, __i+1, __j, _Tp, _Up>::__less(__t, __u)); 311 1.1 mrg } 312 1.1 mrg }; 313 1.1 mrg 314 1.1 mrg template<int __i, typename _Tp, typename _Up> 315 1.1 mrg struct __tuple_compare<0, __i, __i, _Tp, _Up> 316 1.1 mrg { 317 1.1 mrg static bool __eq(const _Tp&, const _Up&) 318 1.1 mrg { return true; } 319 1.1 mrg 320 1.1 mrg static bool __less(const _Tp&, const _Up&) 321 1.1 mrg { return false; } 322 1.1 mrg }; 323 1.1 mrg 324 1.1 mrg template<typename... _TElements, typename... _UElements> 325 1.1 mrg bool 326 1.1 mrg operator==(const tuple<_TElements...>& __t, 327 1.1 mrg const tuple<_UElements...>& __u) 328 1.1 mrg { 329 1.1 mrg typedef tuple<_TElements...> _Tp; 330 1.1 mrg typedef tuple<_UElements...> _Up; 331 1.1 mrg return (__tuple_compare<tuple_size<_Tp>::value - tuple_size<_Up>::value, 332 1.1 mrg 0, tuple_size<_Tp>::value, _Tp, _Up>::__eq(__t, __u)); 333 1.1 mrg } 334 1.1 mrg 335 1.1 mrg template<typename... _TElements, typename... _UElements> 336 1.1 mrg bool 337 1.1 mrg operator<(const tuple<_TElements...>& __t, 338 1.1 mrg const tuple<_UElements...>& __u) 339 1.1 mrg { 340 1.1 mrg typedef tuple<_TElements...> _Tp; 341 1.1 mrg typedef tuple<_UElements...> _Up; 342 1.1 mrg return (__tuple_compare<tuple_size<_Tp>::value - tuple_size<_Up>::value, 343 1.1 mrg 0, tuple_size<_Tp>::value, _Tp, _Up>::__less(__t, __u)); 344 1.1 mrg } 345 1.1 mrg 346 1.1 mrg template<typename... _TElements, typename... _UElements> 347 1.1 mrg inline bool 348 1.1 mrg operator!=(const tuple<_TElements...>& __t, 349 1.1 mrg const tuple<_UElements...>& __u) 350 1.1 mrg { return !(__t == __u); } 351 1.1 mrg 352 1.1 mrg template<typename... _TElements, typename... _UElements> 353 1.1 mrg inline bool 354 1.1 mrg operator>(const tuple<_TElements...>& __t, 355 1.1 mrg const tuple<_UElements...>& __u) 356 1.1 mrg { return __u < __t; } 357 1.1 mrg 358 1.1 mrg template<typename... _TElements, typename... _UElements> 359 1.1 mrg inline bool 360 1.1 mrg operator<=(const tuple<_TElements...>& __t, 361 1.1 mrg const tuple<_UElements...>& __u) 362 1.1 mrg { return !(__u < __t); } 363 1.1 mrg 364 1.1 mrg template<typename... _TElements, typename... _UElements> 365 1.1 mrg inline bool 366 1.1 mrg operator>=(const tuple<_TElements...>& __t, 367 1.1 mrg const tuple<_UElements...>& __u) 368 1.1 mrg { return !(__t < __u); } 369 1.1 mrg 370 1.1 mrg template<typename _Tp> 371 1.1 mrg class reference_wrapper; 372 1.1 mrg 373 1.1 mrg // Helper which adds a reference to a type when given a reference_wrapper 374 1.1 mrg template<typename _Tp> 375 1.1 mrg struct __strip_reference_wrapper 376 1.1 mrg { 377 1.1 mrg typedef _Tp __type; 378 1.1 mrg }; 379 1.1 mrg 380 1.1 mrg template<typename _Tp> 381 1.1 mrg struct __strip_reference_wrapper<reference_wrapper<_Tp> > 382 1.1 mrg { 383 1.1 mrg typedef _Tp& __type; 384 1.1 mrg }; 385 1.1 mrg 386 1.1 mrg template<typename _Tp> 387 1.1 mrg struct __strip_reference_wrapper<const reference_wrapper<_Tp> > 388 1.1 mrg { 389 1.1 mrg typedef _Tp& __type; 390 1.1 mrg }; 391 1.1 mrg 392 1.1 mrg template<typename... _Elements> 393 1.1 mrg inline tuple<typename __strip_reference_wrapper<_Elements>::__type...> 394 1.1 mrg make_tuple(_Elements... __args) 395 1.1 mrg { 396 1.1 mrg typedef tuple<typename __strip_reference_wrapper<_Elements>::__type...> 397 1.1 mrg __result_type; 398 1.1 mrg return __result_type(__args...); 399 1.1 mrg } 400 1.1 mrg 401 1.1 mrg template<typename... _Elements> 402 1.1 mrg inline tuple<_Elements&...> 403 1.1 mrg tie(_Elements&... __args) 404 1.1 mrg { 405 1.1 mrg return tuple<_Elements&...>(__args...); 406 1.1 mrg } 407 1.1 mrg 408 1.1 mrg // A class (and instance) which can be used in 'tie' when an element 409 1.1 mrg // of a tuple is not required 410 1.1 mrg struct _Swallow_assign 411 1.1 mrg { 412 1.1 mrg template<class _Tp> 413 1.1 mrg _Swallow_assign& 414 1.1 mrg operator=(const _Tp&) 415 1.1 mrg { return *this; } 416 1.1 mrg }; 417 1.1 mrg 418 1.1 mrg // TODO: Put this in some kind of shared file. 419 1.1 mrg namespace 420 1.1 mrg { 421 1.1 mrg _Swallow_assign ignore; 422 1.1.1.12 mrg } // anonymous namespace 423 1.1.1.8 mrg } 424 1.1.1.2 mrg 425 1.1.1.2 mrg _GLIBCXX_END_NAMESPACE_VERSION 426 1.1 mrg } 427 1.1 mrg 428 1.1 mrg #endif // _GLIBCXX_TR1_TUPLE 429