From Jason Turner

[unique.ptr]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmplqu9v8b9/{from.md → to.md} +124 -120
tmp/tmplqu9v8b9/{from.md → to.md} RENAMED
@@ -1,6 +1,8 @@
1
- ### Class template `unique_ptr` <a id="unique.ptr">[[unique.ptr]]</a>
 
 
2
 
3
  A *unique pointer* is an object that owns another object and manages
4
  that other object through a pointer. More precisely, a unique pointer is
5
  an object *u* that stores a pointer to a second object *p* and will
6
  dispose of *p* when *u* is itself destroyed (e.g., when leaving block
@@ -15,11 +17,11 @@ denote the associated deleter. Upon request, *u* can *reset* (replace)
15
  *u.p* and *u.d* with another pointer and deleter, but properly disposes
16
  of its owned object via the associated deleter before such replacement
17
  is considered completed.
18
 
19
  Each object of a type `U` instantiated from the `unique_ptr` template
20
- specified in this subclause has the strict ownership semantics,
21
  specified above, of a unique pointer. In partial satisfaction of these
22
  semantics, each such `U` is *Cpp17MoveConstructible* and
23
  *Cpp17MoveAssignable*, but is not *Cpp17CopyConstructible* nor
24
  *Cpp17CopyAssignable*. The template parameter `T` of `unique_ptr` may be
25
  an incomplete type.
@@ -43,27 +45,27 @@ type.
43
 
44
  ``` cpp
45
  namespace std {
46
  template<class T> struct default_delete {
47
  constexpr default_delete() noexcept = default;
48
- template<class U> default_delete(const default_delete<U>&) noexcept;
49
- void operator()(T*) const;
50
  };
51
  }
52
  ```
53
 
54
  ``` cpp
55
- template<class U> default_delete(const default_delete<U>& other) noexcept;
56
  ```
57
 
58
  *Constraints:* `U*` is implicitly convertible to `T*`.
59
 
60
  *Effects:* Constructs a `default_delete` object from another
61
  `default_delete<U>` object.
62
 
63
  ``` cpp
64
- void operator()(T* ptr) const;
65
  ```
66
 
67
  *Mandates:* `T` is a complete type.
68
 
69
  *Effects:* Calls `delete` on `ptr`.
@@ -72,76 +74,78 @@ void operator()(T* ptr) const;
72
 
73
  ``` cpp
74
  namespace std {
75
  template<class T> struct default_delete<T[]> {
76
  constexpr default_delete() noexcept = default;
77
- template<class U> default_delete(const default_delete<U[]>&) noexcept;
78
- template<class U> void operator()(U* ptr) const;
79
  };
80
  }
81
  ```
82
 
83
  ``` cpp
84
- template<class U> default_delete(const default_delete<U[]>& other) noexcept;
85
  ```
86
 
87
  *Constraints:* `U(*)[]` is convertible to `T(*)[]`.
88
 
89
  *Effects:* Constructs a `default_delete` object from another
90
  `default_delete<U[]>` object.
91
 
92
  ``` cpp
93
- template<class U> void operator()(U* ptr) const;
94
  ```
95
 
 
 
96
  *Mandates:* `U` is a complete type.
97
 
98
- *Constraints:* `U(*)[]` is convertible to `T(*)[]`.
99
-
100
  *Effects:* Calls `delete[]` on `ptr`.
101
 
102
  #### `unique_ptr` for single objects <a id="unique.ptr.single">[[unique.ptr.single]]</a>
103
 
 
 
104
  ``` cpp
105
  namespace std {
106
  template<class T, class D = default_delete<T>> class unique_ptr {
107
  public:
108
  using pointer = see below;
109
  using element_type = T;
110
  using deleter_type = D;
111
 
112
  // [unique.ptr.single.ctor], constructors
113
  constexpr unique_ptr() noexcept;
114
- explicit unique_ptr(pointer p) noexcept;
115
- unique_ptr(pointer p, see below d1) noexcept;
116
- unique_ptr(pointer p, see below d2) noexcept;
117
- unique_ptr(unique_ptr&& u) noexcept;
118
  constexpr unique_ptr(nullptr_t) noexcept;
119
  template<class U, class E>
120
- unique_ptr(unique_ptr<U, E>&& u) noexcept;
121
 
122
  // [unique.ptr.single.dtor], destructor
123
- ~unique_ptr();
124
 
125
  // [unique.ptr.single.asgn], assignment
126
- unique_ptr& operator=(unique_ptr&& u) noexcept;
127
  template<class U, class E>
128
- unique_ptr& operator=(unique_ptr<U, E>&& u) noexcept;
129
- unique_ptr& operator=(nullptr_t) noexcept;
130
 
131
  // [unique.ptr.single.observers], observers
132
- add_lvalue_reference_t<T> operator*() const;
133
- pointer operator->() const noexcept;
134
- pointer get() const noexcept;
135
- deleter_type& get_deleter() noexcept;
136
- const deleter_type& get_deleter() const noexcept;
137
- explicit operator bool() const noexcept;
138
 
139
  // [unique.ptr.single.modifiers], modifiers
140
- pointer release() noexcept;
141
- void reset(pointer p = pointer()) noexcept;
142
- void swap(unique_ptr& u) noexcept;
143
 
144
  // disable copy from lvalue
145
  unique_ptr(const unique_ptr&) = delete;
146
  unique_ptr& operator=(const unique_ptr&) = delete;
147
  };
@@ -165,46 +169,43 @@ D>::pointer` shall be a synonym for `remove_reference_t<D>::pointer`.
165
  Otherwise `unique_ptr<T, D>::pointer` shall be a synonym for
166
  `element_type*`. The type `unique_ptr<T,
167
  D>::pointer` shall meet the *Cpp17NullablePointer* requirements (
168
  [[cpp17.nullablepointer]]).
169
 
170
- [*Example 1*: Given an allocator type `X` ([[cpp17.allocator]]) and
171
- letting `A` be a synonym for `allocator_traits<X>`, the types
172
- `A::pointer`, `A::const_pointer`, `A::void_pointer`, and
173
- `A::const_void_pointer` may be used as
174
  `unique_ptr<T, D>::pointer`. — *end example*]
175
 
176
  ##### Constructors <a id="unique.ptr.single.ctor">[[unique.ptr.single.ctor]]</a>
177
 
178
  ``` cpp
179
  constexpr unique_ptr() noexcept;
180
  constexpr unique_ptr(nullptr_t) noexcept;
181
  ```
182
 
 
 
 
183
  *Preconditions:* `D` meets the *Cpp17DefaultConstructible* requirements
184
  ([[cpp17.defaultconstructible]]), and that construction does not throw
185
  an exception.
186
 
187
- *Constraints:* `is_pointer_v<deleter_type>` is `false` and
188
- `is_default_constructible_v<deleter_type>` is `true`.
189
-
190
  *Effects:* Constructs a `unique_ptr` object that owns nothing,
191
  value-initializing the stored pointer and the stored deleter.
192
 
193
  *Ensures:* `get() == nullptr`. `get_deleter()` returns a reference to
194
  the stored deleter.
195
 
196
  ``` cpp
197
- explicit unique_ptr(pointer p) noexcept;
198
  ```
199
 
200
  *Constraints:* `is_pointer_v<deleter_type>` is `false` and
201
  `is_default_constructible_v<deleter_type>` is `true`.
202
 
203
- *Mandates:* This constructor is not selected by class template argument
204
- deduction [[over.match.class.deduct]].
205
-
206
  *Preconditions:* `D` meets the *Cpp17DefaultConstructible* requirements
207
  ([[cpp17.defaultconstructible]]), and that construction does not throw
208
  an exception.
209
 
210
  *Effects:* Constructs a `unique_ptr` which owns `p`, initializing the
@@ -212,19 +213,16 @@ stored pointer with `p` and value-initializing the stored deleter.
212
 
213
  *Ensures:* `get() == p`. `get_deleter()` returns a reference to the
214
  stored deleter.
215
 
216
  ``` cpp
217
- unique_ptr(pointer p, const D& d) noexcept;
218
- unique_ptr(pointer p, remove_reference_t<D>&& d) noexcept;
219
  ```
220
 
221
  *Constraints:* `is_constructible_v<D, decltype(d)>` is `true`.
222
 
223
- *Mandates:* These constructors are not selected by class template
224
- argument deduction [[over.match.class.deduct]].
225
-
226
  *Preconditions:* For the first constructor, if `D` is not a reference
227
  type, `D` meets the *Cpp17CopyConstructible* requirements and such
228
  construction does not exit via an exception. For the second constructor,
229
  if `D` is not a reference type, `D` meets the *Cpp17MoveConstructible*
230
  requirements and such construction does not exit via an exception.
@@ -252,11 +250,11 @@ unique_ptr<int, const D&> p4(new int, D()); // error: rvalue deleter object comb
252
  ```
253
 
254
  — *end example*]
255
 
256
  ``` cpp
257
- unique_ptr(unique_ptr&& u) noexcept;
258
  ```
259
 
260
  *Constraints:* `is_move_constructible_v<D>` is `true`.
261
 
262
  *Preconditions:* If `D` is not a reference type, `D` meets the
@@ -276,11 +274,11 @@ construction. `u.get() == nullptr`. `get_deleter()` returns a reference
276
  to the stored deleter that was constructed from `u.get_deleter()`. If
277
  `D` is a reference type then `get_deleter()` and `u.get_deleter()` both
278
  reference the same lvalue deleter.
279
 
280
  ``` cpp
281
- template<class U, class E> unique_ptr(unique_ptr<U, E>&& u) noexcept;
282
  ```
283
 
284
  *Constraints:*
285
 
286
  - `unique_ptr<U, E>::pointer` is implicitly convertible to `pointer`,
@@ -306,26 +304,25 @@ construction. `u.get() == nullptr`. `get_deleter()` returns a reference
306
  to the stored deleter that was constructed from `u.get_deleter()`.
307
 
308
  ##### Destructor <a id="unique.ptr.single.dtor">[[unique.ptr.single.dtor]]</a>
309
 
310
  ``` cpp
311
- ~unique_ptr();
312
  ```
313
 
314
- *Preconditions:* The expression `get_deleter()(get())` is well-formed,
315
- has well-defined behavior, and does not throw exceptions.
316
 
317
  [*Note 3*: The use of `default_delete` requires `T` to be a complete
318
  type. — *end note*]
319
 
320
- *Effects:* If `get() == nullptr` there are no effects. Otherwise
321
- `get_deleter()(get())`.
322
 
323
  ##### Assignment <a id="unique.ptr.single.asgn">[[unique.ptr.single.asgn]]</a>
324
 
325
  ``` cpp
326
- unique_ptr& operator=(unique_ptr&& u) noexcept;
327
  ```
328
 
329
  *Constraints:* `is_move_assignable_v<D>` is `true`.
330
 
331
  *Preconditions:* If `D` is not a reference type, `D` meets the
@@ -336,16 +333,17 @@ meets the *Cpp17CopyAssignable* requirements and assignment of the
336
  deleter from an lvalue of type `D` does not throw an exception.
337
 
338
  *Effects:* Calls `reset(u.release())` followed by
339
  `get_deleter() = std::forward<D>(u.get_deleter())`.
340
 
 
 
 
341
  *Returns:* `*this`.
342
 
343
- *Ensures:* `u.get() == nullptr`.
344
-
345
  ``` cpp
346
- template<class U, class E> unique_ptr& operator=(unique_ptr<U, E>&& u) noexcept;
347
  ```
348
 
349
  *Constraints:*
350
 
351
  - `unique_ptr<U, E>::pointer` is implicitly convertible to `pointer`,
@@ -360,16 +358,16 @@ deleter from an lvalue of type `E` is well-formed and does not throw an
360
  exception.
361
 
362
  *Effects:* Calls `reset(u.release())` followed by
363
  `get_deleter() = std::forward<E>(u.get_deleter())`.
364
 
365
- *Returns:* `*this`.
366
-
367
  *Ensures:* `u.get() == nullptr`.
368
 
 
 
369
  ``` cpp
370
- unique_ptr& operator=(nullptr_t) noexcept;
371
  ```
372
 
373
  *Effects:* As if by `reset()`.
374
 
375
  *Ensures:* `get() == nullptr`.
@@ -377,128 +375,130 @@ unique_ptr& operator=(nullptr_t) noexcept;
377
  *Returns:* `*this`.
378
 
379
  ##### Observers <a id="unique.ptr.single.observers">[[unique.ptr.single.observers]]</a>
380
 
381
  ``` cpp
382
- add_lvalue_reference_t<T> operator*() const;
383
  ```
384
 
385
  *Preconditions:* `get() != nullptr`.
386
 
387
  *Returns:* `*get()`.
388
 
389
  ``` cpp
390
- pointer operator->() const noexcept;
391
  ```
392
 
393
  *Preconditions:* `get() != nullptr`.
394
 
395
  *Returns:* `get()`.
396
 
397
  [*Note 4*: The use of this function typically requires that `T` be a
398
  complete type. — *end note*]
399
 
400
  ``` cpp
401
- pointer get() const noexcept;
402
  ```
403
 
404
  *Returns:* The stored pointer.
405
 
406
  ``` cpp
407
- deleter_type& get_deleter() noexcept;
408
- const deleter_type& get_deleter() const noexcept;
409
  ```
410
 
411
  *Returns:* A reference to the stored deleter.
412
 
413
  ``` cpp
414
- explicit operator bool() const noexcept;
415
  ```
416
 
417
  *Returns:* `get() != nullptr`.
418
 
419
  ##### Modifiers <a id="unique.ptr.single.modifiers">[[unique.ptr.single.modifiers]]</a>
420
 
421
  ``` cpp
422
- pointer release() noexcept;
423
  ```
424
 
425
  *Ensures:* `get() == nullptr`.
426
 
427
  *Returns:* The value `get()` had at the start of the call to `release`.
428
 
429
  ``` cpp
430
- void reset(pointer p = pointer()) noexcept;
431
  ```
432
 
433
- *Preconditions:* The expression `get_deleter()(get())` is well-formed,
434
- has well-defined behavior, and does not throw exceptions.
435
-
436
- *Effects:* Assigns `p` to the stored pointer, and then if and only if
437
- the old value of the stored pointer, `old_p`, was not equal to
438
- `nullptr`, calls `get_deleter()(old_p)`.
439
 
440
  [*Note 5*: The order of these operations is significant because the
441
- call to `get_deleter()` may destroy `*this`. — *end note*]
442
 
443
  *Ensures:* `get() == p`.
444
 
445
  [*Note 6*: The postcondition does not hold if the call to
446
  `get_deleter()` destroys `*this` since `this->get()` is no longer a
447
  valid expression. — *end note*]
448
 
 
 
 
449
  ``` cpp
450
- void swap(unique_ptr& u) noexcept;
451
  ```
452
 
453
  *Preconditions:* `get_deleter()` is swappable [[swappable.requirements]]
454
  and does not throw an exception under `swap`.
455
 
456
  *Effects:* Invokes `swap` on the stored pointers and on the stored
457
  deleters of `*this` and `u`.
458
 
459
  #### `unique_ptr` for array objects with a runtime length <a id="unique.ptr.runtime">[[unique.ptr.runtime]]</a>
460
 
 
 
461
  ``` cpp
462
  namespace std {
463
  template<class T, class D> class unique_ptr<T[], D> {
464
  public:
465
  using pointer = see below;
466
  using element_type = T;
467
  using deleter_type = D;
468
 
469
  // [unique.ptr.runtime.ctor], constructors
470
  constexpr unique_ptr() noexcept;
471
- template<class U> explicit unique_ptr(U p) noexcept;
472
- template<class U> unique_ptr(U p, see below d) noexcept;
473
- template<class U> unique_ptr(U p, see below d) noexcept;
474
- unique_ptr(unique_ptr&& u) noexcept;
475
  template<class U, class E>
476
- unique_ptr(unique_ptr<U, E>&& u) noexcept;
477
  constexpr unique_ptr(nullptr_t) noexcept;
478
 
479
  // destructor
480
- ~unique_ptr();
481
 
482
  // assignment
483
- unique_ptr& operator=(unique_ptr&& u) noexcept;
484
  template<class U, class E>
485
- unique_ptr& operator=(unique_ptr<U, E>&& u) noexcept;
486
- unique_ptr& operator=(nullptr_t) noexcept;
487
 
488
  // [unique.ptr.runtime.observers], observers
489
- T& operator[](size_t i) const;
490
- pointer get() const noexcept;
491
- deleter_type& get_deleter() noexcept;
492
- const deleter_type& get_deleter() const noexcept;
493
- explicit operator bool() const noexcept;
494
 
495
  // [unique.ptr.runtime.modifiers], modifiers
496
- pointer release() noexcept;
497
- template<class U> void reset(U p) noexcept;
498
- void reset(nullptr_t = nullptr) noexcept;
499
- void swap(unique_ptr& u) noexcept;
500
 
501
  // disable copy from lvalue
502
  unique_ptr(const unique_ptr&) = delete;
503
  unique_ptr& operator=(const unique_ptr&) = delete;
504
  };
@@ -524,11 +524,11 @@ primary template.
524
  The template argument `T` shall be a complete type.
525
 
526
  ##### Constructors <a id="unique.ptr.runtime.ctor">[[unique.ptr.runtime.ctor]]</a>
527
 
528
  ``` cpp
529
- template<class U> explicit unique_ptr(U p) noexcept;
530
  ```
531
 
532
  This constructor behaves the same as the constructor in the primary
533
  template that takes a single parameter of type `pointer`.
534
 
@@ -537,12 +537,12 @@ template that takes a single parameter of type `pointer`.
537
  - `U` is the same type as `pointer`, or
538
  - `pointer` is the same type as `element_type*`, `U` is a pointer type
539
  `V*`, and `V(*)[]` is convertible to `element_type(*)[]`.
540
 
541
  ``` cpp
542
- template<class U> unique_ptr(U p, see below d) noexcept;
543
- template<class U> unique_ptr(U p, see below d) noexcept;
544
  ```
545
 
546
  These constructors behave the same as the constructors in the primary
547
  template that take a parameter of type `pointer` and a second parameter.
548
 
@@ -552,11 +552,11 @@ template that take a parameter of type `pointer` and a second parameter.
552
  - `U` is `nullptr_t`, or
553
  - `pointer` is the same type as `element_type*`, `U` is a pointer type
554
  `V*`, and `V(*)[]` is convertible to `element_type(*)[]`.
555
 
556
  ``` cpp
557
- template<class U, class E> unique_ptr(unique_ptr<U, E>&& u) noexcept;
558
  ```
559
 
560
  This constructor behaves the same as in the primary template.
561
 
562
  *Constraints:* Where `UP` is `unique_ptr<U, E>`:
@@ -572,11 +572,11 @@ This constructor behaves the same as in the primary template.
572
  primary template. — *end note*]
573
 
574
  ##### Assignment <a id="unique.ptr.runtime.asgn">[[unique.ptr.runtime.asgn]]</a>
575
 
576
  ``` cpp
577
- template<class U, class E> unique_ptr& operator=(unique_ptr<U, E>&& u)noexcept;
578
  ```
579
 
580
  This operator behaves the same as in the primary template.
581
 
582
  *Constraints:* Where `UP` is `unique_ptr<U, E>`:
@@ -591,28 +591,28 @@ This operator behaves the same as in the primary template.
591
  primary template. — *end note*]
