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