utility revision 227983
1// -*- C++ -*- 2//===-------------------------- utility -----------------------------------===// 3// 4// The LLVM Compiler Infrastructure 5// 6// This file is dual licensed under the MIT and the University of Illinois Open 7// Source Licenses. See LICENSE.TXT for details. 8// 9//===----------------------------------------------------------------------===// 10 11#ifndef _LIBCPP_UTILITY 12#define _LIBCPP_UTILITY 13 14/* 15 utility synopsis 16 17namespace std 18{ 19 20template <class T> 21 void 22 swap(T& a, T& b); 23 24namespace rel_ops 25{ 26 template<class T> bool operator!=(const T&, const T&); 27 template<class T> bool operator> (const T&, const T&); 28 template<class T> bool operator<=(const T&, const T&); 29 template<class T> bool operator>=(const T&, const T&); 30} 31 32template<class T> 33void 34swap(T& a, T& b) noexcept(is_nothrow_move_constructible<T>::value && 35 is_nothrow_move_assignable<T>::value); 36 37template <class T, size_t N> 38void 39swap(T (&a)[N], T (&b)[N]) noexcept(noexcept(swap(*a, *b))); 40 41template <class T> T&& forward(typename remove_reference<T>::type& t) noexcept; 42template <class T> T&& forward(typename remove_reference<T>::type&& t) noexcept; 43 44template <class T> typename remove_reference<T>::type&& move(T&&) noexcept; 45 46template <class T> 47 typename conditional 48 < 49 !is_nothrow_move_constructible<T>::value && is_copy_constructible<T>::value, 50 const T&, 51 T&& 52 >::type 53 move_if_noexcept(T& x) noexcept; 54 55template <class T> typename add_rvalue_reference<T>::type declval() noexcept; 56 57template <class T1, class T2> 58struct pair 59{ 60 typedef T1 first_type; 61 typedef T2 second_type; 62 63 T1 first; 64 T2 second; 65 66 pair(const pair&) = default; 67 pair(pair&&) = default; 68 constexpr pair(); 69 pair(const T1& x, const T2& y); 70 template <class U, class V> pair(U&& x, V&& y); 71 template <class U, class V> pair(const pair<U, V>& p); 72 template <class U, class V> pair(pair<U, V>&& p); 73 template <class... Args1, class... Args2> 74 pair(piecewise_construct_t, tuple<Args1...> first_args, 75 tuple<Args2...> second_args); 76 77 template <class U, class V> pair& operator=(const pair<U, V>& p); 78 pair& operator=(pair&& p) noexcept(is_nothrow_move_assignable<T1>::value && 79 is_nothrow_move_assignable<T2>::value); 80 template <class U, class V> pair& operator=(pair<U, V>&& p); 81 82 void swap(pair& p) noexcept(noexcept(swap(first, p.first)) && 83 noexcept(swap(second, p.second))); 84}; 85 86template <class T1, class T2> bool operator==(const pair<T1,T2>&, const pair<T1,T2>&); 87template <class T1, class T2> bool operator!=(const pair<T1,T2>&, const pair<T1,T2>&); 88template <class T1, class T2> bool operator< (const pair<T1,T2>&, const pair<T1,T2>&); 89template <class T1, class T2> bool operator> (const pair<T1,T2>&, const pair<T1,T2>&); 90template <class T1, class T2> bool operator>=(const pair<T1,T2>&, const pair<T1,T2>&); 91template <class T1, class T2> bool operator<=(const pair<T1,T2>&, const pair<T1,T2>&); 92 93template <class T1, class T2> pair<V1, V2> make_pair(T1&&, T2&&); 94template <class T1, class T2> 95void 96swap(pair<T1, T2>& x, pair<T1, T2>& y) noexcept(noexcept(x.swap(y))); 97 98struct piecewise_construct_t { }; 99constexpr piecewise_construct_t piecewise_construct = piecewise_construct_t(); 100 101template <class T> class tuple_size; 102template <size_t I, class T> class tuple_element; 103 104template <class T1, class T2> struct tuple_size<std::pair<T1, T2> >; 105template <class T1, class T2> struct tuple_element<0, std::pair<T1, T2> >; 106template <class T1, class T2> struct tuple_element<1, std::pair<T1, T2> >; 107 108template<size_t I, class T1, class T2> 109 typename tuple_element<I, std::pair<T1, T2> >::type& 110 get(std::pair<T1, T2>&) noexcept; 111 112template<size_t I, class T1, class T2> 113 const typename const tuple_element<I, std::pair<T1, T2> >::type& 114 get(const std::pair<T1, T2>&) noexcept; 115 116template<size_t I, class T1, class T2> 117 typename tuple_element<I, std::pair<T1, T2> >::type&& 118 get(std::pair<T1, T2>&&) noexcept; 119 120} // std 121 122*/ 123 124#include <__config> 125#include <__tuple> 126#include <type_traits> 127 128#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 129#pragma GCC system_header 130#endif 131 132_LIBCPP_BEGIN_NAMESPACE_STD 133 134namespace rel_ops 135{ 136 137template<class _Tp> 138inline _LIBCPP_INLINE_VISIBILITY 139bool 140operator!=(const _Tp& __x, const _Tp& __y) 141{ 142 return !(__x == __y); 143} 144 145template<class _Tp> 146inline _LIBCPP_INLINE_VISIBILITY 147bool 148operator> (const _Tp& __x, const _Tp& __y) 149{ 150 return __y < __x; 151} 152 153template<class _Tp> 154inline _LIBCPP_INLINE_VISIBILITY 155bool 156operator<=(const _Tp& __x, const _Tp& __y) 157{ 158 return !(__y < __x); 159} 160 161template<class _Tp> 162inline _LIBCPP_INLINE_VISIBILITY 163bool 164operator>=(const _Tp& __x, const _Tp& __y) 165{ 166 return !(__x < __y); 167} 168 169} // rel_ops 170 171// swap_ranges 172 173template <class _ForwardIterator1, class _ForwardIterator2> 174inline _LIBCPP_INLINE_VISIBILITY 175_ForwardIterator2 176swap_ranges(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2) 177{ 178 for(; __first1 != __last1; ++__first1, ++__first2) 179 swap(*__first1, *__first2); 180 return __first2; 181} 182 183template<class _Tp, size_t _N> 184inline _LIBCPP_INLINE_VISIBILITY 185void 186swap(_Tp (&__a)[_N], _Tp (&__b)[_N]) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value) 187{ 188 _VSTD::swap_ranges(__a, __a + _N, __b); 189} 190 191template <class _Tp> 192inline _LIBCPP_INLINE_VISIBILITY 193#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 194typename conditional 195< 196 !is_nothrow_move_constructible<_Tp>::value && is_copy_constructible<_Tp>::value, 197 const _Tp&, 198 _Tp&& 199>::type 200#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES 201const _Tp& 202#endif 203move_if_noexcept(_Tp& __x) _NOEXCEPT 204{ 205 return _VSTD::move(__x); 206} 207 208struct _LIBCPP_VISIBLE piecewise_construct_t { }; 209//constexpr 210extern const piecewise_construct_t piecewise_construct;// = piecewise_construct_t(); 211 212template <class _T1, class _T2> 213struct _LIBCPP_VISIBLE pair 214{ 215 typedef _T1 first_type; 216 typedef _T2 second_type; 217 218 _T1 first; 219 _T2 second; 220 221 // pair(const pair&) = default; 222 // pair(pair&&) = default; 223 224 _LIBCPP_INLINE_VISIBILITY pair() : first(), second() {} 225 226 _LIBCPP_INLINE_VISIBILITY pair(const _T1& __x, const _T2& __y) 227 : first(__x), second(__y) {} 228 229 template<class _U1, class _U2> 230 _LIBCPP_INLINE_VISIBILITY 231 pair(const pair<_U1, _U2>& __p 232#ifndef _LIBCPP_HAS_NO_ADVANCED_SFINAE 233 ,typename enable_if<is_constructible<_T1, _U1>::value && 234 is_constructible<_T2, _U2>::value>::type* = 0 235#endif 236 ) 237 : first(__p.first), second(__p.second) {} 238 239 _LIBCPP_INLINE_VISIBILITY 240 pair(const pair& __p) 241 _NOEXCEPT_(is_nothrow_copy_constructible<first_type>::value && 242 is_nothrow_copy_constructible<second_type>::value) 243 : first(__p.first), 244 second(__p.second) 245 { 246 } 247 248 _LIBCPP_INLINE_VISIBILITY 249 pair& operator=(const pair& __p) 250 _NOEXCEPT_(is_nothrow_copy_assignable<first_type>::value && 251 is_nothrow_copy_assignable<second_type>::value) 252 { 253 first = __p.first; 254 second = __p.second; 255 return *this; 256 } 257 258#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 259 260 template <class _U1, class _U2, 261 class = typename enable_if<is_constructible<first_type, _U1 >::value && 262 is_constructible<second_type, _U2>::value>::type> 263 _LIBCPP_INLINE_VISIBILITY 264 pair(_U1&& __u1, _U2&& __u2) 265 : first(_VSTD::forward<_U1>(__u1)), 266 second(_VSTD::forward<_U2>(__u2)) 267 {} 268 269 template<class _U1, class _U2> 270 _LIBCPP_INLINE_VISIBILITY 271 pair(pair<_U1, _U2>&& __p, 272 typename enable_if<is_constructible<_T1, _U1>::value && 273 is_constructible<_T2, _U2>::value>::type* = 0) 274 : first(_VSTD::forward<_U1>(__p.first)), 275 second(_VSTD::forward<_U2>(__p.second)) {} 276 277 _LIBCPP_INLINE_VISIBILITY 278 pair(pair&& __p) _NOEXCEPT_(is_nothrow_move_constructible<first_type>::value && 279 is_nothrow_move_constructible<second_type>::value) 280 : first(_VSTD::forward<first_type>(__p.first)), 281 second(_VSTD::forward<second_type>(__p.second)) 282 { 283 } 284 285 _LIBCPP_INLINE_VISIBILITY 286 pair& 287 operator=(pair&& __p) _NOEXCEPT_(is_nothrow_move_assignable<first_type>::value && 288 is_nothrow_move_assignable<second_type>::value) 289 { 290 first = _VSTD::forward<first_type>(__p.first); 291 second = _VSTD::forward<second_type>(__p.second); 292 return *this; 293 } 294 295#ifndef _LIBCPP_HAS_NO_VARIADICS 296 297 template<class _Tuple, 298 class = typename enable_if<__tuple_convertible<_Tuple, pair>::value>::type> 299 _LIBCPP_INLINE_VISIBILITY 300 pair(_Tuple&& __p) 301 : first(_VSTD::forward<typename tuple_element<0, 302 typename __make_tuple_types<_Tuple>::type>::type>(get<0>(__p))), 303 second(_VSTD::forward<typename tuple_element<1, 304 typename __make_tuple_types<_Tuple>::type>::type>(get<1>(__p))) 305 {} 306 307 308 309 template <class... _Args1, class... _Args2, size_t... _I1, size_t... _I2> 310 _LIBCPP_INLINE_VISIBILITY 311 pair(piecewise_construct_t __pc, tuple<_Args1...> __first_args, 312 tuple<_Args2...> __second_args) 313 : pair(__pc, __first_args, __second_args, 314 typename __make_tuple_indices<sizeof...(_Args1)>::type(), 315 typename __make_tuple_indices<sizeof...(_Args2) >::type()) 316 {} 317 318 template <class _Tuple, 319 class = typename enable_if<__tuple_assignable<_Tuple, pair>::value>::type> 320 _LIBCPP_INLINE_VISIBILITY 321 pair& 322 operator=(_Tuple&& __p) 323 { 324 typedef typename __make_tuple_types<_Tuple>::type _TupleRef; 325 typedef typename tuple_element<0, _TupleRef>::type _U0; 326 typedef typename tuple_element<1, _TupleRef>::type _U1; 327 first = _VSTD::forward<_U0>(_VSTD::get<0>(__p)); 328 second = _VSTD::forward<_U1>(_VSTD::get<1>(__p)); 329 return *this; 330 } 331 332#endif // _LIBCPP_HAS_NO_VARIADICS 333 334#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 335 _LIBCPP_INLINE_VISIBILITY 336 void 337 swap(pair& __p) _NOEXCEPT_(__is_nothrow_swappable<first_type>::value && 338 __is_nothrow_swappable<second_type>::value) 339 { 340 _VSTD::iter_swap(&first, &__p.first); 341 _VSTD::iter_swap(&second, &__p.second); 342 } 343private: 344 345#ifndef _LIBCPP_HAS_NO_VARIADICS 346 template <class... _Args1, class... _Args2, size_t... _I1, size_t... _I2> 347 _LIBCPP_INLINE_VISIBILITY 348 pair(piecewise_construct_t, 349 tuple<_Args1...>& __first_args, tuple<_Args2...>& __second_args, 350 __tuple_indices<_I1...>, __tuple_indices<_I2...>); 351#endif // _LIBCPP_HAS_NO_VARIADICS 352}; 353 354template <class _T1, class _T2> 355inline _LIBCPP_INLINE_VISIBILITY 356bool 357operator==(const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y) 358{ 359 return __x.first == __y.first && __x.second == __y.second; 360} 361 362template <class _T1, class _T2> 363inline _LIBCPP_INLINE_VISIBILITY 364bool 365operator!=(const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y) 366{ 367 return !(__x == __y); 368} 369 370template <class _T1, class _T2> 371inline _LIBCPP_INLINE_VISIBILITY 372bool 373operator< (const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y) 374{ 375 return __x.first < __y.first || (!(__y.first < __x.first) && __x.second < __y.second); 376} 377 378template <class _T1, class _T2> 379inline _LIBCPP_INLINE_VISIBILITY 380bool 381operator> (const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y) 382{ 383 return __y < __x; 384} 385 386template <class _T1, class _T2> 387inline _LIBCPP_INLINE_VISIBILITY 388bool 389operator>=(const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y) 390{ 391 return !(__x < __y); 392} 393 394template <class _T1, class _T2> 395inline _LIBCPP_INLINE_VISIBILITY 396bool 397operator<=(const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y) 398{ 399 return !(__y < __x); 400} 401 402template <class _T1, class _T2> 403inline _LIBCPP_INLINE_VISIBILITY 404typename enable_if 405< 406 __is_swappable<_T1>::value && 407 __is_swappable<_T2>::value, 408 void 409>::type 410swap(pair<_T1, _T2>& __x, pair<_T1, _T2>& __y) 411 _NOEXCEPT_((__is_nothrow_swappable<_T1>::value && 412 __is_nothrow_swappable<_T2>::value)) 413{ 414 __x.swap(__y); 415} 416 417#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 418 419template <class _Tp> class reference_wrapper; 420 421template <class _Tp> 422struct ___make_pair_return 423{ 424 typedef _Tp type; 425}; 426 427template <class _Tp> 428struct ___make_pair_return<reference_wrapper<_Tp>> 429{ 430 typedef _Tp& type; 431}; 432 433template <class _Tp> 434struct __make_pair_return 435{ 436 typedef typename ___make_pair_return<typename decay<_Tp>::type>::type type; 437}; 438 439template <class _T1, class _T2> 440inline _LIBCPP_INLINE_VISIBILITY 441pair<typename __make_pair_return<_T1>::type, typename __make_pair_return<_T2>::type> 442make_pair(_T1&& __t1, _T2&& __t2) 443{ 444 return pair<typename __make_pair_return<_T1>::type, typename __make_pair_return<_T2>::type> 445 (_VSTD::forward<_T1>(__t1), _VSTD::forward<_T2>(__t2)); 446} 447 448#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES 449 450template <class _T1, class _T2> 451inline _LIBCPP_INLINE_VISIBILITY 452pair<_T1,_T2> 453make_pair(_T1 __x, _T2 __y) 454{ 455 return pair<_T1, _T2>(__x, __y); 456} 457 458#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 459 460#ifndef _LIBCPP_HAS_NO_VARIADICS 461 462template <class _T1, class _T2> 463 class _LIBCPP_VISIBLE tuple_size<pair<_T1, _T2> > 464 : public integral_constant<size_t, 2> {}; 465 466template <class _T1, class _T2> 467 class _LIBCPP_VISIBLE tuple_size<const pair<_T1, _T2> > 468 : public integral_constant<size_t, 2> {}; 469 470template <class _T1, class _T2> 471class _LIBCPP_VISIBLE tuple_element<0, pair<_T1, _T2> > 472{ 473public: 474 typedef _T1 type; 475}; 476 477template <class _T1, class _T2> 478class _LIBCPP_VISIBLE tuple_element<1, pair<_T1, _T2> > 479{ 480public: 481 typedef _T2 type; 482}; 483 484template <class _T1, class _T2> 485class _LIBCPP_VISIBLE tuple_element<0, const pair<_T1, _T2> > 486{ 487public: 488 typedef const _T1 type; 489}; 490 491template <class _T1, class _T2> 492class _LIBCPP_VISIBLE tuple_element<1, const pair<_T1, _T2> > 493{ 494public: 495 typedef const _T2 type; 496}; 497 498template <size_t _Ip> struct __get_pair; 499 500template <> 501struct __get_pair<0> 502{ 503 template <class _T1, class _T2> 504 static 505 _LIBCPP_INLINE_VISIBILITY 506 _T1& 507 get(pair<_T1, _T2>& __p) _NOEXCEPT {return __p.first;} 508 509 template <class _T1, class _T2> 510 static 511 _LIBCPP_INLINE_VISIBILITY 512 const _T1& 513 get(const pair<_T1, _T2>& __p) _NOEXCEPT {return __p.first;} 514 515#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 516 517 template <class _T1, class _T2> 518 static 519 _LIBCPP_INLINE_VISIBILITY 520 _T1&& 521 get(pair<_T1, _T2>&& __p) _NOEXCEPT {return _VSTD::forward<_T1>(__p.first);} 522 523#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 524}; 525 526template <> 527struct __get_pair<1> 528{ 529 template <class _T1, class _T2> 530 static 531 _LIBCPP_INLINE_VISIBILITY 532 _T2& 533 get(pair<_T1, _T2>& __p) _NOEXCEPT {return __p.second;} 534 535 template <class _T1, class _T2> 536 static 537 _LIBCPP_INLINE_VISIBILITY 538 const _T2& 539 get(const pair<_T1, _T2>& __p) _NOEXCEPT {return __p.second;} 540 541#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 542 543 template <class _T1, class _T2> 544 static 545 _LIBCPP_INLINE_VISIBILITY 546 _T2&& 547 get(pair<_T1, _T2>&& __p) _NOEXCEPT {return _VSTD::forward<_T2>(__p.second);} 548 549#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 550}; 551 552template <size_t _Ip, class _T1, class _T2> 553_LIBCPP_INLINE_VISIBILITY inline 554typename tuple_element<_Ip, pair<_T1, _T2> >::type& 555get(pair<_T1, _T2>& __p) _NOEXCEPT 556{ 557 return __get_pair<_Ip>::get(__p); 558} 559 560template <size_t _Ip, class _T1, class _T2> 561_LIBCPP_INLINE_VISIBILITY inline 562const typename tuple_element<_Ip, pair<_T1, _T2> >::type& 563get(const pair<_T1, _T2>& __p) _NOEXCEPT 564{ 565 return __get_pair<_Ip>::get(__p); 566} 567 568#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 569 570template <size_t _Ip, class _T1, class _T2> 571_LIBCPP_INLINE_VISIBILITY inline 572typename tuple_element<_Ip, pair<_T1, _T2> >::type&& 573get(pair<_T1, _T2>&& __p) _NOEXCEPT 574{ 575 return __get_pair<_Ip>::get(_VSTD::move(__p)); 576} 577 578#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 579 580#endif // _LIBCPP_HAS_NO_VARIADICS 581 582_LIBCPP_END_NAMESPACE_STD 583 584#endif // _LIBCPP_UTILITY 585