From Jason Turner

[smartptr]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp2vi9brs0/{from.md → to.md} +360 -244
tmp/tmp2vi9brs0/{from.md → to.md} RENAMED
@@ -33,11 +33,11 @@ for dynamically allocated memory, passing ownership of dynamically
33
  allocated memory to a function, and returning dynamically allocated
34
  memory from a function. — *end note*]
35
 
36
  #### Default deleters <a id="unique.ptr.dltr">[[unique.ptr.dltr]]</a>
37
 
38
- ##### In general <a id="unique.ptr.dltr.general">[[unique.ptr.dltr.general]]</a>
39
 
40
  The class template `default_delete` serves as the default deleter
41
  (destruction policy) for the class template `unique_ptr`.
42
 
43
  The template parameter `T` of `default_delete` may be an incomplete
@@ -152,10 +152,16 @@ namespace std {
152
  unique_ptr& operator=(const unique_ptr&) = delete;
153
  };
154
  }
155
  ```
156
 
 
 
 
 
 
 
157
  The default type for the template parameter `D` is `default_delete`. A
158
  client-supplied template argument `D` shall be a function object type
159
  [[function.objects]], lvalue reference to function, or lvalue reference
160
  to function object type for which, given a value `d` of type `D` and a
161
  value `ptr` of type `unique_ptr<T, D>::pointer`, the expression `d(ptr)`
@@ -380,11 +386,15 @@ constexpr unique_ptr& operator=(nullptr_t) noexcept;
380
 
381
  ``` cpp
382
  constexpr add_lvalue_reference_t<T> operator*() const noexcept(noexcept(*declval<pointer>()));
383
  ```
384
 
385
- *Preconditions:* `get() != nullptr`.
 
 
 
 
386
 
387
  *Returns:* `*get()`.
388
 
389
  ``` cpp
390
  constexpr pointer operator->() const noexcept;
@@ -610,11 +620,11 @@ constexpr void reset(nullptr_t p = nullptr) noexcept;
610
  ```
611
 
612
  *Effects:* Equivalent to `reset(pointer())`.
613
 
614
  ``` cpp
615
- constexpr template<class U> void reset(U p) noexcept;
616
  ```
617
 
618
  This function behaves the same as the `reset` member of the primary
619
  template.
620
 
@@ -687,11 +697,11 @@ template<class T1, class D1, class T2, class D2>
687
 
688
  *Returns:* `x.get() == y.get()`.
689
 
690
  ``` cpp
691
  template<class T1, class D1, class T2, class D2>
692
- bool operator<(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
693
  ```
694
 
695
  Let `CT` denote
696
 
697
  ``` cpp
@@ -710,34 +720,34 @@ ordering [[alg.sorting]] on the pointer values.
710
 
711
  *Returns:* `less<CT>()(x.get(), y.get())`.
712
 
713
  ``` cpp
714
  template<class T1, class D1, class T2, class D2>
715
- bool operator>(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
716
  ```
717
 
718
  *Returns:* `y < x`.
719
 
720
  ``` cpp
721
  template<class T1, class D1, class T2, class D2>
722
- bool operator<=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
723
  ```
724
 
725
  *Returns:* `!(y < x)`.
726
 
727
  ``` cpp
728
  template<class T1, class D1, class T2, class D2>
729
- bool operator>=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
730
  ```
731
 
732
  *Returns:* `!(x < y)`.
733
 
734
  ``` cpp
735
  template<class T1, class D1, class T2, class D2>
736
  requires three_way_comparable_with<typename unique_ptr<T1, D1>::pointer,
737
  typename unique_ptr<T2, D2>::pointer>
738
- compare_three_way_result_t<typename unique_ptr<T1, D1>::pointer,
739
  typename unique_ptr<T2, D2>::pointer>
740
  operator<=>(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
741
  ```
742
 
743
  *Returns:* `compare_three_way()(x.get(), y.get())`.
@@ -835,20 +845,20 @@ template<class E, class T, class Y, class D>
835
  ``` cpp
836
  namespace std {
837
  class bad_weak_ptr : public exception {
838
  public:
839
  // see [exception] for the specification of the special member functions
840
- const char* what() const noexcept override;
841
  };
842
  }
843
  ```
844
 
845
  An exception of type `bad_weak_ptr` is thrown by the `shared_ptr`
846
  constructor taking a `weak_ptr`.
847
 
848
  ``` cpp
849
- const char* what() const noexcept override;
850
  ```
851
 
852
  *Returns:* An *implementation-defined* NTBS.
853
 
854
  #### Class template `shared_ptr` <a id="util.smartptr.shared">[[util.smartptr.shared]]</a>
@@ -870,68 +880,73 @@ namespace std {
870
 
871
  // [util.smartptr.shared.const], constructors
872
  constexpr shared_ptr() noexcept;
873
  constexpr shared_ptr(nullptr_t) noexcept : shared_ptr() { }
874
  template<class Y>
875
- explicit shared_ptr(Y* p);
876
  template<class Y, class D>
877
- shared_ptr(Y* p, D d);
878
  template<class Y, class D, class A>
879
- shared_ptr(Y* p, D d, A a);
880
  template<class D>
881
- shared_ptr(nullptr_t p, D d);
882
  template<class D, class A>
883
- shared_ptr(nullptr_t p, D d, A a);
884
  template<class Y>
885
- shared_ptr(const shared_ptr<Y>& r, element_type* p) noexcept;
886
  template<class Y>
887
- shared_ptr(shared_ptr<Y>&& r, element_type* p) noexcept;
888
- shared_ptr(const shared_ptr& r) noexcept;
889
  template<class Y>
890
- shared_ptr(const shared_ptr<Y>& r) noexcept;
891
- shared_ptr(shared_ptr&& r) noexcept;
892
  template<class Y>
893
- shared_ptr(shared_ptr<Y>&& r) noexcept;
894
  template<class Y>
895
- explicit shared_ptr(const weak_ptr<Y>& r);
896
  template<class Y, class D>
897
- shared_ptr(unique_ptr<Y, D>&& r);
898
 
899
  // [util.smartptr.shared.dest], destructor
900
- ~shared_ptr();
901
 
902
  // [util.smartptr.shared.assign], assignment
903
- shared_ptr& operator=(const shared_ptr& r) noexcept;
904
  template<class Y>
905
- shared_ptr& operator=(const shared_ptr<Y>& r) noexcept;
906
- shared_ptr& operator=(shared_ptr&& r) noexcept;
907
  template<class Y>
908
- shared_ptr& operator=(shared_ptr<Y>&& r) noexcept;
909
  template<class Y, class D>
910
- shared_ptr& operator=(unique_ptr<Y, D>&& r);
911
 
912
  // [util.smartptr.shared.mod], modifiers
913
- void swap(shared_ptr& r) noexcept;
914
- void reset() noexcept;
915
  template<class Y>
916
- void reset(Y* p);
917
  template<class Y, class D>
918
- void reset(Y* p, D d);
919
  template<class Y, class D, class A>
920
- void reset(Y* p, D d, A a);
921
 
922
  // [util.smartptr.shared.obs], observers
923
- element_type* get() const noexcept;
924
- T& operator*() const noexcept;
925
- T* operator->() const noexcept;
926
- element_type& operator[](ptrdiff_t i) const;
927
- long use_count() const noexcept;
928
- explicit operator bool() const noexcept;
929
  template<class U>
930
- bool owner_before(const shared_ptr<U>& b) const noexcept;
931
  template<class U>
932
- bool owner_before(const weak_ptr<U>& b) const noexcept;
 
 
 
 
 
933
  };
934
 
935
  template<class T>
936
  shared_ptr(weak_ptr<T>) -> shared_ptr<T>;
937
  template<class T, class D>
@@ -963,13 +978,13 @@ For purposes of determining the presence of a data race, member
963
  functions shall access and modify only the `shared_ptr` and `weak_ptr`
964
  objects themselves and not objects they refer to. Changes in
965
  `use_count()` do not reflect modifications that can introduce data
966
  races.
967
 
968
- For the purposes of subclause [[smartptr]], a pointer type `Y*` is said
969
- to be *compatible with* a pointer type `T*` when either `Y*` is
970
- convertible to `T*` or `Y` is `U[N]` and `T` is cv `U[]`.
971
 
972
  ##### Constructors <a id="util.smartptr.shared.const">[[util.smartptr.shared.const]]</a>
973
 
974
  In the constructor definitions below, enables `shared_from_this` with
975
  `p`, for a pointer `p` of type `Y*`, means that if `Y` has an
@@ -977,26 +992,26 @@ unambiguous and accessible base class that is a specialization of
977
  `enable_shared_from_this` [[util.smartptr.enab]], then `remove_cv_t<Y>*`
978
  shall be implicitly convertible to `T*` and the constructor evaluates
979
  the statement:
980
 
981
  ``` cpp
982
- if (p != nullptr && p->weak_this.expired())
983
- p->weak_this = shared_ptr<remove_cv_t<Y>>(*this, const_cast<remove_cv_t<Y>*>(p));
984
  ```
985
 
986
- The assignment to the `weak_this` member is not atomic and conflicts
987
  with any potentially concurrent access to the same object
988
  [[intro.multithread]].
989
 
990
  ``` cpp
991
  constexpr shared_ptr() noexcept;
992
  ```
993
 
994
  *Ensures:* `use_count() == 0 && get() == nullptr`.
995
 
996
  ``` cpp
997
- template<class Y> explicit shared_ptr(Y* p);
998
  ```
999
 
1000
  *Constraints:* When `T` is an array type, the expression `delete[] p` is
1001
  well-formed and either `T` is `U[N]` and `Y(*)[N]` is convertible to
1002
  `T*`, or `T` is `U[]` and `Y(*)[]` is convertible to `T*`. When `T` is
@@ -1020,14 +1035,14 @@ not an array type, `delete[] p` otherwise.
1020
 
1021
  *Throws:* `bad_alloc`, or an *implementation-defined* exception when a
1022
  resource other than memory cannot be obtained.
1023
 
1024
  ``` cpp
1025
- template<class Y, class D> shared_ptr(Y* p, D d);
1026
- template<class Y, class D, class A> shared_ptr(Y* p, D d, A a);
1027
- template<class D> shared_ptr(nullptr_t p, D d);
1028
- template<class D, class A> shared_ptr(nullptr_t p, D d, A a);
1029
  ```
1030
 
1031
  *Constraints:* `is_move_constructible_v<D>` is `true`, and `d(p)` is a
1032
  well-formed expression. For the first two overloads:
1033
 
@@ -1052,12 +1067,12 @@ use. If an exception is thrown, `d(p)` is called.
1052
 
1053
  *Throws:* `bad_alloc`, or an *implementation-defined* exception when a
1054
  resource other than memory cannot be obtained.
1055
 
1056
  ``` cpp
1057
- template<class Y> shared_ptr(const shared_ptr<Y>& r, element_type* p) noexcept;
1058
- template<class Y> shared_ptr(shared_ptr<Y>&& r, element_type* p) noexcept;
1059
  ```
1060
 
1061
  *Effects:* Constructs a `shared_ptr` instance that stores `p` and shares
1062
  ownership with the initial value of `r`.
1063
 
@@ -1070,12 +1085,12 @@ destroyed. — *end note*]
1070
 
1071
  [*Note 2*: This constructor allows creation of an empty `shared_ptr`
1072
  instance with a non-null stored pointer. — *end note*]
1073
 
1074
  ``` cpp
1075
- shared_ptr(const shared_ptr& r) noexcept;
1076
- template<class Y> shared_ptr(const shared_ptr<Y>& r) noexcept;
1077
  ```
1078
 
1079
  *Constraints:* For the second constructor, `Y*` is compatible with `T*`.
1080
 
1081
  *Effects:* If `r` is empty, constructs an empty `shared_ptr` object;
@@ -1083,23 +1098,23 @@ otherwise, constructs a `shared_ptr` object that shares ownership with
1083
  `r`.
1084
 
1085
  *Ensures:* `get() == r.get() && use_count() == r.use_count()`.
1086
 
1087
  ``` cpp
1088
- shared_ptr(shared_ptr&& r) noexcept;
1089
- template<class Y> shared_ptr(shared_ptr<Y>&& r) noexcept;
1090
  ```
1091
 
1092
  *Constraints:* For the second constructor, `Y*` is compatible with `T*`.
1093
 
1094
  *Effects:* Move constructs a `shared_ptr` instance from `r`.
1095
 
1096
  *Ensures:* `*this` contains the old value of `r`. `r` is empty, and
1097
  `r.get() == nullptr`.
1098
 
1099
  ``` cpp
1100
- template<class Y> explicit shared_ptr(const weak_ptr<Y>& r);
1101
  ```
1102
 
1103
  *Constraints:* `Y*` is compatible with `T*`.
1104
 
1105
  *Effects:* Constructs a `shared_ptr` object that shares ownership with
@@ -1109,11 +1124,11 @@ thrown, the constructor has no effect.
1109
  *Ensures:* `use_count() == r.use_count()`.
1110
 
1111
  *Throws:* `bad_weak_ptr` when `r.expired()`.
1112
 
1113
  ``` cpp
1114
- template<class Y, class D> shared_ptr(unique_ptr<Y, D>&& r);
1115
  ```
1116
 
1117
  *Constraints:* `Y*` is compatible with `T*` and
1118
  `unique_ptr<Y, D>::pointer` is convertible to `element_type*`.
1119
 
@@ -1124,11 +1139,11 @@ equivalent to `shared_ptr(r.release(), ref(r.get_deleter()))`. If an
1124
  exception is thrown, the constructor has no effect.
1125
 
1126
  ##### Destructor <a id="util.smartptr.shared.dest">[[util.smartptr.shared.dest]]</a>
1127
 
1128
  ``` cpp
1129
- ~shared_ptr();
1130
  ```
1131
 
