[unique.ptr] # 20 Memory management library [[mem]](./#mem) ## 20.3 Smart pointers [[smartptr]](smartptr#unique.ptr) ### 20.3.1 Unique-ownership pointers [unique.ptr] #### [20.3.1.1](#general) General [[unique.ptr.general]](unique.ptr.general) [1](#general-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2217) A [*unique pointer*](#def:unique_pointer "20.3.1.1 General [unique.ptr.general]") is an object that owns another object and manages that other object through a pointer[.](#general-1.sentence-1) More precisely, a unique pointer is an object *u* that stores a pointer to a second object *p* and will dispose of *p* when *u* is itself destroyed (e.g., when leaving block scope ([[stmt.dcl]](stmt.dcl "8.10 Declaration statement")))[.](#general-1.sentence-2) In this context, *u* is said to [*own*](#def:own "20.3.1.1 General [unique.ptr.general]") p[.](#general-1.sentence-3) [2](#general-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2225) The mechanism by which *u* disposes of *p* is known as*p*'s associated [*deleter*](#def:deleter "20.3.1.1 General [unique.ptr.general]"), a function object whose correct invocation results in *p*'s appropriate disposition (typically its deletion)[.](#general-2.sentence-1) [3](#general-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2230) Let the notation *u.p* denote the pointer stored by *u*, and let *u.d* denote the associated deleter[.](#general-3.sentence-1) Upon request, *u* can[*reset*](#def:reset "20.3.1.1 General [unique.ptr.general]") (replace) *u.p* and *u.d* with another pointer and deleter, but properly disposes of its owned object via the associated deleter before such replacement is considered completed[.](#general-3.sentence-2) [4](#general-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2237) Each object of a type U instantiated from the unique_ptr template specified in [unique.ptr] has the strict ownership semantics, specified above, of a unique pointer[.](#general-4.sentence-1) In partial satisfaction of these semantics, each such U is [*Cpp17MoveConstructible*](utility.arg.requirements#:Cpp17MoveConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") and [*Cpp17MoveAssignable*](utility.arg.requirements#:Cpp17MoveAssignable "16.4.4.2 Template argument requirements [utility.arg.requirements]"), but is not[*Cpp17CopyConstructible*](utility.arg.requirements#:Cpp17CopyConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") nor [*Cpp17CopyAssignable*](utility.arg.requirements#:Cpp17CopyAssignable "16.4.4.2 Template argument requirements [utility.arg.requirements]")[.](#general-4.sentence-2) The template parameter T of unique_ptr may be an incomplete type[.](#general-4.sentence-3) [5](#general-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2245) [*Note [1](#general-note-1)*: The uses of unique_ptr include providing exception safety for dynamically allocated memory, passing ownership of dynamically allocated memory to a function, and returning dynamically allocated memory from a function[.](#general-5.sentence-1) — *end note*] #### [20.3.1.2](#dltr) Default deleters [[unique.ptr.dltr]](unique.ptr.dltr) #### [20.3.1.2.1](#dltr.general) General [[unique.ptr.dltr.general]](unique.ptr.dltr.general) [1](#dltr.general-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2258) The class template default_delete serves as the default deleter (destruction policy) for the class template unique_ptr[.](#dltr.general-1.sentence-1) [2](#dltr.general-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2262) The template parameter T of default_delete may be an incomplete type[.](#dltr.general-2.sentence-1) #### [20.3.1.2.2](#dltr.dflt) default_delete [[unique.ptr.dltr.dflt]](unique.ptr.dltr.dflt) namespace std {template struct default_delete {constexpr default_delete() noexcept = default; template constexpr default_delete(const default_delete&) noexcept; constexpr void operator()(T*) const; };} [🔗](#lib:default_delete,constructor) `template constexpr default_delete(const default_delete& other) noexcept; ` [1](#dltr.dflt-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2284) *Constraints*: U* is implicitly convertible to T*[.](#dltr.dflt-1.sentence-1) [2](#dltr.dflt-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2288) *Effects*: Constructs a default_delete object from another default_delete object[.](#dltr.dflt-2.sentence-1) [🔗](#lib:operator(),default_delete) `constexpr void operator()(T* ptr) const; ` [3](#dltr.dflt-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2300) *Mandates*: T is a complete type[.](#dltr.dflt-3.sentence-1) [4](#dltr.dflt-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2304) *Effects*: Calls delete on ptr[.](#dltr.dflt-4.sentence-1) #### [20.3.1.2.3](#dltr.dflt1) default_delete [[unique.ptr.dltr.dflt1]](unique.ptr.dltr.dflt1) namespace std {template struct default_delete {constexpr default_delete() noexcept = default; template constexpr default_delete(const default_delete&) noexcept; template constexpr void operator()(U* ptr) const; };} [🔗](#lib:default_delete,constructor_) `template constexpr default_delete(const default_delete& other) noexcept; ` [1](#dltr.dflt1-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2327) *Constraints*: U(*)[] is convertible to T(*)[][.](#dltr.dflt1-1.sentence-1) [2](#dltr.dflt1-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2331) *Effects*: Constructs a default_delete object from another default_delete object[.](#dltr.dflt1-2.sentence-1) [🔗](#lib:operator(),default_delete_) `template constexpr void operator()(U* ptr) const; ` [3](#dltr.dflt1-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2342) *Constraints*: U(*)[] is convertible to T(*)[][.](#dltr.dflt1-3.sentence-1) [4](#dltr.dflt1-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2346) *Mandates*: U is a complete type[.](#dltr.dflt1-4.sentence-1) [5](#dltr.dflt1-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2350) *Effects*: Calls delete[] on ptr[.](#dltr.dflt1-5.sentence-1) #### [20.3.1.3](#single) unique_ptr for single objects [[unique.ptr.single]](unique.ptr.single) #### [20.3.1.3.1](#single.general) General [[unique.ptr.single.general]](unique.ptr.single.general) [🔗](#lib:unique_ptr) namespace std {template> class unique_ptr {public:using pointer = *see below*; using element_type = T; using deleter_type = D; // [[unique.ptr.single.ctor]](#single.ctor "20.3.1.3.2 Constructors"), constructorsconstexpr unique_ptr() noexcept; constexpr explicit unique_ptr(type_identity_t p) noexcept; constexpr unique_ptr(type_identity_t p, *see below* d1) noexcept; constexpr unique_ptr(type_identity_t p, *see below* d2) noexcept; constexpr unique_ptr(unique_ptr&& u) noexcept; constexpr unique_ptr(nullptr_t) noexcept; templateconstexpr unique_ptr(unique_ptr&& u) noexcept; // [[unique.ptr.single.dtor]](#single.dtor "20.3.1.3.3 Destructor"), destructorconstexpr ~unique_ptr(); // [[unique.ptr.single.asgn]](#single.asgn "20.3.1.3.4 Assignment"), assignmentconstexpr unique_ptr& operator=(unique_ptr&& u) noexcept; templateconstexpr unique_ptr& operator=(unique_ptr&& u) noexcept; constexpr unique_ptr& operator=(nullptr_t) noexcept; // [[unique.ptr.single.observers]](#single.observers "20.3.1.3.5 Observers"), observersconstexpr add_lvalue_reference_t operator*() const noexcept(*see below*); constexpr pointer operator->() const noexcept; constexpr pointer get() const noexcept; constexpr deleter_type& get_deleter() noexcept; constexpr const deleter_type& get_deleter() const noexcept; constexpr explicit operator bool() const noexcept; // [[unique.ptr.single.modifiers]](#single.modifiers "20.3.1.3.6 Modifiers"), modifiersconstexpr pointer release() noexcept; constexpr void reset(pointer p = pointer()) noexcept; constexpr void swap(unique_ptr& u) noexcept; // disable copy from lvalue unique_ptr(const unique_ptr&) = delete; unique_ptr& operator=(const unique_ptr&) = delete; };} [1](#single.general-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2407) A program that instantiates the definition of unique_ptr is ill-formed if T* is an invalid type[.](#single.general-1.sentence-1) [*Note [1](#single.general-note-1)*: This prevents the instantiation of specializations such asunique_ptr and unique_ptr[.](#single.general-1.sentence-2) — *end note*] [2](#single.general-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2415) The default type for the template parameter D isdefault_delete[.](#single.general-2.sentence-1) A client-supplied template argumentD shall be a function object type ([[function.objects]](function.objects "22.10 Function objects")), lvalue reference to function, or lvalue reference to function object type for which, given a value d of type D and a valueptr of type unique_ptr​::​pointer, the expressiond(ptr) is valid and has the effect of disposing of the pointer as appropriate for that deleter[.](#single.general-2.sentence-2) [3](#single.general-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2427) If the deleter's type D is not a reference type, D shall meet the [*Cpp17Destructible*](utility.arg.requirements#:Cpp17Destructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") requirements (Table [35](utility.arg.requirements#tab:cpp17.destructible "Table 35: Cpp17Destructible requirements"))[.](#single.general-3.sentence-1) [4](#single.general-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2431) If the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") remove_reference_t​::​pointer is valid and denotes a type ([[temp.deduct]](temp.deduct "13.10.3 Template argument deduction")), then unique_ptr​::​pointer shall be a synonym for remove_reference_t​::​pointer[.](#single.general-4.sentence-1) Otherwiseunique_ptr​::​pointer shall be a synonym for element_type*[.](#single.general-4.sentence-2) The type unique_ptr​::​pointer shall meet the [*Cpp17NullablePointer*](nullablepointer.requirements#:Cpp17NullablePointer "16.4.4.4 Cpp17NullablePointer requirements [nullablepointer.requirements]") requirements (Table [36](nullablepointer.requirements#tab:cpp17.nullablepointer "Table 36: Cpp17NullablePointer requirements"))[.](#single.general-4.sentence-3) [5](#single.general-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2439) [*Example [1](#single.general-example-1)*: Given an allocator type X ([[allocator.requirements.general]](allocator.requirements.general "16.4.4.6.1 General")) and letting A be a synonym for allocator_traits, the types A​::​pointer,A​::​const_pointer, A​::​void_pointer, and A​::​const_void_pointer may be used as unique_ptr​::​pointer[.](#single.general-5.sentence-1) — *end example*] #### [20.3.1.3.2](#single.ctor) Constructors [[unique.ptr.single.ctor]](unique.ptr.single.ctor) [🔗](#lib:unique_ptr,constructor) `constexpr unique_ptr() noexcept; constexpr unique_ptr(nullptr_t) noexcept; ` [1](#single.ctor-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2456) *Constraints*: is_pointer_v is false andis_default_constructible_v is true[.](#single.ctor-1.sentence-1) [2](#single.ctor-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2461) *Preconditions*: D meets the [*Cpp17DefaultConstructible*](utility.arg.requirements#:Cpp17DefaultConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") requirements (Table [30](utility.arg.requirements#tab:cpp17.defaultconstructible "Table 30: Cpp17DefaultConstructible requirements")), and that construction does not throw an exception[.](#single.ctor-2.sentence-1) [3](#single.ctor-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2466) *Effects*: Constructs a unique_ptr object that owns nothing, value-initializing the stored pointer and the stored deleter[.](#single.ctor-3.sentence-1) [4](#single.ctor-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2471) *Postconditions*: get() == nullptr[.](#single.ctor-4.sentence-1) get_deleter() returns a reference to the stored deleter[.](#single.ctor-4.sentence-2) [🔗](#lib:unique_ptr,constructor_) `constexpr explicit unique_ptr(type_identity_t p) noexcept; ` [5](#single.ctor-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2483) *Constraints*: is_pointer_v is false andis_default_constructible_v is true[.](#single.ctor-5.sentence-1) [6](#single.ctor-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2488) *Preconditions*: D meets the [*Cpp17DefaultConstructible*](utility.arg.requirements#:Cpp17DefaultConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") requirements (Table [30](utility.arg.requirements#tab:cpp17.defaultconstructible "Table 30: Cpp17DefaultConstructible requirements")), and that construction does not throw an exception[.](#single.ctor-6.sentence-1) [7](#single.ctor-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2493) *Effects*: Constructs a unique_ptr which ownsp, initializing the stored pointer with p and value-initializing the stored deleter[.](#single.ctor-7.sentence-1) [8](#single.ctor-8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2499) *Postconditions*: get() == p[.](#single.ctor-8.sentence-1) get_deleter() returns a reference to the stored deleter[.](#single.ctor-8.sentence-2) [🔗](#lib:unique_ptr,constructor__) `constexpr unique_ptr(type_identity_t p, const D& d) noexcept; constexpr unique_ptr(type_identity_t p, remove_reference_t&& d) noexcept; ` [9](#single.ctor-9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2512) *Constraints*: is_constructible_v is true[.](#single.ctor-9.sentence-1) [10](#single.ctor-10) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2516) *Preconditions*: For the first constructor, if D is not a reference type,D meets the [*Cpp17CopyConstructible*](utility.arg.requirements#:Cpp17CopyConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") requirements and such construction does not exit via an exception[.](#single.ctor-10.sentence-1) For the second constructor, if D is not a reference type,D meets the [*Cpp17MoveConstructible*](utility.arg.requirements#:Cpp17MoveConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") requirements and such construction does not exit via an exception[.](#single.ctor-10.sentence-2) [11](#single.ctor-11) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2525) *Effects*: Constructs a unique_ptr object which owns p, initializing the stored pointer with p and initializing the deleter from std​::​forward(d)[.](#single.ctor-11.sentence-1) [12](#single.ctor-12) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2531) *Postconditions*: get() == p[.](#single.ctor-12.sentence-1) get_deleter() returns a reference to the stored deleter[.](#single.ctor-12.sentence-2) If D is a reference type then get_deleter() returns a reference to the lvalue d[.](#single.ctor-12.sentence-3) [13](#single.ctor-13) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2538) *Remarks*: If D is a reference type, the second constructor is defined as deleted[.](#single.ctor-13.sentence-1) [14](#single.ctor-14) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2543) [*Example [1](#single.ctor-example-1)*: D d; unique_ptr p1(new int, D()); // D must be [*Cpp17MoveConstructible*](utility.arg.requirements#:Cpp17MoveConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") unique_ptr p2(new int, d); // D must be [*Cpp17CopyConstructible*](utility.arg.requirements#:Cpp17CopyConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") unique_ptr p3(new int, d); // p3 holds a reference to d unique_ptr p4(new int, D()); // error: rvalue deleter object combined// with reference deleter type — *end example*] [🔗](#lib:unique_ptr,constructor___) `constexpr unique_ptr(unique_ptr&& u) noexcept; ` [15](#single.ctor-15) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2562) *Constraints*: is_move_constructible_v is true[.](#single.ctor-15.sentence-1) [16](#single.ctor-16) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2566) *Preconditions*: If D is not a reference type,D meets the [*Cpp17MoveConstructible*](utility.arg.requirements#:Cpp17MoveConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") requirements (Table [31](utility.arg.requirements#tab:cpp17.moveconstructible "Table 31: Cpp17MoveConstructible requirements"))[.](#single.ctor-16.sentence-1) Construction of the deleter from an rvalue of type D does not throw an exception[.](#single.ctor-16.sentence-2) [17](#single.ctor-17) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2575) *Effects*: Constructs a unique_ptr fromu[.](#single.ctor-17.sentence-1) If D is a reference type, this deleter is copy constructed from u's deleter; otherwise, this deleter is move constructed from u's deleter[.](#single.ctor-17.sentence-2) [*Note [1](#single.ctor-note-1)*: The construction of the deleter can be implemented with std​::​forward[.](#single.ctor-17.sentence-3) — *end note*] [18](#single.ctor-18) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2586) *Postconditions*: get() yields the value u.get() yielded before the construction[.](#single.ctor-18.sentence-1) u.get() == nullptr[.](#single.ctor-18.sentence-2) get_deleter() returns a reference to the stored deleter that was constructed fromu.get_deleter()[.](#single.ctor-18.sentence-3) If D is a reference type thenget_deleter() and u.get_deleter() both reference the same lvalue deleter[.](#single.ctor-18.sentence-4) [🔗](#lib:unique_ptr,constructor____) `template constexpr unique_ptr(unique_ptr&& u) noexcept; ` [19](#single.ctor-19) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2603) *Constraints*: - [(19.1)](#single.ctor-19.1) unique_ptr​::​pointer is implicitly convertible to pointer, - [(19.2)](#single.ctor-19.2) U is not an array type, and - [(19.3)](#single.ctor-19.3) either D is a reference type and E is the same type as D, orD is not a reference type and E is implicitly convertible to D[.](#single.ctor-19.sentence-1) [20](#single.ctor-20) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2612) *Preconditions*: If E is not a reference type, construction of the deleter from an rvalue of type E is well-formed and does not throw an exception[.](#single.ctor-20.sentence-1) Otherwise, E is a reference type and construction of the deleter from an lvalue of type E is well-formed and does not throw an exception[.](#single.ctor-20.sentence-2) [21](#single.ctor-21) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2621) *Effects*: Constructs a unique_ptr from u[.](#single.ctor-21.sentence-1) If E is a reference type, this deleter is copy constructed fromu's deleter; otherwise, this deleter is move constructed from u's deleter[.](#single.ctor-21.sentence-2) [*Note [2](#single.ctor-note-2)*: The deleter constructor can be implemented withstd​::​forward[.](#single.ctor-21.sentence-3) — *end note*] [22](#single.ctor-22) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2632) *Postconditions*: get() yields the value u.get() yielded before the construction[.](#single.ctor-22.sentence-1) u.get() == nullptr[.](#single.ctor-22.sentence-2) get_deleter() returns a reference to the stored deleter that was constructed fromu.get_deleter()[.](#single.ctor-22.sentence-3) #### [20.3.1.3.3](#single.dtor) Destructor [[unique.ptr.single.dtor]](unique.ptr.single.dtor) [🔗](#lib:unique_ptr,destructor) `constexpr ~unique_ptr(); ` [1](#single.dtor-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2649) *Effects*: Equivalent to:if (get()) get_deleter()(get()); [*Note [1](#single.dtor-note-1)*: The use of default_delete requires T to be a complete type[.](#single.dtor-1.sentence-1) — *end note*] [2](#single.dtor-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2657) *Remarks*: The behavior is undefined if the evaluation of get_deleter()(get()) throws an exception[.](#single.dtor-2.sentence-1) #### [20.3.1.3.4](#single.asgn) Assignment [[unique.ptr.single.asgn]](unique.ptr.single.asgn) [🔗](#lib:operator=,unique_ptr) `constexpr unique_ptr& operator=(unique_ptr&& u) noexcept; ` [1](#single.asgn-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2671) *Constraints*: is_move_assignable_v is true[.](#single.asgn-1.sentence-1) [2](#single.asgn-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2675) *Preconditions*: If D is not a reference type, D meets the[*Cpp17MoveAssignable*](utility.arg.requirements#:Cpp17MoveAssignable "16.4.4.2 Template argument requirements [utility.arg.requirements]") requirements (Table [33](utility.arg.requirements#tab:cpp17.moveassignable "Table 33: Cpp17MoveAssignable requirements")) and assignment of the deleter from an rvalue of type D does not throw an exception[.](#single.asgn-2.sentence-1) Otherwise, D is a reference type;remove_reference_t meets the [*Cpp17CopyAssignable*](utility.arg.requirements#:Cpp17CopyAssignable "16.4.4.2 Template argument requirements [utility.arg.requirements]") requirements and assignment of the deleter from an lvalue of type D does not throw an exception[.](#single.asgn-2.sentence-2) [3](#single.asgn-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2685) *Effects*: Calls reset(u.release()) followed byget_deleter() = std​::​forward(u.get_deleter())[.](#single.asgn-3.sentence-1) [4](#single.asgn-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2690) *Postconditions*: If this != addressof(u),u.get() == nullptr, otherwise u.get() is unchanged[.](#single.asgn-4.sentence-1) [5](#single.asgn-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2696) *Returns*: *this[.](#single.asgn-5.sentence-1) [🔗](#lib:operator=,unique_ptr_) `template constexpr unique_ptr& operator=(unique_ptr&& u) noexcept; ` [6](#single.asgn-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2707) *Constraints*: - [(6.1)](#single.asgn-6.1) unique_ptr​::​pointer is implicitly convertible to pointer, and - [(6.2)](#single.asgn-6.2) U is not an array type, and - [(6.3)](#single.asgn-6.3) is_assignable_v is true[.](#single.asgn-6.sentence-1) [7](#single.asgn-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2715) *Preconditions*: If E is not a reference type, assignment of the deleter from an rvalue of type E is well-formed and does not throw an exception[.](#single.asgn-7.sentence-1) Otherwise, E is a reference type and assignment of the deleter from an lvalue of type E is well-formed and does not throw an exception[.](#single.asgn-7.sentence-2) [8](#single.asgn-8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2724) *Effects*: Calls reset(u.release()) followed byget_deleter() = std​::​forward(u.get_deleter())[.](#single.asgn-8.sentence-1) [9](#single.asgn-9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2729) *Postconditions*: u.get() == nullptr[.](#single.asgn-9.sentence-1) [10](#single.asgn-10) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2733) *Returns*: *this[.](#single.asgn-10.sentence-1) [🔗](#lib:operator=,unique_ptr__) `constexpr unique_ptr& operator=(nullptr_t) noexcept; ` [11](#single.asgn-11) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2744) *Effects*: As if by reset()[.](#single.asgn-11.sentence-1) [12](#single.asgn-12) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2748) *Postconditions*: get() == nullptr[.](#single.asgn-12.sentence-1) [13](#single.asgn-13) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2752) *Returns*: *this[.](#single.asgn-13.sentence-1) #### [20.3.1.3.5](#single.observers) Observers [[unique.ptr.single.observers]](unique.ptr.single.observers) [🔗](#lib:operator*,unique_ptr) `constexpr add_lvalue_reference_t operator*() const noexcept(noexcept(*declval())); ` [1](#single.observers-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2765) *Mandates*: reference_converts_from_temporary_v, decltype( *declval())> is false[.](#single.observers-1.sentence-1) [2](#single.observers-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2769) *Preconditions*: get() != nullptr is true[.](#single.observers-2.sentence-1) [3](#single.observers-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2773) *Returns*: *get()[.](#single.observers-3.sentence-1) [🔗](#lib:operator-%3e,unique_ptr) `constexpr pointer operator->() const noexcept; ` [4](#single.observers-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2785) *Preconditions*: get() != nullptr[.](#single.observers-4.sentence-1) [5](#single.observers-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2789) *Returns*: get()[.](#single.observers-5.sentence-1) [6](#single.observers-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2793) [*Note [1](#single.observers-note-1)*: The use of this function typically requires that T be a complete type[.](#single.observers-6.sentence-1) — *end note*] [🔗](#lib:get,unique_ptr) `constexpr pointer get() const noexcept; ` [7](#single.observers-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2805) *Returns*: The stored pointer[.](#single.observers-7.sentence-1) [🔗](#lib:get_deleter,unique_ptr) `constexpr deleter_type& get_deleter() noexcept; constexpr const deleter_type& get_deleter() const noexcept; ` [8](#single.observers-8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2817) *Returns*: A reference to the stored deleter[.](#single.observers-8.sentence-1) [🔗](#lib:operator_bool,unique_ptr) `constexpr explicit operator bool() const noexcept; ` [9](#single.observers-9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2828) *Returns*: get() != nullptr[.](#single.observers-9.sentence-1) #### [20.3.1.3.6](#single.modifiers) Modifiers [[unique.ptr.single.modifiers]](unique.ptr.single.modifiers) [🔗](#lib:release,unique_ptr) `constexpr pointer release() noexcept; ` [1](#single.modifiers-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2841) *Postconditions*: get() == nullptr[.](#single.modifiers-1.sentence-1) [2](#single.modifiers-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2845) *Returns*: The value get() had at the start of the call to release[.](#single.modifiers-2.sentence-1) [🔗](#lib:reset,unique_ptr) `constexpr void reset(pointer p = pointer()) noexcept; ` [3](#single.modifiers-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2857) *Effects*: Assigns p to the stored pointer, and then, with the old value of the stored pointer, old_p, evaluates if (old_p) get_deleter()(old_p); [*Note [1](#single.modifiers-note-1)*: The order of these operations is significant because the call to get_deleter() might destroy *this[.](#single.modifiers-3.sentence-1) — *end note*] [4](#single.modifiers-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2867) *Postconditions*: get() == p[.](#single.modifiers-4.sentence-1) [*Note [2](#single.modifiers-note-2)*: The postcondition does not hold if the call to get_deleter() destroys *this since this->get() is no longer a valid expression[.](#single.modifiers-4.sentence-2) — *end note*] [5](#single.modifiers-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2875) *Remarks*: The behavior is undefined if the evaluation of get_deleter()(old_p) throws an exception[.](#single.modifiers-5.sentence-1) [🔗](#lib:swap,unique_ptr) `constexpr void swap(unique_ptr& u) noexcept; ` [6](#single.modifiers-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2887) *Preconditions*: get_deleter() is swappable ([[swappable.requirements]](swappable.requirements "16.4.4.3 Swappable requirements")) and does not throw an exception under swap[.](#single.modifiers-6.sentence-1) [7](#single.modifiers-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2892) *Effects*: Invokes swap on the stored pointers and on the stored deleters of *this and u[.](#single.modifiers-7.sentence-1) #### [20.3.1.4](#runtime) unique_ptr for array objects with a runtime length [[unique.ptr.runtime]](unique.ptr.runtime) #### [20.3.1.4.1](#runtime.general) General [[unique.ptr.runtime.general]](unique.ptr.runtime.general) [🔗](#lib:unique_ptr_) namespace std {template class unique_ptr {public:using pointer = *see below*; using element_type = T; using deleter_type = D; // [[unique.ptr.runtime.ctor]](#runtime.ctor "20.3.1.4.2 Constructors"), constructorsconstexpr unique_ptr() noexcept; template constexpr explicit unique_ptr(U p) noexcept; template constexpr unique_ptr(U p, *see below* d) noexcept; template constexpr unique_ptr(U p, *see below* d) noexcept; constexpr unique_ptr(unique_ptr&& u) noexcept; templateconstexpr unique_ptr(unique_ptr&& u) noexcept; constexpr unique_ptr(nullptr_t) noexcept; // destructorconstexpr ~unique_ptr(); // assignmentconstexpr unique_ptr& operator=(unique_ptr&& u) noexcept; templateconstexpr unique_ptr& operator=(unique_ptr&& u) noexcept; constexpr unique_ptr& operator=(nullptr_t) noexcept; // [[unique.ptr.runtime.observers]](#runtime.observers "20.3.1.4.4 Observers"), observersconstexpr T& operator[](size_t i) const; constexpr pointer get() const noexcept; constexpr deleter_type& get_deleter() noexcept; constexpr const deleter_type& get_deleter() const noexcept; constexpr explicit operator bool() const noexcept; // [[unique.ptr.runtime.modifiers]](#runtime.modifiers "20.3.1.4.5 Modifiers"), modifiersconstexpr pointer release() noexcept; template constexpr void reset(U p) noexcept; constexpr void reset(nullptr_t = nullptr) noexcept; constexpr void swap(unique_ptr& u) noexcept; // disable copy from lvalue unique_ptr(const unique_ptr&) = delete; unique_ptr& operator=(const unique_ptr&) = delete; };} [1](#runtime.general-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2950) A specialization for array types is provided with a slightly altered interface[.](#runtime.general-1.sentence-1) - [(1.1)](#runtime.general-1.1) Conversions between different types ofunique_ptr that would be disallowed for the corresponding pointer-to-array types, and conversions to or from the non-array forms ofunique_ptr, produce an ill-formed program[.](#runtime.general-1.1.sentence-1) - [(1.2)](#runtime.general-1.2) Pointers to types derived from T are rejected by the constructors, and by reset[.](#runtime.general-1.2.sentence-1) - [(1.3)](#runtime.general-1.3) The observers operator* andoperator-> are not provided[.](#runtime.general-1.3.sentence-1) - [(1.4)](#runtime.general-1.4) The indexing observer operator[] is provided[.](#runtime.general-1.4.sentence-1) - [(1.5)](#runtime.general-1.5) The default deleter will call delete[][.](#runtime.general-1.5.sentence-1) [2](#runtime.general-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2972) Descriptions are provided below only for members that differ from the primary template[.](#runtime.general-2.sentence-1) [3](#runtime.general-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2976) The template argument T shall be a complete type[.](#runtime.general-3.sentence-1) #### [20.3.1.4.2](#runtime.ctor) Constructors [[unique.ptr.runtime.ctor]](unique.ptr.runtime.ctor) [🔗](#lib:unique_ptr,constructor_____) `template constexpr explicit unique_ptr(U p) noexcept; ` [1](#runtime.ctor-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2987) This constructor behaves the same as the constructor in the primary template that takes a single parameter of type pointer[.](#runtime.ctor-1.sentence-1) [2](#runtime.ctor-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2992) *Constraints*: - [(2.1)](#runtime.ctor-2.1) U is the same type as pointer, or - [(2.2)](#runtime.ctor-2.2) pointer is the same type as element_type*,U is a pointer type V*, andV(*)[] is convertible to element_type(*)[][.](#runtime.ctor-2.sentence-1) [🔗](#lib:unique_ptr,constructor______) `template constexpr unique_ptr(U p, see below d) noexcept; template constexpr unique_ptr(U p, see below d) noexcept; ` [3](#runtime.ctor-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3009) These constructors behave the same as the constructors in the primary template that take a parameter of type pointer and a second parameter[.](#runtime.ctor-3.sentence-1) [4](#runtime.ctor-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3014) *Constraints*: - [(4.1)](#runtime.ctor-4.1) U is the same type as pointer, - [(4.2)](#runtime.ctor-4.2) U is nullptr_t, or - [(4.3)](#runtime.ctor-4.3) pointer is the same type as element_type*, U is a pointer type V*, and V(*)[] is convertible to element_type(*)[][.](#runtime.ctor-4.sentence-1) [🔗](#lib:unique_ptr,constructor_______) `template constexpr unique_ptr(unique_ptr&& u) noexcept; ` [5](#runtime.ctor-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3031) This constructor behaves the same as in the primary template[.](#runtime.ctor-5.sentence-1) [6](#runtime.ctor-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3034) *Constraints*: Where UP is unique_ptr: - [(6.1)](#runtime.ctor-6.1) U is an array type, and - [(6.2)](#runtime.ctor-6.2) pointer is the same type as element_type*, and - [(6.3)](#runtime.ctor-6.3) UP​::​pointer is the same type as UP​::​element_type*, and - [(6.4)](#runtime.ctor-6.4) UP​::​element_type(*)[] is convertible to element_type(*)[], and - [(6.5)](#runtime.ctor-6.5) either D is a reference type and E is the same type as D, or D is not a reference type and E is implicitly convertible to D[.](#runtime.ctor-6.sentence-1) [*Note [1](#runtime.ctor-note-1)*: This replaces the *Constraints*: specification of the primary template[.](#runtime.ctor-6.sentence-2) — *end note*] #### [20.3.1.4.3](#runtime.asgn) Assignment [[unique.ptr.runtime.asgn]](unique.ptr.runtime.asgn) [🔗](#lib:operator=,unique_ptr___) `template constexpr unique_ptr& operator=(unique_ptr&& u) noexcept; ` [1](#runtime.asgn-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3059) This operator behaves the same as in the primary template[.](#runtime.asgn-1.sentence-1) [2](#runtime.asgn-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3062) *Constraints*: Where UP is unique_ptr: - [(2.1)](#runtime.asgn-2.1) U is an array type, and - [(2.2)](#runtime.asgn-2.2) pointer is the same type as element_type*, and - [(2.3)](#runtime.asgn-2.3) UP​::​pointer is the same type as UP​::​element_type*, and - [(2.4)](#runtime.asgn-2.4) UP​::​element_type(*)[] is convertible to element_type(*)[], and - [(2.5)](#runtime.asgn-2.5) is_assignable_v is true[.](#runtime.asgn-2.sentence-1) [*Note [1](#runtime.asgn-note-1)*: This replaces the *Constraints*: specification of the primary template[.](#runtime.asgn-2.sentence-2) — *end note*] #### [20.3.1.4.4](#runtime.observers) Observers [[unique.ptr.runtime.observers]](unique.ptr.runtime.observers) [🔗](#lib:operator%5b%5d,unique_ptr) `constexpr T& operator[](size_t i) const; ` [1](#runtime.observers-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3086) *Preconditions*: i < the number of elements in the array to which the stored pointer points[.](#runtime.observers-1.sentence-1) [2](#runtime.observers-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3092) *Returns*: get()[i][.](#runtime.observers-2.sentence-1) #### [20.3.1.4.5](#runtime.modifiers) Modifiers [[unique.ptr.runtime.modifiers]](unique.ptr.runtime.modifiers) [🔗](#lib:reset,unique_ptr_) `constexpr void reset(nullptr_t p = nullptr) noexcept; ` [1](#runtime.modifiers-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3105) *Effects*: Equivalent to reset(pointer())[.](#runtime.modifiers-1.sentence-1) [🔗](#lib:reset,unique_ptr__) `template constexpr void reset(U p) noexcept; ` [2](#runtime.modifiers-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3116) This function behaves the same as the reset member of the primary template[.](#runtime.modifiers-2.sentence-1) [3](#runtime.modifiers-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3120) *Constraints*: - [(3.1)](#runtime.modifiers-3.1) U is the same type as pointer, or - [(3.2)](#runtime.modifiers-3.2) pointer is the same type as element_type*, U is a pointer type V*, and V(*)[] is convertible to element_type(*)[][.](#runtime.modifiers-3.sentence-1) #### [20.3.1.5](#create) Creation [[unique.ptr.create]](unique.ptr.create) [🔗](#lib:make_unique) `template constexpr unique_ptr make_unique(Args&&... args); ` [1](#create-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3138) *Constraints*: T is not an array type[.](#create-1.sentence-1) [2](#create-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3142) *Returns*: unique_ptr(new T(std​::​forward(args)...))[.](#create-2.sentence-1) [🔗](#lib:make_unique_) `template constexpr unique_ptr make_unique(size_t n); ` [3](#create-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3154) *Constraints*: T is an array of unknown bound[.](#create-3.sentence-1) [4](#create-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3158) *Returns*: unique_ptr(new remove_extent_t[n]())[.](#create-4.sentence-1) [🔗](#lib:make_unique__) `template unspecified make_unique(Args&&...) = delete; ` [5](#create-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3170) *Constraints*: T is an array of known bound[.](#create-5.sentence-1) [🔗](#lib:make_unique___) `template constexpr unique_ptr make_unique_for_overwrite(); ` [6](#create-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3182) *Constraints*: T is not an array type[.](#create-6.sentence-1) [7](#create-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3186) *Returns*: unique_ptr(new T)[.](#create-7.sentence-1) [🔗](#lib:make_unique____) `template constexpr unique_ptr make_unique_for_overwrite(size_t n); ` [8](#create-8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3197) *Constraints*: T is an array of unknown bound[.](#create-8.sentence-1) [9](#create-9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3201) *Returns*: unique_ptr(new remove_extent_t[n])[.](#create-9.sentence-1) [🔗](#lib:make_unique_____) `template unspecified make_unique_for_overwrite(Args&&...) = delete; ` [10](#create-10) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3212) *Constraints*: T is an array of known bound[.](#create-10.sentence-1) #### [20.3.1.6](#special) Specialized algorithms [[unique.ptr.special]](unique.ptr.special) [🔗](#lib:swap(unique_ptr&,_unique_ptr&)) `template constexpr void swap(unique_ptr& x, unique_ptr& y) noexcept; ` [1](#special-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3225) *Constraints*: is_swappable_v is true[.](#special-1.sentence-1) [2](#special-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3229) *Effects*: Calls x.swap(y)[.](#special-2.sentence-1) [🔗](#lib:operator==,unique_ptr) `template constexpr bool operator==(const unique_ptr& x, const unique_ptr& y); ` [3](#special-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3241) *Returns*: x.get() == y.get()[.](#special-3.sentence-1) [🔗](#lib:operator%3c,unique_ptr) `template constexpr bool operator<(const unique_ptr& x, const unique_ptr& y); ` [4](#special-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3253) Let CT denotecommon_type_t::pointer, typename unique_ptr::pointer> [5](#special-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3260) *Mandates*: - [(5.1)](#special-5.1) unique_ptr​::​pointer is implicitly convertible to CT and - [(5.2)](#special-5.2) unique_ptr​::​pointer is implicitly convertible to CT[.](#special-5.sentence-1) [6](#special-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3267) *Preconditions*: The specializationless is a function object type ([[function.objects]](function.objects "22.10 Function objects")) that induces a strict weak ordering ([[alg.sorting]](alg.sorting "26.8 Sorting and related operations")) on the pointer values[.](#special-6.sentence-1) [7](#special-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3273) *Returns*: less()(x.get(), y.get())[.](#special-7.sentence-1) [🔗](#lib:operator%3e,unique_ptr) `template constexpr bool operator>(const unique_ptr& x, const unique_ptr& y); ` [8](#special-8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3285) *Returns*: y < x[.](#special-8.sentence-1) [🔗](#lib:operator%3c=,unique_ptr) `template constexpr bool operator<=(const unique_ptr& x, const unique_ptr& y); ` [9](#special-9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3297) *Returns*: !(y < x)[.](#special-9.sentence-1) [🔗](#lib:operator%3e=,unique_ptr) `template constexpr bool operator>=(const unique_ptr& x, const unique_ptr& y); ` [10](#special-10) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3309) *Returns*: !(x < y)[.](#special-10.sentence-1) [🔗](#lib:operator%3c=%3e,unique_ptr) `template requires [three_way_comparable_with](cmp.concept#concept:three_way_comparable_with "17.12.4 Concept three_­way_­comparable [cmp.concept]")::pointer, typename unique_ptr::pointer> constexpr compare_three_way_result_t::pointer, typename unique_ptr::pointer> operator<=>(const unique_ptr& x, const unique_ptr& y); ` [11](#special-11) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3325) *Returns*: compare_three_way()(x.get(), y.get())[.](#special-11.sentence-1) [🔗](#lib:operator==,unique_ptr_) `template constexpr bool operator==(const unique_ptr& x, nullptr_t) noexcept; ` [12](#special-12) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3337) *Returns*: !x[.](#special-12.sentence-1) [🔗](#lib:operator%3c,unique_ptr_) `template constexpr bool operator<(const unique_ptr& x, nullptr_t); template constexpr bool operator<(nullptr_t, const unique_ptr& x); ` [13](#special-13) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3351) *Preconditions*: The specialization less​::​pointer> is a function object type ([[function.objects]](function.objects "22.10 Function objects")) that induces a strict weak ordering ([[alg.sorting]](alg.sorting "26.8 Sorting and related operations")) on the pointer values[.](#special-13.sentence-1) [14](#special-14) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3357) *Returns*: The first function template returnsless::pointer>()(x.get(), nullptr) The second function template returnsless::pointer>()(nullptr, x.get()) [🔗](#lib:operator%3e,unique_ptr_) `template constexpr bool operator>(const unique_ptr& x, nullptr_t); template constexpr bool operator>(nullptr_t, const unique_ptr& x); ` [15](#special-15) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3378) *Returns*: The first function template returns nullptr < x[.](#special-15.sentence-1) The second function template returns x < nullptr[.](#special-15.sentence-2) [🔗](#lib:operator%3c=,unique_ptr_) `template constexpr bool operator<=(const unique_ptr& x, nullptr_t); template constexpr bool operator<=(nullptr_t, const unique_ptr& x); ` [16](#special-16) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3393) *Returns*: The first function template returns !(nullptr < x)[.](#special-16.sentence-1) The second function template returns !(x < nullptr)[.](#special-16.sentence-2) [🔗](#lib:operator%3e=,unique_ptr_) `template constexpr bool operator>=(const unique_ptr& x, nullptr_t); template constexpr bool operator>=(nullptr_t, const unique_ptr& x); ` [17](#special-17) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3408) *Returns*: The first function template returns !(x < nullptr)[.](#special-17.sentence-1) The second function template returns !(nullptr < x)[.](#special-17.sentence-2) [🔗](#lib:operator%3c=%3e,unique_ptr_) `template requires [three_way_comparable](cmp.concept#concept:three_way_comparable "17.12.4 Concept three_­way_­comparable [cmp.concept]")::pointer> constexpr compare_three_way_result_t::pointer> operator<=>(const unique_ptr& x, nullptr_t); ` [18](#special-18) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3423) *Returns*: compare_three_way()(x.get(), static_cast::pointer>(nullptr)). #### [20.3.1.7](#io) I/O [[unique.ptr.io]](unique.ptr.io) [🔗](#lib:operator%3c%3c,unique_ptr) `template basic_ostream& operator<<(basic_ostream& os, const unique_ptr& p); ` [1](#io-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3439) *Constraints*: os << p.get() is a valid expression[.](#io-1.sentence-1) [2](#io-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3443) *Effects*: Equivalent to: os << p.get(); [3](#io-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3447) *Returns*: os[.](#io-3.sentence-1)