Skip to content

Commit 8470fab

Browse files
authored
Merge 2023-06 LWG Motion 16
P1901R2 Enabling the Use of weak_ptr as Keys in Unordered Associative Containers
2 parents 895283e + 1954f1b commit 8470fab

File tree

2 files changed

+180
-16
lines changed

2 files changed

+180
-16
lines changed

source/memory.tex

Lines changed: 179 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -551,6 +551,12 @@
551551
// \ref{util.smartptr.ownerless}, class template \tcode{owner_less}
552552
template<class T = void> struct owner_less;
553553

554+
// \ref{util.smartptr.owner.hash}, struct \tcode{owner_hash}
555+
struct owner_hash;
556+
557+
// \ref{util.smartptr.owner.equal}, struct \tcode{owner_equal}
558+
struct owner_equal;
559+
554560
// \ref{util.smartptr.enab}, class template \tcode{enable_shared_from_this}
555561
template<class T> class enable_shared_from_this;
556562

@@ -3227,6 +3233,11 @@
32273233
bool owner_before(const shared_ptr<U>& b) const noexcept;
32283234
template<class U>
32293235
bool owner_before(const weak_ptr<U>& b) const noexcept;
3236+
size_t owner_hash() const noexcept;
3237+
template<class U>
3238+
bool owner_equal(const shared_ptr<U>& b) const noexcept;
3239+
template<class U>
3240+
bool owner_equal(const weak_ptr<U>& b) const noexcept;
32303241
};
32313242

32323243
template<class T>
@@ -3833,14 +3844,45 @@
38333844
\returns
38343845
An unspecified value such that
38353846
\begin{itemize}
3836-
\item \tcode{x.owner_before(y)} defines a strict weak ordering as defined in~\ref{alg.sorting};
3837-
3838-
\item under the equivalence relation defined by \tcode{owner_before},
3839-
\tcode{!a.owner_before(b) \&\& !b.owner_before(a)}, two \tcode{shared_ptr} or
3840-
\tcode{weak_ptr} instances are equivalent if and only if they share ownership or
3841-
are both empty.
3847+
\item
3848+
\tcode{owner_before(b)} defines a strict weak ordering as defined in~\ref{alg.sorting};
3849+
\item
3850+
\tcode{!owner_before(b) \&\& !b.owner_before(*this)} is \tcode{true}
3851+
if and only if \tcode{owner_equal(b)} is \tcode{true}.
38423852
\end{itemize}
3853+
\end{itemdescr}
3854+
3855+
\indexlibrarymember{owner_hash}{shared_ptr}%
3856+
\begin{itemdecl}
3857+
size_t owner_hash() const noexcept;
3858+
\end{itemdecl}
38433859

3860+
\begin{itemdescr}
3861+
\pnum
3862+
\returns
3863+
An unspecified value such that,
3864+
for any object \tcode{x} where \tcode{owner_equal(x)} is \tcode{true},
3865+
\tcode{owner_hash() == x.owner_hash()} is \tcode{true}.
3866+
\end{itemdescr}
3867+
3868+
\indexlibrarymember{owner_equal}{shared_ptr}%
3869+
\begin{itemdecl}
3870+
template<class U>
3871+
bool owner_equal(const shared_ptr<U>& b) const noexcept;
3872+
template<class U>
3873+
bool owner_equal(const weak_ptr<U>& b) const noexcept;
3874+
\end{itemdecl}
3875+
3876+
\begin{itemdescr}
3877+
\pnum
3878+
\returns
3879+
\tcode{true} if and only if
3880+
\tcode{*this} and \tcode{b} share ownership or are both empty.
3881+
Otherwise returns \tcode{false}.
3882+
3883+
\pnum
3884+
\remarks
3885+
\tcode{owner_equal} is an equivalence relation.
38443886
\end{itemdescr}
38453887

38463888
\rSec4[util.smartptr.shared.create]{Creation}
@@ -4511,6 +4553,11 @@
45114553
bool owner_before(const shared_ptr<U>& b) const noexcept;
45124554
template<class U>
45134555
bool owner_before(const weak_ptr<U>& b) const noexcept;
4556+
size_t owner_hash() const noexcept;
4557+
template<class U>
4558+
bool owner_equal(const shared_ptr<U>& b) const noexcept;
4559+
template<class U>
4560+
bool owner_equal(const weak_ptr<U>& b) const noexcept;
45144561
};
45154562

