1// -*- C++ -*- 2//===----------------------------------------------------------------------===// 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_FUNCTIONAL_BASE 12#define _LIBCPP_FUNCTIONAL_BASE 13 14#include <__config> 15#include <type_traits> 16#include <typeinfo> 17#include <exception> 18#include <new> 19 20#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 21#pragma GCC system_header 22#endif 23 24_LIBCPP_BEGIN_NAMESPACE_STD 25 26template <class _Arg, class _Result> 27struct _LIBCPP_TEMPLATE_VIS unary_function 28{ 29 typedef _Arg argument_type; 30 typedef _Result result_type; 31}; 32 33template <class _Arg1, class _Arg2, class _Result> 34struct _LIBCPP_TEMPLATE_VIS binary_function 35{ 36 typedef _Arg1 first_argument_type; 37 typedef _Arg2 second_argument_type; 38 typedef _Result result_type; 39}; 40 41template <class _Tp> 42struct __has_result_type 43{ 44private: 45 struct __two {char __lx; char __lxx;}; 46 template <class _Up> static __two __test(...); 47 template <class _Up> static char __test(typename _Up::result_type* = 0); 48public: 49 static const bool value = sizeof(__test<_Tp>(0)) == 1; 50}; 51 52#if _LIBCPP_STD_VER > 11 53template <class _Tp = void> 54#else 55template <class _Tp> 56#endif 57struct _LIBCPP_TEMPLATE_VIS less : binary_function<_Tp, _Tp, bool> 58{ 59 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 60 bool operator()(const _Tp& __x, const _Tp& __y) const 61 {return __x < __y;} 62}; 63 64#if _LIBCPP_STD_VER > 11 65template <> 66struct _LIBCPP_TEMPLATE_VIS less<void> 67{ 68 template <class _T1, class _T2> 69 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 70 auto operator()(_T1&& __t, _T2&& __u) const 71 _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) < _VSTD::forward<_T2>(__u))) 72 -> decltype (_VSTD::forward<_T1>(__t) < _VSTD::forward<_T2>(__u)) 73 { return _VSTD::forward<_T1>(__t) < _VSTD::forward<_T2>(__u); } 74 typedef void is_transparent; 75}; 76#endif 77 78// __weak_result_type 79 80template <class _Tp> 81struct __derives_from_unary_function 82{ 83private: 84 struct __two {char __lx; char __lxx;}; 85 static __two __test(...); 86 template <class _Ap, class _Rp> 87 static unary_function<_Ap, _Rp> 88 __test(const volatile unary_function<_Ap, _Rp>*); 89public: 90 static const bool value = !is_same<decltype(__test((_Tp*)0)), __two>::value; 91 typedef decltype(__test((_Tp*)0)) type; 92}; 93 94template <class _Tp> 95struct __derives_from_binary_function 96{ 97private: 98 struct __two {char __lx; char __lxx;}; 99 static __two __test(...); 100 template <class _A1, class _A2, class _Rp> 101 static binary_function<_A1, _A2, _Rp> 102 __test(const volatile binary_function<_A1, _A2, _Rp>*); 103public: 104 static const bool value = !is_same<decltype(__test((_Tp*)0)), __two>::value; 105 typedef decltype(__test((_Tp*)0)) type; 106}; 107 108template <class _Tp, bool = __derives_from_unary_function<_Tp>::value> 109struct __maybe_derive_from_unary_function // bool is true 110 : public __derives_from_unary_function<_Tp>::type 111{ 112}; 113 114template <class _Tp> 115struct __maybe_derive_from_unary_function<_Tp, false> 116{ 117}; 118 119template <class _Tp, bool = __derives_from_binary_function<_Tp>::value> 120struct __maybe_derive_from_binary_function // bool is true 121 : public __derives_from_binary_function<_Tp>::type 122{ 123}; 124 125template <class _Tp> 126struct __maybe_derive_from_binary_function<_Tp, false> 127{ 128}; 129 130template <class _Tp, bool = __has_result_type<_Tp>::value> 131struct __weak_result_type_imp // bool is true 132 : public __maybe_derive_from_unary_function<_Tp>, 133 public __maybe_derive_from_binary_function<_Tp> 134{ 135 typedef typename _Tp::result_type result_type; 136}; 137 138template <class _Tp> 139struct __weak_result_type_imp<_Tp, false> 140 : public __maybe_derive_from_unary_function<_Tp>, 141 public __maybe_derive_from_binary_function<_Tp> 142{ 143}; 144 145template <class _Tp> 146struct __weak_result_type 147 : public __weak_result_type_imp<_Tp> 148{ 149}; 150 151// 0 argument case 152 153template <class _Rp> 154struct __weak_result_type<_Rp ()> 155{ 156 typedef _Rp result_type; 157}; 158 159template <class _Rp> 160struct __weak_result_type<_Rp (&)()> 161{ 162 typedef _Rp result_type; 163}; 164 165template <class _Rp> 166struct __weak_result_type<_Rp (*)()> 167{ 168 typedef _Rp result_type; 169}; 170 171// 1 argument case 172 173template <class _Rp, class _A1> 174struct __weak_result_type<_Rp (_A1)> 175 : public unary_function<_A1, _Rp> 176{ 177}; 178 179template <class _Rp, class _A1> 180struct __weak_result_type<_Rp (&)(_A1)> 181 : public unary_function<_A1, _Rp> 182{ 183}; 184 185template <class _Rp, class _A1> 186struct __weak_result_type<_Rp (*)(_A1)> 187 : public unary_function<_A1, _Rp> 188{ 189}; 190 191template <class _Rp, class _Cp> 192struct __weak_result_type<_Rp (_Cp::*)()> 193 : public unary_function<_Cp*, _Rp> 194{ 195}; 196 197template <class _Rp, class _Cp> 198struct __weak_result_type<_Rp (_Cp::*)() const> 199 : public unary_function<const _Cp*, _Rp> 200{ 201}; 202 203template <class _Rp, class _Cp> 204struct __weak_result_type<_Rp (_Cp::*)() volatile> 205 : public unary_function<volatile _Cp*, _Rp> 206{ 207}; 208 209template <class _Rp, class _Cp> 210struct __weak_result_type<_Rp (_Cp::*)() const volatile> 211 : public unary_function<const volatile _Cp*, _Rp> 212{ 213}; 214 215// 2 argument case 216 217template <class _Rp, class _A1, class _A2> 218struct __weak_result_type<_Rp (_A1, _A2)> 219 : public binary_function<_A1, _A2, _Rp> 220{ 221}; 222 223template <class _Rp, class _A1, class _A2> 224struct __weak_result_type<_Rp (*)(_A1, _A2)> 225 : public binary_function<_A1, _A2, _Rp> 226{ 227}; 228 229template <class _Rp, class _A1, class _A2> 230struct __weak_result_type<_Rp (&)(_A1, _A2)> 231 : public binary_function<_A1, _A2, _Rp> 232{ 233}; 234 235template <class _Rp, class _Cp, class _A1> 236struct __weak_result_type<_Rp (_Cp::*)(_A1)> 237 : public binary_function<_Cp*, _A1, _Rp> 238{ 239}; 240 241template <class _Rp, class _Cp, class _A1> 242struct __weak_result_type<_Rp (_Cp::*)(_A1) const> 243 : public binary_function<const _Cp*, _A1, _Rp> 244{ 245}; 246 247template <class _Rp, class _Cp, class _A1> 248struct __weak_result_type<_Rp (_Cp::*)(_A1) volatile> 249 : public binary_function<volatile _Cp*, _A1, _Rp> 250{ 251}; 252 253template <class _Rp, class _Cp, class _A1> 254struct __weak_result_type<_Rp (_Cp::*)(_A1) const volatile> 255 : public binary_function<const volatile _Cp*, _A1, _Rp> 256{ 257}; 258 259 260#ifndef _LIBCPP_HAS_NO_VARIADICS 261// 3 or more arguments 262 263template <class _Rp, class _A1, class _A2, class _A3, class ..._A4> 264struct __weak_result_type<_Rp (_A1, _A2, _A3, _A4...)> 265{ 266 typedef _Rp result_type; 267}; 268 269template <class _Rp, class _A1, class _A2, class _A3, class ..._A4> 270struct __weak_result_type<_Rp (&)(_A1, _A2, _A3, _A4...)> 271{ 272 typedef _Rp result_type; 273}; 274 275template <class _Rp, class _A1, class _A2, class _A3, class ..._A4> 276struct __weak_result_type<_Rp (*)(_A1, _A2, _A3, _A4...)> 277{ 278 typedef _Rp result_type; 279}; 280 281template <class _Rp, class _Cp, class _A1, class _A2, class ..._A3> 282struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...)> 283{ 284 typedef _Rp result_type; 285}; 286 287template <class _Rp, class _Cp, class _A1, class _A2, class ..._A3> 288struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) const> 289{ 290 typedef _Rp result_type; 291}; 292 293template <class _Rp, class _Cp, class _A1, class _A2, class ..._A3> 294struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) volatile> 295{ 296 typedef _Rp result_type; 297}; 298 299template <class _Rp, class _Cp, class _A1, class _A2, class ..._A3> 300struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) const volatile> 301{ 302 typedef _Rp result_type; 303}; 304 305#endif // _LIBCPP_HAS_NO_VARIADICS 306 307#ifndef _LIBCPP_CXX03_LANG 308 309template <class _Tp, class ..._Args> 310struct __invoke_return 311{ 312 typedef decltype(__invoke(_VSTD::declval<_Tp>(), _VSTD::declval<_Args>()...)) type; 313}; 314 315#else // defined(_LIBCPP_CXX03_LANG) 316 317#include <__functional_base_03> 318 319#endif // !defined(_LIBCPP_CXX03_LANG) 320 321 322template <class _Ret> 323struct __invoke_void_return_wrapper 324{ 325#ifndef _LIBCPP_HAS_NO_VARIADICS 326 template <class ..._Args> 327 static _Ret __call(_Args&&... __args) { 328 return __invoke(_VSTD::forward<_Args>(__args)...); 329 } 330#else 331 template <class _Fn> 332 static _Ret __call(_Fn __f) { 333 return __invoke(__f); 334 } 335 336 template <class _Fn, class _A0> 337 static _Ret __call(_Fn __f, _A0& __a0) { 338 return __invoke(__f, __a0); 339 } 340 341 template <class _Fn, class _A0, class _A1> 342 static _Ret __call(_Fn __f, _A0& __a0, _A1& __a1) { 343 return __invoke(__f, __a0, __a1); 344 } 345 346 template <class _Fn, class _A0, class _A1, class _A2> 347 static _Ret __call(_Fn __f, _A0& __a0, _A1& __a1, _A2& __a2){ 348 return __invoke(__f, __a0, __a1, __a2); 349 } 350#endif 351}; 352 353template <> 354struct __invoke_void_return_wrapper<void> 355{ 356#ifndef _LIBCPP_HAS_NO_VARIADICS 357 template <class ..._Args> 358 static void __call(_Args&&... __args) { 359 __invoke(_VSTD::forward<_Args>(__args)...); 360 } 361#else 362 template <class _Fn> 363 static void __call(_Fn __f) { 364 __invoke(__f); 365 } 366 367 template <class _Fn, class _A0> 368 static void __call(_Fn __f, _A0& __a0) { 369 __invoke(__f, __a0); 370 } 371 372 template <class _Fn, class _A0, class _A1> 373 static void __call(_Fn __f, _A0& __a0, _A1& __a1) { 374 __invoke(__f, __a0, __a1); 375 } 376 377 template <class _Fn, class _A0, class _A1, class _A2> 378 static void __call(_Fn __f, _A0& __a0, _A1& __a1, _A2& __a2) { 379 __invoke(__f, __a0, __a1, __a2); 380 } 381#endif 382}; 383 384template <class _Tp> 385class _LIBCPP_TEMPLATE_VIS reference_wrapper 386 : public __weak_result_type<_Tp> 387{ 388public: 389 // types 390 typedef _Tp type; 391private: 392 type* __f_; 393 394public: 395 // construct/copy/destroy 396 _LIBCPP_INLINE_VISIBILITY reference_wrapper(type& __f) _NOEXCEPT 397 : __f_(_VSTD::addressof(__f)) {} 398#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 399 private: reference_wrapper(type&&); public: // = delete; // do not bind to temps 400#endif 401 402 // access 403 _LIBCPP_INLINE_VISIBILITY operator type& () const _NOEXCEPT {return *__f_;} 404 _LIBCPP_INLINE_VISIBILITY type& get() const _NOEXCEPT {return *__f_;} 405 406#ifndef _LIBCPP_HAS_NO_VARIADICS 407 // invoke 408 template <class... _ArgTypes> 409 _LIBCPP_INLINE_VISIBILITY 410 typename __invoke_of<type&, _ArgTypes...>::type 411 operator() (_ArgTypes&&... __args) const { 412 return __invoke(get(), _VSTD::forward<_ArgTypes>(__args)...); 413 } 414#else 415 416 _LIBCPP_INLINE_VISIBILITY 417 typename __invoke_return<type>::type 418 operator() () const { 419 return __invoke(get()); 420 } 421 422 template <class _A0> 423 _LIBCPP_INLINE_VISIBILITY 424 typename __invoke_return0<type, _A0>::type 425 operator() (_A0& __a0) const { 426 return __invoke(get(), __a0); 427 } 428 429 template <class _A0> 430 _LIBCPP_INLINE_VISIBILITY 431 typename __invoke_return0<type, _A0 const>::type 432 operator() (_A0 const& __a0) const { 433 return __invoke(get(), __a0); 434 } 435 436 template <class _A0, class _A1> 437 _LIBCPP_INLINE_VISIBILITY 438 typename __invoke_return1<type, _A0, _A1>::type 439 operator() (_A0& __a0, _A1& __a1) const { 440 return __invoke(get(), __a0, __a1); 441 } 442 443 template <class _A0, class _A1> 444 _LIBCPP_INLINE_VISIBILITY 445 typename __invoke_return1<type, _A0 const, _A1>::type 446 operator() (_A0 const& __a0, _A1& __a1) const { 447 return __invoke(get(), __a0, __a1); 448 } 449 450 template <class _A0, class _A1> 451 _LIBCPP_INLINE_VISIBILITY 452 typename __invoke_return1<type, _A0, _A1 const>::type 453 operator() (_A0& __a0, _A1 const& __a1) const { 454 return __invoke(get(), __a0, __a1); 455 } 456 457 template <class _A0, class _A1> 458 _LIBCPP_INLINE_VISIBILITY 459 typename __invoke_return1<type, _A0 const, _A1 const>::type 460 operator() (_A0 const& __a0, _A1 const& __a1) const { 461 return __invoke(get(), __a0, __a1); 462 } 463 464 template <class _A0, class _A1, class _A2> 465 _LIBCPP_INLINE_VISIBILITY 466 typename __invoke_return2<type, _A0, _A1, _A2>::type 467 operator() (_A0& __a0, _A1& __a1, _A2& __a2) const { 468 return __invoke(get(), __a0, __a1, __a2); 469 } 470 471 template <class _A0, class _A1, class _A2> 472 _LIBCPP_INLINE_VISIBILITY 473 typename __invoke_return2<type, _A0 const, _A1, _A2>::type 474 operator() (_A0 const& __a0, _A1& __a1, _A2& __a2) const { 475 return __invoke(get(), __a0, __a1, __a2); 476 } 477 478 template <class _A0, class _A1, class _A2> 479 _LIBCPP_INLINE_VISIBILITY 480 typename __invoke_return2<type, _A0, _A1 const, _A2>::type 481 operator() (_A0& __a0, _A1 const& __a1, _A2& __a2) const { 482 return __invoke(get(), __a0, __a1, __a2); 483 } 484 485 template <class _A0, class _A1, class _A2> 486 _LIBCPP_INLINE_VISIBILITY 487 typename __invoke_return2<type, _A0, _A1, _A2 const>::type 488 operator() (_A0& __a0, _A1& __a1, _A2 const& __a2) const { 489 return __invoke(get(), __a0, __a1, __a2); 490 } 491 492 template <class _A0, class _A1, class _A2> 493 _LIBCPP_INLINE_VISIBILITY 494 typename __invoke_return2<type, _A0 const, _A1 const, _A2>::type 495 operator() (_A0 const& __a0, _A1 const& __a1, _A2& __a2) const { 496 return __invoke(get(), __a0, __a1, __a2); 497 } 498 499 template <class _A0, class _A1, class _A2> 500 _LIBCPP_INLINE_VISIBILITY 501 typename __invoke_return2<type, _A0 const, _A1, _A2 const>::type 502 operator() (_A0 const& __a0, _A1& __a1, _A2 const& __a2) const { 503 return __invoke(get(), __a0, __a1, __a2); 504 } 505 506 template <class _A0, class _A1, class _A2> 507 _LIBCPP_INLINE_VISIBILITY 508 typename __invoke_return2<type, _A0, _A1 const, _A2 const>::type 509 operator() (_A0& __a0, _A1 const& __a1, _A2 const& __a2) const { 510 return __invoke(get(), __a0, __a1, __a2); 511 } 512 513 template <class _A0, class _A1, class _A2> 514 _LIBCPP_INLINE_VISIBILITY 515 typename __invoke_return2<type, _A0 const, _A1 const, _A2 const>::type 516 operator() (_A0 const& __a0, _A1 const& __a1, _A2 const& __a2) const { 517 return __invoke(get(), __a0, __a1, __a2); 518 } 519#endif // _LIBCPP_HAS_NO_VARIADICS 520}; 521 522 523template <class _Tp> 524inline _LIBCPP_INLINE_VISIBILITY 525reference_wrapper<_Tp> 526ref(_Tp& __t) _NOEXCEPT 527{ 528 return reference_wrapper<_Tp>(__t); 529} 530 531template <class _Tp> 532inline _LIBCPP_INLINE_VISIBILITY 533reference_wrapper<_Tp> 534ref(reference_wrapper<_Tp> __t) _NOEXCEPT 535{ 536 return ref(__t.get()); 537} 538 539template <class _Tp> 540inline _LIBCPP_INLINE_VISIBILITY 541reference_wrapper<const _Tp> 542cref(const _Tp& __t) _NOEXCEPT 543{ 544 return reference_wrapper<const _Tp>(__t); 545} 546 547template <class _Tp> 548inline _LIBCPP_INLINE_VISIBILITY 549reference_wrapper<const _Tp> 550cref(reference_wrapper<_Tp> __t) _NOEXCEPT 551{ 552 return cref(__t.get()); 553} 554 555#ifndef _LIBCPP_CXX03_LANG 556template <class _Tp> void ref(const _Tp&&) = delete; 557template <class _Tp> void cref(const _Tp&&) = delete; 558#endif 559 560#if _LIBCPP_STD_VER > 11 561template <class _Tp1, class _Tp2 = void> 562struct __is_transparent 563{ 564private: 565 struct __two {char __lx; char __lxx;}; 566 template <class _Up> static __two __test(...); 567 template <class _Up> static char __test(typename _Up::is_transparent* = 0); 568public: 569 static const bool value = sizeof(__test<_Tp1>(0)) == 1; 570}; 571#endif 572 573// allocator_arg_t 574 575struct _LIBCPP_TEMPLATE_VIS allocator_arg_t { }; 576 577#if defined(_LIBCPP_HAS_NO_CONSTEXPR) || defined(_LIBCPP_BUILDING_MEMORY) 578extern const allocator_arg_t allocator_arg; 579#else 580constexpr allocator_arg_t allocator_arg = allocator_arg_t(); 581#endif 582 583// uses_allocator 584 585template <class _Tp> 586struct __has_allocator_type 587{ 588private: 589 struct __two {char __lx; char __lxx;}; 590 template <class _Up> static __two __test(...); 591 template <class _Up> static char __test(typename _Up::allocator_type* = 0); 592public: 593 static const bool value = sizeof(__test<_Tp>(0)) == 1; 594}; 595 596template <class _Tp, class _Alloc, bool = __has_allocator_type<_Tp>::value> 597struct __uses_allocator 598 : public integral_constant<bool, 599 is_convertible<_Alloc, typename _Tp::allocator_type>::value> 600{ 601}; 602 603template <class _Tp, class _Alloc> 604struct __uses_allocator<_Tp, _Alloc, false> 605 : public false_type 606{ 607}; 608 609template <class _Tp, class _Alloc> 610struct _LIBCPP_TEMPLATE_VIS uses_allocator 611 : public __uses_allocator<_Tp, _Alloc> 612{ 613}; 614 615#if _LIBCPP_STD_VER > 14 616template <class _Tp, class _Alloc> 617constexpr size_t uses_allocator_v = uses_allocator<_Tp, _Alloc>::value; 618#endif 619 620#ifndef _LIBCPP_HAS_NO_VARIADICS 621 622// allocator construction 623 624template <class _Tp, class _Alloc, class ..._Args> 625struct __uses_alloc_ctor_imp 626{ 627 typedef typename __uncvref<_Alloc>::type _RawAlloc; 628 static const bool __ua = uses_allocator<_Tp, _RawAlloc>::value; 629 static const bool __ic = 630 is_constructible<_Tp, allocator_arg_t, _Alloc, _Args...>::value; 631 static const int value = __ua ? 2 - __ic : 0; 632}; 633 634template <class _Tp, class _Alloc, class ..._Args> 635struct __uses_alloc_ctor 636 : integral_constant<int, __uses_alloc_ctor_imp<_Tp, _Alloc, _Args...>::value> 637 {}; 638 639template <class _Tp, class _Allocator, class... _Args> 640inline _LIBCPP_INLINE_VISIBILITY 641void __user_alloc_construct_impl (integral_constant<int, 0>, _Tp *__storage, const _Allocator &, _Args &&... __args ) 642{ 643 new (__storage) _Tp (_VSTD::forward<_Args>(__args)...); 644} 645 646// FIXME: This should have a version which takes a non-const alloc. 647template <class _Tp, class _Allocator, class... _Args> 648inline _LIBCPP_INLINE_VISIBILITY 649void __user_alloc_construct_impl (integral_constant<int, 1>, _Tp *__storage, const _Allocator &__a, _Args &&... __args ) 650{ 651 new (__storage) _Tp (allocator_arg, __a, _VSTD::forward<_Args>(__args)...); 652} 653 654// FIXME: This should have a version which takes a non-const alloc. 655template <class _Tp, class _Allocator, class... _Args> 656inline _LIBCPP_INLINE_VISIBILITY 657void __user_alloc_construct_impl (integral_constant<int, 2>, _Tp *__storage, const _Allocator &__a, _Args &&... __args ) 658{ 659 new (__storage) _Tp (_VSTD::forward<_Args>(__args)..., __a); 660} 661 662// FIXME: Theis should have a version which takes a non-const alloc. 663template <class _Tp, class _Allocator, class... _Args> 664inline _LIBCPP_INLINE_VISIBILITY 665void __user_alloc_construct (_Tp *__storage, const _Allocator &__a, _Args &&... __args) 666{ 667 __user_alloc_construct_impl( 668 __uses_alloc_ctor<_Tp, _Allocator>(), 669 __storage, __a, _VSTD::forward<_Args>(__args)... 670 ); 671} 672#endif // _LIBCPP_HAS_NO_VARIADICS 673 674_LIBCPP_END_NAMESPACE_STD 675 676#endif // _LIBCPP_FUNCTIONAL_BASE 677