[unique.ptr.single]

# 20 Memory management library [[mem]](./#mem)

## 20.3 Smart pointers [[smartptr]](smartptr#unique.ptr.single)

### 20.3.1 Unique-ownership pointers [[unique.ptr]](unique.ptr#single)

#### 20.3.1.3 unique_ptr for single objects [unique.ptr.single]

#### [20.3.1.3.1](#general) General [[unique.ptr.single.general]](unique.ptr.single.general)

[ð](#lib:unique_ptr)

namespace std {template<class T, class D = default_delete<T>> class unique_ptr {public:using pointer = *see below*; using element_type = T; using deleter_type = D; // [[unique.ptr.single.ctor]](#ctor "20.3.1.3.2 Constructors"), constructorsconstexpr unique_ptr() noexcept; constexpr explicit unique_ptr(type_identity_t<pointer> p) noexcept; constexpr unique_ptr(type_identity_t<pointer> p, *see below* d1) noexcept; constexpr unique_ptr(type_identity_t<pointer> p, *see below* d2) noexcept; constexpr unique_ptr(unique_ptr&& u) noexcept; constexpr unique_ptr(nullptr_t) noexcept; template<class U, class E>constexpr unique_ptr(unique_ptr<U, E>&& u) noexcept; // [[unique.ptr.single.dtor]](#dtor "20.3.1.3.3 Destructor"), destructorconstexpr ~unique_ptr(); // [[unique.ptr.single.asgn]](#asgn "20.3.1.3.4 Assignment"), assignmentconstexpr unique_ptr& operator=(unique_ptr&& u) noexcept; template<class U, class E>constexpr unique_ptr& operator=(unique_ptr<U, E>&& u) noexcept; constexpr unique_ptr& operator=(nullptr_t) noexcept; // [[unique.ptr.single.observers]](#observers "20.3.1.3.5 Observers"), observersconstexpr add_lvalue_reference_t<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]](#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](#general-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2407)

A program that instantiates the definition of unique_ptr<T, D> is ill-formed if T* is an invalid type[.](#general-1.sentence-1)

[*Note [1](#general-note-1)*:

This prevents the instantiation of specializations such asunique_ptr<T&, D> and unique_ptr<int() const, D>[.](#general-1.sentence-2)

â *end note*]

[2](#general-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2415)

The default type for the template parameter D isdefault_delete[.](#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<T, D>​::​pointer, the expressiond(ptr) is valid and has the effect of disposing of the
pointer as appropriate for that deleter[.](#general-2.sentence-2)

[3](#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"))[.](#general-3.sentence-1)

[4](#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<D>​::​pointer is valid and denotes a
type ([[temp.deduct]](temp.deduct "13.10.3 Template argument deduction")), then unique_ptr<T,
D>​::​pointer shall be a synonym for remove_reference_t<D>​::​pointer[.](#general-4.sentence-1)

Otherwiseunique_ptr<T, D>​::​pointer shall be a synonym for element_type*[.](#general-4.sentence-2)

The type unique_ptr<T,
D>​::​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"))[.](#general-4.sentence-3)

[5](#general-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2439)

[*Example [1](#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<X>, the types A​::​pointer,A​::​const_pointer, A​::​void_pointer, and A​::​const_void_pointer may be used as unique_ptr<T, D>​::​pointer[.](#general-5.sentence-1)

â *end example*]

#### [20.3.1.3.2](#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](#ctor-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2456)

*Constraints*: is_pointer_v<deleter_type> is false andis_default_constructible_v<deleter_type> is true[.](#ctor-1.sentence-1)

[2](#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[.](#ctor-2.sentence-1)

[3](#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[.](#ctor-3.sentence-1)

[4](#ctor-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2471)

*Postconditions*: get() == nullptr[.](#ctor-4.sentence-1)

get_deleter() returns a reference to the stored deleter[.](#ctor-4.sentence-2)

[ð](#lib:unique_ptr,constructor_)

`constexpr explicit unique_ptr(type_identity_t<pointer> p) noexcept;
`

[5](#ctor-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2483)

*Constraints*: is_pointer_v<deleter_type> is false andis_default_constructible_v<deleter_type> is true[.](#ctor-5.sentence-1)

[6](#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[.](#ctor-6.sentence-1)

[7](#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[.](#ctor-7.sentence-1)

[8](#ctor-8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2499)

*Postconditions*: get() == p[.](#ctor-8.sentence-1)

get_deleter() returns a reference to the stored deleter[.](#ctor-8.sentence-2)

[ð](#lib:unique_ptr,constructor__)

`constexpr unique_ptr(type_identity_t<pointer> p, const D& d) noexcept;
constexpr unique_ptr(type_identity_t<pointer> p, remove_reference_t<D>&& d) noexcept;
`

[9](#ctor-9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2512)

*Constraints*: is_constructible_v<D, decltype(d)> is true[.](#ctor-9.sentence-1)

[10](#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[.](#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[.](#ctor-10.sentence-2)

[11](#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<decltype(d)>(d)[.](#ctor-11.sentence-1)

[12](#ctor-12)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2531)

*Postconditions*: get() == p[.](#ctor-12.sentence-1)

get_deleter() returns a reference to the stored
deleter[.](#ctor-12.sentence-2)

If D is a reference type then get_deleter() returns a reference to the lvalue d[.](#ctor-12.sentence-3)

[13](#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[.](#ctor-13.sentence-1)

[14](#ctor-14)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2543)

[*Example [1](#ctor-example-1)*: D d;
unique_ptr<int, D> p1(new int, D()); // D must be [*Cpp17MoveConstructible*](utility.arg.requirements#:Cpp17MoveConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") unique_ptr<int, D> p2(new int, d); // D must be [*Cpp17CopyConstructible*](utility.arg.requirements#:Cpp17CopyConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") unique_ptr<int, D&> p3(new int, d); // p3 holds a reference to d unique_ptr<int, const D&> 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](#ctor-15)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2562)

*Constraints*: is_move_constructible_v<D> is true[.](#ctor-15.sentence-1)

[16](#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"))[.](#ctor-16.sentence-1)

Construction
of the deleter from an rvalue of type D does not
throw an exception[.](#ctor-16.sentence-2)

[17](#ctor-17)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2575)

*Effects*: Constructs a unique_ptr fromu[.](#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[.](#ctor-17.sentence-2)

[*Note [1](#ctor-note-1)*:

The
construction of the deleter can be implemented with std​::​forward<D>[.](#ctor-17.sentence-3)

â *end note*]

[18](#ctor-18)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2586)

*Postconditions*: get() yields the value u.get() yielded before the construction[.](#ctor-18.sentence-1)

u.get() == nullptr[.](#ctor-18.sentence-2)

get_deleter() returns a reference
to the stored deleter that was constructed fromu.get_deleter()[.](#ctor-18.sentence-3)

If D is a reference type thenget_deleter() and u.get_deleter() both reference
the same lvalue deleter[.](#ctor-18.sentence-4)

[ð](#lib:unique_ptr,constructor____)

`template<class U, class E> constexpr unique_ptr(unique_ptr<U, E>&& u) noexcept;
`

[19](#ctor-19)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2603)

*Constraints*: 

- [(19.1)](#ctor-19.1)

unique_ptr<U, E>​::​pointer is implicitly convertible to pointer,

- [(19.2)](#ctor-19.2)

U is not an array type, and

- [(19.3)](#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[.](#ctor-19.sentence-1)

[20](#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[.](#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[.](#ctor-20.sentence-2)

[21](#ctor-21)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2621)

*Effects*: Constructs a unique_ptr from u[.](#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[.](#ctor-21.sentence-2)

[*Note [2](#ctor-note-2)*:

The deleter constructor can be implemented withstd​::​forward<E>[.](#ctor-21.sentence-3)

â *end note*]

[22](#ctor-22)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2632)

*Postconditions*: get() yields the value u.get() yielded before the construction[.](#ctor-22.sentence-1)

u.get() == nullptr[.](#ctor-22.sentence-2)

get_deleter() returns a reference
to the stored deleter that was constructed fromu.get_deleter()[.](#ctor-22.sentence-3)

#### [20.3.1.3.3](#dtor) Destructor [[unique.ptr.single.dtor]](unique.ptr.single.dtor)

[ð](#lib:unique_ptr,destructor)

`constexpr ~unique_ptr();
`

[1](#dtor-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2649)

*Effects*: Equivalent to:if (get()) get_deleter()(get());

[*Note [1](#dtor-note-1)*:

The use of default_delete requires T to be a complete type[.](#dtor-1.sentence-1)

â *end note*]

[2](#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[.](#dtor-2.sentence-1)

#### [20.3.1.3.4](#asgn) Assignment [[unique.ptr.single.asgn]](unique.ptr.single.asgn)

[ð](#lib:operator=,unique_ptr)

`constexpr unique_ptr& operator=(unique_ptr&& u) noexcept;
`

[1](#asgn-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2671)

*Constraints*: is_move_assignable_v<D> is true[.](#asgn-1.sentence-1)

[2](#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[.](#asgn-2.sentence-1)

Otherwise, D is a reference type;remove_reference_t<D> 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[.](#asgn-2.sentence-2)

[3](#asgn-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2685)

*Effects*: Calls reset(u.release()) followed byget_deleter() = std​::​forward<D>(u.get_deleter())[.](#asgn-3.sentence-1)

[4](#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[.](#asgn-4.sentence-1)

[5](#asgn-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2696)

*Returns*: *this[.](#asgn-5.sentence-1)

[ð](#lib:operator=,unique_ptr_)

`template<class U, class E> constexpr unique_ptr& operator=(unique_ptr<U, E>&& u) noexcept;
`

[6](#asgn-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2707)

*Constraints*: 

- [(6.1)](#asgn-6.1)

unique_ptr<U, E>​::​pointer is implicitly convertible to pointer, and

- [(6.2)](#asgn-6.2)

U is not an array type, and

- [(6.3)](#asgn-6.3)

is_assignable_v<D&, E&&> is true[.](#asgn-6.sentence-1)

[7](#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[.](#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[.](#asgn-7.sentence-2)

[8](#asgn-8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2724)

*Effects*: Calls reset(u.release()) followed byget_deleter() = std​::​forward<E>(u.get_deleter())[.](#asgn-8.sentence-1)

[9](#asgn-9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2729)

*Postconditions*: u.get() == nullptr[.](#asgn-9.sentence-1)

[10](#asgn-10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2733)

*Returns*: *this[.](#asgn-10.sentence-1)

[ð](#lib:operator=,unique_ptr__)

`constexpr unique_ptr& operator=(nullptr_t) noexcept;
`

[11](#asgn-11)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2744)

*Effects*: As if by reset()[.](#asgn-11.sentence-1)

[12](#asgn-12)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2748)

*Postconditions*: get() == nullptr[.](#asgn-12.sentence-1)

[13](#asgn-13)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2752)

*Returns*: *this[.](#asgn-13.sentence-1)

#### [20.3.1.3.5](#observers) Observers [[unique.ptr.single.observers]](unique.ptr.single.observers)

[ð](#lib:operator*,unique_ptr)

`constexpr add_lvalue_reference_t<T> operator*() const noexcept(noexcept(*declval<pointer>()));
`

[1](#observers-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2765)

*Mandates*: reference_converts_from_temporary_v<add_lvalue_reference_t<T>, decltype(  
*declval<pointer>())> is false[.](#observers-1.sentence-1)

[2](#observers-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2769)

*Preconditions*: get() != nullptr is true[.](#observers-2.sentence-1)

[3](#observers-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2773)

*Returns*: *get()[.](#observers-3.sentence-1)

[ð](#lib:operator-%3e,unique_ptr)

`constexpr pointer operator->() const noexcept;
`

[4](#observers-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2785)

*Preconditions*: get() != nullptr[.](#observers-4.sentence-1)

[5](#observers-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2789)

*Returns*: get()[.](#observers-5.sentence-1)

[6](#observers-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2793)

[*Note [1](#observers-note-1)*:

The use of this function typically requires that T be a complete type[.](#observers-6.sentence-1)

â *end note*]

[ð](#lib:get,unique_ptr)

`constexpr pointer get() const noexcept;
`

[7](#observers-7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2805)

*Returns*: The stored pointer[.](#observers-7.sentence-1)

[ð](#lib:get_deleter,unique_ptr)

`constexpr deleter_type& get_deleter() noexcept;
constexpr const deleter_type& get_deleter() const noexcept;
`

[8](#observers-8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2817)

*Returns*: A reference to the stored deleter[.](#observers-8.sentence-1)

[ð](#lib:operator_bool,unique_ptr)

`constexpr explicit operator bool() const noexcept;
`

[9](#observers-9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2828)

*Returns*: get() != nullptr[.](#observers-9.sentence-1)

#### [20.3.1.3.6](#modifiers) Modifiers [[unique.ptr.single.modifiers]](unique.ptr.single.modifiers)

[ð](#lib:release,unique_ptr)

`constexpr pointer release() noexcept;
`

[1](#modifiers-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2841)

*Postconditions*: get() == nullptr[.](#modifiers-1.sentence-1)

[2](#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[.](#modifiers-2.sentence-1)

[ð](#lib:reset,unique_ptr)

`constexpr void reset(pointer p = pointer()) noexcept;
`

[3](#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](#modifiers-note-1)*:

The order of these operations is significant
because the call to get_deleter() might destroy *this[.](#modifiers-3.sentence-1)

â *end note*]

[4](#modifiers-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2867)

*Postconditions*: get() == p[.](#modifiers-4.sentence-1)

[*Note [2](#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[.](#modifiers-4.sentence-2)

â *end note*]

[5](#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[.](#modifiers-5.sentence-1)

[ð](#lib:swap,unique_ptr)

`constexpr void swap(unique_ptr& u) noexcept;
`

[6](#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[.](#modifiers-6.sentence-1)

[7](#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[.](#modifiers-7.sentence-1)