45164563
template<class T>
@@ -4711,15 +4758,45 @@
47114758
\returns
47124759
An unspecified value such that
47134760
\begin{itemize}
4714-
\item \tcode{x.owner_before(y)} defines a strict weak ordering as defined in~\ref{alg.sorting};
4761+
\item \tcode{owner_before(b)} defines a strict weak ordering as defined in~\ref{alg.sorting};
47154762

4716-
\item under the equivalence relation defined by \tcode{owner_before},
4717-
\tcode{!a.owner_before(b) \&\& !b.owner_before(a)}, two \tcode{shared_ptr} or
4718-
\tcode{weak_ptr} instances are equivalent if and only if they share ownership or are
4719-
both empty.
4763+
\item \tcode{!owner_before(b) \&\& !b.owner_before(*this)} is \tcode{true}
4764+
if and only if \tcode{owner_equal(b)} is \tcode{true}.
47204765
\end{itemize}
47214766
\end{itemdescr}
47224767

4768+
\indexlibrarymember{owner_hash}{weak_ptr}%
4769+
\begin{itemdecl}
4770+
size_t owner_hash() const noexcept;
4771+
\end{itemdecl}
4772+
4773+
\begin{itemdescr}
4774+
\pnum
4775+
\returns
4776+
An unspecified value such that,
4777+
for any object \tcode{x} where \tcode{owner_equal(x)} is \tcode{true},
4778+
\tcode{owner_hash() == x.owner_hash()} is \tcode{true}.
4779+
\end{itemdescr}
4780+
4781+
\indexlibrarymember{owner_equal}{weak_ptr}%
4782+
\begin{itemdecl}
4783+
template<class U>
4784+
bool owner_equal(const shared_ptr<U>& b) const noexcept;
4785+
template<class U>
4786+
bool owner_equal(const weak_ptr<U>& b) const noexcept;
4787+
\end{itemdecl}
4788+
4789+
\begin{itemdescr}
4790+
\pnum
4791+
\returns
4792+
\tcode{true} if and only if
4793+
\tcode{*this} and \tcode{b} share ownership or are both empty.
4794+
Otherwise returns \tcode{false}.
4795+
4796+
\pnum
4797+
\remarks
4798+
\tcode{owner_equal} is an equivalence relation.
4799+
\end{itemdescr}
47234800

47244801
\rSec4[util.smartptr.weak.spec]{Specialized algorithms}
47254802

@@ -4782,13 +4859,99 @@
47824859
\item \tcode{operator()} defines a strict weak ordering as defined in~\ref{alg.sorting};
47834860

47844861
\item
4785-
two \tcode{shared_ptr} or \tcode{weak_ptr} instances are equivalent
4786-
under the equivalence relation defined by \tcode{operator()},
4787-
\tcode{!operator()(a, b) \&\& !operator()(b, a)},
4788-
if and only if they share ownership or are both empty.
4862+
\tcode{!operator()(a, b) \&\& !operator()(b, a)} is \tcode{true}
4863+
if and only if \tcode{a.owner_equal(b)} is \tcode{true}.
47894864
\end{itemize}
47904865
\end{note}
47914866

