Changeset 40340461 in mainline
- Timestamp:
- 2018-07-05T21:41:20Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 4bea22a
- Parents:
- 7e7c1aac
- git-author:
- Dzejrou <dzejrou@…> (2018-03-28 14:22:48)
- git-committer:
- Dzejrou <dzejrou@…> (2018-07-05 21:41:20)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/cpp/include/impl/memory.hpp
r7e7c1aac r40340461 428 428 return first; 429 429 } 430 431 /** 432 * 20.8, smart pointers: 433 */ 434 435 template<class T> 436 struct default_delete 437 { 438 default_delete() noexcept = default; 439 440 template<class U, class = enable_if_t<is_convertible_v<U*, T*>, void>> 441 default_delete(const default_delete<U>&) noexcept 442 { /* DUMMY BODY */ } 443 444 template<class U> 445 void operator()(U* ptr) 446 { 447 delete ptr; 448 } 449 }; 450 451 template<class T> 452 struct default_delete<T[]> 453 { 454 default_delete() noexcept = default; 455 456 template<class U, class = enable_if_t<is_convertible_v<U(*)[], T(*)[]>, void>> 457 default_delete(const default_delete<U[]>&) noexcept 458 { /* DUMMY BODY */ } 459 460 template<class U, class = enable_if_t<is_convertible_v<U(*)[], T(*)[]>, void>> 461 void operator()(U* ptr) 462 { 463 delete[] ptr; 464 } 465 }; 466 467 template<class T, class D = default_delete<T>> 468 class unique_ptr; 469 470 namespace aux 471 { 472 template<class P, class D, class = void> 473 struct get_unique_pointer: type_is<typename P::element_type*> 474 { /* DUMMY BODY */ }; 475 476 template<class P, class D> 477 struct get_unique_pointer<P, D, void_t<typename remove_reference_t<D>::pointer>> 478 : type_is<typename remove_reference_t<D>::pointer> 479 { /* DUMMY BODY */ }; 480 } 481 482 template<class T, class D> 483 class unique_ptr 484 { 485 public: 486 using element_type = T; 487 using deleter_type = D; 488 using pointer = typename aux::get_unique_pointer<unique_ptr<T, D>, D>::type; 489 490 /** 491 * 20.8.1.2.1, constructors: 492 */ 493 494 constexpr unique_ptr() noexcept 495 : ptr_{}, deleter_{} 496 { /* DUMMY BODY */ } 497 498 explicit unique_ptr(pointer ptr) noexcept 499 : ptr_{ptr}, deleter_{} 500 { /* DUMMY BODY */ } 501 502 unique_ptr(pointer ptr, /* TODO */ int d) noexcept; 503 504 unique_ptr(pointer ptr, /* TODO */ char d) noexcept; 505 506 unique_ptr(unique_ptr&& other) 507 : ptr_{move(other.ptr_)}, deleter_{forward<deleter_type>(other.deleter_)} 508 { 509 other.ptr_ = nullptr; 510 } 511 512 constexpr unique_ptr(nullptr_t) 513 : unique_ptr{} 514 { /* DUMMY BODY */ } 515 516 template< 517 class U, class E, 518 class = enable_if_t< 519 is_convertible_v< 520 typename unique_ptr<U, E>::pointer, 521 pointer 522 >, void 523 > 524 > 525 unique_ptr(unique_ptr<U, E>&& other) noexcept 526 : ptr_{move(other.ptr_)}, deleter_{forward<D>(other.deleter_)} 527 { 528 other.ptr_ = nullptr; 529 } 530 531 /** 532 * 20.8.1.2.2, destructor: 533 */ 534 535 ~unique_ptr() 536 { 537 if (ptr_) 538 deleter_(ptr_); 539 } 540 541 /** 542 * 20.8.1.2.3, assignment: 543 */ 544 545 unique_ptr& operator=(unique_ptr&& rhs) noexcept 546 { 547 reset(rhs.release()); 548 deleter_ = forward<deleter_type>(rhs.get_deleter()); 549 550 return *this; 551 } 552 553 template< 554 class U, class E, 555 class = enable_if_t< 556 is_convertible_v< 557 typename unique_ptr<U, E>::pointer, 558 pointer 559 > && !is_array_v<U>, void 560 > 561 > 562 unique_ptr& operator=(unique_ptr<U, E>&& rhs) noexcept 563 { 564 reset(rhs.release()); 565 deleter_ = forward<E>(rhs.get_deleter()); 566 567 return *this; 568 } 569 570 unique_ptr& operator=(nullptr_t) noexcept 571 { 572 reset(); 573 574 return *this; 575 } 576 577 /** 578 * 20.8.1.2.4, observers: 579 */ 580 581 add_lvalue_reference_t<element_type> operator*() const 582 { 583 return *ptr_; 584 } 585 586 pointer operator->() const noexcept 587 { 588 return ptr_; 589 } 590 591 pointer get() const noexcept 592 { 593 return ptr_; 594 } 595 596 deleter_type& get_deleter() noexcept 597 { 598 return deleter_; 599 } 600 601 const deleter_type& get_deleter() const noexcept 602 { 603 return deleter_; 604 } 605 606 explicit operator bool() const noexcept 607 { 608 return ptr_ != nullptr; 609 } 610 611 /** 612 * 20.8.1.2.5, modifiers: 613 */ 614 615 pointer release() noexcept 616 { 617 auto ret = ptr_; 618 ptr_ = nullptr; 619 620 return ret; 621 } 622 623 void reset(pointer ptr = pointer{}) noexcept 624 { 625 /** 626 * Note: Order is significant, deleter may delete 627 * *this. 628 */ 629 auto old = ptr_; 630 ptr_ = ptr; 631 632 if (old) 633 deleter_(old); 634 } 635 636 void swap(unique_ptr& other) noexcept 637 { 638 std::swap(ptr_, other.ptr_); 639 std::swap(deleter_, other.deleter_); 640 } 641 642 unique_ptr(const unique_ptr&) = delete; 643 unique_ptr& operator=(const unique_ptr&) = delete; 644 645 private: 646 pointer ptr_; 647 deleter_type deleter_; 648 }; 649 650 namespace aux 651 { 652 template<class From, class To> 653 struct is_convertible_array: is_convertible<From(*)[], To(*)[]> 654 { /* DUMMY BODY */ }; 655 656 template<class From, class To> 657 inline constexpr bool is_convertible_array_v = is_convertible_array<From, To>::value; 658 659 template<class T, class D, class U, class E> 660 struct compatible_ptrs: integral_constant< 661 bool, 662 is_array_v<U> && is_same_v< 663 typename unique_ptr<T, D>::pointer, 664 typename unique_ptr<T, D>::element_type* 665 > && is_same_v< 666 typename unique_ptr<U, E>::pointer, 667 typename unique_ptr<U, E>::element_type* 668 > && is_convertible_array_v< 669 typename unique_ptr<T, D>::element_type, 670 typename unique_ptr<U, E>::element_type 671 > && ((is_reference_v<D> && is_same_v<D, E>) || 672 (!is_reference_v<D> && is_convertible_v<E, D>)) 673 > 674 { /* DUMMY BODY */ }; 675 676 template<class T, class D, class U, class E> 677 inline constexpr bool compatible_ptrs_v = compatible_ptrs<T, D, U, E>::value; 678 } 679 680 template<class T, class D> 681 class unique_ptr<T[], D> 682 { 683 public: 684 using element_type = T; 685 using deleter_type = D; 686 using pointer = typename aux::get_unique_pointer<unique_ptr<T[], D>, D>::type; 687 688 /** 689 * 20.8.1.3.1, constructors: 690 */ 691 692 constexpr unique_ptr() noexcept 693 : ptr_{}, deleter_{} 694 { /* DUMMY BODY */ } 695 696 template< 697 class U, 698 class = enable_if_t< 699 is_same_v<U, T> || aux::is_convertible_array_v<U, T>, void 700 > 701 > 702 explicit unique_ptr(U ptr) noexcept 703 : ptr_{ptr}, deleter_{} 704 { /* DUMMY BODY */ } 705 706 template< 707 class U, class E, 708 class = enable_if_t<aux::compatible_ptrs_v<T, D, U, E>, void> 709 > 710 unique_ptr(U ptr, /* TODO */ int d) noexcept; 711 712 template< 713 class U, class E, 714 class = enable_if_t<aux::compatible_ptrs_v<T, D, U, E>, void> 715 > 716 unique_ptr(U ptr, /* TODO */ char d) noexcept; 717 718 unique_ptr(unique_ptr&& other) noexcept 719 : ptr_{move(other.ptr_)}, deleter_{forward<deleter_type>(other.deleter_)} 720 { 721 other.ptr_ = nullptr; 722 } 723 724 template< 725 class U, class E, 726 class = enable_if_t< 727 is_same_v<U, pointer> || 728 (is_same_v<pointer, element_type*> && is_pointer_v<U> && 729 aux::is_convertible_array_v<remove_pointer_t<U>, element_type>), 730 void 731 > 732 > 733 unique_ptr(unique_ptr<U, E>&& other) noexcept 734 : ptr_{move(other.ptr_)}, deleter_{forward<D>(other.deleter_)} 735 { 736 other.ptr_ = nullptr; 737 } 738 739 constexpr unique_ptr(nullptr_t) noexcept 740 : unique_ptr{} 741 { /* DUMMY BODY */ } 742 743 ~unique_ptr() 744 { 745 if (ptr_) 746 deleter_(ptr_); 747 } 748 749 /** 750 * 20.8.1.3.2, assignment: 751 */ 752 753 unique_ptr& operator=(unique_ptr&& rhs) noexcept 754 { 755 reset(rhs.release()); 756 deleter_ = forward<deleter_type>(rhs.get_deleter()); 757 758 return *this; 759 } 760 761 template< 762 class U, class E, 763 class = enable_if_t<aux::compatible_ptrs_v<T, D, U, E>, void> 764 > 765 unique_ptr& operator=(unique_ptr<U, E>&& rhs) noexcept 766 { 767 reset(rhs.release()); 768 deleter_ = forward<E>(rhs.get_deleter()); 769 770 return *this; 771 } 772 773 unique_ptr& operator=(nullptr_t) noexcept 774 { 775 reset(); 776 777 return *this; 778 } 779 780 /** 781 * 20.8.1.3.3, observers: 782 */ 783 784 element_type& operator[](size_t idx) const 785 { 786 return ptr_[idx]; 787 } 788 789 pointer get() const noexcept 790 { 791 return ptr_; 792 } 793 794 deleter_type& get_deleter() noexcept 795 { 796 return deleter_; 797 } 798 799 const deleter_type& get_deleter() const noexcept 800 { 801 return deleter_; 802 } 803 804 explicit operator bool() const noexcept 805 { 806 return ptr_ != nullptr; 807 } 808 809 /** 810 * 20.8.1.3.4, modifiers: 811 */ 812 813 pointer release() noexcept 814 { 815 auto ret = ptr_; 816 ptr_ = nullptr; 817 818 return ret; 819 } 820 821 template< 822 class U, 823 class = enable_if_t< 824 is_same_v<U, pointer> || 825 (is_same_v<pointer, element_type*> && is_pointer_v<U> && 826 aux::is_convertible_array_v<remove_pointer_t<U>, element_type>), 827 void 828 > 829 > 830 void reset(U ptr) noexcept 831 { 832 /** 833 * Note: Order is significant, deleter may delete 834 * *this. 835 */ 836 auto old = ptr_; 837 ptr_ = ptr; 838 839 if (old) 840 deleter_(old); 841 } 842 843 void reset(nullptr_t = nullptr) noexcept 844 { 845 reset(pointer{}); 846 } 847 848 void swap(unique_ptr& other) noexcept 849 { 850 std::swap(ptr_, other.ptr_); 851 std::swap(deleter_, other.deleter_); 852 } 853 854 unique_ptr(const unique_ptr&) = delete; 855 unique_ptr& operator=(const unique_ptr&) = delete; 856 857 private: 858 pointer ptr_; 859 deleter_type deleter_; 860 }; 861 862 namespace aux 863 { 864 template<class T> 865 struct is_unbound_array: false_type 866 { /* DUMMY BODY */ }; 867 868 template<class T> 869 struct is_unbound_array<T[]>: true_type 870 { /* DUMMY BODY */ }; 871 872 template<class T> 873 struct is_bound_array: false_type 874 { /* DUMMY BODY */ }; 875 876 template<class T, size_t N> 877 struct is_bound_array<T[N]>: true_type 878 { /* DUMMY BODY */ }; 879 } 880 881 template< 882 class T, class... Args, 883 class = enable_if_t<!is_array_v<T>, void> 884 > 885 unique_ptr<T> make_unique(Args&&... args) 886 { 887 return unique_ptr<T>(new T(forward<Args>(args)...)); 888 } 889 890 template< 891 class T, class = enable_if_t<aux::is_unbound_array<T>::value, void> 892 > 893 unique_ptr<T> make_unique(size_t n) 894 { 895 return unique_ptr<T>(new remove_extent_t<T>[n]()); 896 } 897 898 template< 899 class T, class... Args, 900 class = enable_if_t<aux::is_bound_array<T>::value, void> 901 > 902 void make_unique(Args&&...) = delete; 903 904 template<class T, class D> 905 void swap(unique_ptr<T, D>& lhs, unique_ptr<T, D>& rhs) noexcept 906 { 907 lhs.swap(rhs); 908 } 909 910 template<class T1, class D1, class T2, class D2> 911 bool operator==(const unique_ptr<T1, D1>& lhs, 912 const unique_ptr<T2, D2>& rhs) 913 { 914 return lhs.get() == rhs.get(); 915 } 916 917 template<class T1, class D1, class T2, class D2> 918 bool operator!=(const unique_ptr<T1, D1>& lhs, 919 const unique_ptr<T2, D2>& rhs) 920 { 921 return lhs.get() != rhs.get(); 922 } 923 924 template<class T1, class D1, class T2, class D2> 925 bool operator<(const unique_ptr<T1, D1>& lhs, 926 const unique_ptr<T2, D2>& rhs) 927 { 928 return lhs.get() < rhs.get(); 929 } 930 931 template<class T1, class D1, class T2, class D2> 932 bool operator<=(const unique_ptr<T1, D1>& lhs, 933 const unique_ptr<T2, D2>& rhs) 934 { 935 return !(rhs < lhs); 936 } 937 938 template<class T1, class D1, class T2, class D2> 939 bool operator>(const unique_ptr<T1, D1>& lhs, 940 const unique_ptr<T2, D2>& rhs) 941 { 942 return rhs < lhs; 943 } 944 945 template<class T1, class D1, class T2, class D2> 946 bool operator>=(const unique_ptr<T1, D1>& lhs, 947 const unique_ptr<T2, D2>& rhs) 948 { 949 return !(lhs < rhs); 950 } 951 952 template<class T, class D> 953 bool operator==(const unique_ptr<T, D>& ptr, nullptr_t) noexcept 954 { 955 return !ptr; 956 } 957 958 template<class T, class D> 959 bool operator==(nullptr_t, const unique_ptr<T, D>& ptr) noexcept 960 { 961 return !ptr; 962 } 963 964 template<class T, class D> 965 bool operator!=(const unique_ptr<T, D>& ptr, nullptr_t) noexcept 966 { 967 return static_cast<bool>(ptr); 968 } 969 970 template<class T, class D> 971 bool operator!=(nullptr_t, const unique_ptr<T, D>& ptr) noexcept 972 { 973 return static_cast<bool>(ptr); 974 } 975 976 template<class T, class D> 977 bool operator<(const unique_ptr<T, D>& ptr, nullptr_t) 978 { 979 return ptr.get() < nullptr; 980 } 981 982 template<class T, class D> 983 bool operator<(nullptr_t, const unique_ptr<T, D>& ptr) 984 { 985 return nullptr < ptr.get(); 986 } 987 988 template<class T, class D> 989 bool operator<=(const unique_ptr<T, D>& ptr, nullptr_t) 990 { 991 return !(nullptr < ptr); 992 } 993 994 template<class T, class D> 995 bool operator<=(nullptr_t, const unique_ptr<T, D>& ptr) 996 { 997 return !(ptr < nullptr); 998 } 999 1000 template<class T, class D> 1001 bool operator>(const unique_ptr<T, D>& ptr, nullptr_t) 1002 { 1003 return nullptr < ptr; 1004 } 1005 1006 template<class T, class D> 1007 bool operator>(nullptr_t, const unique_ptr<T, D>& ptr) 1008 { 1009 return ptr < nullptr; 1010 } 1011 1012 template<class T, class D> 1013 bool operator>=(const unique_ptr<T, D>& ptr, nullptr_t) 1014 { 1015 return !(ptr < nullptr); 1016 } 1017 1018 template<class T, class D> 1019 bool operator>=(nullptr_t, const unique_ptr<T, D>& ptr) 1020 { 1021 return !(nullptr < ptr); 1022 } 430 1023 } 431 1024
Note:
See TracChangeset
for help on using the changeset viewer.