1132
  *Effects:*
1133
 
1134
  - If `*this` is empty or shares ownership with another `shared_ptr`
@@ -1144,12 +1159,12 @@ been destroyed all `shared_ptr` instances that shared ownership with
1144
  value. — *end note*]
1145
 
1146
  ##### Assignment <a id="util.smartptr.shared.assign">[[util.smartptr.shared.assign]]</a>
1147
 
1148
  ``` cpp
1149
- shared_ptr& operator=(const shared_ptr& r) noexcept;
1150
- template<class Y> shared_ptr& operator=(const shared_ptr<Y>& r) noexcept;
1151
  ```
1152
 
1153
  *Effects:* Equivalent to `shared_ptr(r).swap(*this)`.
1154
 
1155
  *Returns:* `*this`.
@@ -1171,68 +1186,68 @@ q = p;
1171
  both assignments can be no-ops.
1172
 
1173
  — *end note*]
1174
 
1175
  ``` cpp
1176
- shared_ptr& operator=(shared_ptr&& r) noexcept;
1177
- template<class Y> shared_ptr& operator=(shared_ptr<Y>&& r) noexcept;
1178
  ```
1179
 
1180
  *Effects:* Equivalent to `shared_ptr(std::move(r)).swap(*this)`.
1181
 
1182
  *Returns:* `*this`.
1183
 
1184
  ``` cpp
1185
- template<class Y, class D> shared_ptr& operator=(unique_ptr<Y, D>&& r);
1186
  ```
1187
 
1188
  *Effects:* Equivalent to `shared_ptr(std::move(r)).swap(*this)`.
1189
 
1190
  *Returns:* `*this`.
1191
 
1192
  ##### Modifiers <a id="util.smartptr.shared.mod">[[util.smartptr.shared.mod]]</a>
1193
 
1194
  ``` cpp
1195
- void swap(shared_ptr& r) noexcept;
1196
  ```
1197
 
1198
  *Effects:* Exchanges the contents of `*this` and `r`.
1199
 
1200
  ``` cpp
1201
- void reset() noexcept;
1202
  ```
1203
 
1204
  *Effects:* Equivalent to `shared_ptr().swap(*this)`.
1205
 
1206
  ``` cpp
1207
- template<class Y> void reset(Y* p);
1208
  ```
1209
 
1210
  *Effects:* Equivalent to `shared_ptr(p).swap(*this)`.
1211
 
1212
  ``` cpp
1213
- template<class Y, class D> void reset(Y* p, D d);
1214
  ```
1215
 
1216
  *Effects:* Equivalent to `shared_ptr(p, d).swap(*this)`.
1217
 
1218
  ``` cpp
1219
- template<class Y, class D, class A> void reset(Y* p, D d, A a);
1220
  ```
1221
 
1222
  *Effects:* Equivalent to `shared_ptr(p, d, a).swap(*this)`.
1223
 
1224
  ##### Observers <a id="util.smartptr.shared.obs">[[util.smartptr.shared.obs]]</a>
1225
 
1226
  ``` cpp
1227
- element_type* get() const noexcept;
1228
  ```
1229
 
1230
  *Returns:* The stored pointer.
1231
 
1232
  ``` cpp
1233
- T& operator*() const noexcept;
1234
  ```
1235
 
1236
  *Preconditions:* `get() != nullptr`.
1237
 
1238
  *Returns:* `*get()`.
@@ -1242,11 +1257,11 @@ whether this member function is declared. If it is declared, it is
1242
  unspecified what its return type is, except that the declaration
1243
  (although not necessarily the definition) of the function shall be
1244
  well-formed.
1245
 
1246
  ``` cpp
1247
- T* operator->() const noexcept;
1248
  ```
1249
 
1250
  *Preconditions:* `get() != nullptr`.
1251
 
1252
  *Returns:* `get()`.
@@ -1255,15 +1270,16 @@ T* operator->() const noexcept;
1255
  member function is declared. If it is declared, it is unspecified what
1256
  its return type is, except that the declaration (although not
1257
  necessarily the definition) of the function shall be well-formed.
1258
 
1259
  ``` cpp
1260
- element_type& operator[](ptrdiff_t i) const;
1261
  ```
1262
 
1263
- *Preconditions:* `get() != nullptr && i >= 0`. If `T` is `U[N]`,
1264
- `i < N`.
 
1265
 
1266
  *Returns:* `get()[i]`.
1267
 
1268
  *Throws:* Nothing.
1269
 
@@ -1271,11 +1287,11 @@ element_type& operator[](ptrdiff_t i) const;
1271
  member function is declared. If it is declared, it is unspecified what
1272
  its return type is, except that the declaration (although not
1273
  necessarily the definition) of the function shall be well-formed.
1274
 
1275
  ``` cpp
1276
- long use_count() const noexcept;
1277
  ```
1278
 
1279
  *Synchronization:* None.
1280
 
1281
  *Returns:* The number of `shared_ptr` objects, `*this` included, that
@@ -1291,45 +1307,62 @@ share ownership with `*this`, or `0` when `*this` is empty.
1291
  `use_count()`, the result is approximate. In particular,
1292
  `use_count() == 1` does not imply that accesses through a previously
1293
  destroyed `shared_ptr` have in any sense completed. — *end note*]
1294
 
1295
  ``` cpp
1296
- explicit operator bool() const noexcept;
1297
  ```
1298
 
1299
  *Returns:* `get() != nullptr`.
1300
 
1301
  ``` cpp
1302
- template<class U> bool owner_before(const shared_ptr<U>& b) const noexcept;
1303
- template<class U> bool owner_before(const weak_ptr<U>& b) const noexcept;
1304
  ```
1305
 
1306
  *Returns:* An unspecified value such that
1307
 
1308
- - `x.owner_before(y)` defines a strict weak ordering as defined
1309
  in  [[alg.sorting]];
1310
- - under the equivalence relation defined by `owner_before`,
1311
- `!a.owner_before(b) && !b.owner_before(a)`, two `shared_ptr` or
1312
- `weak_ptr` instances are equivalent if and only if they share
1313
- ownership or are both empty.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1314
 
1315
  ##### Creation <a id="util.smartptr.shared.create">[[util.smartptr.shared.create]]</a>
1316
 
1317
  The common requirements that apply to all `make_shared`,
1318
  `allocate_shared`, `make_shared_for_overwrite`, and
1319
  `allocate_shared_for_overwrite` overloads, unless specified otherwise,
1320
  are described below.
1321
 
1322
  ``` cpp
1323
  template<class T, ...>
1324
- shared_ptr<T> make_shared(args);
1325
  template<class T, class A, ...>
1326
- shared_ptr<T> allocate_shared(const A& a, args);
1327
  template<class T, ...>
1328
- shared_ptr<T> make_shared_for_overwrite(args);
1329
  template<class T, class A, ...>
1330
- shared_ptr<T> allocate_shared_for_overwrite(const A& a, args);
1331
  ```
1332
 
1333
  *Preconditions:* `A` meets the *Cpp17Allocator*
1334
  requirements [[allocator.requirements.general]].
1335
 
@@ -1370,56 +1403,58 @@ the initialization of the object.
1370
  suitable to hold an object of type `U`.
1371
  - When a (sub)object of a non-array type `U` is specified to have an
1372
  initial value of `v`, or `U(l...)`, where `l...` is a list of
1373
  constructor arguments, `allocate_shared` shall initialize this
1374
  (sub)object via the expression
1375
- - `allocator_traits<A2>::construct(a2, pv, v)` or
1376
- - `allocator_traits<A2>::construct(a2, pv, l...)`
1377
 
1378
- respectively, where `pv` points to storage suitable to hold an object
1379
- of type `U` and `a2` of type `A2` is a rebound copy of the allocator
1380
- `a` passed to `allocate_shared` such that its `value_type` is
1381
- `remove_cv_t<U>`.
1382
  - When a (sub)object of non-array type `U` is specified to have a
1383
  default initial value, `make_shared` shall initialize this (sub)object
1384
  via the expression `::new(pv) U()`, where `pv` has type `void*` and
1385
  points to storage suitable to hold an object of type `U`.
1386
  - When a (sub)object of non-array type `U` is specified to have a
1387
- default initial value, `allocate_shared` shall initialize this
1388
- (sub)object via the expression
1389
- `allocator_traits<A2>::construct(a2, pv)`, where `pv` points to
1390
- storage suitable to hold an object of type `U` and `a2` of type `A2`
1391
- is a rebound copy of the allocator `a` passed to `allocate_shared`
1392
- such that its `value_type` is `remove_cv_t<U>`.
1393
  - When a (sub)object of non-array type `U` is initialized by
1394
  `make_shared_for_overwrite` or `allocate_shared_for_overwrite`, it is
1395
  initialized via the expression `::new(pv) U`, where `pv` has type
1396
  `void*` and points to storage suitable to hold an object of type `U`.
1397
  - Array elements are initialized in ascending order of their addresses.
1398
  - When the lifetime of the object managed by the return value ends, or
1399
  when the initialization of an array element throws an exception, the
1400
  initialized elements are destroyed in the reverse order of their
1401
  original construction.
1402
  - When a (sub)object of non-array type `U` that was initialized by
1403
- `make_shared` is to be destroyed, it is destroyed via the expression
1404
- `pv->~U()` where `pv` points to that object of type `U`.
 
 
1405
  - When a (sub)object of non-array type `U` that was initialized by
1406
  `allocate_shared` is to be destroyed, it is destroyed via the
1407
- expression `allocator_traits<A2>::destroy(a2, pv)` where `pv` points
1408
- to that object of type `remove_cv_t<U>` and `a2` of type `A2` is a
1409
- rebound copy of the allocator `a` passed to `allocate_shared` such
1410
- that its `value_type` is `remove_cv_t<U>`.
1411
 
1412
  [*Note 7*: These functions will typically allocate more memory than
1413
  `sizeof(T)` to allow for internal bookkeeping structures such as
1414
  reference counts. — *end note*]
1415
 
1416
  ``` cpp
1417
  template<class T, class... Args>
1418
- shared_ptr<T> make_shared(Args&&... args); // T is not array
1419
  template<class T, class A, class... Args>
1420
- shared_ptr<T> allocate_shared(const A& a, Args&&... args); // T is not array
1421
  ```
1422
 
1423
  *Constraints:* `T` is not an array type.
1424
 
1425
  *Returns:* A `shared_ptr` to an object of type `T` with an initial value
@@ -1438,14 +1473,14 @@ shared_ptr<vector<int>> q = make_shared<vector<int>>(16, 1);
1438
  ```
1439
 
1440
  — *end example*]
1441
 
1442
  ``` cpp
1443
- template<class T> shared_ptr<T>
1444
- make_shared(size_t N); // T is U[]
1445
  template<class T, class A>
1446
- shared_ptr<T> allocate_shared(const A& a, size_t N); // T is U[]
1447
  ```
1448
 
1449
  *Constraints:* `T` is of the form `U[]`.
1450
 
1451
  *Returns:* A `shared_ptr` to an object of type `U[N]` with a default
@@ -1462,13 +1497,13 @@ shared_ptr<double[][2][2]> q = make_shared<double[][2][2]>(6);
1462
 
1463
  — *end example*]
1464
 
1465
  ``` cpp
1466
  template<class T>
1467
- shared_ptr<T> make_shared(); // T is U[N]
1468
  template<class T, class A>
1469
- shared_ptr<T> allocate_shared(const A& a); // T is U[N]
1470
  ```
1471
 
1472
  *Constraints:* `T` is of the form `U[N]`.
1473
 
1474
  *Returns:* A `shared_ptr` to an object of type `T` with a default
@@ -1485,14 +1520,14 @@ shared_ptr<double[6][2][2]> q = make_shared<double[6][2][2]>();
1485
 
1486
  — *end example*]
1487
 
1488
  ``` cpp
1489
  template<class T>
1490
- shared_ptr<T> make_shared(size_t N,
1491
  const remove_extent_t<T>& u); // T is U[]
1492
  template<class T, class A>
1493
- shared_ptr<T> allocate_shared(const A& a, size_t N,
1494
  const remove_extent_t<T>& u); // T is U[]
1495
  ```
1496
 
1497
  *Constraints:* `T` is of the form `U[]`.
1498
 
@@ -1512,13 +1547,13 @@ shared_ptr<vector<int>[]> r = make_shared<vector<int>[]>(4, {1, 2});
1512
 
1513
  — *end example*]
1514
 
1515
  ``` cpp
1516
  template<class T>
1517
- shared_ptr<T> make_shared(const remove_extent_t<T>& u); // T is U[N]
1518
  template<class T, class A>
1519
- shared_ptr<T> allocate_shared(const A& a,
1520
  const remove_extent_t<T>& u); // T is U[N]
1521
  ```
1522
 
1523
  *Constraints:* `T` is of the form `U[N]`.
1524
 
@@ -1538,13 +1573,13 @@ shared_ptr<vector<int>[4]> r = make_shared<vector<int>[4]>({1, 2});
1538
 
1539
  — *end example*]
1540
 
1541
  ``` cpp
1542
  template<class T>
1543
- shared_ptr<T> make_shared_for_overwrite();
1544
  template<class T, class A>
1545
- shared_ptr<T> allocate_shared_for_overwrite(const A& a);
1546
  ```
1547
 
1548
  *Constraints:* `T` is not an array of unknown bound.
1549
 
1550
  *Returns:* A `shared_ptr` to an object of type `T`.
@@ -1562,13 +1597,13 @@ shared_ptr<double[1024]> q = make_shared_for_overwrite<double[1024]>();
1562
 
1563
  — *end example*]
1564
 
1565
  ``` cpp
1566
  template<class T>
1567
- shared_ptr<T> make_shared_for_overwrite(size_t N);
1568
  template<class T, class A>