592
 
593
  ##### Observers <a id="unique.ptr.runtime.observers">[[unique.ptr.runtime.observers]]</a>
594
 
595
  ``` cpp
596
- T& operator[](size_t i) const;
597
  ```
598
 
599
  *Preconditions:* `i` < the number of elements in the array to which the
600
  stored pointer points.
601
 
602
  *Returns:* `get()[i]`.
603
 
604
  ##### Modifiers <a id="unique.ptr.runtime.modifiers">[[unique.ptr.runtime.modifiers]]</a>
605
 
606
  ``` cpp
607
- void reset(nullptr_t p = nullptr) noexcept;
608
  ```
609
 
610
  *Effects:* Equivalent to `reset(pointer())`.
611
 
612
  ``` cpp
613
- template<class U> void reset(U p) noexcept;
614
  ```
615
 
616
  This function behaves the same as the `reset` member of the primary
617
  template.
618
 
@@ -623,19 +623,19 @@ template.
623
  `V*`, and `V(*)[]` is convertible to `element_type(*)[]`.
624
 
625
  #### Creation <a id="unique.ptr.create">[[unique.ptr.create]]</a>
626
 
627
  ``` cpp
628
- template<class T, class... Args> unique_ptr<T> make_unique(Args&&... args);
629
  ```
