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