4867+
\rSec3[util.smartptr.owner.hash]{Struct \tcode{owner_hash}}
4868+
4869+
\pnum
4870+
The class \tcode{owner_hash} provides ownership-based hashing.
4871+
4872+
\indexlibraryglobal{owner_hash}%
4873+
\begin{codeblock}
4874+
namespace std {
4875+
struct owner_hash {
4876+
template<class T>
4877+
size_t operator()(const shared_ptr<T>&) const noexcept;
4878+
4879+
template<class T>
4880+
size_t operator()(const weak_ptr<T>&) const noexcept;
4881+
4882+
using is_transparent = @\unspec@;
4883+
};
4884+
}
4885+
\end{codeblock}
4886+
4887+
\indexlibrarymember{operator()}{owner_hash}%
4888+
\begin{itemdecl}
4889+
template<class T>
4890+
size_t operator()(const shared_ptr<T>& x) const noexcept;
4891+
template<class T>
4892+
size_t operator()(const weak_ptr<T>& x) const noexcept;
4893+
\end{itemdecl}
4894+
4895+
\begin{itemdescr}
4896+
\pnum
4897+
\returns
4898+
\tcode{x.owner_hash()}.
4899+
4900+
\pnum
4901+
\begin{note}
4902+
For any object \tcode{y} where \tcode{x.owner_equal(y)} is \tcode{true},
4903+
\tcode{x.owner_hash() == y.owner_hash()} is \tcode{true}.
4904+
\end{note}
4905+
\end{itemdescr}
4906+
4907+
\rSec3[util.smartptr.owner.equal]{Struct \tcode{owner_equal}}
4908+
4909+
\pnum
4910+
The class \tcode{owner_equal} provides
4911+
ownership-based mixed equality comparisons of shared and weak pointers.
4912+
4913+
\indexlibraryglobal{owner_equal}%
4914+
\begin{codeblock}
4915+
namespace std {
4916+
struct owner_equal {
4917+
template<class T, class U>
4918+
bool operator()(const shared_ptr<T>&, const shared_ptr<U>&) const noexcept;
4919+
template<class T, class U>
4920+
bool operator()(const shared_ptr<T>&, const weak_ptr<U>&) const noexcept;
4921+
template<class T, class U>
4922+
bool operator()(const weak_ptr<T>&, const shared_ptr<U>&) const noexcept;
4923+
template<class T, class U>
4924+
bool operator()(const weak_ptr<T>&, const weak_ptr<U>&) const noexcept;
4925+
4926+
using is_transparent = @\unspec@;
4927+
};
4928+
}
4929+
\end{codeblock}
4930+
4931+
\indexlibrarymember{operator()}{owner_equal}%
4932+
\begin{itemdecl}
4933+
template<class T, class U>
4934+
bool operator()(const shared_ptr<T>& x, const shared_ptr<U>& y) const noexcept;
4935+
template<class T, class U>
4936+
bool operator()(const shared_ptr<T>& x, const weak_ptr<U>& y) const noexcept;
4937+
template<class T, class U>
4938+
bool operator()(const weak_ptr<T>& x, const shared_ptr<U>& y) const noexcept;
4939+
template<class T, class U>
4940+
bool operator()(const weak_ptr<T>& x, const weak_ptr<U>& y) const noexcept;
4941+
\end{itemdecl}
4942+
4943+
\begin{itemdescr}
4944+
\pnum
4945+
\returns
4946+
\tcode{x.owner_equal(y)}.
4947+
4948+
\pnum
4949+
\begin{note}
4950+
\tcode{x.owner_equal(y)} is \tcode{true}
4951+
if and only if \tcode{x} and \tcode{y} share ownership or are both empty.
4952+
\end{note}
4953+
\end{itemdescr}
4954+
47924955
\rSec3[util.smartptr.enab]{Class template \tcode{enable_shared_from_this}}
47934956

47944957
\pnum
@@ -4806,7 +4969,7 @@
48064969
shared_ptr<X> p(new X);
48074970
shared_ptr<X> q = p->shared_from_this();
48084971
assert(p == q);
4809-
assert(!p.owner_before(q) && !q.owner_before(p)); // p and q share ownership
4972+
assert(p.owner_equal(q)); // \tcode{p} and \tcode{q} share ownership
48104973
}
48114974
\end{codeblock}
48124975
\end{example}

source/support.tex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -742,6 +742,7 @@
742742
#define @\defnlibxname{cpp_lib_shared_ptr_weak_type}@ 201606L // also in \libheader{memory}
743743
#define @\defnlibxname{cpp_lib_shared_timed_mutex}@ 201402L // also in \libheader{shared_mutex}
744744
#define @\defnlibxname{cpp_lib_shift}@ 202202L // also in \libheader{algorithm}
745+
#define @\defnlibxname{cpp_lib_smart_pointer_owner_equality}@ 202306L // also in \libheader{memory}
745746
#define @\defnlibxname{cpp_lib_smart_ptr_for_overwrite}@ 202002L // also in \libheader{memory}
746747
#define @\defnlibxname{cpp_lib_source_location}@ 201907L // freestanding, also in \libheader{source_location}
747748
#define @\defnlibxname{cpp_lib_span}@ 202002L // also in \libheader{span}

0 commit comments

Comments
 (0)