630
 
631
  *Constraints:* `T` is not an array type.
632
 
633
  *Returns:* `unique_ptr<T>(new T(std::forward<Args>(args)...))`.
634
 
635
  ``` cpp
636
- template<class T> unique_ptr<T> make_unique(size_t n);
637
  ```
638
 
639
  *Constraints:* `T` is an array of unknown bound.
640
 
641
  *Returns:* `unique_ptr<T>(new remove_extent_t<T>[n]())`.
@@ -645,19 +645,19 @@ template<class T, class... Args> unspecified make_unique(Args&&...) = delete;
645
  ```
646
 
647
  *Constraints:* `T` is an array of known bound.
648
 
649
  ``` cpp
650
- template<class T> unique_ptr<T> make_unique_for_overwrite();
651
  ```
652
 
653
  *Constraints:* `T` is not an array type.
654
 
655
  *Returns:* `unique_ptr<T>(new T)`.
656
 
657
  ``` cpp
658
- template<class T> unique_ptr<T> make_unique_for_overwrite(size_t n);
659
  ```
660
 
661
  *Constraints:* `T` is an array of unknown bound.
662
 
663
  *Returns:* `unique_ptr<T>(new remove_extent_t<T>[n])`.
@@ -669,20 +669,20 @@ template<class T, class... Args> unspecified make_unique_for_overwrite(Args&&...
669
  *Constraints:* `T` is an array of known bound.
670
 
671
  #### Specialized algorithms <a id="unique.ptr.special">[[unique.ptr.special]]</a>
672
 
673
  ``` cpp
