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