1569
- shared_ptr<T> allocate_shared_for_overwrite(const A& a, size_t N);
1570
  ```
1571
 
1572
  *Constraints:* `T` is an array of unknown bound.
1573
 
1574
  *Returns:* A `shared_ptr` to an object of type `U[N]`, where `U` is
@@ -1585,59 +1620,59 @@ shared_ptr<double[]> p = make_shared_for_overwrite<double[]>(1024);
1585
 
1586
  ##### Comparison <a id="util.smartptr.shared.cmp">[[util.smartptr.shared.cmp]]</a>
1587
 
1588
  ``` cpp
1589
  template<class T, class U>
1590
- bool operator==(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
1591
  ```
1592
 
1593
  *Returns:* `a.get() == b.get()`.
1594
 
1595
  ``` cpp
1596
  template<class T>
1597
- bool operator==(const shared_ptr<T>& a, nullptr_t) noexcept;
1598
  ```
1599
 
1600
  *Returns:* `!a`.
1601
 
1602
  ``` cpp
1603
  template<class T, class U>
1604
- strong_ordering operator<=>(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
1605
  ```
1606
 
1607
  *Returns:* `compare_three_way()(a.get(), b.get())`.
1608
 
1609
  [*Note 8*: Defining a comparison operator function allows `shared_ptr`
1610
  objects to be used as keys in associative containers. — *end note*]
1611
 
1612
  ``` cpp
1613
  template<class T>
1614
- strong_ordering operator<=>(const shared_ptr<T>& a, nullptr_t) noexcept;
1615
  ```
1616
 
1617
  *Returns:*
1618
 
1619
  ``` cpp
1620
- compare_three_way()(a.get(), static_cast<typename shared_ptr<T>::element_type*>(nullptr).
1621
  ```
1622
 
1623
  ##### Specialized algorithms <a id="util.smartptr.shared.spec">[[util.smartptr.shared.spec]]</a>
1624
 
1625
  ``` cpp
1626
  template<class T>
1627
- void swap(shared_ptr<T>& a, shared_ptr<T>& b) noexcept;
1628
  ```
1629
 
1630
  *Effects:* Equivalent to `a.swap(b)`.
1631
 
1632
  ##### Casts <a id="util.smartptr.shared.cast">[[util.smartptr.shared.cast]]</a>
1633
 
1634
  ``` cpp
1635
  template<class T, class U>
1636
- shared_ptr<T> static_pointer_cast(const shared_ptr<U>& r) noexcept;
1637
  template<class T, class U>
1638
- shared_ptr<T> static_pointer_cast(shared_ptr<U>&& r) noexcept;
1639
  ```
1640
 
1641
  *Mandates:* The expression `static_cast<T*>((U*)nullptr)` is
1642
  well-formed.
1643
 
@@ -1649,19 +1684,18 @@ shared_ptr<T>(R, static_cast<typename shared_ptr<T>::element_type*>(r.get()))
1649
 
1650
  where *`R`* is `r` for the first overload, and `std::move(r)` for the
1651
  second.
1652
 
1653
  [*Note 9*: The seemingly equivalent expression
1654
- `shared_ptr<T>(static_cast<T*>(r.get()))` will eventually result in
1655
- undefined behavior, attempting to delete the same object
1656
- twice. — *end note*]
1657
 
1658
  ``` cpp
1659
  template<class T, class U>
1660
- shared_ptr<T> dynamic_pointer_cast(const shared_ptr<U>& r) noexcept;
1661
  template<class T, class U>
1662
- shared_ptr<T> dynamic_pointer_cast(shared_ptr<U>&& r) noexcept;
1663
  ```
1664
 
1665
  *Mandates:* The expression `dynamic_cast<T*>((U*)nullptr)` is
1666
  well-formed. The expression
1667
  `dynamic_cast<typename shared_ptr<T>::element_type*>(r.get())` is
@@ -1677,19 +1711,18 @@ well-defined behavior.
1677
  returns a non-null value `p`, `shared_ptr<T>(`*`R`*`, p)`, where *`R`*
1678
  is `r` for the first overload, and `std::move(r)` for the second.
1679
  - Otherwise, `shared_ptr<T>()`.
1680
 
1681
  [*Note 10*: The seemingly equivalent expression
1682
- `shared_ptr<T>(dynamic_cast<T*>(r.get()))` will eventually result in
1683
- undefined behavior, attempting to delete the same object
1684
- twice. — *end note*]
1685
 
1686
  ``` cpp
1687
  template<class T, class U>
1688
- shared_ptr<T> const_pointer_cast(const shared_ptr<U>& r) noexcept;
1689
  template<class T, class U>
1690
- shared_ptr<T> const_pointer_cast(shared_ptr<U>&& r) noexcept;
1691
  ```
1692
 
1693
  *Mandates:* The expression `const_cast<T*>((U*)nullptr)` is well-formed.
1694
 
1695
  *Returns:*
@@ -1700,13 +1733,12 @@ shared_ptr<T>(R, const_cast<typename shared_ptr<T>::element_type*>(r.get()))
1700
 
1701
  where *`R`* is `r` for the first overload, and `std::move(r)` for the
1702
  second.
1703
 
1704
  [*Note 11*: The seemingly equivalent expression
1705
- `shared_ptr<T>(const_cast<T*>(r.get()))` will eventually result in
1706
- undefined behavior, attempting to delete the same object
1707
- twice. — *end note*]
1708
 
1709
  ``` cpp
1710
  template<class T, class U>
1711
  shared_ptr<T> reinterpret_pointer_cast(const shared_ptr<U>& r) noexcept;
1712
  template<class T, class U>
@@ -1724,19 +1756,18 @@ shared_ptr<T>(R, reinterpret_cast<typename shared_ptr<T>::element_type*>(r.get()
1724
 
1725
  where *`R`* is `r` for the first overload, and `std::move(r)` for the
1726
  second.
1727
 
1728
  [*Note 12*: The seemingly equivalent expression
1729
- `shared_ptr<T>(reinterpret_cast<T*>(r.get()))` will eventually result in
1730
- undefined behavior, attempting to delete the same object
1731
- twice. — *end note*]
1732
 
1733
  ##### `get_deleter` <a id="util.smartptr.getdeleter">[[util.smartptr.getdeleter]]</a>
1734
 
1735
  ``` cpp
1736
  template<class D, class T>
1737
- D* get_deleter(const shared_ptr<T>& p) noexcept;
1738
  ```
1739
 
1740
  *Returns:* If `p` owns a deleter `d` of type cv-unqualified `D`, returns
1741
  `addressof(d)`; otherwise returns `nullptr`. The returned pointer
1742
  remains valid as long as there exists a `shared_ptr` instance that owns
@@ -1773,43 +1804,48 @@ namespace std {
1773
  using element_type = remove_extent_t<T>;
1774
 
1775
  // [util.smartptr.weak.const], constructors
1776
  constexpr weak_ptr() noexcept;
1777
  template<class Y>
1778
- weak_ptr(const shared_ptr<Y>& r) noexcept;
1779
- weak_ptr(const weak_ptr& r) noexcept;
1780
  template<class Y>
1781
- weak_ptr(const weak_ptr<Y>& r) noexcept;
1782
- weak_ptr(weak_ptr&& r) noexcept;
1783
  template<class Y>
1784
- weak_ptr(weak_ptr<Y>&& r) noexcept;
1785
 
1786
  // [util.smartptr.weak.dest], destructor
1787
- ~weak_ptr();
1788
 
1789
  // [util.smartptr.weak.assign], assignment
1790
- weak_ptr& operator=(const weak_ptr& r) noexcept;
1791
  template<class Y>
1792
- weak_ptr& operator=(const weak_ptr<Y>& r) noexcept;
1793
  template<class Y>
1794
- weak_ptr& operator=(const shared_ptr<Y>& r) noexcept;
1795
- weak_ptr& operator=(weak_ptr&& r) noexcept;
1796
  template<class Y>
1797
- weak_ptr& operator=(weak_ptr<Y>&& r) noexcept;
1798
 
1799
  // [util.smartptr.weak.mod], modifiers
1800
- void swap(weak_ptr& r) noexcept;
1801
- void reset() noexcept;
1802
 
1803
  // [util.smartptr.weak.obs], observers
1804
- long use_count() const noexcept;
1805
- bool expired() const noexcept;
1806
- shared_ptr<T> lock() const noexcept;
1807
  template<class U>
1808
- bool owner_before(const shared_ptr<U>& b) const noexcept;
1809
  template<class U>
1810
- bool owner_before(const weak_ptr<U>& b) const noexcept;
 
 
 
 
 
1811
  };
1812
 
1813
  template<class T>
1814
  weak_ptr(shared_ptr<T>) -> weak_ptr<T>;
1815
  }
@@ -1829,13 +1865,13 @@ constexpr weak_ptr() noexcept;
1829
  pointer value.
1830
 
1831
  *Ensures:* `use_count() == 0`.
1832
 
1833
  ``` cpp
1834
- weak_ptr(const weak_ptr& r) noexcept;
1835
- template<class Y> weak_ptr(const weak_ptr<Y>& r) noexcept;
1836
- template<class Y> weak_ptr(const shared_ptr<Y>& r) noexcept;
1837
  ```
1838
 
1839
  *Constraints:* For the second and third constructors, `Y*` is compatible
1840
  with `T*`.
1841
 
@@ -1845,12 +1881,12 @@ that shares ownership with `r` and stores a copy of the pointer stored
1845
  in `r`.
1846
 
1847
  *Ensures:* `use_count() == r.use_count()`.
1848
 
1849
  ``` cpp
1850
- weak_ptr(weak_ptr&& r) noexcept;
1851
- template<class Y> weak_ptr(weak_ptr<Y>&& r) noexcept;
1852
  ```
1853
 
1854
  *Constraints:* For the second constructor, `Y*` is compatible with `T*`.
1855
 
1856
  *Effects:* Move constructs a `weak_ptr` instance from `r`.
@@ -1859,95 +1895,112 @@ template<class Y> weak_ptr(weak_ptr<Y>&& r) noexcept;
1859
  null pointer value, and `r.use_count() == 0`.
1860
 
1861
  ##### Destructor <a id="util.smartptr.weak.dest">[[util.smartptr.weak.dest]]</a>
1862
 
1863
  ``` cpp
1864
- ~weak_ptr();
1865
  ```
1866
 
1867
  *Effects:* Destroys this `weak_ptr` object but has no effect on the
1868
  object its stored pointer points to.
1869
 
1870
  ##### Assignment <a id="util.smartptr.weak.assign">[[util.smartptr.weak.assign]]</a>
1871
 
1872
  ``` cpp
1873
- weak_ptr& operator=(const weak_ptr& r) noexcept;
1874
- template<class Y> weak_ptr& operator=(const weak_ptr<Y>& r) noexcept;
1875
- template<class Y> weak_ptr& operator=(const shared_ptr<Y>& r) noexcept;
1876
  ```
1877
 
1878
  *Effects:* Equivalent to `weak_ptr(r).swap(*this)`.
1879
 
1880
  *Returns:* `*this`.
1881
 
1882
  *Remarks:* The implementation may meet the effects (and the implied
1883
  guarantees) via different means, without creating a temporary object.
1884
 
1885
  ``` cpp
1886
- weak_ptr& operator=(weak_ptr&& r) noexcept;
1887
- template<class Y> weak_ptr& operator=(weak_ptr<Y>&& r) noexcept;
1888
  ```
1889
 
1890
  *Effects:* Equivalent to `weak_ptr(std::move(r)).swap(*this)`.
1891
 
1892
  *Returns:* `*this`.
1893
 
1894
  ##### Modifiers <a id="util.smartptr.weak.mod">[[util.smartptr.weak.mod]]</a>
1895
 
1896
  ``` cpp
1897
- void swap(weak_ptr& r) noexcept;
1898
  ```
1899
 
1900
  *Effects:* Exchanges the contents of `*this` and `r`.
1901
 
1902
  ``` cpp
1903
- void reset() noexcept;
1904
  ```
1905
 
1906
  *Effects:* Equivalent to `weak_ptr().swap(*this)`.
1907
 
1908
  ##### Observers <a id="util.smartptr.weak.obs">[[util.smartptr.weak.obs]]</a>
1909
 
1910
  ``` cpp
1911
- long use_count() const noexcept;
1912
  ```
1913
 
1914
  *Returns:* `0` if `*this` is empty; otherwise, the number of
1915
  `shared_ptr` instances that share ownership with `*this`.
1916
 
1917
  ``` cpp
1918
- bool expired() const noexcept;
1919
  ```
1920
 
1921
  *Returns:* `use_count() == 0`.
1922
 
1923
  ``` cpp
1924
- shared_ptr<T> lock() const noexcept;
1925
  ```
1926
 
1927
  *Returns:* `expired() ? shared_ptr<T>() : shared_ptr<T>(*this)`,
1928
  executed atomically.
1929
 
1930
  ``` cpp
1931
- template<class U> bool owner_before(const shared_ptr<U>& b) const noexcept;
1932
- template<class U> bool owner_before(const weak_ptr<U>& b) const noexcept;
1933
  ```
1934
 
1935
  *Returns:* An unspecified value such that
1936
 
1937
- - `x.owner_before(y)` defines a strict weak ordering as defined
1938
  in  [[alg.sorting]];
1939
- - under the equivalence relation defined by `owner_before`,
1940
- `!a.owner_before(b) && !b.owner_before(a)`, two `shared_ptr` or
1941
- `weak_ptr` instances are equivalent if and only if they share
1942
- ownership or are both empty.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1943
 
1944
  ##### Specialized algorithms <a id="util.smartptr.weak.spec">[[util.smartptr.weak.spec]]</a>
1945
 
1946
  ``` cpp
1947
  template<class T>
1948
- void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept;
1949
  ```
1950
 
1951
  *Effects:* Equivalent to `a.swap(b)`.
1952
 
1953
  #### Class template `owner_less` <a id="util.smartptr.ownerless">[[util.smartptr.ownerless]]</a>
@@ -1958,30 +2011,30 @@ of shared and weak pointers.
1958
  ``` cpp
1959
  namespace std {
1960
  template<class T = void> struct owner_less;
1961
 
1962
  template<class T> struct owner_less<shared_ptr<T>> {
1963
- bool operator()(const shared_ptr<T>&, const shared_ptr<T>&) const noexcept;
1964
- bool operator()(const shared_ptr<T>&, const weak_ptr<T>&) const noexcept;
1965
- bool operator()(const weak_ptr<T>&, const shared_ptr<T>&) const noexcept;
1966
  };
1967
 
1968
  template<class T> struct owner_less<weak_ptr<T>> {
1969
- bool operator()(const weak_ptr<T>&, const weak_ptr<T>&) const noexcept;
1970
- bool operator()(const shared_ptr<T>&, const weak_ptr<T>&) const noexcept;
1971
- bool operator()(const weak_ptr<T>&, const shared_ptr<T>&) const noexcept;
1972
  };
1973
 
1974
  template<> struct owner_less<void> {
1975
  template<class T, class U>
1976
- bool operator()(const shared_ptr<T>&, const shared_ptr<U>&) const noexcept;
1977
  template<class T, class U>
1978
- bool operator()(const shared_ptr<T>&, const weak_ptr<U>&) const noexcept;
1979
  template<class T, class U>
1980
- bool operator()(const weak_ptr<T>&, const shared_ptr<U>&) const noexcept;
1981
  template<class T, class U>
1982
- bool operator()(const weak_ptr<T>&, const weak_ptr<U>&) const noexcept;
1983
 
1984
  using is_transparent = unspecified;
1985
  };
1986
  }
1987
  ```
@@ -1992,17 +2045,83 @@ namespace std {
1992
 
1993
  Note that
1994
 
1995
  - `operator()` defines a strict weak ordering as defined in 
1996
  [[alg.sorting]];
1997
- - two `shared_ptr` or `weak_ptr` instances are equivalent under the
1998
- equivalence relation defined by `operator()`,
1999
- `!operator()(a, b) && !operator()(b, a)`, if and only if they share
2000
- ownership or are both empty.
2001
 
2002
  — *end note*]
2003
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2004
  #### Class template `enable_shared_from_this` <a id="util.smartptr.enab">[[util.smartptr.enab]]</a>
2005
 
2006
  A class `T` can inherit from `enable_shared_from_this<T>` to inherit the
2007
  `shared_from_this` member functions that obtain a `shared_ptr` instance
2008
  pointing to `*this`.
@@ -2014,68 +2133,68 @@ struct X: public enable_shared_from_this<X> { };
2014
 
2015
  int main() {
2016
  shared_ptr<X> p(new X);
2017
  shared_ptr<X> q = p->shared_from_this();
2018
  assert(p == q);
2019
- assert(!p.owner_before(q) && !q.owner_before(p)); // p and q share ownership
2020
  }
2021
  ```
2022
 
2023
  — *end example*]
2024
 
2025
  ``` cpp
2026
  namespace std {
2027
  template<class T> class enable_shared_from_this {
2028
  protected:
2029
  constexpr enable_shared_from_this() noexcept;
2030
- enable_shared_from_this(const enable_shared_from_this&) noexcept;
2031
- enable_shared_from_this& operator=(const enable_shared_from_this&) noexcept;
2032
- ~enable_shared_from_this();
2033
 
2034
  public:
2035
- shared_ptr<T> shared_from_this();
2036
- shared_ptr<T const> shared_from_this() const;
2037
- weak_ptr<T> weak_from_this() noexcept;
2038
- weak_ptr<T const> weak_from_this() const noexcept;
2039
 
2040
  private:
2041
- mutable weak_ptr<T> weak_this; // exposition only
2042
  };
2043
  }
2044
  ```
2045
 
2046
  The template parameter `T` of `enable_shared_from_this` may be an
2047
  incomplete type.
2048
 
2049
  ``` cpp
2050
  constexpr enable_shared_from_this() noexcept;
2051
- enable_shared_from_this(const enable_shared_from_this<T>&) noexcept;
2052
  ```
2053
 
2054
- *Effects:* Value-initializes `weak_this`.
2055
 
2056
  ``` cpp
2057
- enable_shared_from_this<T>& operator=(const enable_shared_from_this<T>&) noexcept;
2058
  ```
2059
 
2060
  *Returns:* `*this`.
2061
 
2062
- [*Note 1*: `weak_this` is not changed. — *end note*]
2063
 
2064
  ``` cpp
2065
- shared_ptr<T> shared_from_this();
2066
- shared_ptr<T const> shared_from_this() const;
2067
  ```
2068
 
2069
- *Returns:* `shared_ptr<T>(weak_this)`.
2070
 
2071
  ``` cpp
2072
- weak_ptr<T> weak_from_this() noexcept;
2073
- weak_ptr<T const> weak_from_this() const noexcept;
2074
  ```
2075
 
2076
- *Returns:* `weak_this`.
2077
 
2078
  ### Smart pointer hash support <a id="util.smartptr.hash">[[util.smartptr.hash]]</a>
2079
 
2080
  ``` cpp
2081
  template<class T, class D> struct hash<unique_ptr<T, D>>;
@@ -2136,16 +2255,16 @@ pointer value and manually delete it on error or failure.
2136
  ``` cpp
2137
  namespace std {
2138
  template<class Smart, class Pointer, class... Args>
2139
  class out_ptr_t {
2140
  public:
2141
- explicit out_ptr_t(Smart&, Args...);
2142
  out_ptr_t(const out_ptr_t&) = delete;
2143
 
2144
- ~out_ptr_t();
2145
 
2146
- operator Pointer*() const noexcept;
2147
  operator void**() const noexcept;
2148
 
2149
  private:
2150
  Smart& s; // exposition only
2151
  tuple<Args...> a; // exposition only
@@ -2169,41 +2288,40 @@ template.
2169
 
2170
  Evaluations of the conversion functions on the same object may conflict
2171
  [[intro.races]].
2172
 
2173
  ``` cpp
2174
- explicit out_ptr_t(Smart& smart, Args... args);
2175
  ```
2176
 
2177
  *Effects:* Initializes `s` with `smart`, `a` with
2178
  `std::forward<Args>(args)...`, and value-initializes `p`. Then,
2179
  equivalent to:
2180
 
2181
- - ``` cpp
 
2182
  s.reset();
2183
  ```
2184
 
2185
  if the expression `s.reset()` is well-formed;
2186
-
2187
  - otherwise,
2188
  ``` cpp
2189
  s = Smart();
2190
  ```
2191
 
2192
  if `is_constructible_v<Smart>` is `true`;
2193
-
2194
  - otherwise, the program is ill-formed.
2195
 
2196
  [*Note 1*: The constructor is not `noexcept` to allow for a variety of
2197
  non-terminating and safe implementation strategies. For example, an
2198
  implementation can allocate a `shared_ptr`’s internal node in the
2199
  constructor and let implementation-defined exceptions escape safely. The
2200
  destructor can then move the allocated control block in directly and
2201
  avoid any other exceptions. — *end note*]
2202
 
2203
  ``` cpp
2204
- ~out_ptr_t();
2205
  ```
2206
 
2207
  Let `SP` be *`POINTER_OF_OR`*`(Smart, Pointer)` [[memory.general]].
2208
 
2209
  *Effects:* Equivalent to:
@@ -2229,11 +2347,11 @@ Let `SP` be *`POINTER_OF_OR`*`(Smart, Pointer)` [[memory.general]].
2229
 
2230
  if `is_constructible_v<Smart, SP, Args...>` is `true`;
2231
  - otherwise, the program is ill-formed.
2232
 
2233
  ``` cpp
2234
- operator Pointer*() const noexcept;
2235
  ```
2236
 
2237
  *Preconditions:* `operator void**()` has not been called on `*this`.
2238
 
2239
  *Returns:* `addressof(const_cast<Pointer&>(p))`.
@@ -2264,18 +2382,18 @@ implementations. — *end note*]
2264
 
2265
  #### Function template `out_ptr` <a id="out.ptr">[[out.ptr]]</a>
2266
 
2267
  ``` cpp
2268
  template<class Pointer = void, class Smart, class... Args>
2269
- auto out_ptr(Smart& s, Args&&... args);
2270
  ```
2271
 
2272
  Let `P` be `Pointer` if `is_void_v<Pointer>` is `false`, otherwise
2273
  *`POINTER_OF`*`(Smart)`.
2274
 
2275
  *Returns:*
2276
- `out_ptr_t<Smart, P, Args&&...>(s, std::forward<Args>(args)...)`
2277
 
2278
  #### Class template `inout_ptr_t` <a id="inout.ptr.t">[[inout.ptr.t]]</a>
2279
 
2280
  `inout_ptr_t` is a class template used to adapt types such as smart
2281
  pointers [[smartptr]] for functions that use output pointer parameters
@@ -2315,16 +2433,16 @@ place.
2315
  ``` cpp
2316
  namespace std {
2317
  template<class Smart, class Pointer, class... Args>
2318
  class inout_ptr_t {
2319
  public:
2320
- explicit inout_ptr_t(Smart&, Args...);
2321
  inout_ptr_t(const inout_ptr_t&) = delete;
2322
 
2323
- ~inout_ptr_t();
2324
 
2325
- operator Pointer*() const noexcept;
2326
  operator void**() const noexcept;
2327
 
2328
  private:
2329
  Smart& s; // exposition only
2330
  tuple<Args...> a; // exposition only
@@ -2346,11 +2464,11 @@ template.
2346
 
2347
  Evaluations of the conversion functions on the same object may conflict
2348
  [[intro.races]].
2349
 
2350
  ``` cpp
2351
- explicit inout_ptr_t(Smart& smart, Args... args);
2352
  ```
2353
 
2354
  *Effects:* Initializes `s` with `smart`, `a` with
2355
  `std::forward<Args>(args)...`, and `p` to either
2356
 
@@ -2363,11 +2481,11 @@ explicit inout_ptr_t(Smart& smart, Args... args);
2363
  non-terminating and safe implementation strategies. For example, an
2364
  intrusive pointer implementation with a control block can allocate in
2365
  the constructor and safely fail with an exception. — *end note*]
2366
 
2367
  ``` cpp
2368
- ~inout_ptr_t();
2369
  ```
2370
 
2371
  Let `SP` be *`POINTER_OF_OR`*`(Smart, Pointer)` [[memory.general]].
2372
 
2373
  Let *release-statement* be `s.release();` if an implementation does not
@@ -2375,14 +2493,12 @@ call `s.release()` in the constructor. Otherwise, it is empty.
2375
 
2376
  *Effects:* Equivalent to:
2377
 
2378
  -
2379
  ``` cpp
2380
- if (p) {
2381
  apply([&](auto&&... args) {
2382
  s = Smart(static_cast<SP>(p), std::forward<Args>(args)...); }, std::move(a));
2383
- }
2384
  ```
2385
 
2386
  if `is_pointer_v<Smart>` is `true`;
2387
  - otherwise,
2388
  ``` cpp
@@ -2407,11 +2523,11 @@ call `s.release()` in the constructor. Otherwise, it is empty.
2407
 
2408
  if `is_constructible_v<Smart, SP, Args...>` is `true`;
2409
  - otherwise, the program is ill-formed.
2410
 
2411
  ``` cpp
2412
- operator Pointer*() const noexcept;
2413
  ```
2414
 
2415
  *Preconditions:* `operator void**()` has not been called on `*this`.
2416
 
2417
  *Returns:* `addressof(const_cast<Pointer&>(p))`.
@@ -2442,11 +2558,11 @@ implementations. — *end note*]
2442
 
2443
  #### Function template `inout_ptr` <a id="inout.ptr">[[inout.ptr]]</a>
2444
 
2445
  ``` cpp
2446
  template<class Pointer = void, class Smart, class... Args>
2447
- auto inout_ptr(Smart& s, Args&&... args);
2448
  ```
2449
 
2450
  Let `P` be `Pointer` if `is_void_v<Pointer>` is `false`, otherwise
2451
  *`POINTER_OF`*`(Smart)`.
2452
 
 
33
  allocated memory to a function, and returning dynamically allocated
34
  memory from a function. — *end note*]
35
 
36
  #### Default deleters <a id="unique.ptr.dltr">[[unique.ptr.dltr]]</a>
37
 
38
+ ##### General <a id="unique.ptr.dltr.general">[[unique.ptr.dltr.general]]</a>
39
 
40
  The class template `default_delete` serves as the default deleter
41
  (destruction policy) for the class template `unique_ptr`.
42
 
43
  The template parameter `T` of `default_delete` may be an incomplete
 
152
  unique_ptr& operator=(const unique_ptr&) = delete;
153
  };
154
  }
155
  ```
156
 
157
+ A program that instantiates the definition of `unique_ptr<T, D>` is
158
+ ill-formed if `T*` is an invalid type.
159
+
160
+ [*Note 1*: This prevents the instantiation of specializations such as
161
+ `unique_ptr<T&, D>` and `unique_ptr<int() const, D>`. — *end note*]
162
+
163
  The default type for the template parameter `D` is `default_delete`. A
164
  client-supplied template argument `D` shall be a function object type
165
  [[function.objects]], lvalue reference to function, or lvalue reference
166
  to function object type for which, given a value `d` of type `D` and a
167
  value `ptr` of type `unique_ptr<T, D>::pointer`, the expression `d(ptr)`
 
386
 
387
  ``` cpp
388
  constexpr add_lvalue_reference_t<T> operator*() const noexcept(noexcept(*declval<pointer>()));
389
  ```
390
 
391
+ *Mandates:*
392
+ `reference_converts_from_temporary_v<add_lvalue_reference_t<T>, decltype(*declval<pointer>())>`
393
+ is `false`.
394
+
395
+ *Preconditions:* `get() != nullptr` is `true`.
396
 
397
  *Returns:* `*get()`.
398
 
399
  ``` cpp
400
  constexpr pointer operator->() const noexcept;
 
620
  ```
621
 
622
  *Effects:* Equivalent to `reset(pointer())`.
623
 
624
  ``` cpp
625
+ template<class U> constexpr void reset(U p) noexcept;
626
  ```
627
 
628
  This function behaves the same as the `reset` member of the primary
629
  template.
630
 
 
697
 
698
  *Returns:* `x.get() == y.get()`.
699
 
700
  ``` cpp
701
  template<class T1, class D1, class T2, class D2>
702
+ constexpr bool operator<(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
703
  ```
704
 
705
  Let `CT` denote
706
 
707
  ``` cpp
 
720
 
721
  *Returns:* `less<CT>()(x.get(), y.get())`.
722
 
723
  ``` cpp
724
  template<class T1, class D1, class T2, class D2>
725
+ constexpr bool operator>(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
726
  ```
727
 
728
  *Returns:* `y < x`.
729
 
730
  ``` cpp
731
  template<class T1, class D1, class T2, class D2>
732
+ constexpr bool operator<=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
733
  ```
734
 
735
  *Returns:* `!(y < x)`.
736
 
737
  ``` cpp
738
  template<class T1, class D1, class T2, class D2>
739
+ constexpr bool operator>=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
740
  ```
741
 
742
  *Returns:* `!(x < y)`.
743
 
744
  ``` cpp
745
  template<class T1, class D1, class T2, class D2>
746
  requires three_way_comparable_with<typename unique_ptr<T1, D1>::pointer,
747
  typename unique_ptr<T2, D2>::pointer>
748
+ constexpr compare_three_way_result_t<typename unique_ptr<T1, D1>::pointer,
749
  typename unique_ptr<T2, D2>::pointer>
750
  operator<=>(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
751
  ```
752
 
753
  *Returns:* `compare_three_way()(x.get(), y.get())`.
 
845
  ``` cpp
846
  namespace std {
847
  class bad_weak_ptr : public exception {
848
  public:
849
  // see [exception] for the specification of the special member functions
850
+ constexpr const char* what() const noexcept override;
851
  };
852
  }
853
  ```
854
 
855
  An exception of type `bad_weak_ptr` is thrown by the `shared_ptr`
856
  constructor taking a `weak_ptr`.
857
 
858
  ``` cpp
859
+ constexpr const char* what() const noexcept override;
860
  ```
861
 
862
  *Returns:* An *implementation-defined* NTBS.
863
 
864
  #### Class template `shared_ptr` <a id="util.smartptr.shared">[[util.smartptr.shared]]</a>
 
880
 
881
  // [util.smartptr.shared.const], constructors
882
  constexpr shared_ptr() noexcept;
883
  constexpr shared_ptr(nullptr_t) noexcept : shared_ptr() { }
884
  template<class Y>
885
+ constexpr explicit shared_ptr(Y* p);
886
  template<class Y, class D>
887
+ constexpr shared_ptr(Y* p, D d);
888
  template<class Y, class D, class A>
889
+ constexpr shared_ptr(Y* p, D d, A a);
890
  template<class D>
891
+ constexpr shared_ptr(nullptr_t p, D d);
892
  template<class D, class A>
893
+ constexpr shared_ptr(nullptr_t p, D d, A a);
894
  template<class Y>
895
+ constexpr shared_ptr(const shared_ptr<Y>& r, element_type* p) noexcept;
896
  template<class Y>
897
+ constexpr shared_ptr(shared_ptr<Y>&& r, element_type* p) noexcept;
898
+ constexpr shared_ptr(const shared_ptr& r) noexcept;
899
  template<class Y>
900
+ constexpr shared_ptr(const shared_ptr<Y>& r) noexcept;
901
+ constexpr shared_ptr(shared_ptr&& r) noexcept;
902
  template<class Y>
903
+ constexpr shared_ptr(shared_ptr<Y>&& r) noexcept;
904
  template<class Y>
905
+ constexpr explicit shared_ptr(const weak_ptr<Y>& r);
906
  template<class Y, class D>
907
+ constexpr shared_ptr(unique_ptr<Y, D>&& r);
908
 
909
  // [util.smartptr.shared.dest], destructor
910
+ constexpr ~shared_ptr();
911
 
912
  // [util.smartptr.shared.assign], assignment
913
+ constexpr shared_ptr& operator=(const shared_ptr& r) noexcept;
914
  template<class Y>
915
+ constexpr shared_ptr& operator=(const shared_ptr<Y>& r) noexcept;
916
+ constexpr shared_ptr& operator=(shared_ptr&& r) noexcept;
917
  template<class Y>
918
+ constexpr shared_ptr& operator=(shared_ptr<Y>&& r) noexcept;
919
  template<class Y, class D>
920
+ constexpr shared_ptr& operator=(unique_ptr<Y, D>&& r);
921
 
922
  // [util.smartptr.shared.mod], modifiers
923
+ constexpr void swap(shared_ptr& r) noexcept;
924
+ constexpr void reset() noexcept;
925
  template<class Y>
926
+ constexpr void reset(Y* p);
927
  template<class Y, class D>
928
+ constexpr void reset(Y* p, D d);
929
  template<class Y, class D, class A>
930
+ constexpr void reset(Y* p, D d, A a);
931
 
932
  // [util.smartptr.shared.obs], observers
933
+ constexpr element_type* get() const noexcept;
934
+ constexpr T& operator*() const noexcept;
935
+ constexpr T* operator->() const noexcept;
936
+ constexpr element_type& operator[](ptrdiff_t i) const;
937
+ constexpr long use_count() const noexcept;
938
+ constexpr explicit operator bool() const noexcept;
939
  template<class U>
940
+ constexpr bool owner_before(const shared_ptr<U>& b) const noexcept;
941
  template<class U>
942
+ constexpr bool owner_before(const weak_ptr<U>& b) const noexcept;
943
+ size_t owner_hash() const noexcept;
944
+ template<class U>
945
+ constexpr bool owner_equal(const shared_ptr<U>& b) const noexcept;
946
+ template<class U>
947
+ constexpr bool owner_equal(const weak_ptr<U>& b) const noexcept;
948
  };
949
 
950
  template<class T>
951
  shared_ptr(weak_ptr<T>) -> shared_ptr<T>;
952
  template<class T, class D>
 
978
  functions shall access and modify only the `shared_ptr` and `weak_ptr`
979
  objects themselves and not objects they refer to. Changes in
980
  `use_count()` do not reflect modifications that can introduce data
981
  races.
982
 
983
+ For the purposes of [[smartptr]], a pointer type `Y*` is said to be
984
+ *compatible with* a pointer type `T*` when either `Y*` is convertible to
985
+ `T*` or `Y` is `U[N]` and `T` is cv `U[]`.
986
 
987
  ##### Constructors <a id="util.smartptr.shared.const">[[util.smartptr.shared.const]]</a>
988
 
989
  In the constructor definitions below, enables `shared_from_this` with
990
  `p`, for a pointer `p` of type `Y*`, means that if `Y` has an
 
992
  `enable_shared_from_this` [[util.smartptr.enab]], then `remove_cv_t<Y>*`
993
  shall be implicitly convertible to `T*` and the constructor evaluates
994
  the statement:
995
 
996
  ``` cpp
997
+ if (p != nullptr && p->weak-this.expired())
998
+ p->weak-this = shared_ptr<remove_cv_t<Y>>(*this, const_cast<remove_cv_t<Y>*>(p));
999
  ```
1000
 
1001
+ The assignment to the *`weak-this`* member is not atomic and conflicts
1002
  with any potentially concurrent access to the same object
1003
  [[intro.multithread]].
1004
 
1005
  ``` cpp
1006
  constexpr shared_ptr() noexcept;
1007
  ```
1008
 
1009
  *Ensures:* `use_count() == 0 && get() == nullptr`.
1010
 
1011
  ``` cpp
1012
+ template<class Y> constexpr explicit shared_ptr(Y* p);
1013
  ```
1014
 
1015
  *Constraints:* When `T` is an array type, the expression `delete[] p` is
1016
  well-formed and either `T` is `U[N]` and `Y(*)[N]` is convertible to
1017
  `T*`, or `T` is `U[]` and `Y(*)[]` is convertible to `T*`. When `T` is
 
1035
 
1036
  *Throws:* `bad_alloc`, or an *implementation-defined* exception when a
1037
  resource other than memory cannot be obtained.
1038
 
1039
  ``` cpp
1040
+ template<class Y, class D> constexpr shared_ptr(Y* p, D d);
1041
+ template<class Y, class D, class A> constexpr shared_ptr(Y* p, D d, A a);
1042
+ template<class D> constexpr shared_ptr(nullptr_t p, D d);
1043
+ template<class D, class A> constexpr shared_ptr(nullptr_t p, D d, A a);
1044
  ```
1045
 
1046
  *Constraints:* `is_move_constructible_v<D>` is `true`, and `d(p)` is a
1047
  well-formed expression. For the first two overloads:
1048
 
 
1067
 
1068
  *Throws:* `bad_alloc`, or an *implementation-defined* exception when a
1069
  resource other than memory cannot be obtained.
1070
 
1071
  ``` cpp
1072
+ template<class Y> constexpr shared_ptr(const shared_ptr<Y>& r, element_type* p) noexcept;
1073
+ template<class Y> constexpr shared_ptr(shared_ptr<Y>&& r, element_type* p) noexcept;
1074
  ```
1075
 
1076
  *Effects:* Constructs a `shared_ptr` instance that stores `p` and shares
1077
  ownership with the initial value of `r`.
1078
 
 
1085
 
1086
  [*Note 2*: This constructor allows creation of an empty `shared_ptr`
1087
  instance with a non-null stored pointer. — *end note*]
1088
 
1089
  ``` cpp
1090
+ constexpr shared_ptr(const shared_ptr& r) noexcept;
1091
+ template<class Y> constexpr shared_ptr(const shared_ptr<Y>& r) noexcept;
1092
  ```
1093
 
1094
  *Constraints:* For the second constructor, `Y*` is compatible with `T*`.
1095
 
1096
  *Effects:* If `r` is empty, constructs an empty `shared_ptr` object;
 
1098
  `r`.
1099
 
1100
  *Ensures:* `get() == r.get() && use_count() == r.use_count()`.
1101
 
1102
  ``` cpp
1103
+ constexpr shared_ptr(shared_ptr&& r) noexcept;
1104
+ template<class Y> constexpr shared_ptr(shared_ptr<Y>&& r) noexcept;
1105
  ```
1106
 
1107
  *Constraints:* For the second constructor, `Y*` is compatible with `T*`.
1108
 
1109
  *Effects:* Move constructs a `shared_ptr` instance from `r`.
1110
 
1111
  *Ensures:* `*this` contains the old value of `r`. `r` is empty, and
1112
  `r.get() == nullptr`.
1113
 
1114
  ``` cpp
1115
+ template<class Y> constexpr explicit shared_ptr(const weak_ptr<Y>& r);
1116
  ```
1117
 
1118
  *Constraints:* `Y*` is compatible with `T*`.
1119
 
1120
  *Effects:* Constructs a `shared_ptr` object that shares ownership with
 
1124
  *Ensures:* `use_count() == r.use_count()`.
1125
 
1126
  *Throws:* `bad_weak_ptr` when `r.expired()`.
1127
 
1128
  ``` cpp
1129
+ template<class Y, class D> constexpr shared_ptr(unique_ptr<Y, D>&& r);
1130
  ```
1131
 
1132
  *Constraints:* `Y*` is compatible with `T*` and
1133
  `unique_ptr<Y, D>::pointer` is convertible to `element_type*`.
1134
 
 
1139
  exception is thrown, the constructor has no effect.
1140
 
1141
  ##### Destructor <a id="util.smartptr.shared.dest">[[util.smartptr.shared.dest]]</a>
1142
 
1143
  ``` cpp
1144
+ constexpr ~shared_ptr();
1145
  ```
1146
 
1147
  *Effects:*
1148
 
1149
  - If `*this` is empty or shares ownership with another `shared_ptr`
 
1159
  value. — *end note*]
1160
 
1161
  ##### Assignment <a id="util.smartptr.shared.assign">[[util.smartptr.shared.assign]]</a>
1162
 
1163
  ``` cpp
1164
+ constexpr shared_ptr& operator=(const shared_ptr& r) noexcept;
1165
+ template<class Y> constexpr shared_ptr& operator=(const shared_ptr<Y>& r) noexcept;
1166
  ```
1167
 
1168
  *Effects:* Equivalent to `shared_ptr(r).swap(*this)`.
1169
 
1170
  *Returns:* `*this`.
 
1186
  both assignments can be no-ops.
1187
 
1188
  — *end note*]
1189
 
1190
  ``` cpp
1191
+ constexpr shared_ptr& operator=(shared_ptr&& r) noexcept;
1192
+ template<class Y> constexpr shared_ptr& operator=(shared_ptr<Y>&& r) noexcept;
1193
  ```
1194
 
1195
  *Effects:* Equivalent to `shared_ptr(std::move(r)).swap(*this)`.
1196
 
1197
  *Returns:* `*this`.
1198
 
1199
  ``` cpp
1200
+ template<class Y, class D> constexpr shared_ptr& operator=(unique_ptr<Y, D>&& r);
1201
  ```
1202
 
1203
  *Effects:* Equivalent to `shared_ptr(std::move(r)).swap(*this)`.
1204
 
1205
  *Returns:* `*this`.
1206
 
1207
  ##### Modifiers <a id="util.smartptr.shared.mod">[[util.smartptr.shared.mod]]</a>
1208
 
1209
  ``` cpp
1210
+ constexpr void swap(shared_ptr& r) noexcept;
1211
  ```
1212
 
1213
  *Effects:* Exchanges the contents of `*this` and `r`.
1214
 
1215
  ``` cpp
1216
+ constexpr void reset() noexcept;
1217
  ```
1218
 
1219
  *Effects:* Equivalent to `shared_ptr().swap(*this)`.
1220
 
1221
  ``` cpp
1222
+ template<class Y> constexpr void reset(Y* p);
1223
  ```
1224
 
1225
  *Effects:* Equivalent to `shared_ptr(p).swap(*this)`.
1226
 
1227
  ``` cpp
1228
+ template<class Y, class D> constexpr void reset(Y* p, D d);
1229
  ```
1230
 
1231
  *Effects:* Equivalent to `shared_ptr(p, d).swap(*this)`.
1232
 
1233
  ``` cpp
1234
+ template<class Y, class D, class A> constexpr void reset(Y* p, D d, A a);
1235
  ```
1236
 
1237
  *Effects:* Equivalent to `shared_ptr(p, d, a).swap(*this)`.
1238
 
1239
  ##### Observers <a id="util.smartptr.shared.obs">[[util.smartptr.shared.obs]]</a>
1240
 
1241
  ``` cpp
1242
+ constexpr element_type* get() const noexcept;
1243
  ```
1244
 
1245
  *Returns:* The stored pointer.
1246
 
1247
  ``` cpp
1248
+ constexpr T& operator*() const noexcept;
1249
  ```
1250
 
1251
  *Preconditions:* `get() != nullptr`.
1252
 
1253
  *Returns:* `*get()`.
 
1257
  unspecified what its return type is, except that the declaration
1258
  (although not necessarily the definition) of the function shall be
1259
  well-formed.
1260
 
1261
  ``` cpp
1262
+ constexpr T* operator->() const noexcept;
1263
  ```
1264
 
1265
  *Preconditions:* `get() != nullptr`.
1266
 
1267
  *Returns:* `get()`.
 
1270
  member function is declared. If it is declared, it is unspecified what
1271
  its return type is, except that the declaration (although not
1272
  necessarily the definition) of the function shall be well-formed.
1273
 
1274
  ``` cpp
1275
+ constexpr element_type& operator[](ptrdiff_t i) const;
1276
  ```
1277
 
1278
+ *Preconditions:* `get() != nullptr` is `true`.
1279
+
1280
+ `i` ≥ 0. If `T` is `U[N]`, `i` < `N`.
1281
 
1282
  *Returns:* `get()[i]`.
1283
 
1284
  *Throws:* Nothing.
1285
 
 
1287
  member function is declared. If it is declared, it is unspecified what
1288
  its return type is, except that the declaration (although not
1289
  necessarily the definition) of the function shall be well-formed.
1290
 
1291
  ``` cpp
1292
+ constexpr long use_count() const noexcept;
1293
  ```
1294
 
1295
  *Synchronization:* None.
1296
 
1297
  *Returns:* The number of `shared_ptr` objects, `*this` included, that
 
1307
  `use_count()`, the result is approximate. In particular,
1308
  `use_count() == 1` does not imply that accesses through a previously
1309
  destroyed `shared_ptr` have in any sense completed. — *end note*]
1310
 
1311
  ``` cpp
1312
+ constexpr explicit operator bool() const noexcept;
1313
  ```
1314
 
1315
  *Returns:* `get() != nullptr`.
1316
 
1317
  ``` cpp
1318
+ template<class U> constexpr bool owner_before(const shared_ptr<U>& b) const noexcept;
1319
+ template<class U> constexpr bool owner_before(const weak_ptr<U>& b) const noexcept;
1320
  ```
1321
 
1322
  *Returns:* An unspecified value such that
1323
 
1324
+ - `owner_before(b)` defines a strict weak ordering as defined
1325
  in  [[alg.sorting]];
1326
+ - `!owner_before(b) && !b.owner_before(*this)` is `true` if and only if
1327
+ `owner_equal(b)` is `true`.
1328
+
1329
+ ``` cpp
1330
+ size_t owner_hash() const noexcept;
1331
+ ```
1332
+
1333
+ *Returns:* An unspecified value such that, for any object `x` where
1334
+ `owner_equal(x)` is `true`, `owner_hash() == x.owner_hash()` is `true`.
1335
+
1336
+ ``` cpp
1337
+ template<class U>
1338
+ constexpr bool owner_equal(const shared_ptr<U>& b) const noexcept;
1339
+ template<class U>
1340
+ constexpr bool owner_equal(const weak_ptr<U>& b) const noexcept;
1341
+ ```
1342
+
1343
+ *Returns:* `true` if and only if `*this` and `b` share ownership or are
1344
+ both empty. Otherwise returns `false`.
1345
+
1346
+ *Remarks:* `owner_equal` is an equivalence relation.
1347
 
1348
  ##### Creation <a id="util.smartptr.shared.create">[[util.smartptr.shared.create]]</a>
1349
 
1350
  The common requirements that apply to all `make_shared`,
1351
  `allocate_shared`, `make_shared_for_overwrite`, and
1352
  `allocate_shared_for_overwrite` overloads, unless specified otherwise,
1353
  are described below.
1354
 
1355
  ``` cpp
1356
  template<class T, ...>
1357
+ constexpr shared_ptr<T> make_shared(args);
1358
  template<class T, class A, ...>
1359
+ constexpr shared_ptr<T> allocate_shared(const A& a, args);
1360
  template<class T, ...>
1361
+ constexpr shared_ptr<T> make_shared_for_overwrite(args);
1362
  template<class T, class A, ...>
1363
+ constexpr shared_ptr<T> allocate_shared_for_overwrite(const A& a, args);
1364
  ```
1365
 
1366
  *Preconditions:* `A` meets the *Cpp17Allocator*
1367
  requirements [[allocator.requirements.general]].
1368
 
 
1403
  suitable to hold an object of type `U`.
1404
  - When a (sub)object of a non-array type `U` is specified to have an
1405
  initial value of `v`, or `U(l...)`, where `l...` is a list of
1406
  constructor arguments, `allocate_shared` shall initialize this
1407
  (sub)object via the expression
1408
+ - `allocator_traits<A2>::construct(a2, pu, v)` or
1409
+ - `allocator_traits<A2>::construct(a2, pu, l...)`
1410
 
1411
+ respectively, where `pu` is a pointer of type `remove_cv_t<U>*`
1412
+ pointing to storage suitable to hold an object of type
1413
+ `remove_cv_t<U>` and `a2` of type `A2` is a potentially rebound copy
1414
+ of the allocator `a` passed to `allocate_shared`.
1415
  - When a (sub)object of non-array type `U` is specified to have a
1416
  default initial value, `make_shared` shall initialize this (sub)object
1417
  via the expression `::new(pv) U()`, where `pv` has type `void*` and
1418
  points to storage suitable to hold an object of type `U`.
1419
  - When a (sub)object of non-array type `U` is specified to have a
1420
+ default initial value, `allocate_shared` initializes this (sub)object
1421
+ via the expression `allocator_traits<A2>::construct(a2, pu)`, where
1422
+ `pu` is a pointer of type `remove_cv_t<U>*` pointing to storage
1423
+ suitable to hold an object of type `remove_cv_t<U>` and `a2` of type
1424
+ `A2` is a potentially rebound copy of the allocator `a` passed to
1425
+ `allocate_shared`.
1426
  - When a (sub)object of non-array type `U` is initialized by
1427
  `make_shared_for_overwrite` or `allocate_shared_for_overwrite`, it is
1428
  initialized via the expression `::new(pv) U`, where `pv` has type
1429
  `void*` and points to storage suitable to hold an object of type `U`.
1430
  - Array elements are initialized in ascending order of their addresses.
1431
  - When the lifetime of the object managed by the return value ends, or
1432
  when the initialization of an array element throws an exception, the
1433
  initialized elements are destroyed in the reverse order of their
1434
  original construction.
1435
  - When a (sub)object of non-array type `U` that was initialized by
1436
+ `make_shared`, `make_shared_for_overwrite`, or
1437
+ `allocate_shared_for_overwrite` is to be destroyed, it is destroyed
1438
+ via the expression `pu->~U()` where `pu` points to that object of type
1439
+ `U`.
1440
  - When a (sub)object of non-array type `U` that was initialized by
1441
  `allocate_shared` is to be destroyed, it is destroyed via the
1442
+ expression `allocator_traits<A2>::destroy(a2, pu)` where `pu` is a
1443
+ pointer of type `remove_cv_t<U>*` pointing to that object of type
1444
+ `remove_cv_t<U>` and `a2` of type `A2` is a potentially rebound copy
1445
+ of the allocator `a` passed to `allocate_shared`.
1446
 
1447
  [*Note 7*: These functions will typically allocate more memory than
1448
  `sizeof(T)` to allow for internal bookkeeping structures such as
1449
  reference counts. — *end note*]
1450
 
1451
  ``` cpp
1452
  template<class T, class... Args>
1453
+ constexpr shared_ptr<T> make_shared(Args&&... args); // T is not array
1454
  template<class T, class A, class... Args>
1455
+ constexpr shared_ptr<T> allocate_shared(const A& a, Args&&... args); // T is not array
1456
  ```
1457
 
1458
  *Constraints:* `T` is not an array type.
1459
 
1460
  *Returns:* A `shared_ptr` to an object of type `T` with an initial value
 
1473
  ```
1474
 
1475
  — *end example*]
1476
 
1477
  ``` cpp
1478
+ template<class T>
1479
+ constexpr shared_ptr<T> make_shared(size_t N); // T is U[]
1480
  template<class T, class A>
1481
+ constexpr shared_ptr<T> allocate_shared(const A& a, size_t N); // T is U[]
1482
  ```
1483
 
1484
  *Constraints:* `T` is of the form `U[]`.
1485
 
1486
  *Returns:* A `shared_ptr` to an object of type `U[N]` with a default
 
1497
 
1498
  — *end example*]
1499
 
1500
  ``` cpp
1501
  template<class T>
1502
+ constexpr shared_ptr<T> make_shared(); // T is U[N]
1503
  template<class T, class A>
1504
+ constexpr shared_ptr<T> allocate_shared(const A& a); // T is U[N]
1505
  ```
1506
 
1507
  *Constraints:* `T` is of the form `U[N]`.
1508
 
1509
  *Returns:* A `shared_ptr` to an object of type `T` with a default
 
1520
 
1521
  — *end example*]
1522
 
1523
  ``` cpp
1524
  template<class T>
1525
+ constexpr shared_ptr<T> make_shared(size_t N,
1526
  const remove_extent_t<T>& u); // T is U[]
1527
  template<class T, class A>
1528
+ constexpr shared_ptr<T> allocate_shared(const A& a, size_t N,
1529
  const remove_extent_t<T>& u); // T is U[]
1530
  ```
1531
 
1532
  *Constraints:* `T` is of the form `U[]`.
1533
 
 
1547
 
1548
  — *end example*]
1549
 
1550
  ``` cpp
1551
  template<class T>
1552
+ constexpr shared_ptr<T> make_shared(const remove_extent_t<T>& u); // T is U[N]
1553
  template<class T, class A>
1554
+ constexpr shared_ptr<T> allocate_shared(const A& a,
1555
  const remove_extent_t<T>& u); // T is U[N]
1556
  ```
1557
 
1558
  *Constraints:* `T` is of the form `U[N]`.
1559
 
 
1573
 
1574
  — *end example*]
1575
 
1576
  ``` cpp
1577
  template<class T>
1578
+ constexpr shared_ptr<T> make_shared_for_overwrite();
1579
  template<class T, class A>
1580
+ constexpr shared_ptr<T> allocate_shared_for_overwrite(const A& a);
1581
  ```
1582
 
1583
  *Constraints:* `T` is not an array of unknown bound.
1584
 
1585
  *Returns:* A `shared_ptr` to an object of type `T`.
 
1597
 
1598
  — *end example*]
1599
 
1600
  ``` cpp
1601
  template<class T>
1602
+ constexpr shared_ptr<T> make_shared_for_overwrite(size_t N);
1603
  template<class T, class A>
1604
+ constexpr shared_ptr<T> allocate_shared_for_overwrite(const A& a, size_t N);
1605
  ```
1606
 
1607
  *Constraints:* `T` is an array of unknown bound.
1608
 
1609
  *Returns:* A `shared_ptr` to an object of type `U[N]`, where `U` is
 
1620
 
1621
  ##### Comparison <a id="util.smartptr.shared.cmp">[[util.smartptr.shared.cmp]]</a>
1622
 
1623
  ``` cpp
1624
  template<class T, class U>
1625
+ constexpr bool operator==(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
1626
  ```
1627
 
1628
  *Returns:* `a.get() == b.get()`.
1629
 
1630
  ``` cpp
1631
  template<class T>
1632
+ constexpr bool operator==(const shared_ptr<T>& a, nullptr_t) noexcept;
1633
  ```
1634
 
1635
  *Returns:* `!a`.
1636
 
1637
  ``` cpp
1638
  template<class T, class U>
1639
+ constexpr strong_ordering operator<=>(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
1640
  ```
1641
 
1642
  *Returns:* `compare_three_way()(a.get(), b.get())`.
1643
 
1644
  [*Note 8*: Defining a comparison operator function allows `shared_ptr`
1645
  objects to be used as keys in associative containers. — *end note*]
1646
 
1647
  ``` cpp
1648
  template<class T>
1649
+ constexpr strong_ordering operator<=>(const shared_ptr<T>& a, nullptr_t) noexcept;
1650
  ```
1651
 
1652
  *Returns:*
1653
 
1654
  ``` cpp
1655
+ compare_three_way()(a.get(), static_cast<typename shared_ptr<T>::element_type*>(nullptr))
1656
  ```
1657
 
1658
  ##### Specialized algorithms <a id="util.smartptr.shared.spec">[[util.smartptr.shared.spec]]</a>
1659
 
1660
  ``` cpp
1661
  template<class T>
1662
+ constexpr void swap(shared_ptr<T>& a, shared_ptr<T>& b) noexcept;
1663
  ```
1664
 
1665
  *Effects:* Equivalent to `a.swap(b)`.
1666
 
1667
  ##### Casts <a id="util.smartptr.shared.cast">[[util.smartptr.shared.cast]]</a>
1668
 
1669
  ``` cpp
1670
  template<class T, class U>
1671
+ constexpr shared_ptr<T> static_pointer_cast(const shared_ptr<U>& r) noexcept;
1672
  template<class T, class U>
1673
+ constexpr shared_ptr<T> static_pointer_cast(shared_ptr<U>&& r) noexcept;
1674
  ```
1675
 
1676
  *Mandates:* The expression `static_cast<T*>((U*)nullptr)` is
1677
  well-formed.
1678
 
 
1684
 
1685
  where *`R`* is `r` for the first overload, and `std::move(r)` for the
1686
  second.
1687
 
1688
  [*Note 9*: The seemingly equivalent expression
1689
+ `shared_ptr<T>(static_cast<T*>(r.get()))` can result in undefined
1690
+ behavior, attempting to delete the same object twice. — *end note*]
 
1691
 
1692
  ``` cpp
1693
  template<class T, class U>
1694
+ constexpr shared_ptr<T> dynamic_pointer_cast(const shared_ptr<U>& r) noexcept;
1695
  template<class T, class U>
1696
+ constexpr shared_ptr<T> dynamic_pointer_cast(shared_ptr<U>&& r) noexcept;
1697
  ```
1698
 
1699
  *Mandates:* The expression `dynamic_cast<T*>((U*)nullptr)` is
1700
  well-formed. The expression
1701
  `dynamic_cast<typename shared_ptr<T>::element_type*>(r.get())` is
 
1711
  returns a non-null value `p`, `shared_ptr<T>(`*`R`*`, p)`, where *`R`*
1712
  is `r` for the first overload, and `std::move(r)` for the second.
1713
  - Otherwise, `shared_ptr<T>()`.
1714
 
1715
  [*Note 10*: The seemingly equivalent expression
1716
+ `shared_ptr<T>(dynamic_cast<T*>(r.get()))` can result in undefined
1717
+ behavior, attempting to delete the same object twice. — *end note*]
 
1718
 
1719
  ``` cpp
1720
  template<class T, class U>
1721
+ constexpr shared_ptr<T> const_pointer_cast(const shared_ptr<U>& r) noexcept;
1722
  template<class T, class U>
1723
+ constexpr shared_ptr<T> const_pointer_cast(shared_ptr<U>&& r) noexcept;
1724
  ```
1725
 
1726
  *Mandates:* The expression `const_cast<T*>((U*)nullptr)` is well-formed.
1727
 
1728
  *Returns:*
 
1733
 
1734
  where *`R`* is `r` for the first overload, and `std::move(r)` for the
1735
  second.
1736
 
1737
  [*Note 11*: The seemingly equivalent expression
1738
+ `shared_ptr<T>(const_cast<T*>(r.get()))` can result in undefined
1739
+ behavior, attempting to delete the same object twice. — *end note*]
 
1740
 
1741
  ``` cpp
1742
  template<class T, class U>
1743
  shared_ptr<T> reinterpret_pointer_cast(const shared_ptr<U>& r) noexcept;
1744
  template<class T, class U>
 
1756
 
1757
  where *`R`* is `r` for the first overload, and `std::move(r)` for the
1758
  second.
1759
 
1760
  [*Note 12*: The seemingly equivalent expression
1761
+ `shared_ptr<T>(reinterpret_cast<T*>(r.get()))` can result in undefined
1762
+ behavior, attempting to delete the same object twice. — *end note*]
 
1763
 
1764
  ##### `get_deleter` <a id="util.smartptr.getdeleter">[[util.smartptr.getdeleter]]</a>
1765
 
1766
  ``` cpp
1767
  template<class D, class T>
1768
+ constexpr D* get_deleter(const shared_ptr<T>& p) noexcept;
1769
  ```
1770
 
1771
  *Returns:* If `p` owns a deleter `d` of type cv-unqualified `D`, returns
1772
  `addressof(d)`; otherwise returns `nullptr`. The returned pointer
1773
  remains valid as long as there exists a `shared_ptr` instance that owns
 
1804
  using element_type = remove_extent_t<T>;
1805
 
1806
  // [util.smartptr.weak.const], constructors
1807
  constexpr weak_ptr() noexcept;
1808
  template<class Y>
1809
+ constexpr weak_ptr(const shared_ptr<Y>& r) noexcept;
1810
+ constexpr weak_ptr(const weak_ptr& r) noexcept;
1811
  template<class Y>
1812
+ constexpr weak_ptr(const weak_ptr<Y>& r) noexcept;
1813
+ constexpr weak_ptr(weak_ptr&& r) noexcept;
1814
  template<class Y>
1815
+ constexpr weak_ptr(weak_ptr<Y>&& r) noexcept;
1816
 
1817
  // [util.smartptr.weak.dest], destructor
1818
+ constexpr ~weak_ptr();
1819
 
1820
  // [util.smartptr.weak.assign], assignment
1821
+ constexpr weak_ptr& operator=(const weak_ptr& r) noexcept;
1822
  template<class Y>
1823
+ constexpr weak_ptr& operator=(const weak_ptr<Y>& r) noexcept;
1824
  template<class Y>
1825
+ constexpr weak_ptr& operator=(const shared_ptr<Y>& r) noexcept;
1826
+ constexpr weak_ptr& operator=(weak_ptr&& r) noexcept;
1827
  template<class Y>
1828
+ constexpr weak_ptr& operator=(weak_ptr<Y>&& r) noexcept;
1829
 
1830
  // [util.smartptr.weak.mod], modifiers
1831
+ constexpr void swap(weak_ptr& r) noexcept;
1832
+ constexpr void reset() noexcept;
1833
 
1834
  // [util.smartptr.weak.obs], observers
1835
+ constexpr long use_count() const noexcept;
1836
+ constexpr bool expired() const noexcept;
1837
+ constexpr shared_ptr<T> lock() const noexcept;
1838
  template<class U>
1839
+ constexpr bool owner_before(const shared_ptr<U>& b) const noexcept;
1840
  template<class U>
1841
+ constexpr bool owner_before(const weak_ptr<U>& b) const noexcept;
1842
+ size_t owner_hash() const noexcept;
1843
+ template<class U>
1844
+ constexpr bool owner_equal(const shared_ptr<U>& b) const noexcept;
1845
+ template<class U>
1846
+ constexpr bool owner_equal(const weak_ptr<U>& b) const noexcept;
1847
  };
1848
 
1849
  template<class T>
1850
  weak_ptr(shared_ptr<T>) -> weak_ptr<T>;
1851
  }
 
1865
  pointer value.
1866
 
1867
  *Ensures:* `use_count() == 0`.
1868
 
1869
  ``` cpp
1870
+ constexpr weak_ptr(const weak_ptr& r) noexcept;
1871
+ template<class Y> constexpr weak_ptr(const weak_ptr<Y>& r) noexcept;
1872
+ template<class Y> constexpr weak_ptr(const shared_ptr<Y>& r) noexcept;
1873
  ```
1874
 
1875
  *Constraints:* For the second and third constructors, `Y*` is compatible
1876
  with `T*`.
1877
 
 
1881
  in `r`.
1882
 
1883
  *Ensures:* `use_count() == r.use_count()`.
1884
 
1885
  ``` cpp
1886
+ constexpr weak_ptr(weak_ptr&& r) noexcept;
1887
+ template<class Y> constexpr weak_ptr(weak_ptr<Y>&& r) noexcept;
1888
  ```
1889
 
1890
  *Constraints:* For the second constructor, `Y*` is compatible with `T*`.
1891
 
1892
  *Effects:* Move constructs a `weak_ptr` instance from `r`.
 
1895
  null pointer value, and `r.use_count() == 0`.
1896
 
1897
  ##### Destructor <a id="util.smartptr.weak.dest">[[util.smartptr.weak.dest]]</a>
1898
 
1899
  ``` cpp
1900
+ constexpr ~weak_ptr();
1901
  ```
1902
 
1903
  *Effects:* Destroys this `weak_ptr` object but has no effect on the
1904
  object its stored pointer points to.
1905
 
1906
  ##### Assignment <a id="util.smartptr.weak.assign">[[util.smartptr.weak.assign]]</a>
1907
 
1908
  ``` cpp
1909
+ constexpr weak_ptr& operator=(const weak_ptr& r) noexcept;
1910
+ template<class Y> constexpr weak_ptr& operator=(const weak_ptr<Y>& r) noexcept;
1911
+ template<class Y> constexpr weak_ptr& operator=(const shared_ptr<Y>& r) noexcept;
1912
  ```
1913
 
1914
  *Effects:* Equivalent to `weak_ptr(r).swap(*this)`.
1915
 
1916
  *Returns:* `*this`.
1917
 
1918
  *Remarks:* The implementation may meet the effects (and the implied
1919
  guarantees) via different means, without creating a temporary object.
1920
 
1921
  ``` cpp
1922
+ constexpr weak_ptr& operator=(weak_ptr&& r) noexcept;
1923
+ template<class Y> constexpr weak_ptr& operator=(weak_ptr<Y>&& r) noexcept;
1924
  ```
1925
 
1926
  *Effects:* Equivalent to `weak_ptr(std::move(r)).swap(*this)`.
1927
 
1928
  *Returns:* `*this`.
1929
 
1930
  ##### Modifiers <a id="util.smartptr.weak.mod">[[util.smartptr.weak.mod]]</a>
1931
 
1932
  ``` cpp
1933
+ constexpr void swap(weak_ptr& r) noexcept;
1934
  ```
1935
 
1936
  *Effects:* Exchanges the contents of `*this` and `r`.
1937
 
1938
  ``` cpp
1939
+ constexpr void reset() noexcept;
1940
  ```
1941
 
1942
  *Effects:* Equivalent to `weak_ptr().swap(*this)`.
1943
 
1944
  ##### Observers <a id="util.smartptr.weak.obs">[[util.smartptr.weak.obs]]</a>
1945
 
1946
  ``` cpp
1947
+ constexpr long use_count() const noexcept;
1948
  ```
1949
 
1950
  *Returns:* `0` if `*this` is empty; otherwise, the number of
1951
  `shared_ptr` instances that share ownership with `*this`.
1952
 
1953
  ``` cpp
1954
+ constexpr bool expired() const noexcept;
1955
  ```
1956
 
1957
  *Returns:* `use_count() == 0`.
1958
 
1959
  ``` cpp
1960
+ constexpr shared_ptr<T> lock() const noexcept;
1961
  ```
1962
 
1963
  *Returns:* `expired() ? shared_ptr<T>() : shared_ptr<T>(*this)`,
1964
  executed atomically.
1965
 
1966
  ``` cpp
1967
+ template<class U> constexpr bool owner_before(const shared_ptr<U>& b) const noexcept;
1968
+ template<class U> constexpr bool owner_before(const weak_ptr<U>& b) const noexcept;
1969
  ```
1970
 
1971
  *Returns:* An unspecified value such that
1972
 
1973
+ - `owner_before(b)` defines a strict weak ordering as defined
1974
  in  [[alg.sorting]];
1975
+ - `!owner_before(b) && !b.owner_before(*this)` is `true` if and only if
1976
+ `owner_equal(b)` is `true`.
1977
+
1978
+ ``` cpp
1979
+ size_t owner_hash() const noexcept;
1980
+ ```
1981
+
1982
+ *Returns:* An unspecified value such that, for any object `x` where
1983
+ `owner_equal(x)` is `true`, `owner_hash() == x.owner_hash()` is `true`.
1984
+
1985
+ ``` cpp
1986
+ template<class U>
1987
+ constexpr bool owner_equal(const shared_ptr<U>& b) const noexcept;
1988
+ template<class U>
1989
+ constexpr bool owner_equal(const weak_ptr<U>& b) const noexcept;
1990
+ ```
1991
+
1992
+ *Returns:* `true` if and only if `*this` and `b` share ownership or are
1993
+ both empty. Otherwise returns `false`.
1994
+
1995
+ *Remarks:* `owner_equal` is an equivalence relation.
1996
 
1997
  ##### Specialized algorithms <a id="util.smartptr.weak.spec">[[util.smartptr.weak.spec]]</a>
1998
 
1999
  ``` cpp
2000
  template<class T>
2001
+ constexpr void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept;
2002
  ```
2003
 
2004
  *Effects:* Equivalent to `a.swap(b)`.
2005
 
2006
  #### Class template `owner_less` <a id="util.smartptr.ownerless">[[util.smartptr.ownerless]]</a>
 
2011
  ``` cpp
2012
  namespace std {
2013
  template<class T = void> struct owner_less;
2014
 
2015
  template<class T> struct owner_less<shared_ptr<T>> {
2016
+ constexpr bool operator()(const shared_ptr<T>&, const shared_ptr<T>&) const noexcept;
2017
+ constexpr bool operator()(const shared_ptr<T>&, const weak_ptr<T>&) const noexcept;
2018
+ constexpr bool operator()(const weak_ptr<T>&, const shared_ptr<T>&) const noexcept;
2019
  };
2020
 
2021
  template<class T> struct owner_less<weak_ptr<T>> {
2022
+ constexpr bool operator()(const weak_ptr<T>&, const weak_ptr<T>&) const noexcept;
2023
+ constexpr bool operator()(const shared_ptr<T>&, const weak_ptr<T>&) const noexcept;
2024
+ constexpr bool operator()(const weak_ptr<T>&, const shared_ptr<T>&) const noexcept;
2025
  };
2026
 
2027
  template<> struct owner_less<void> {
2028
  template<class T, class U>
2029
+ constexpr bool operator()(const shared_ptr<T>&, const shared_ptr<U>&) const noexcept;
2030
  template<class T, class U>
2031
+ constexpr bool operator()(const shared_ptr<T>&, const weak_ptr<U>&) const noexcept;
2032
  template<class T, class U>
2033
+ constexpr bool operator()(const weak_ptr<T>&, const shared_ptr<U>&) const noexcept;
2034
  template<class T, class U>
2035
+ constexpr bool operator()(const weak_ptr<T>&, const weak_ptr<U>&) const noexcept;
2036
 
2037
  using is_transparent = unspecified;
2038
  };
2039
  }
2040
  ```
 
2045
 
2046
  Note that
2047
 
2048
  - `operator()` defines a strict weak ordering as defined in 
2049
  [[alg.sorting]];
2050
+ - `!operator()(a, b) && !operator()(b, a)` is `true` if and only if
2051
+ `a.owner_equal(b)` is `true`.
 
 
2052
 
2053
  — *end note*]
2054
 
2055
+ #### Struct `owner_hash` <a id="util.smartptr.owner.hash">[[util.smartptr.owner.hash]]</a>
2056
+
2057
+ The class `owner_hash` provides ownership-based hashing.
2058
+
2059
+ ``` cpp
2060
+ namespace std {
2061
+ struct owner_hash {
2062
+ template<class T>
2063
+ size_t operator()(const shared_ptr<T>&) const noexcept;
2064
+
2065
+ template<class T>
2066
+ size_t operator()(const weak_ptr<T>&) const noexcept;
2067
+
2068
+ using is_transparent = unspecified;
2069
+ };
2070
+ }
2071
+ ```
2072
+
2073
+ ``` cpp
2074
+ template<class T>
2075
+ size_t operator()(const shared_ptr<T>& x) const noexcept;
2076
+ template<class T>
2077
+ size_t operator()(const weak_ptr<T>& x) const noexcept;
2078
+ ```
2079
+
2080
+ *Returns:* `x.owner_hash()`.
2081
+
2082
+ [*Note 1*: For any object `y` where `x.owner_equal(y)` is `true`,
2083
+ `x.owner_hash() == y.owner_hash()` is `true`. — *end note*]
2084
+
2085
+ #### Struct `owner_equal` <a id="util.smartptr.owner.equal">[[util.smartptr.owner.equal]]</a>
2086
+
2087
+ The class `owner_equal` provides ownership-based mixed equality
2088
+ comparisons of shared and weak pointers.
2089
+
2090
+ ``` cpp
2091
+ namespace std {
2092
+ struct owner_equal {
2093
+ template<class T, class U>
2094
+ constexpr bool operator()(const shared_ptr<T>&, const shared_ptr<U>&) const noexcept;
2095
+ template<class T, class U>
2096
+ constexpr bool operator()(const shared_ptr<T>&, const weak_ptr<U>&) const noexcept;
2097
+ template<class T, class U>
2098
+ constexpr bool operator()(const weak_ptr<T>&, const shared_ptr<U>&) const noexcept;
2099
+ template<class T, class U>
2100
+ constexpr bool operator()(const weak_ptr<T>&, const weak_ptr<U>&) const noexcept;
2101
+
2102
+ using is_transparent = unspecified;
2103
+ };
2104
+ }
2105
+ ```
2106
+
2107
+ ``` cpp
2108
+ template<class T, class U>
2109
+ constexpr bool operator()(const shared_ptr<T>& x, const shared_ptr<U>& y) const noexcept;
2110
+ template<class T, class U>
2111
+ constexpr bool operator()(const shared_ptr<T>& x, const weak_ptr<U>& y) const noexcept;
2112
+ template<class T, class U>
2113
+ constexpr bool operator()(const weak_ptr<T>& x, const shared_ptr<U>& y) const noexcept;
2114
+ template<class T, class U>
2115
+ constexpr bool operator()(const weak_ptr<T>& x, const weak_ptr<U>& y) const noexcept;
2116
+ ```
2117
+
2118
+ *Returns:* `x.owner_equal(y)`.
2119
+
2120
+ [*Note 1*: `x.owner_equal(y)` is `true` if and only if `x` and `y`
2121
+ share ownership or are both empty. — *end note*]
2122
+
2123
  #### Class template `enable_shared_from_this` <a id="util.smartptr.enab">[[util.smartptr.enab]]</a>
2124
 
2125
  A class `T` can inherit from `enable_shared_from_this<T>` to inherit the
2126
  `shared_from_this` member functions that obtain a `shared_ptr` instance
2127
  pointing to `*this`.
 
2133
 
2134
  int main() {
2135
  shared_ptr<X> p(new X);
2136
  shared_ptr<X> q = p->shared_from_this();
2137
  assert(p == q);
2138
+ assert(p.owner_equal(q)); // p and q share ownership
2139
  }
2140
  ```
2141
 
2142
  — *end example*]