674
- template<class T, class D> void swap(unique_ptr<T, D>& x, unique_ptr<T, D>& y) noexcept;
675
  ```
676
 
677
  *Constraints:* `is_swappable_v<D>` is `true`.
678
 
679
  *Effects:* Calls `x.swap(y)`.
680
 
681
  ``` cpp
682
  template<class T1, class D1, class T2, class D2>
683
- bool operator==(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
684
  ```
685
 
686
  *Returns:* `x.get() == y.get()`.
687
 
688
  ``` cpp
@@ -740,20 +740,20 @@ template<class T1, class D1, class T2, class D2>
740
 
741
  *Returns:* `compare_three_way()(x.get(), y.get())`.
742
 
743
  ``` cpp
744
  template<class T, class D>
745
- bool operator==(const unique_ptr<T, D>& x, nullptr_t) noexcept;
746
  ```
747
 
748
  *Returns:* `!x`.
749
 
750
  ``` cpp
751
  template<class T, class D>
752
- bool operator<(const unique_ptr<T, D>& x, nullptr_t);
753
  template<class T, class D>
754
- bool operator<(nullptr_t, const unique_ptr<T, D>& x);
755
  ```
756
 
757
  *Preconditions:* The specialization `less<unique_ptr<T, D>::pointer>` is
758
  a function object type [[function.objects]] that induces a strict weak
759
  ordering [[alg.sorting]] on the pointer values.
@@ -770,46 +770,50 @@ The second function template returns
770
  less<unique_ptr<T, D>::pointer>()(nullptr, x.get())
771
  ```
772
 
773
  ``` cpp
774
  template<class T, class D>
775
- bool operator>(const unique_ptr<T, D>& x, nullptr_t);
776
  template<class T, class D>
777
- bool operator>(nullptr_t, const unique_ptr<T, D>& x);
778
  ```
779
 
780
  *Returns:* The first function template returns `nullptr < x`. The second
781
  function template returns `x < nullptr`.
782
 
783
  ``` cpp
784
  template<class T, class D>
785
- bool operator<=(const unique_ptr<T, D>& x, nullptr_t);
786
  template<class T, class D>
787
- bool operator<=(nullptr_t, const unique_ptr<T, D>& x);
788
  ```
789
 
790
  *Returns:* The first function template returns `!(nullptr < x)`. The
791
  second function template returns `!(x < nullptr)`.
792
 
793
  ``` cpp
794
  template<class T, class D>
795
- bool operator>=(const unique_ptr<T, D>& x, nullptr_t);
796
  template<class T, class D>
797
- bool operator>=(nullptr_t, const unique_ptr<T, D>& x);
798
  ```
799
 
800
  *Returns:* The first function template returns `!(x < nullptr)`. The
801
  second function template returns `!(nullptr < x)`.
802
 
803
  ``` cpp
804
  template<class T, class D>
805
- requires three_way_comparable_with<typename unique_ptr<T, D>::pointer, nullptr_t>
806
- compare_three_way_result_t<typename unique_ptr<T, D>::pointer, nullptr_t>
807
  operator<=>(const unique_ptr<T, D>& x, nullptr_t);
808
  ```
809
 
810
- *Returns:* `compare_three_way()(x.get(), nullptr)`.
 
 
 
 
811
 
812
  #### I/O <a id="unique.ptr.io">[[unique.ptr.io]]</a>
813
 
814
  ``` cpp
815
  template<class E, class T, class Y, class D>
 
1
+ ### Unique-ownership pointers <a id="unique.ptr">[[unique.ptr]]</a>
2
+
3
+ #### General <a id="unique.ptr.general">[[unique.ptr.general]]</a>
4
 
5
  A *unique pointer* is an object that owns another object and manages
6
  that other object through a pointer. More precisely, a unique pointer is
7
  an object *u* that stores a pointer to a second object *p* and will
8
  dispose of *p* when *u* is itself destroyed (e.g., when leaving block
 
17
  *u.p* and *u.d* with another pointer and deleter, but properly disposes
18
  of its owned object via the associated deleter before such replacement
19
  is considered completed.
20
 
21
  Each object of a type `U` instantiated from the `unique_ptr` template
22
+ specified in [[unique.ptr]] has the strict ownership semantics,
23
  specified above, of a unique pointer. In partial satisfaction of these
24
  semantics, each such `U` is *Cpp17MoveConstructible* and
25
  *Cpp17MoveAssignable*, but is not *Cpp17CopyConstructible* nor
26
  *Cpp17CopyAssignable*. The template parameter `T` of `unique_ptr` may be
27
  an incomplete type.
 
45
 
46
  ``` cpp
47
  namespace std {
48
  template<class T> struct default_delete {
49
  constexpr default_delete() noexcept = default;
50
+ template<class U> constexpr default_delete(const default_delete<U>&) noexcept;
51
+ constexpr void operator()(T*) const;
52
  };
53
  }
54
  ```
55
 
56
  ``` cpp
57
+ template<class U> constexpr default_delete(const default_delete<U>& other) noexcept;
58
  ```
59
 
60
  *Constraints:* `U*` is implicitly convertible to `T*`.
61
 
62
  *Effects:* Constructs a `default_delete` object from another
63
  `default_delete<U>` object.
64
 
65
  ``` cpp
66
+ constexpr void operator()(T* ptr) const;
67
  ```
68
 
69
  *Mandates:* `T` is a complete type.
70
 
71
  *Effects:* Calls `delete` on `ptr`.
 
74
 
75
  ``` cpp
76
  namespace std {
77
  template<class T> struct default_delete<T[]> {
78
  constexpr default_delete() noexcept = default;
79
+ template<class U> constexpr default_delete(const default_delete<U[]>&) noexcept;
80
+ template<class U> constexpr void operator()(U* ptr) const;
81
  };
82
  }
83
  ```
84
 
85
  ``` cpp
86
+ template<class U> constexpr default_delete(const default_delete<U[]>& other) noexcept;
87
  ```
88
 
89
  *Constraints:* `U(*)[]` is convertible to `T(*)[]`.
90
 
91
  *Effects:* Constructs a `default_delete` object from another
92
  `default_delete<U[]>` object.
93
 
94
  ``` cpp
95
+ template<class U> constexpr void operator()(U* ptr) const;
96
  ```
97
 
98
+ *Constraints:* `U(*)[]` is convertible to `T(*)[]`.
99
+
100
  *Mandates:* `U` is a complete type.
101
 
 
 
102
  *Effects:* Calls `delete[]` on `ptr`.
103
 
104
  #### `unique_ptr` for single objects <a id="unique.ptr.single">[[unique.ptr.single]]</a>
105
 
106
+ ##### General <a id="unique.ptr.single.general">[[unique.ptr.single.general]]</a>
107
+
108
  ``` cpp
109
  namespace std {
110
  template<class T, class D = default_delete<T>> class unique_ptr {
111
  public:
112
  using pointer = see below;
113
  using element_type = T;
114
  using deleter_type = D;
115
 
116
  // [unique.ptr.single.ctor], constructors
117
  constexpr unique_ptr() noexcept;
118
+ constexpr explicit unique_ptr(type_identity_t<pointer> p) noexcept;
119
+ constexpr unique_ptr(type_identity_t<pointer> p, see below d1) noexcept;
120
+ constexpr unique_ptr(type_identity_t<pointer> p, see below d2) noexcept;
121
+ constexpr unique_ptr(unique_ptr&& u) noexcept;
122
  constexpr unique_ptr(nullptr_t) noexcept;
123
  template<class U, class E>
124
+ constexpr unique_ptr(unique_ptr<U, E>&& u) noexcept;
125
 
126
  // [unique.ptr.single.dtor], destructor
127
+ constexpr ~unique_ptr();
128
 
129
  // [unique.ptr.single.asgn], assignment
130
+ constexpr unique_ptr& operator=(unique_ptr&& u) noexcept;
131
  template<class U, class E>
132
+ constexpr unique_ptr& operator=(unique_ptr<U, E>&& u) noexcept;
133
+ constexpr unique_ptr& operator=(nullptr_t) noexcept;
134
 
135
  // [unique.ptr.single.observers], observers
136
+ constexpr add_lvalue_reference_t<T> operator*() const noexcept(see below);
137
+ constexpr pointer operator->() const noexcept;
138
+ constexpr pointer get() const noexcept;
139
+ constexpr deleter_type& get_deleter() noexcept;
140
+ constexpr const deleter_type& get_deleter() const noexcept;
141
+ constexpr explicit operator bool() const noexcept;
142
 
143
  // [unique.ptr.single.modifiers], modifiers
144
+ constexpr pointer release() noexcept;
145
+ constexpr void reset(pointer p = pointer()) noexcept;
146
+ constexpr void swap(unique_ptr& u) noexcept;
147
 
148
  // disable copy from lvalue
149
  unique_ptr(const unique_ptr&) = delete;
150
  unique_ptr& operator=(const unique_ptr&) = delete;
151
  };
 
169
  Otherwise `unique_ptr<T, D>::pointer` shall be a synonym for
170
  `element_type*`. The type `unique_ptr<T,
171
  D>::pointer` shall meet the *Cpp17NullablePointer* requirements (
172
  [[cpp17.nullablepointer]]).
173
 
174
+ [*Example 1*: Given an allocator type `X`
175
+ [[allocator.requirements.general]] and letting `A` be a synonym for
176
+ `allocator_traits<X>`, the types `A::pointer`, `A::const_pointer`,
177
+ `A::void_pointer`, and `A::const_void_pointer` may be used as
178
  `unique_ptr<T, D>::pointer`. — *end example*]
179
 
180
  ##### Constructors <a id="unique.ptr.single.ctor">[[unique.ptr.single.ctor]]</a>
181
 
182
  ``` cpp
183
  constexpr unique_ptr() noexcept;
184
  constexpr unique_ptr(nullptr_t) noexcept;
185
  ```
186
 
187
+ *Constraints:* `is_pointer_v<deleter_type>` is `false` and
188
+ `is_default_constructible_v<deleter_type>` is `true`.
189
+
190
  *Preconditions:* `D` meets the *Cpp17DefaultConstructible* requirements
191
  ([[cpp17.defaultconstructible]]), and that construction does not throw
192
  an exception.
193
 
 
 
 
194
  *Effects:* Constructs a `unique_ptr` object that owns nothing,
195
  value-initializing the stored pointer and the stored deleter.
196
 
197
  *Ensures:* `get() == nullptr`. `get_deleter()` returns a reference to
198
  the stored deleter.
199
 
200
  ``` cpp
201
+ constexpr explicit unique_ptr(type_identity_t<pointer> p) noexcept;
202
  ```
203
 
204
  *Constraints:* `is_pointer_v<deleter_type>` is `false` and
205
  `is_default_constructible_v<deleter_type>` is `true`.
206
 
 
 
 
207
  *Preconditions:* `D` meets the *Cpp17DefaultConstructible* requirements
208
  ([[cpp17.defaultconstructible]]), and that construction does not throw
209
  an exception.
210
 
211
  *Effects:* Constructs a `unique_ptr` which owns `p`, initializing the
 
213
 
214
  *Ensures:* `get() == p`. `get_deleter()` returns a reference to the
215
  stored deleter.
216
 
217
  ``` cpp
218
+ constexpr unique_ptr(type_identity_t<pointer> p, const D& d) noexcept;
219
+ constexpr unique_ptr(type_identity_t<pointer> p, remove_reference_t<D>&& d) noexcept;
220
  ```
221
 
222
  *Constraints:* `is_constructible_v<D, decltype(d)>` is `true`.
223
 
 
 
 
224
  *Preconditions:* For the first constructor, if `D` is not a reference
225
  type, `D` meets the *Cpp17CopyConstructible* requirements and such
226
  construction does not exit via an exception. For the second constructor,
227
  if `D` is not a reference type, `D` meets the *Cpp17MoveConstructible*
228
  requirements and such construction does not exit via an exception.
 
250
  ```
251
 
252
  — *end example*]
253
 
254
  ``` cpp
255
+ constexpr unique_ptr(unique_ptr&& u) noexcept;
256
  ```
257
 
258
  *Constraints:* `is_move_constructible_v<D>` is `true`.
259
 
260
  *Preconditions:* If `D` is not a reference type, `D` meets the
 
274
  to the stored deleter that was constructed from `u.get_deleter()`. If
275
  `D` is a reference type then `get_deleter()` and `u.get_deleter()` both
276
  reference the same lvalue deleter.
277
 
278
  ``` cpp
279
+ template<class U, class E> constexpr unique_ptr(unique_ptr<U, E>&& u) noexcept;
280
  ```
281
 
282
  *Constraints:*
283
 
284
  - `unique_ptr<U, E>::pointer` is implicitly convertible to `pointer`,
 
304
  to the stored deleter that was constructed from `u.get_deleter()`.
305
 
306
  ##### Destructor <a id="unique.ptr.single.dtor">[[unique.ptr.single.dtor]]</a>
307
 
308
  ``` cpp
309
+ constexpr ~unique_ptr();
310
  ```
311
 
312
+ *Effects:* Equivalent to: `if (get()) get_deleter()(get());`
 
313
 
314
  [*Note 3*: The use of `default_delete` requires `T` to be a complete
315
  type. — *end note*]
316
 
317
+ *Remarks:* The behavior is undefined if the evaluation of
318
+ `get_deleter()(get())` throws an exception.
319
 
320
  ##### Assignment <a id="unique.ptr.single.asgn">[[unique.ptr.single.asgn]]</a>
321
 
322
  ``` cpp
323
+ constexpr unique_ptr& operator=(unique_ptr&& u) noexcept;
324
  ```
325
 
326
  *Constraints:* `is_move_assignable_v<D>` is `true`.
327
 
328
  *Preconditions:* If `D` is not a reference type, `D` meets the
 
333
  deleter from an lvalue of type `D` does not throw an exception.
334
 
335
  *Effects:* Calls `reset(u.release())` followed by
336
  `get_deleter() = std::forward<D>(u.get_deleter())`.
337
 
338
+ *Ensures:* If `this != addressof(u)`, `u.get() == nullptr`, otherwise
339
+ `u.get()` is unchanged.
340
+
341
  *Returns:* `*this`.
342
 
 
 
343
  ``` cpp
344
+ template<class U, class E> constexpr unique_ptr& operator=(unique_ptr<U, E>&& u) noexcept;
345
  ```
346
 
347
  *Constraints:*
348
 
349
  - `unique_ptr<U, E>::pointer` is implicitly convertible to `pointer`,
 
358
  exception.
359
 
360
  *Effects:* Calls `reset(u.release())` followed by
361
  `get_deleter() = std::forward<E>(u.get_deleter())`.
362
 
 
 
363
  *Ensures:* `u.get() == nullptr`.
364
 
365
+ *Returns:* `*this`.
366
+
367
  ``` cpp
368
+ constexpr unique_ptr& operator=(nullptr_t) noexcept;
369
  ```
370
 
371
  *Effects:* As if by `reset()`.
372
 
373
  *Ensures:* `get() == nullptr`.
 
375
  *Returns:* `*this`.
376
 
377
  ##### Observers <a id="unique.ptr.single.observers">[[unique.ptr.single.observers]]</a>
378
 
379
  ``` cpp
380
+ constexpr add_lvalue_reference_t<T> operator*() const noexcept(noexcept(*declval<pointer>()));
381
  ```
382
 
383
  *Preconditions:* `get() != nullptr`.
384
 
385
  *Returns:* `*get()`.
386
 
387
  ``` cpp
388
+ constexpr pointer operator->() const noexcept;
389
  ```
390
 
391
  *Preconditions:* `get() != nullptr`.
392
 
393
  *Returns:* `get()`.
394
 
395
  [*Note 4*: The use of this function typically requires that `T` be a
396
  complete type. — *end note*]
397
 
398
  ``` cpp
399
+ constexpr pointer get() const noexcept;
400
  ```
401
 
402
  *Returns:* The stored pointer.
403
 
404
  ``` cpp
405
+ constexpr deleter_type& get_deleter() noexcept;
406
+ constexpr const deleter_type& get_deleter() const noexcept;
407
  ```
408
 
409
  *Returns:* A reference to the stored deleter.
410
 
411
  ``` cpp
412
+ constexpr explicit operator bool() const noexcept;
413
  ```
414
 
415
  *Returns:* `get() != nullptr`.
416
 
417
  ##### Modifiers <a id="unique.ptr.single.modifiers">[[unique.ptr.single.modifiers]]</a>
418
 
419
  ``` cpp
420
+ constexpr pointer release() noexcept;
421
  ```
422
 
423
  *Ensures:* `get() == nullptr`.
424
 
425
  *Returns:* The value `get()` had at the start of the call to `release`.
426
 
427
  ``` cpp
428
+ constexpr void reset(pointer p = pointer()) noexcept;
429
  ```
430
 
431
+ *Effects:* Assigns `p` to the stored pointer, and then, with the old
432
+ value of the stored pointer, `old_p`, evaluates
433
+ `if (old_p) get_deleter()(old_p);`
 
 
 
434
 
435
  [*Note 5*: The order of these operations is significant because the
436
+ call to `get_deleter()` might destroy `*this`. — *end note*]
437
 
438
  *Ensures:* `get() == p`.
439
 
440
  [*Note 6*: The postcondition does not hold if the call to
441
  `get_deleter()` destroys `*this` since `this->get()` is no longer a
442
  valid expression. — *end note*]
443
 
444
+ *Remarks:* The behavior is undefined if the evaluation of
445
+ `get_deleter()(old_p)` throws an exception.
446
+
447
  ``` cpp
448
+ constexpr void swap(unique_ptr& u) noexcept;
449
  ```
450
 
451
  *Preconditions:* `get_deleter()` is swappable [[swappable.requirements]]
452
  and does not throw an exception under `swap`.
453
 
454
  *Effects:* Invokes `swap` on the stored pointers and on the stored
455
  deleters of `*this` and `u`.
456
 
457
  #### `unique_ptr` for array objects with a runtime length <a id="unique.ptr.runtime">[[unique.ptr.runtime]]</a>
458
 
459
+ ##### General <a id="unique.ptr.runtime.general">[[unique.ptr.runtime.general]]</a>
460
+
461
  ``` cpp
462
  namespace std {
463
  template<class T, class D> class unique_ptr<T[], D> {
464
  public:
465
  using pointer = see below;
466
  using element_type = T;
467
  using deleter_type = D;
468
 
469
  // [unique.ptr.runtime.ctor], constructors
470
  constexpr unique_ptr() noexcept;
471
+ template<class U> constexpr explicit unique_ptr(U p) noexcept;
472
+ template<class U> constexpr unique_ptr(U p, see below d) noexcept;
473
+ template<class U> constexpr unique_ptr(U p, see below d) noexcept;
474
+ constexpr unique_ptr(unique_ptr&& u) noexcept;
475
  template<class U, class E>
476
+ constexpr unique_ptr(unique_ptr<U, E>&& u) noexcept;
477
  constexpr unique_ptr(nullptr_t) noexcept;
478
 
479
  // destructor
480
+ constexpr ~unique_ptr();
481
 
482
  // assignment
483
+ constexpr unique_ptr& operator=(unique_ptr&& u) noexcept;
484
  template<class U, class E>
485
+ constexpr unique_ptr& operator=(unique_ptr<U, E>&& u) noexcept;
486
+ constexpr unique_ptr& operator=(nullptr_t) noexcept;
487
 
488
  // [unique.ptr.runtime.observers], observers
489
+ constexpr T& operator[](size_t i) const;
490
+ constexpr pointer get() const noexcept;
491
+ constexpr deleter_type& get_deleter() noexcept;
492
+ constexpr const deleter_type& get_deleter() const noexcept;
493
+ constexpr explicit operator bool() const noexcept;
494
 
495
  // [unique.ptr.runtime.modifiers], modifiers
496
+ constexpr pointer release() noexcept;
497
+ template<class U> constexpr void reset(U p) noexcept;
498
+ constexpr void reset(nullptr_t = nullptr) noexcept;
499
+ constexpr void swap(unique_ptr& u) noexcept;
500
 
501
  // disable copy from lvalue
502
  unique_ptr(const unique_ptr&) = delete;
503
  unique_ptr& operator=(const unique_ptr&) = delete;
504
  };
 
524
  The template argument `T` shall be a complete type.
525
 
526
  ##### Constructors <a id="unique.ptr.runtime.ctor">[[unique.ptr.runtime.ctor]]</a>
527
 
528
  ``` cpp
529
+ template<class U> constexpr explicit unique_ptr(U p) noexcept;
530
  ```
531
 
532
  This constructor behaves the same as the constructor in the primary
533
  template that takes a single parameter of type `pointer`.
534
 
 
537
  - `U` is the same type as `pointer`, or
538
  - `pointer` is the same type as `element_type*`, `U` is a pointer type
539
  `V*`, and `V(*)[]` is convertible to `element_type(*)[]`.
540
 
541
  ``` cpp
542
+ template<class U> constexpr unique_ptr(U p, see below d) noexcept;
543
+ template<class U> constexpr unique_ptr(U p, see below d) noexcept;
544
  ```
545
 
546
  These constructors behave the same as the constructors in the primary
547
  template that take a parameter of type `pointer` and a second parameter.
548
 
 
552
  - `U` is `nullptr_t`, or
553
  - `pointer` is the same type as `element_type*`, `U` is a pointer type
554
  `V*`, and `V(*)[]` is convertible to `element_type(*)[]`.
555
 
556
  ``` cpp
557
+ template<class U, class E> constexpr unique_ptr(unique_ptr<U, E>&& u) noexcept;
558
  ```
559
 
560
  This constructor behaves the same as in the primary template.
561
 
562
  *Constraints:* Where `UP` is `unique_ptr<U, E>`:
 
572
  primary template. — *end note*]
573
 
574
  ##### Assignment <a id="unique.ptr.runtime.asgn">[[unique.ptr.runtime.asgn]]</a>
575
 
576
  ``` cpp
577
+ template<class U, class E> constexpr unique_ptr& operator=(unique_ptr<U, E>&& u) noexcept;
578
  ```
579
 
580
  This operator behaves the same as in the primary template.
581
 
582
  *Constraints:* Where `UP` is `unique_ptr<U, E>`:
 
591
  primary template. — *end note*]
592
 
593
  ##### Observers <a id="unique.ptr.runtime.observers">[[unique.ptr.runtime.observers]]</a>
594
 
595
  ``` cpp
596
+ constexpr T& operator[](size_t i) const;
597
  ```
598
 
599
  *Preconditions:* `i` < the number of elements in the array to which the
600
  stored pointer points.
601
 
602
  *Returns:* `get()[i]`.
603
 
604
  ##### Modifiers <a id="unique.ptr.runtime.modifiers">[[unique.ptr.runtime.modifiers]]</a>
605
 
606
  ``` cpp
607
+ constexpr void reset(nullptr_t p = nullptr) noexcept;
608
  ```
609
 
610
  *Effects:* Equivalent to `reset(pointer())`.
611
 
612
  ``` cpp
613
+ constexpr template<class U> void reset(U p) noexcept;
614
  ```
615
 
616
  This function behaves the same as the `reset` member of the primary
617
  template.
618
 
 
623
  `V*`, and `V(*)[]` is convertible to `element_type(*)[]`.
624
 
625
  #### Creation <a id="unique.ptr.create">[[unique.ptr.create]]</a>
626
 
627
  ``` cpp
628
+ template<class T, class... Args> constexpr unique_ptr<T> make_unique(Args&&... args);
629
  ```
630
 
631
  *Constraints:* `T` is not an array type.
632
 
633
  *Returns:* `unique_ptr<T>(new T(std::forward<Args>(args)...))`.
634
 
635
  ``` cpp
636
+ template<class T> constexpr unique_ptr<T> make_unique(size_t n);
637
  ```
638
 
639
  *Constraints:* `T` is an array of unknown bound.
640
 
641
  *Returns:* `unique_ptr<T>(new remove_extent_t<T>[n]())`.
 
645
  ```
646
 
647
  *Constraints:* `T` is an array of known bound.
648
 
649
  ``` cpp
650
+ template<class T> constexpr unique_ptr<T> make_unique_for_overwrite();
651
  ```
652
 
653
  *Constraints:* `T` is not an array type.
654
 
655
  *Returns:* `unique_ptr<T>(new T)`.
656
 
657
  ``` cpp
658
+ template<class T> constexpr unique_ptr<T> make_unique_for_overwrite(size_t n);
659
  ```
660
 
661
  *Constraints:* `T` is an array of unknown bound.
662
 
663
  *Returns:* `unique_ptr<T>(new remove_extent_t<T>[n])`.
 
669
  *Constraints:* `T` is an array of known bound.
670
 
671
  #### Specialized algorithms <a id="unique.ptr.special">[[unique.ptr.special]]</a>
672
 
673
  ``` cpp
674
+ template<class T, class D> constexpr void swap(unique_ptr<T, D>& x, unique_ptr<T, D>& y) noexcept;
675
  ```
676
 
677
  *Constraints:* `is_swappable_v<D>` is `true`.
678
 
679
  *Effects:* Calls `x.swap(y)`.
680
 
681
  ``` cpp
682
  template<class T1, class D1, class T2, class D2>
683
+ constexpr bool operator==(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
684
  ```
685
 
686
  *Returns:* `x.get() == y.get()`.
687
 
688
  ``` cpp
 
740
 
741
  *Returns:* `compare_three_way()(x.get(), y.get())`.
742
 
743
  ``` cpp
744
  template<class T, class D>
745
+ constexpr bool operator==(const unique_ptr<T, D>& x, nullptr_t) noexcept;
746
  ```
747
 
748
  *Returns:* `!x`.
749
 
750
  ``` cpp
751
  template<class T, class D>
752
+ constexpr bool operator<(const unique_ptr<T, D>& x, nullptr_t);
753
  template<class T, class D>
754
+ constexpr bool operator<(nullptr_t, const unique_ptr<T, D>& x);
755
  ```
756
 
757
  *Preconditions:* The specialization `less<unique_ptr<T, D>::pointer>` is
758
  a function object type [[function.objects]] that induces a strict weak
759
  ordering [[alg.sorting]] on the pointer values.
 
770
  less<unique_ptr<T, D>::pointer>()(nullptr, x.get())
771
  ```
772
 
773
  ``` cpp
774
  template<class T, class D>
775
+ constexpr bool operator>(const unique_ptr<T, D>& x, nullptr_t);
776
  template<class T, class D>
777
+ constexpr bool operator>(nullptr_t, const unique_ptr<T, D>& x);
778
  ```
779
 
780
  *Returns:* The first function template returns `nullptr < x`. The second
781
  function template returns `x < nullptr`.
782
 
783
  ``` cpp
784
  template<class T, class D>
785
+ constexpr bool operator<=(const unique_ptr<T, D>& x, nullptr_t);
786
  template<class T, class D>
787
+ constexpr bool operator<=(nullptr_t, const unique_ptr<T, D>& x);
788
  ```
789
 
790
  *Returns:* The first function template returns `!(nullptr < x)`. The
791
  second function template returns `!(x < nullptr)`.
792
 
793
  ``` cpp
794
  template<class T, class D>
795
+ constexpr bool operator>=(const unique_ptr<T, D>& x, nullptr_t);
796
  template<class T, class D>
797
+ constexpr bool operator>=(nullptr_t, const unique_ptr<T, D>& x);
798
  ```
799
 
800
  *Returns:* The first function template returns `!(x < nullptr)`. The
801
  second function template returns `!(nullptr < x)`.
802
 
803
  ``` cpp
804
  template<class T, class D>
805
+ requires three_way_comparable<typename unique_ptr<T, D>::pointer>
806
+ constexpr compare_three_way_result_t<typename unique_ptr<T, D>::pointer>
807
  operator<=>(const unique_ptr<T, D>& x, nullptr_t);
808
  ```
809
 
810
+ *Returns:*
811
+
812
+ ``` cpp
813
+ compare_three_way()(x.get(), static_cast<typename unique_ptr<T, D>::pointer>(nullptr)).
814
+ ```
815
 
816
  #### I/O <a id="unique.ptr.io">[[unique.ptr.io]]</a>
817
 
818
  ``` cpp
819
  template<class E, class T, class Y, class D>