2143
 
2144
  ``` cpp
2145
  namespace std {
2146
  template<class T> class enable_shared_from_this {
2147
  protected:
2148
  constexpr enable_shared_from_this() noexcept;
2149
+ constexpr enable_shared_from_this(const enable_shared_from_this&) noexcept;
2150
+ constexpr enable_shared_from_this& operator=(const enable_shared_from_this&) noexcept;
2151
+ constexpr ~enable_shared_from_this();
2152
 
2153
  public:
2154
+ constexpr shared_ptr<T> shared_from_this();
2155
+ constexpr shared_ptr<T const> shared_from_this() const;
2156
+ constexpr weak_ptr<T> weak_from_this() noexcept;
2157
+ constexpr weak_ptr<T const> weak_from_this() const noexcept;
2158
 
2159
  private:
2160
+ mutable weak_ptr<T> weak-this; // exposition only
2161
  };
2162
  }
2163
  ```
2164
 
2165
  The template parameter `T` of `enable_shared_from_this` may be an
2166
  incomplete type.
2167
 
2168
  ``` cpp
2169
  constexpr enable_shared_from_this() noexcept;
2170
+ constexpr enable_shared_from_this(const enable_shared_from_this<T>&) noexcept;
2171
  ```
2172
 
2173
+ *Effects:* Value-initializes *weak-this*.
2174
 
2175
  ``` cpp
2176
+ constexpr enable_shared_from_this<T>& operator=(const enable_shared_from_this<T>&) noexcept;
2177
  ```
2178
 
2179
  *Returns:* `*this`.
2180
 
2181
+ [*Note 1*: *weak-this* is not changed. — *end note*]
2182
 
2183
  ``` cpp
2184
+ constexpr shared_ptr<T> shared_from_this();
2185
+ constexpr shared_ptr<T const> shared_from_this() const;
2186
  ```
2187
 
2188
+ *Returns:* `shared_ptr<T>(`*`weak-this`*`)`.
2189
 
2190
  ``` cpp
2191
+ constexpr weak_ptr<T> weak_from_this() noexcept;
2192
+ constexpr weak_ptr<T const> weak_from_this() const noexcept;
2193
  ```
2194
 
2195
+ *Returns:* *weak-this*.
2196
 
2197
  ### Smart pointer hash support <a id="util.smartptr.hash">[[util.smartptr.hash]]</a>
2198
 
2199
  ``` cpp
2200
  template<class T, class D> struct hash<unique_ptr<T, D>>;
 
2255
  ``` cpp
2256
  namespace std {
2257
  template<class Smart, class Pointer, class... Args>
2258
  class out_ptr_t {
2259
  public:
2260
+ constexpr explicit out_ptr_t(Smart&, Args...);
2261
  out_ptr_t(const out_ptr_t&) = delete;
2262
 
2263
+ constexpr ~out_ptr_t();
2264
 
2265
+ constexpr operator Pointer*() const noexcept;
2266
  operator void**() const noexcept;
2267
 
2268
  private:
2269
  Smart& s; // exposition only
2270
  tuple<Args...> a; // exposition only
 
2288
 
2289
  Evaluations of the conversion functions on the same object may conflict
2290
  [[intro.races]].
2291
 
2292
  ``` cpp
2293
+ constexpr explicit out_ptr_t(Smart& smart, Args... args);
2294
  ```
2295
 
2296
  *Effects:* Initializes `s` with `smart`, `a` with
2297
  `std::forward<Args>(args)...`, and value-initializes `p`. Then,
2298
  equivalent to:
2299
 
2300
+ -
2301
+ ``` cpp
2302
  s.reset();
2303
  ```
2304
 
2305
  if the expression `s.reset()` is well-formed;
 
2306
  - otherwise,
2307
  ``` cpp
2308
  s = Smart();
2309
  ```
2310
 
2311
  if `is_constructible_v<Smart>` is `true`;
 
2312
  - otherwise, the program is ill-formed.
2313
 
2314
  [*Note 1*: The constructor is not `noexcept` to allow for a variety of
2315
  non-terminating and safe implementation strategies. For example, an
2316
  implementation can allocate a `shared_ptr`’s internal node in the
2317
  constructor and let implementation-defined exceptions escape safely. The
2318
  destructor can then move the allocated control block in directly and
2319
  avoid any other exceptions. — *end note*]
2320
 
2321
  ``` cpp
2322
+ constexpr ~out_ptr_t();
2323
  ```
2324
 
2325
  Let `SP` be *`POINTER_OF_OR`*`(Smart, Pointer)` [[memory.general]].
2326
 
2327
  *Effects:* Equivalent to:
 
2347
 
2348
  if `is_constructible_v<Smart, SP, Args...>` is `true`;
2349
  - otherwise, the program is ill-formed.
2350
 
2351
  ``` cpp
2352
+ constexpr operator Pointer*() const noexcept;
2353
  ```
2354
 
2355
  *Preconditions:* `operator void**()` has not been called on `*this`.
2356
 
2357
  *Returns:* `addressof(const_cast<Pointer&>(p))`.
 
2382
 
2383
  #### Function template `out_ptr` <a id="out.ptr">[[out.ptr]]</a>
2384
 
2385
  ``` cpp
2386
  template<class Pointer = void, class Smart, class... Args>
2387
+ constexpr auto out_ptr(Smart& s, Args&&... args);
2388
  ```
2389
 
2390
  Let `P` be `Pointer` if `is_void_v<Pointer>` is `false`, otherwise
2391
  *`POINTER_OF`*`(Smart)`.
2392
 
2393
  *Returns:*
2394
+ `out_ptr_t<Smart, P, Args&&...>(s, std::forward<Args>(args)...)`.
2395
 
2396
  #### Class template `inout_ptr_t` <a id="inout.ptr.t">[[inout.ptr.t]]</a>
2397
 
2398
  `inout_ptr_t` is a class template used to adapt types such as smart
2399
  pointers [[smartptr]] for functions that use output pointer parameters
 
2433
  ``` cpp
2434
  namespace std {
2435
  template<class Smart, class Pointer, class... Args>
2436
  class inout_ptr_t {
2437
  public:
2438
+ constexpr explicit inout_ptr_t(Smart&, Args...);
2439
  inout_ptr_t(const inout_ptr_t&) = delete;
2440
 
2441
+ constexpr ~inout_ptr_t();
2442
 
2443
+ constexpr operator Pointer*() const noexcept;
2444
  operator void**() const noexcept;
2445
 
2446
  private:
2447
  Smart& s; // exposition only
2448
  tuple<Args...> a; // exposition only
 
2464
 
2465
  Evaluations of the conversion functions on the same object may conflict
2466
  [[intro.races]].
2467
 
2468
  ``` cpp
2469
+ constexpr explicit inout_ptr_t(Smart& smart, Args... args);
2470
  ```
2471
 
2472
  *Effects:* Initializes `s` with `smart`, `a` with
2473
  `std::forward<Args>(args)...`, and `p` to either
2474
 
 
2481
  non-terminating and safe implementation strategies. For example, an
2482
  intrusive pointer implementation with a control block can allocate in
2483
  the constructor and safely fail with an exception. — *end note*]
2484
 
2485
  ``` cpp
2486
+ constexpr ~inout_ptr_t();
2487
  ```
2488
 
2489
  Let `SP` be *`POINTER_OF_OR`*`(Smart, Pointer)` [[memory.general]].
2490
 
2491
  Let *release-statement* be `s.release();` if an implementation does not
 
2493
 
2494
  *Effects:* Equivalent to:
2495
 
2496
  -
2497
  ``` cpp
 
2498
  apply([&](auto&&... args) {
2499
  s = Smart(static_cast<SP>(p), std::forward<Args>(args)...); }, std::move(a));
 
2500
  ```
2501
 
2502
  if `is_pointer_v<Smart>` is `true`;
2503
  - otherwise,
2504
  ``` cpp
 
2523
 
2524
  if `is_constructible_v<Smart, SP, Args...>` is `true`;
2525
  - otherwise, the program is ill-formed.
2526
 
2527
  ``` cpp
2528
+ constexpr operator Pointer*() const noexcept;
2529
  ```
2530
 
2531
  *Preconditions:* `operator void**()` has not been called on `*this`.
2532
 
2533
  *Returns:* `addressof(const_cast<Pointer&>(p))`.
 
2558
 
2559
  #### Function template `inout_ptr` <a id="inout.ptr">[[inout.ptr]]</a>
2560
 
2561
  ``` cpp
2562
  template<class Pointer = void, class Smart, class... Args>
2563
+ constexpr auto inout_ptr(Smart& s, Args&&... args);
2564
  ```
2565
 
2566
  Let `P` be `Pointer` if `is_void_v<Pointer>` is `false`, otherwise
2567
  *`POINTER_OF`*`(Smart)`.
2568