Init
This commit is contained in:
1919
cppdraft/util/sharedptr.md
Normal file
1919
cppdraft/util/sharedptr.md
Normal file
File diff suppressed because it is too large
Load Diff
675
cppdraft/util/smartptr/atomic.md
Normal file
675
cppdraft/util/smartptr/atomic.md
Normal file
@@ -0,0 +1,675 @@
|
||||
[util.smartptr.atomic]
|
||||
|
||||
# 32 Concurrency support library [[thread]](./#thread)
|
||||
|
||||
## 32.5 Atomic operations [[atomics]](atomics#util.smartptr.atomic)
|
||||
|
||||
### 32.5.8 Class template atomic [[atomics.types.generic]](atomics.types.generic#util.smartptr.atomic)
|
||||
|
||||
#### 32.5.8.7 Partial specializations for smart pointers [util.smartptr.atomic]
|
||||
|
||||
#### [32.5.8.7.1](#general) General [[util.smartptr.atomic.general]](util.smartptr.atomic.general)
|
||||
|
||||
[1](#general-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6072)
|
||||
|
||||
The library provides partial specializations of the atomic template
|
||||
for shared-ownership smart pointers ([[util.sharedptr]](util.sharedptr "20.3.2 Shared-ownership pointers"))[.](#general-1.sentence-1)
|
||||
|
||||
[*Note [1](#general-note-1)*:
|
||||
|
||||
The partial specializations are declared in header [<memory>](memory.syn#header:%3cmemory%3e "20.2.2 Header <memory> synopsis [memory.syn]")[.](#general-1.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
|
||||
The behavior of all operations is as specified in [[atomics.types.generic]](atomics.types.generic "32.5.8 Class template atomic"),
|
||||
unless specified otherwise[.](#general-1.sentence-3)
|
||||
|
||||
The template parameter T of these partial specializations
|
||||
may be an incomplete type[.](#general-1.sentence-4)
|
||||
|
||||
[2](#general-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6083)
|
||||
|
||||
All changes to an atomic smart pointer in [util.smartptr.atomic], and
|
||||
all associated use_count increments,
|
||||
are guaranteed to be performed atomically[.](#general-2.sentence-1)
|
||||
|
||||
Associated use_count decrements
|
||||
are sequenced after the atomic operation,
|
||||
but are not required to be part of it[.](#general-2.sentence-2)
|
||||
|
||||
Any associated deletion and deallocation
|
||||
are sequenced after the atomic update step and
|
||||
are not part of the atomic operation[.](#general-2.sentence-3)
|
||||
|
||||
[*Note [2](#general-note-2)*:
|
||||
|
||||
If the atomic operation uses locks,
|
||||
locks acquired by the implementation
|
||||
will be held when any use_count adjustments are performed, and
|
||||
will not be held when any destruction or deallocation
|
||||
resulting from this is performed[.](#general-2.sentence-4)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[3](#general-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6101)
|
||||
|
||||
[*Example [1](#general-example-1)*: template<typename T> class atomic_list {struct node { T t;
|
||||
shared_ptr<node> next; };
|
||||
atomic<shared_ptr<node>> head;
|
||||
|
||||
public: shared_ptr<node> find(T t) const {auto p = head.load(); while (p && p->t != t) p = p->next; return p; }void push_front(T t) {auto p = make_shared<node>();
|
||||
p->t = t;
|
||||
p->next = head; while (!head.compare_exchange_weak(p->next, p)) {}}}; â *end example*]
|
||||
|
||||
#### [32.5.8.7.2](#shared) Partial specialization for shared_ptr [[util.smartptr.atomic.shared]](util.smartptr.atomic.shared)
|
||||
|
||||
[ð](#lib:atomic%3cshared_ptr%3cT%3e%3e)
|
||||
|
||||
namespace std {template<class T> struct atomic<shared_ptr<T>> {using value_type = shared_ptr<T>; static constexpr bool is_always_lock_free = *implementation-defined*; bool is_lock_free() const noexcept; constexpr atomic() noexcept; constexpr atomic(nullptr_t) noexcept : atomic() { }constexpr atomic(shared_ptr<T> desired) noexcept;
|
||||
atomic(const atomic&) = delete; void operator=(const atomic&) = delete; constexpr shared_ptr<T> load(memory_order order = memory_order::seq_cst) const noexcept; constexpr operator shared_ptr<T>() const noexcept; constexpr void store(shared_ptr<T> desired,
|
||||
memory_order order = memory_order::seq_cst) noexcept; constexpr void operator=(shared_ptr<T> desired) noexcept; constexpr void operator=(nullptr_t) noexcept; constexpr shared_ptr<T> exchange(shared_ptr<T> desired,
|
||||
memory_order order = memory_order::seq_cst) noexcept; constexpr bool compare_exchange_weak(shared_ptr<T>& expected, shared_ptr<T> desired,
|
||||
memory_order success, memory_order failure) noexcept; constexpr bool compare_exchange_strong(shared_ptr<T>& expected, shared_ptr<T> desired,
|
||||
memory_order success, memory_order failure) noexcept; constexpr bool compare_exchange_weak(shared_ptr<T>& expected, shared_ptr<T> desired,
|
||||
memory_order order = memory_order::seq_cst) noexcept; constexpr bool compare_exchange_strong(shared_ptr<T>& expected, shared_ptr<T> desired,
|
||||
memory_order order = memory_order::seq_cst) noexcept; constexpr void wait(shared_ptr<T> old,
|
||||
memory_order order = memory_order::seq_cst) const noexcept; constexpr void notify_one() noexcept; constexpr void notify_all() noexcept; private: shared_ptr<T> p; // *exposition only*};}
|
||||
|
||||
[ð](#lib:atomic%3cshared_ptr%3cT%3e%3e,constructor)
|
||||
|
||||
`constexpr atomic() noexcept;
|
||||
`
|
||||
|
||||
[1](#shared-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6181)
|
||||
|
||||
*Effects*: Value-initializes p[.](#shared-1.sentence-1)
|
||||
|
||||
[ð](#lib:atomic%3cshared_ptr%3cT%3e%3e,constructor_)
|
||||
|
||||
`constexpr atomic(shared_ptr<T> desired) noexcept;
|
||||
`
|
||||
|
||||
[2](#shared-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6192)
|
||||
|
||||
*Effects*: Initializes the object with the value desired[.](#shared-2.sentence-1)
|
||||
|
||||
Initialization is not an atomic operation ([[intro.multithread]](intro.multithread "6.10.2 Multi-threaded executions and data races"))[.](#shared-2.sentence-2)
|
||||
|
||||
[*Note [1](#shared-note-1)*:
|
||||
|
||||
It is possible to have an access to
|
||||
an atomic object A race with its construction,
|
||||
for example,
|
||||
by communicating the address of the just-constructed object A to another thread via memory_order::relaxed operations
|
||||
on a suitable atomic pointer variable, and
|
||||
then immediately accessing A in the receiving thread[.](#shared-2.sentence-3)
|
||||
|
||||
This results in undefined behavior[.](#shared-2.sentence-4)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[ð](#lib:store,atomic%3cshared_ptr%3cT%3e%3e)
|
||||
|
||||
`constexpr void store(shared_ptr<T> desired, memory_order order = memory_order::seq_cst) noexcept;
|
||||
`
|
||||
|
||||
[3](#shared-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6214)
|
||||
|
||||
*Preconditions*: order ismemory_order::relaxed,memory_order::release, ormemory_order::seq_cst[.](#shared-3.sentence-1)
|
||||
|
||||
[4](#shared-4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6221)
|
||||
|
||||
*Effects*: Atomically replaces the value pointed to by this with
|
||||
the value of desired as if by p.swap(desired)[.](#shared-4.sentence-1)
|
||||
|
||||
Memory is affected according to the value of order[.](#shared-4.sentence-2)
|
||||
|
||||
[ð](#lib:operator=,atomic%3cshared_ptr%3cT%3e%3e)
|
||||
|
||||
`constexpr void operator=(shared_ptr<T> desired) noexcept;
|
||||
`
|
||||
|
||||
[5](#shared-5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6234)
|
||||
|
||||
*Effects*: Equivalent to store(desired)[.](#shared-5.sentence-1)
|
||||
|
||||
[ð](#lib:operator=,atomic%3cshared_ptr%3cT%3e%3e_)
|
||||
|
||||
`constexpr void operator=(nullptr_t) noexcept;
|
||||
`
|
||||
|
||||
[6](#shared-6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6245)
|
||||
|
||||
*Effects*: Equivalent to store(nullptr)[.](#shared-6.sentence-1)
|
||||
|
||||
[ð](#lib:load,atomic%3cshared_ptr%3cT%3e%3e)
|
||||
|
||||
`constexpr shared_ptr<T> load(memory_order order = memory_order::seq_cst) const noexcept;
|
||||
`
|
||||
|
||||
[7](#shared-7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6256)
|
||||
|
||||
*Preconditions*: order ismemory_order::relaxed,memory_order::acquire, ormemory_order::seq_cst[.](#shared-7.sentence-1)
|
||||
|
||||
[8](#shared-8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6263)
|
||||
|
||||
*Effects*: Memory is affected according to the value of order[.](#shared-8.sentence-1)
|
||||
|
||||
[9](#shared-9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6267)
|
||||
|
||||
*Returns*: Atomically returns p[.](#shared-9.sentence-1)
|
||||
|
||||
[ð](#lib:operator_shared_ptr%3cT%3e,atomic%3cshared_ptr%3cT%3e%3e)
|
||||
|
||||
`constexpr operator shared_ptr<T>() const noexcept;
|
||||
`
|
||||
|
||||
[10](#shared-10)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6278)
|
||||
|
||||
*Effects*: Equivalent to: return load();
|
||||
|
||||
[ð](#lib:exchange,atomic%3cshared_ptr%3cT%3e%3e)
|
||||
|
||||
`constexpr shared_ptr<T> exchange(shared_ptr<T> desired,
|
||||
memory_order order = memory_order::seq_cst) noexcept;
|
||||
`
|
||||
|
||||
[11](#shared-11)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6290)
|
||||
|
||||
*Effects*: Atomically replaces p with desired as if by p.swap(desired)[.](#shared-11.sentence-1)
|
||||
|
||||
Memory is affected according to the value of order[.](#shared-11.sentence-2)
|
||||
|
||||
This is an atomic read-modify-write operation ([[intro.races]](intro.races "6.10.2.2 Data races"))[.](#shared-11.sentence-3)
|
||||
|
||||
[12](#shared-12)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6297)
|
||||
|
||||
*Returns*: Atomically returns the value of p immediately before the effects[.](#shared-12.sentence-1)
|
||||
|
||||
[ð](#lib:compare_exchange_weak,atomic%3cshared_ptr%3cT%3e%3e)
|
||||
|
||||
`constexpr bool compare_exchange_weak(shared_ptr<T>& expected, shared_ptr<T> desired,
|
||||
memory_order success, memory_order failure) noexcept;
|
||||
constexpr bool compare_exchange_strong(shared_ptr<T>& expected, shared_ptr<T> desired,
|
||||
memory_order success, memory_order failure) noexcept;
|
||||
`
|
||||
|
||||
[13](#shared-13)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6312)
|
||||
|
||||
*Preconditions*: failure ismemory_order::relaxed,memory_order::acquire, ormemory_order::seq_cst[.](#shared-13.sentence-1)
|
||||
|
||||
[14](#shared-14)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6319)
|
||||
|
||||
*Effects*: If p is equivalent to expected,
|
||||
assigns desired to p and
|
||||
has synchronization semantics corresponding to the value of success,
|
||||
otherwise assigns p to expected and
|
||||
has synchronization semantics corresponding to the value of failure[.](#shared-14.sentence-1)
|
||||
|
||||
[15](#shared-15)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6327)
|
||||
|
||||
*Returns*: true if p was equivalent to expected,false otherwise[.](#shared-15.sentence-1)
|
||||
|
||||
[16](#shared-16)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6332)
|
||||
|
||||
*Remarks*: Two shared_ptr objects are equivalent if
|
||||
they store the same pointer value and
|
||||
either share ownership or are both empty[.](#shared-16.sentence-1)
|
||||
|
||||
The weak form may fail spuriously[.](#shared-16.sentence-2)
|
||||
|
||||
See [[atomics.types.operations]](atomics.types.operations "32.5.8.2 Operations on atomic types")[.](#shared-16.sentence-3)
|
||||
|
||||
[17](#shared-17)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6339)
|
||||
|
||||
If the operation returns true,expected is not accessed after the atomic update and
|
||||
the operation is an atomic read-modify-write operation ([[intro.multithread]](intro.multithread "6.10.2 Multi-threaded executions and data races"))
|
||||
on the memory pointed to by this[.](#shared-17.sentence-1)
|
||||
|
||||
Otherwise, the operation is an atomic load operation on that memory, andexpected is updated with the existing value
|
||||
read from the atomic object in the attempted atomic update[.](#shared-17.sentence-2)
|
||||
|
||||
The use_count update corresponding to the write to expected is part of the atomic operation[.](#shared-17.sentence-3)
|
||||
|
||||
The write to expected itself
|
||||
is not required to be part of the atomic operation[.](#shared-17.sentence-4)
|
||||
|
||||
[ð](#lib:compare_exchange_weak,atomic%3cshared_ptr%3cT%3e%3e_)
|
||||
|
||||
`constexpr bool compare_exchange_weak(shared_ptr<T>& expected, shared_ptr<T> desired,
|
||||
memory_order order = memory_order::seq_cst) noexcept;
|
||||
`
|
||||
|
||||
[18](#shared-18)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6360)
|
||||
|
||||
*Effects*: Equivalent to:return compare_exchange_weak(expected, desired, order, fail_order); where fail_order is the same as order except that a value of memory_order::acq_rel shall be replaced by the value memory_order::acquire and
|
||||
a value of memory_order::release shall be replaced by the value memory_order::relaxed[.](#shared-18.sentence-1)
|
||||
|
||||
[ð](#lib:compare_exchange_strong,atomic%3cshared_ptr%3cT%3e%3e_)
|
||||
|
||||
`constexpr bool compare_exchange_strong(shared_ptr<T>& expected, shared_ptr<T> desired,
|
||||
memory_order order = memory_order::seq_cst) noexcept;
|
||||
`
|
||||
|
||||
[19](#shared-19)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6380)
|
||||
|
||||
*Effects*: Equivalent to:return compare_exchange_strong(expected, desired, order, fail_order); where fail_order is the same as order except that a value of memory_order::acq_rel shall be replaced by the value memory_order::acquire and
|
||||
a value of memory_order::release shall be replaced by the value memory_order::relaxed[.](#shared-19.sentence-1)
|
||||
|
||||
[ð](#lib:wait,atomic%3cshared_ptr%3cT%3e%3e)
|
||||
|
||||
`constexpr void wait(shared_ptr<T> old, memory_order order = memory_order::seq_cst) const noexcept;
|
||||
`
|
||||
|
||||
[20](#shared-20)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6399)
|
||||
|
||||
*Preconditions*: order ismemory_order::relaxed,memory_order::acquire, ormemory_order::seq_cst[.](#shared-20.sentence-1)
|
||||
|
||||
[21](#shared-21)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6406)
|
||||
|
||||
*Effects*: Repeatedly performs the following steps, in order:
|
||||
|
||||
- [(21.1)](#shared-21.1)
|
||||
|
||||
Evaluates load(order) and compares it to old[.](#shared-21.1.sentence-1)
|
||||
|
||||
- [(21.2)](#shared-21.2)
|
||||
|
||||
If the two are not equivalent, returns[.](#shared-21.2.sentence-1)
|
||||
|
||||
- [(21.3)](#shared-21.3)
|
||||
|
||||
Blocks until it
|
||||
is unblocked by an atomic notifying operation or is unblocked spuriously[.](#shared-21.3.sentence-1)
|
||||
|
||||
[22](#shared-22)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6419)
|
||||
|
||||
*Remarks*: Two shared_ptr objects are equivalent
|
||||
if they store the same pointer and either share ownership or are both empty[.](#shared-22.sentence-1)
|
||||
|
||||
This function is an atomic waiting operation ([[atomics.wait]](atomics.wait "32.5.6 Waiting and notifying"))[.](#shared-22.sentence-2)
|
||||
|
||||
[ð](#lib:notify_one,atomic%3cshared_ptr%3cT%3e%3e)
|
||||
|
||||
`constexpr void notify_one() noexcept;
|
||||
`
|
||||
|
||||
[23](#shared-23)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6432)
|
||||
|
||||
*Effects*: Unblocks the execution of at least one atomic waiting operation
|
||||
that is eligible to be unblocked ([[atomics.wait]](atomics.wait "32.5.6 Waiting and notifying")) by this call,
|
||||
if any such atomic waiting operations exist[.](#shared-23.sentence-1)
|
||||
|
||||
[24](#shared-24)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6438)
|
||||
|
||||
*Remarks*: This function is an atomic notifying operation ([[atomics.wait]](atomics.wait "32.5.6 Waiting and notifying"))[.](#shared-24.sentence-1)
|
||||
|
||||
[ð](#lib:notify_all,atomic%3cshared_ptr%3cT%3e%3e)
|
||||
|
||||
`constexpr void notify_all() noexcept;
|
||||
`
|
||||
|
||||
[25](#shared-25)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6449)
|
||||
|
||||
*Effects*: Unblocks the execution of all atomic waiting operations
|
||||
that are eligible to be unblocked ([[atomics.wait]](atomics.wait "32.5.6 Waiting and notifying")) by this call[.](#shared-25.sentence-1)
|
||||
|
||||
[26](#shared-26)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6454)
|
||||
|
||||
*Remarks*: This function is an atomic notifying operation ([[atomics.wait]](atomics.wait "32.5.6 Waiting and notifying"))[.](#shared-26.sentence-1)
|
||||
|
||||
#### [32.5.8.7.3](#weak) Partial specialization for weak_ptr [[util.smartptr.atomic.weak]](util.smartptr.atomic.weak)
|
||||
|
||||
[ð](#lib:atomic%3cweak_ptr%3cT%3e%3e)
|
||||
|
||||
namespace std {template<class T> struct atomic<weak_ptr<T>> {using value_type = weak_ptr<T>; static constexpr bool is_always_lock_free = *implementation-defined*; bool is_lock_free() const noexcept; constexpr atomic() noexcept; constexpr atomic(weak_ptr<T> desired) noexcept;
|
||||
atomic(const atomic&) = delete; void operator=(const atomic&) = delete; constexpr weak_ptr<T> load(memory_order order = memory_order::seq_cst) const noexcept; constexpr operator weak_ptr<T>() const noexcept; constexpr void store(weak_ptr<T> desired,
|
||||
memory_order order = memory_order::seq_cst) noexcept; constexpr void operator=(weak_ptr<T> desired) noexcept; constexpr weak_ptr<T> exchange(weak_ptr<T> desired,
|
||||
memory_order order = memory_order::seq_cst) noexcept; constexpr bool compare_exchange_weak(weak_ptr<T>& expected, weak_ptr<T> desired,
|
||||
memory_order success, memory_order failure) noexcept; constexpr bool compare_exchange_strong(weak_ptr<T>& expected, weak_ptr<T> desired,
|
||||
memory_order success, memory_order failure) noexcept; constexpr bool compare_exchange_weak(weak_ptr<T>& expected, weak_ptr<T> desired,
|
||||
memory_order order = memory_order::seq_cst) noexcept; constexpr bool compare_exchange_strong(weak_ptr<T>& expected, weak_ptr<T> desired,
|
||||
memory_order order = memory_order::seq_cst) noexcept; constexpr void wait(weak_ptr<T> old,
|
||||
memory_order order = memory_order::seq_cst) const noexcept; constexpr void notify_one() noexcept; constexpr void notify_all() noexcept; private: weak_ptr<T> p; // *exposition only*};}
|
||||
|
||||
[ð](#lib:atomic%3cweak_ptr%3cT%3e%3e,constructor)
|
||||
|
||||
`constexpr atomic() noexcept;
|
||||
`
|
||||
|
||||
[1](#weak-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6509)
|
||||
|
||||
*Effects*: Value-initializes p[.](#weak-1.sentence-1)
|
||||
|
||||
[ð](#lib:atomic%3cweak_ptr%3cT%3e%3e,constructor_)
|
||||
|
||||
`constexpr atomic(weak_ptr<T> desired) noexcept;
|
||||
`
|
||||
|
||||
[2](#weak-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6520)
|
||||
|
||||
*Effects*: Initializes the object with the value desired[.](#weak-2.sentence-1)
|
||||
|
||||
Initialization is not an atomic operation ([[intro.multithread]](intro.multithread "6.10.2 Multi-threaded executions and data races"))[.](#weak-2.sentence-2)
|
||||
|
||||
[*Note [1](#weak-note-1)*:
|
||||
|
||||
It is possible to have an access to
|
||||
an atomic object A race with its construction,
|
||||
for example,
|
||||
by communicating the address of the just-constructed object A to another thread via memory_order::relaxed operations
|
||||
on a suitable atomic pointer variable, and
|
||||
then immediately accessing A in the receiving thread[.](#weak-2.sentence-3)
|
||||
|
||||
This results in undefined behavior[.](#weak-2.sentence-4)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[ð](#lib:store,atomic%3cweak_ptr%3cT%3e%3e)
|
||||
|
||||
`constexpr void store(weak_ptr<T> desired, memory_order order = memory_order::seq_cst) noexcept;
|
||||
`
|
||||
|
||||
[3](#weak-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6542)
|
||||
|
||||
*Preconditions*: order ismemory_order::relaxed,memory_order::release, ormemory_order::seq_cst[.](#weak-3.sentence-1)
|
||||
|
||||
[4](#weak-4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6549)
|
||||
|
||||
*Effects*: Atomically replaces the value pointed to by this with
|
||||
the value of desired as if by p.swap(desired)[.](#weak-4.sentence-1)
|
||||
|
||||
Memory is affected according to the value of order[.](#weak-4.sentence-2)
|
||||
|
||||
[ð](#lib:operator=,atomic%3cweak_ptr%3cT%3e%3e)
|
||||
|
||||
`constexpr void operator=(weak_ptr<T> desired) noexcept;
|
||||
`
|
||||
|
||||
[5](#weak-5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6562)
|
||||
|
||||
*Effects*: Equivalent to store(desired)[.](#weak-5.sentence-1)
|
||||
|
||||
[ð](#lib:load,atomic%3cweak_ptr%3cT%3e%3e)
|
||||
|
||||
`constexpr weak_ptr<T> load(memory_order order = memory_order::seq_cst) const noexcept;
|
||||
`
|
||||
|
||||
[6](#weak-6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6573)
|
||||
|
||||
*Preconditions*: order ismemory_order::relaxed,memory_order::acquire, ormemory_order::seq_cst[.](#weak-6.sentence-1)
|
||||
|
||||
[7](#weak-7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6580)
|
||||
|
||||
*Effects*: Memory is affected according to the value of order[.](#weak-7.sentence-1)
|
||||
|
||||
[8](#weak-8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6584)
|
||||
|
||||
*Returns*: Atomically returns p[.](#weak-8.sentence-1)
|
||||
|
||||
[ð](#lib:operator_weak_ptr%3cT%3e,atomic%3cweak_ptr%3cT%3e%3e)
|
||||
|
||||
`constexpr operator weak_ptr<T>() const noexcept;
|
||||
`
|
||||
|
||||
[9](#weak-9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6595)
|
||||
|
||||
*Effects*: Equivalent to: return load();
|
||||
|
||||
[ð](#lib:exchange,atomic%3cweak_ptr%3cT%3e%3e)
|
||||
|
||||
`constexpr weak_ptr<T> exchange(weak_ptr<T> desired,
|
||||
memory_order order = memory_order::seq_cst) noexcept;
|
||||
`
|
||||
|
||||
[10](#weak-10)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6607)
|
||||
|
||||
*Effects*: Atomically replaces p with desired as if by p.swap(desired)[.](#weak-10.sentence-1)
|
||||
|
||||
Memory is affected according to the value of order[.](#weak-10.sentence-2)
|
||||
|
||||
This is an atomic read-modify-write operation ([[intro.races]](intro.races "6.10.2.2 Data races"))[.](#weak-10.sentence-3)
|
||||
|
||||
[11](#weak-11)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6614)
|
||||
|
||||
*Returns*: Atomically returns the value of p immediately before the effects[.](#weak-11.sentence-1)
|
||||
|
||||
[ð](#lib:compare_exchange_weak,atomic%3cweak_ptr%3cT%3e%3e)
|
||||
|
||||
`constexpr bool compare_exchange_weak(weak_ptr<T>& expected, weak_ptr<T> desired,
|
||||
memory_order success, memory_order failure) noexcept;
|
||||
constexpr bool compare_exchange_strong(weak_ptr<T>& expected, weak_ptr<T> desired,
|
||||
memory_order success, memory_order failure) noexcept;
|
||||
`
|
||||
|
||||
[12](#weak-12)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6628)
|
||||
|
||||
*Preconditions*: failure ismemory_order::relaxed,memory_order::acquire, ormemory_order::seq_cst[.](#weak-12.sentence-1)
|
||||
|
||||
[13](#weak-13)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6635)
|
||||
|
||||
*Effects*: If p is equivalent to expected,
|
||||
assigns desired to p and
|
||||
has synchronization semantics corresponding to the value of success,
|
||||
otherwise assigns p to expected and
|
||||
has synchronization semantics corresponding to the value of failure[.](#weak-13.sentence-1)
|
||||
|
||||
[14](#weak-14)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6643)
|
||||
|
||||
*Returns*: true if p was equivalent to expected,false otherwise[.](#weak-14.sentence-1)
|
||||
|
||||
[15](#weak-15)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6648)
|
||||
|
||||
*Remarks*: Two weak_ptr objects are equivalent if
|
||||
they store the same pointer value and
|
||||
either share ownership or are both empty[.](#weak-15.sentence-1)
|
||||
|
||||
The weak form may fail spuriously[.](#weak-15.sentence-2)
|
||||
|
||||
See [[atomics.types.operations]](atomics.types.operations "32.5.8.2 Operations on atomic types")[.](#weak-15.sentence-3)
|
||||
|
||||
[16](#weak-16)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6655)
|
||||
|
||||
If the operation returns true,expected is not accessed after the atomic update and
|
||||
the operation is an atomic read-modify-write operation ([[intro.multithread]](intro.multithread "6.10.2 Multi-threaded executions and data races"))
|
||||
on the memory pointed to by this[.](#weak-16.sentence-1)
|
||||
|
||||
Otherwise, the operation is an atomic load operation on that memory, andexpected is updated with the existing value
|
||||
read from the atomic object in the attempted atomic update[.](#weak-16.sentence-2)
|
||||
|
||||
The use_count update corresponding to the write to expected is part of the atomic operation[.](#weak-16.sentence-3)
|
||||
|
||||
The write to expected itself
|
||||
is not required to be part of the atomic operation[.](#weak-16.sentence-4)
|
||||
|
||||
[ð](#lib:compare_exchange_weak,atomic%3cweak_ptr%3cT%3e%3e_)
|
||||
|
||||
`constexpr bool compare_exchange_weak(weak_ptr<T>& expected, weak_ptr<T> desired,
|
||||
memory_order order = memory_order::seq_cst) noexcept;
|
||||
`
|
||||
|
||||
[17](#weak-17)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6676)
|
||||
|
||||
*Effects*: Equivalent to:return compare_exchange_weak(expected, desired, order, fail_order); where fail_order is the same as order except that a value of memory_order::acq_rel shall be replaced by the value memory_order::acquire and
|
||||
a value of memory_order::release shall be replaced by the value memory_order::relaxed[.](#weak-17.sentence-1)
|
||||
|
||||
[ð](#lib:compare_exchange_strong,atomic%3cweak_ptr%3cT%3e%3e)
|
||||
|
||||
`constexpr bool compare_exchange_strong(weak_ptr<T>& expected, weak_ptr<T> desired,
|
||||
memory_order order = memory_order::seq_cst) noexcept;
|
||||
`
|
||||
|
||||
[18](#weak-18)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6696)
|
||||
|
||||
*Effects*: Equivalent to:return compare_exchange_strong(expected, desired, order, fail_order); where fail_order is the same as order except that a value of memory_order::acq_rel shall be replaced by the value memory_order::acquire and
|
||||
a value of memory_order::release shall be replaced by the value memory_order::relaxed[.](#weak-18.sentence-1)
|
||||
|
||||
[ð](#lib:wait,atomic%3cweak_ptr%3cT%3e%3e)
|
||||
|
||||
`constexpr void wait(weak_ptr<T> old, memory_order order = memory_order::seq_cst) const noexcept;
|
||||
`
|
||||
|
||||
[19](#weak-19)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6715)
|
||||
|
||||
*Preconditions*: order ismemory_order::relaxed,memory_order::acquire, ormemory_order::seq_cst[.](#weak-19.sentence-1)
|
||||
|
||||
[20](#weak-20)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6722)
|
||||
|
||||
*Effects*: Repeatedly performs the following steps, in order:
|
||||
|
||||
- [(20.1)](#weak-20.1)
|
||||
|
||||
Evaluates load(order) and compares it to old[.](#weak-20.1.sentence-1)
|
||||
|
||||
- [(20.2)](#weak-20.2)
|
||||
|
||||
If the two are not equivalent, returns[.](#weak-20.2.sentence-1)
|
||||
|
||||
- [(20.3)](#weak-20.3)
|
||||
|
||||
Blocks until it
|
||||
is unblocked by an atomic notifying operation or is unblocked spuriously[.](#weak-20.3.sentence-1)
|
||||
|
||||
[21](#weak-21)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6735)
|
||||
|
||||
*Remarks*: Two weak_ptr objects are equivalent
|
||||
if they store the same pointer and either share ownership or are both empty[.](#weak-21.sentence-1)
|
||||
|
||||
This function is an atomic waiting operation ([[atomics.wait]](atomics.wait "32.5.6 Waiting and notifying"))[.](#weak-21.sentence-2)
|
||||
|
||||
[ð](#lib:notify_one,atomic%3cweak_ptr%3cT%3e%3e)
|
||||
|
||||
`constexpr void notify_one() noexcept;
|
||||
`
|
||||
|
||||
[22](#weak-22)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6749)
|
||||
|
||||
*Effects*: Unblocks the execution of at least one atomic waiting operation
|
||||
that is eligible to be unblocked ([[atomics.wait]](atomics.wait "32.5.6 Waiting and notifying")) by this call,
|
||||
if any such atomic waiting operations exist[.](#weak-22.sentence-1)
|
||||
|
||||
[23](#weak-23)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6755)
|
||||
|
||||
*Remarks*: This function is an atomic notifying operation ([[atomics.wait]](atomics.wait "32.5.6 Waiting and notifying"))[.](#weak-23.sentence-1)
|
||||
|
||||
[ð](#lib:notify_all,atomic%3cweak_ptr%3cT%3e%3e)
|
||||
|
||||
`constexpr void notify_all() noexcept;
|
||||
`
|
||||
|
||||
[24](#weak-24)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6766)
|
||||
|
||||
*Effects*: Unblocks the execution of all atomic waiting operations
|
||||
that are eligible to be unblocked ([[atomics.wait]](atomics.wait "32.5.6 Waiting and notifying")) by this call[.](#weak-24.sentence-1)
|
||||
|
||||
[25](#weak-25)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6771)
|
||||
|
||||
*Remarks*: This function is an atomic notifying operation ([[atomics.wait]](atomics.wait "32.5.6 Waiting and notifying"))[.](#weak-25.sentence-1)
|
||||
68
cppdraft/util/smartptr/atomic/general.md
Normal file
68
cppdraft/util/smartptr/atomic/general.md
Normal file
@@ -0,0 +1,68 @@
|
||||
[util.smartptr.atomic.general]
|
||||
|
||||
# 32 Concurrency support library [[thread]](./#thread)
|
||||
|
||||
## 32.5 Atomic operations [[atomics]](atomics#util.smartptr.atomic.general)
|
||||
|
||||
### 32.5.8 Class template atomic [[atomics.types.generic]](atomics.types.generic#util.smartptr.atomic.general)
|
||||
|
||||
#### 32.5.8.7 Partial specializations for smart pointers [[util.smartptr.atomic]](util.smartptr.atomic#general)
|
||||
|
||||
#### 32.5.8.7.1 General [util.smartptr.atomic.general]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6072)
|
||||
|
||||
The library provides partial specializations of the atomic template
|
||||
for shared-ownership smart pointers ([[util.sharedptr]](util.sharedptr "20.3.2 Shared-ownership pointers"))[.](#1.sentence-1)
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
The partial specializations are declared in header [<memory>](memory.syn#header:%3cmemory%3e "20.2.2 Header <memory> synopsis [memory.syn]")[.](#1.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
|
||||
The behavior of all operations is as specified in [[atomics.types.generic]](atomics.types.generic "32.5.8 Class template atomic"),
|
||||
unless specified otherwise[.](#1.sentence-3)
|
||||
|
||||
The template parameter T of these partial specializations
|
||||
may be an incomplete type[.](#1.sentence-4)
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6083)
|
||||
|
||||
All changes to an atomic smart pointer in [[util.smartptr.atomic]](util.smartptr.atomic "32.5.8.7 Partial specializations for smart pointers"), and
|
||||
all associated use_count increments,
|
||||
are guaranteed to be performed atomically[.](#2.sentence-1)
|
||||
|
||||
Associated use_count decrements
|
||||
are sequenced after the atomic operation,
|
||||
but are not required to be part of it[.](#2.sentence-2)
|
||||
|
||||
Any associated deletion and deallocation
|
||||
are sequenced after the atomic update step and
|
||||
are not part of the atomic operation[.](#2.sentence-3)
|
||||
|
||||
[*Note [2](#note-2)*:
|
||||
|
||||
If the atomic operation uses locks,
|
||||
locks acquired by the implementation
|
||||
will be held when any use_count adjustments are performed, and
|
||||
will not be held when any destruction or deallocation
|
||||
resulting from this is performed[.](#2.sentence-4)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6101)
|
||||
|
||||
[*Example [1](#example-1)*: template<typename T> class atomic_list {struct node { T t;
|
||||
shared_ptr<node> next; };
|
||||
atomic<shared_ptr<node>> head;
|
||||
|
||||
public: shared_ptr<node> find(T t) const {auto p = head.load(); while (p && p->t != t) p = p->next; return p; }void push_front(T t) {auto p = make_shared<node>();
|
||||
p->t = t;
|
||||
p->next = head; while (!head.compare_exchange_weak(p->next, p)) {}}}; â *end example*]
|
||||
318
cppdraft/util/smartptr/atomic/shared.md
Normal file
318
cppdraft/util/smartptr/atomic/shared.md
Normal file
@@ -0,0 +1,318 @@
|
||||
[util.smartptr.atomic.shared]
|
||||
|
||||
# 32 Concurrency support library [[thread]](./#thread)
|
||||
|
||||
## 32.5 Atomic operations [[atomics]](atomics#util.smartptr.atomic.shared)
|
||||
|
||||
### 32.5.8 Class template atomic [[atomics.types.generic]](atomics.types.generic#util.smartptr.atomic.shared)
|
||||
|
||||
#### 32.5.8.7 Partial specializations for smart pointers [[util.smartptr.atomic]](util.smartptr.atomic#shared)
|
||||
|
||||
#### 32.5.8.7.2 Partial specialization for shared_ptr [util.smartptr.atomic.shared]
|
||||
|
||||
[ð](#lib:atomic%3cshared_ptr%3cT%3e%3e)
|
||||
|
||||
namespace std {template<class T> struct atomic<shared_ptr<T>> {using value_type = shared_ptr<T>; static constexpr bool is_always_lock_free = *implementation-defined*; bool is_lock_free() const noexcept; constexpr atomic() noexcept; constexpr atomic(nullptr_t) noexcept : atomic() { }constexpr atomic(shared_ptr<T> desired) noexcept;
|
||||
atomic(const atomic&) = delete; void operator=(const atomic&) = delete; constexpr shared_ptr<T> load(memory_order order = memory_order::seq_cst) const noexcept; constexpr operator shared_ptr<T>() const noexcept; constexpr void store(shared_ptr<T> desired,
|
||||
memory_order order = memory_order::seq_cst) noexcept; constexpr void operator=(shared_ptr<T> desired) noexcept; constexpr void operator=(nullptr_t) noexcept; constexpr shared_ptr<T> exchange(shared_ptr<T> desired,
|
||||
memory_order order = memory_order::seq_cst) noexcept; constexpr bool compare_exchange_weak(shared_ptr<T>& expected, shared_ptr<T> desired,
|
||||
memory_order success, memory_order failure) noexcept; constexpr bool compare_exchange_strong(shared_ptr<T>& expected, shared_ptr<T> desired,
|
||||
memory_order success, memory_order failure) noexcept; constexpr bool compare_exchange_weak(shared_ptr<T>& expected, shared_ptr<T> desired,
|
||||
memory_order order = memory_order::seq_cst) noexcept; constexpr bool compare_exchange_strong(shared_ptr<T>& expected, shared_ptr<T> desired,
|
||||
memory_order order = memory_order::seq_cst) noexcept; constexpr void wait(shared_ptr<T> old,
|
||||
memory_order order = memory_order::seq_cst) const noexcept; constexpr void notify_one() noexcept; constexpr void notify_all() noexcept; private: shared_ptr<T> p; // *exposition only*};}
|
||||
|
||||
[ð](#lib:atomic%3cshared_ptr%3cT%3e%3e,constructor)
|
||||
|
||||
`constexpr atomic() noexcept;
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6181)
|
||||
|
||||
*Effects*: Value-initializes p[.](#1.sentence-1)
|
||||
|
||||
[ð](#lib:atomic%3cshared_ptr%3cT%3e%3e,constructor_)
|
||||
|
||||
`constexpr atomic(shared_ptr<T> desired) noexcept;
|
||||
`
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6192)
|
||||
|
||||
*Effects*: Initializes the object with the value desired[.](#2.sentence-1)
|
||||
|
||||
Initialization is not an atomic operation ([[intro.multithread]](intro.multithread "6.10.2 Multi-threaded executions and data races"))[.](#2.sentence-2)
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
It is possible to have an access to
|
||||
an atomic object A race with its construction,
|
||||
for example,
|
||||
by communicating the address of the just-constructed object A to another thread via memory_order::relaxed operations
|
||||
on a suitable atomic pointer variable, and
|
||||
then immediately accessing A in the receiving thread[.](#2.sentence-3)
|
||||
|
||||
This results in undefined behavior[.](#2.sentence-4)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[ð](#lib:store,atomic%3cshared_ptr%3cT%3e%3e)
|
||||
|
||||
`constexpr void store(shared_ptr<T> desired, memory_order order = memory_order::seq_cst) noexcept;
|
||||
`
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6214)
|
||||
|
||||
*Preconditions*: order ismemory_order::relaxed,memory_order::release, ormemory_order::seq_cst[.](#3.sentence-1)
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6221)
|
||||
|
||||
*Effects*: Atomically replaces the value pointed to by this with
|
||||
the value of desired as if by p.swap(desired)[.](#4.sentence-1)
|
||||
|
||||
Memory is affected according to the value of order[.](#4.sentence-2)
|
||||
|
||||
[ð](#lib:operator=,atomic%3cshared_ptr%3cT%3e%3e)
|
||||
|
||||
`constexpr void operator=(shared_ptr<T> desired) noexcept;
|
||||
`
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6234)
|
||||
|
||||
*Effects*: Equivalent to store(desired)[.](#5.sentence-1)
|
||||
|
||||
[ð](#lib:operator=,atomic%3cshared_ptr%3cT%3e%3e_)
|
||||
|
||||
`constexpr void operator=(nullptr_t) noexcept;
|
||||
`
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6245)
|
||||
|
||||
*Effects*: Equivalent to store(nullptr)[.](#6.sentence-1)
|
||||
|
||||
[ð](#lib:load,atomic%3cshared_ptr%3cT%3e%3e)
|
||||
|
||||
`constexpr shared_ptr<T> load(memory_order order = memory_order::seq_cst) const noexcept;
|
||||
`
|
||||
|
||||
[7](#7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6256)
|
||||
|
||||
*Preconditions*: order ismemory_order::relaxed,memory_order::acquire, ormemory_order::seq_cst[.](#7.sentence-1)
|
||||
|
||||
[8](#8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6263)
|
||||
|
||||
*Effects*: Memory is affected according to the value of order[.](#8.sentence-1)
|
||||
|
||||
[9](#9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6267)
|
||||
|
||||
*Returns*: Atomically returns p[.](#9.sentence-1)
|
||||
|
||||
[ð](#lib:operator_shared_ptr%3cT%3e,atomic%3cshared_ptr%3cT%3e%3e)
|
||||
|
||||
`constexpr operator shared_ptr<T>() const noexcept;
|
||||
`
|
||||
|
||||
[10](#10)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6278)
|
||||
|
||||
*Effects*: Equivalent to: return load();
|
||||
|
||||
[ð](#lib:exchange,atomic%3cshared_ptr%3cT%3e%3e)
|
||||
|
||||
`constexpr shared_ptr<T> exchange(shared_ptr<T> desired,
|
||||
memory_order order = memory_order::seq_cst) noexcept;
|
||||
`
|
||||
|
||||
[11](#11)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6290)
|
||||
|
||||
*Effects*: Atomically replaces p with desired as if by p.swap(desired)[.](#11.sentence-1)
|
||||
|
||||
Memory is affected according to the value of order[.](#11.sentence-2)
|
||||
|
||||
This is an atomic read-modify-write operation ([[intro.races]](intro.races "6.10.2.2 Data races"))[.](#11.sentence-3)
|
||||
|
||||
[12](#12)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6297)
|
||||
|
||||
*Returns*: Atomically returns the value of p immediately before the effects[.](#12.sentence-1)
|
||||
|
||||
[ð](#lib:compare_exchange_weak,atomic%3cshared_ptr%3cT%3e%3e)
|
||||
|
||||
`constexpr bool compare_exchange_weak(shared_ptr<T>& expected, shared_ptr<T> desired,
|
||||
memory_order success, memory_order failure) noexcept;
|
||||
constexpr bool compare_exchange_strong(shared_ptr<T>& expected, shared_ptr<T> desired,
|
||||
memory_order success, memory_order failure) noexcept;
|
||||
`
|
||||
|
||||
[13](#13)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6312)
|
||||
|
||||
*Preconditions*: failure ismemory_order::relaxed,memory_order::acquire, ormemory_order::seq_cst[.](#13.sentence-1)
|
||||
|
||||
[14](#14)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6319)
|
||||
|
||||
*Effects*: If p is equivalent to expected,
|
||||
assigns desired to p and
|
||||
has synchronization semantics corresponding to the value of success,
|
||||
otherwise assigns p to expected and
|
||||
has synchronization semantics corresponding to the value of failure[.](#14.sentence-1)
|
||||
|
||||
[15](#15)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6327)
|
||||
|
||||
*Returns*: true if p was equivalent to expected,false otherwise[.](#15.sentence-1)
|
||||
|
||||
[16](#16)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6332)
|
||||
|
||||
*Remarks*: Two shared_ptr objects are equivalent if
|
||||
they store the same pointer value and
|
||||
either share ownership or are both empty[.](#16.sentence-1)
|
||||
|
||||
The weak form may fail spuriously[.](#16.sentence-2)
|
||||
|
||||
See [[atomics.types.operations]](atomics.types.operations "32.5.8.2 Operations on atomic types")[.](#16.sentence-3)
|
||||
|
||||
[17](#17)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6339)
|
||||
|
||||
If the operation returns true,expected is not accessed after the atomic update and
|
||||
the operation is an atomic read-modify-write operation ([[intro.multithread]](intro.multithread "6.10.2 Multi-threaded executions and data races"))
|
||||
on the memory pointed to by this[.](#17.sentence-1)
|
||||
|
||||
Otherwise, the operation is an atomic load operation on that memory, andexpected is updated with the existing value
|
||||
read from the atomic object in the attempted atomic update[.](#17.sentence-2)
|
||||
|
||||
The use_count update corresponding to the write to expected is part of the atomic operation[.](#17.sentence-3)
|
||||
|
||||
The write to expected itself
|
||||
is not required to be part of the atomic operation[.](#17.sentence-4)
|
||||
|
||||
[ð](#lib:compare_exchange_weak,atomic%3cshared_ptr%3cT%3e%3e_)
|
||||
|
||||
`constexpr bool compare_exchange_weak(shared_ptr<T>& expected, shared_ptr<T> desired,
|
||||
memory_order order = memory_order::seq_cst) noexcept;
|
||||
`
|
||||
|
||||
[18](#18)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6360)
|
||||
|
||||
*Effects*: Equivalent to:return compare_exchange_weak(expected, desired, order, fail_order); where fail_order is the same as order except that a value of memory_order::acq_rel shall be replaced by the value memory_order::acquire and
|
||||
a value of memory_order::release shall be replaced by the value memory_order::relaxed[.](#18.sentence-1)
|
||||
|
||||
[ð](#lib:compare_exchange_strong,atomic%3cshared_ptr%3cT%3e%3e_)
|
||||
|
||||
`constexpr bool compare_exchange_strong(shared_ptr<T>& expected, shared_ptr<T> desired,
|
||||
memory_order order = memory_order::seq_cst) noexcept;
|
||||
`
|
||||
|
||||
[19](#19)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6380)
|
||||
|
||||
*Effects*: Equivalent to:return compare_exchange_strong(expected, desired, order, fail_order); where fail_order is the same as order except that a value of memory_order::acq_rel shall be replaced by the value memory_order::acquire and
|
||||
a value of memory_order::release shall be replaced by the value memory_order::relaxed[.](#19.sentence-1)
|
||||
|
||||
[ð](#lib:wait,atomic%3cshared_ptr%3cT%3e%3e)
|
||||
|
||||
`constexpr void wait(shared_ptr<T> old, memory_order order = memory_order::seq_cst) const noexcept;
|
||||
`
|
||||
|
||||
[20](#20)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6399)
|
||||
|
||||
*Preconditions*: order ismemory_order::relaxed,memory_order::acquire, ormemory_order::seq_cst[.](#20.sentence-1)
|
||||
|
||||
[21](#21)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6406)
|
||||
|
||||
*Effects*: Repeatedly performs the following steps, in order:
|
||||
|
||||
- [(21.1)](#21.1)
|
||||
|
||||
Evaluates load(order) and compares it to old[.](#21.1.sentence-1)
|
||||
|
||||
- [(21.2)](#21.2)
|
||||
|
||||
If the two are not equivalent, returns[.](#21.2.sentence-1)
|
||||
|
||||
- [(21.3)](#21.3)
|
||||
|
||||
Blocks until it
|
||||
is unblocked by an atomic notifying operation or is unblocked spuriously[.](#21.3.sentence-1)
|
||||
|
||||
[22](#22)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6419)
|
||||
|
||||
*Remarks*: Two shared_ptr objects are equivalent
|
||||
if they store the same pointer and either share ownership or are both empty[.](#22.sentence-1)
|
||||
|
||||
This function is an atomic waiting operation ([[atomics.wait]](atomics.wait "32.5.6 Waiting and notifying"))[.](#22.sentence-2)
|
||||
|
||||
[ð](#lib:notify_one,atomic%3cshared_ptr%3cT%3e%3e)
|
||||
|
||||
`constexpr void notify_one() noexcept;
|
||||
`
|
||||
|
||||
[23](#23)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6432)
|
||||
|
||||
*Effects*: Unblocks the execution of at least one atomic waiting operation
|
||||
that is eligible to be unblocked ([[atomics.wait]](atomics.wait "32.5.6 Waiting and notifying")) by this call,
|
||||
if any such atomic waiting operations exist[.](#23.sentence-1)
|
||||
|
||||
[24](#24)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6438)
|
||||
|
||||
*Remarks*: This function is an atomic notifying operation ([[atomics.wait]](atomics.wait "32.5.6 Waiting and notifying"))[.](#24.sentence-1)
|
||||
|
||||
[ð](#lib:notify_all,atomic%3cshared_ptr%3cT%3e%3e)
|
||||
|
||||
`constexpr void notify_all() noexcept;
|
||||
`
|
||||
|
||||
[25](#25)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6449)
|
||||
|
||||
*Effects*: Unblocks the execution of all atomic waiting operations
|
||||
that are eligible to be unblocked ([[atomics.wait]](atomics.wait "32.5.6 Waiting and notifying")) by this call[.](#25.sentence-1)
|
||||
|
||||
[26](#26)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6454)
|
||||
|
||||
*Remarks*: This function is an atomic notifying operation ([[atomics.wait]](atomics.wait "32.5.6 Waiting and notifying"))[.](#26.sentence-1)
|
||||
307
cppdraft/util/smartptr/atomic/weak.md
Normal file
307
cppdraft/util/smartptr/atomic/weak.md
Normal file
@@ -0,0 +1,307 @@
|
||||
[util.smartptr.atomic.weak]
|
||||
|
||||
# 32 Concurrency support library [[thread]](./#thread)
|
||||
|
||||
## 32.5 Atomic operations [[atomics]](atomics#util.smartptr.atomic.weak)
|
||||
|
||||
### 32.5.8 Class template atomic [[atomics.types.generic]](atomics.types.generic#util.smartptr.atomic.weak)
|
||||
|
||||
#### 32.5.8.7 Partial specializations for smart pointers [[util.smartptr.atomic]](util.smartptr.atomic#weak)
|
||||
|
||||
#### 32.5.8.7.3 Partial specialization for weak_ptr [util.smartptr.atomic.weak]
|
||||
|
||||
[ð](#lib:atomic%3cweak_ptr%3cT%3e%3e)
|
||||
|
||||
namespace std {template<class T> struct atomic<weak_ptr<T>> {using value_type = weak_ptr<T>; static constexpr bool is_always_lock_free = *implementation-defined*; bool is_lock_free() const noexcept; constexpr atomic() noexcept; constexpr atomic(weak_ptr<T> desired) noexcept;
|
||||
atomic(const atomic&) = delete; void operator=(const atomic&) = delete; constexpr weak_ptr<T> load(memory_order order = memory_order::seq_cst) const noexcept; constexpr operator weak_ptr<T>() const noexcept; constexpr void store(weak_ptr<T> desired,
|
||||
memory_order order = memory_order::seq_cst) noexcept; constexpr void operator=(weak_ptr<T> desired) noexcept; constexpr weak_ptr<T> exchange(weak_ptr<T> desired,
|
||||
memory_order order = memory_order::seq_cst) noexcept; constexpr bool compare_exchange_weak(weak_ptr<T>& expected, weak_ptr<T> desired,
|
||||
memory_order success, memory_order failure) noexcept; constexpr bool compare_exchange_strong(weak_ptr<T>& expected, weak_ptr<T> desired,
|
||||
memory_order success, memory_order failure) noexcept; constexpr bool compare_exchange_weak(weak_ptr<T>& expected, weak_ptr<T> desired,
|
||||
memory_order order = memory_order::seq_cst) noexcept; constexpr bool compare_exchange_strong(weak_ptr<T>& expected, weak_ptr<T> desired,
|
||||
memory_order order = memory_order::seq_cst) noexcept; constexpr void wait(weak_ptr<T> old,
|
||||
memory_order order = memory_order::seq_cst) const noexcept; constexpr void notify_one() noexcept; constexpr void notify_all() noexcept; private: weak_ptr<T> p; // *exposition only*};}
|
||||
|
||||
[ð](#lib:atomic%3cweak_ptr%3cT%3e%3e,constructor)
|
||||
|
||||
`constexpr atomic() noexcept;
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6509)
|
||||
|
||||
*Effects*: Value-initializes p[.](#1.sentence-1)
|
||||
|
||||
[ð](#lib:atomic%3cweak_ptr%3cT%3e%3e,constructor_)
|
||||
|
||||
`constexpr atomic(weak_ptr<T> desired) noexcept;
|
||||
`
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6520)
|
||||
|
||||
*Effects*: Initializes the object with the value desired[.](#2.sentence-1)
|
||||
|
||||
Initialization is not an atomic operation ([[intro.multithread]](intro.multithread "6.10.2 Multi-threaded executions and data races"))[.](#2.sentence-2)
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
It is possible to have an access to
|
||||
an atomic object A race with its construction,
|
||||
for example,
|
||||
by communicating the address of the just-constructed object A to another thread via memory_order::relaxed operations
|
||||
on a suitable atomic pointer variable, and
|
||||
then immediately accessing A in the receiving thread[.](#2.sentence-3)
|
||||
|
||||
This results in undefined behavior[.](#2.sentence-4)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[ð](#lib:store,atomic%3cweak_ptr%3cT%3e%3e)
|
||||
|
||||
`constexpr void store(weak_ptr<T> desired, memory_order order = memory_order::seq_cst) noexcept;
|
||||
`
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6542)
|
||||
|
||||
*Preconditions*: order ismemory_order::relaxed,memory_order::release, ormemory_order::seq_cst[.](#3.sentence-1)
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6549)
|
||||
|
||||
*Effects*: Atomically replaces the value pointed to by this with
|
||||
the value of desired as if by p.swap(desired)[.](#4.sentence-1)
|
||||
|
||||
Memory is affected according to the value of order[.](#4.sentence-2)
|
||||
|
||||
[ð](#lib:operator=,atomic%3cweak_ptr%3cT%3e%3e)
|
||||
|
||||
`constexpr void operator=(weak_ptr<T> desired) noexcept;
|
||||
`
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6562)
|
||||
|
||||
*Effects*: Equivalent to store(desired)[.](#5.sentence-1)
|
||||
|
||||
[ð](#lib:load,atomic%3cweak_ptr%3cT%3e%3e)
|
||||
|
||||
`constexpr weak_ptr<T> load(memory_order order = memory_order::seq_cst) const noexcept;
|
||||
`
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6573)
|
||||
|
||||
*Preconditions*: order ismemory_order::relaxed,memory_order::acquire, ormemory_order::seq_cst[.](#6.sentence-1)
|
||||
|
||||
[7](#7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6580)
|
||||
|
||||
*Effects*: Memory is affected according to the value of order[.](#7.sentence-1)
|
||||
|
||||
[8](#8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6584)
|
||||
|
||||
*Returns*: Atomically returns p[.](#8.sentence-1)
|
||||
|
||||
[ð](#lib:operator_weak_ptr%3cT%3e,atomic%3cweak_ptr%3cT%3e%3e)
|
||||
|
||||
`constexpr operator weak_ptr<T>() const noexcept;
|
||||
`
|
||||
|
||||
[9](#9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6595)
|
||||
|
||||
*Effects*: Equivalent to: return load();
|
||||
|
||||
[ð](#lib:exchange,atomic%3cweak_ptr%3cT%3e%3e)
|
||||
|
||||
`constexpr weak_ptr<T> exchange(weak_ptr<T> desired,
|
||||
memory_order order = memory_order::seq_cst) noexcept;
|
||||
`
|
||||
|
||||
[10](#10)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6607)
|
||||
|
||||
*Effects*: Atomically replaces p with desired as if by p.swap(desired)[.](#10.sentence-1)
|
||||
|
||||
Memory is affected according to the value of order[.](#10.sentence-2)
|
||||
|
||||
This is an atomic read-modify-write operation ([[intro.races]](intro.races "6.10.2.2 Data races"))[.](#10.sentence-3)
|
||||
|
||||
[11](#11)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6614)
|
||||
|
||||
*Returns*: Atomically returns the value of p immediately before the effects[.](#11.sentence-1)
|
||||
|
||||
[ð](#lib:compare_exchange_weak,atomic%3cweak_ptr%3cT%3e%3e)
|
||||
|
||||
`constexpr bool compare_exchange_weak(weak_ptr<T>& expected, weak_ptr<T> desired,
|
||||
memory_order success, memory_order failure) noexcept;
|
||||
constexpr bool compare_exchange_strong(weak_ptr<T>& expected, weak_ptr<T> desired,
|
||||
memory_order success, memory_order failure) noexcept;
|
||||
`
|
||||
|
||||
[12](#12)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6628)
|
||||
|
||||
*Preconditions*: failure ismemory_order::relaxed,memory_order::acquire, ormemory_order::seq_cst[.](#12.sentence-1)
|
||||
|
||||
[13](#13)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6635)
|
||||
|
||||
*Effects*: If p is equivalent to expected,
|
||||
assigns desired to p and
|
||||
has synchronization semantics corresponding to the value of success,
|
||||
otherwise assigns p to expected and
|
||||
has synchronization semantics corresponding to the value of failure[.](#13.sentence-1)
|
||||
|
||||
[14](#14)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6643)
|
||||
|
||||
*Returns*: true if p was equivalent to expected,false otherwise[.](#14.sentence-1)
|
||||
|
||||
[15](#15)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6648)
|
||||
|
||||
*Remarks*: Two weak_ptr objects are equivalent if
|
||||
they store the same pointer value and
|
||||
either share ownership or are both empty[.](#15.sentence-1)
|
||||
|
||||
The weak form may fail spuriously[.](#15.sentence-2)
|
||||
|
||||
See [[atomics.types.operations]](atomics.types.operations "32.5.8.2 Operations on atomic types")[.](#15.sentence-3)
|
||||
|
||||
[16](#16)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6655)
|
||||
|
||||
If the operation returns true,expected is not accessed after the atomic update and
|
||||
the operation is an atomic read-modify-write operation ([[intro.multithread]](intro.multithread "6.10.2 Multi-threaded executions and data races"))
|
||||
on the memory pointed to by this[.](#16.sentence-1)
|
||||
|
||||
Otherwise, the operation is an atomic load operation on that memory, andexpected is updated with the existing value
|
||||
read from the atomic object in the attempted atomic update[.](#16.sentence-2)
|
||||
|
||||
The use_count update corresponding to the write to expected is part of the atomic operation[.](#16.sentence-3)
|
||||
|
||||
The write to expected itself
|
||||
is not required to be part of the atomic operation[.](#16.sentence-4)
|
||||
|
||||
[ð](#lib:compare_exchange_weak,atomic%3cweak_ptr%3cT%3e%3e_)
|
||||
|
||||
`constexpr bool compare_exchange_weak(weak_ptr<T>& expected, weak_ptr<T> desired,
|
||||
memory_order order = memory_order::seq_cst) noexcept;
|
||||
`
|
||||
|
||||
[17](#17)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6676)
|
||||
|
||||
*Effects*: Equivalent to:return compare_exchange_weak(expected, desired, order, fail_order); where fail_order is the same as order except that a value of memory_order::acq_rel shall be replaced by the value memory_order::acquire and
|
||||
a value of memory_order::release shall be replaced by the value memory_order::relaxed[.](#17.sentence-1)
|
||||
|
||||
[ð](#lib:compare_exchange_strong,atomic%3cweak_ptr%3cT%3e%3e)
|
||||
|
||||
`constexpr bool compare_exchange_strong(weak_ptr<T>& expected, weak_ptr<T> desired,
|
||||
memory_order order = memory_order::seq_cst) noexcept;
|
||||
`
|
||||
|
||||
[18](#18)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6696)
|
||||
|
||||
*Effects*: Equivalent to:return compare_exchange_strong(expected, desired, order, fail_order); where fail_order is the same as order except that a value of memory_order::acq_rel shall be replaced by the value memory_order::acquire and
|
||||
a value of memory_order::release shall be replaced by the value memory_order::relaxed[.](#18.sentence-1)
|
||||
|
||||
[ð](#lib:wait,atomic%3cweak_ptr%3cT%3e%3e)
|
||||
|
||||
`constexpr void wait(weak_ptr<T> old, memory_order order = memory_order::seq_cst) const noexcept;
|
||||
`
|
||||
|
||||
[19](#19)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6715)
|
||||
|
||||
*Preconditions*: order ismemory_order::relaxed,memory_order::acquire, ormemory_order::seq_cst[.](#19.sentence-1)
|
||||
|
||||
[20](#20)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6722)
|
||||
|
||||
*Effects*: Repeatedly performs the following steps, in order:
|
||||
|
||||
- [(20.1)](#20.1)
|
||||
|
||||
Evaluates load(order) and compares it to old[.](#20.1.sentence-1)
|
||||
|
||||
- [(20.2)](#20.2)
|
||||
|
||||
If the two are not equivalent, returns[.](#20.2.sentence-1)
|
||||
|
||||
- [(20.3)](#20.3)
|
||||
|
||||
Blocks until it
|
||||
is unblocked by an atomic notifying operation or is unblocked spuriously[.](#20.3.sentence-1)
|
||||
|
||||
[21](#21)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6735)
|
||||
|
||||
*Remarks*: Two weak_ptr objects are equivalent
|
||||
if they store the same pointer and either share ownership or are both empty[.](#21.sentence-1)
|
||||
|
||||
This function is an atomic waiting operation ([[atomics.wait]](atomics.wait "32.5.6 Waiting and notifying"))[.](#21.sentence-2)
|
||||
|
||||
[ð](#lib:notify_one,atomic%3cweak_ptr%3cT%3e%3e)
|
||||
|
||||
`constexpr void notify_one() noexcept;
|
||||
`
|
||||
|
||||
[22](#22)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6749)
|
||||
|
||||
*Effects*: Unblocks the execution of at least one atomic waiting operation
|
||||
that is eligible to be unblocked ([[atomics.wait]](atomics.wait "32.5.6 Waiting and notifying")) by this call,
|
||||
if any such atomic waiting operations exist[.](#22.sentence-1)
|
||||
|
||||
[23](#23)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6755)
|
||||
|
||||
*Remarks*: This function is an atomic notifying operation ([[atomics.wait]](atomics.wait "32.5.6 Waiting and notifying"))[.](#23.sentence-1)
|
||||
|
||||
[ð](#lib:notify_all,atomic%3cweak_ptr%3cT%3e%3e)
|
||||
|
||||
`constexpr void notify_all() noexcept;
|
||||
`
|
||||
|
||||
[24](#24)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6766)
|
||||
|
||||
*Effects*: Unblocks the execution of all atomic waiting operations
|
||||
that are eligible to be unblocked ([[atomics.wait]](atomics.wait "32.5.6 Waiting and notifying")) by this call[.](#24.sentence-1)
|
||||
|
||||
[25](#25)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6771)
|
||||
|
||||
*Remarks*: This function is an atomic notifying operation ([[atomics.wait]](atomics.wait "32.5.6 Waiting and notifying"))[.](#25.sentence-1)
|
||||
92
cppdraft/util/smartptr/enab.md
Normal file
92
cppdraft/util/smartptr/enab.md
Normal file
@@ -0,0 +1,92 @@
|
||||
[util.smartptr.enab]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.3 Smart pointers [[smartptr]](smartptr#util.smartptr.enab)
|
||||
|
||||
### 20.3.2 Shared-ownership pointers [[util.sharedptr]](util.sharedptr#util.smartptr.enab)
|
||||
|
||||
#### 20.3.2.7 Class template enable_shared_from_this [util.smartptr.enab]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5289)
|
||||
|
||||
A class T can inherit from enable_shared_from_this<T> to inherit the shared_from_this member functions that obtain
|
||||
a shared_ptr instance pointing to *this[.](#1.sentence-1)
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5295)
|
||||
|
||||
[*Example [1](#example-1)*: struct X: public enable_shared_from_this<X> { };
|
||||
|
||||
int main() { shared_ptr<X> p(new X);
|
||||
shared_ptr<X> q = p->shared_from_this();
|
||||
assert(p == q);
|
||||
assert(p.owner_equal(q)); // p and q share ownership} â *end example*]
|
||||
|
||||
namespace std {template<class T> class enable_shared_from_this {protected:constexpr enable_shared_from_this() noexcept; constexpr enable_shared_from_this(const enable_shared_from_this&) noexcept; constexpr enable_shared_from_this& operator=(const enable_shared_from_this&) noexcept; constexpr ~enable_shared_from_this(); public:constexpr shared_ptr<T> shared_from_this(); constexpr shared_ptr<T const> shared_from_this() const; constexpr weak_ptr<T> weak_from_this() noexcept; constexpr weak_ptr<T const> weak_from_this() const noexcept; private:mutable weak_ptr<T> *weak-this*; // *exposition only*};}
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5330)
|
||||
|
||||
The template parameter T of enable_shared_from_this may be an incomplete type[.](#3.sentence-1)
|
||||
|
||||
[ð](#lib:enable_shared_from_this,constructor)
|
||||
|
||||
`constexpr enable_shared_from_this() noexcept;
|
||||
constexpr enable_shared_from_this(const enable_shared_from_this<T>&) noexcept;
|
||||
`
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5341)
|
||||
|
||||
*Effects*: Value-initializes *weak-this*[.](#4.sentence-1)
|
||||
|
||||
[ð](#lib:operator=,enable_shared_from_this)
|
||||
|
||||
`constexpr enable_shared_from_this<T>& operator=(const enable_shared_from_this<T>&) noexcept;
|
||||
`
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5352)
|
||||
|
||||
*Returns*: *this[.](#5.sentence-1)
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5356)
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
*weak-this* is not changed[.](#6.sentence-1)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[ð](#lib:shared_ptr)
|
||||
|
||||
`constexpr shared_ptr<T> shared_from_this();
|
||||
constexpr shared_ptr<T const> shared_from_this() const;
|
||||
`
|
||||
|
||||
[7](#7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5370)
|
||||
|
||||
*Returns*: shared_ptr<T>(*weak-this*)[.](#7.sentence-1)
|
||||
|
||||
[ð](#lib:weak_ptr)
|
||||
|
||||
`constexpr weak_ptr<T> weak_from_this() noexcept;
|
||||
constexpr weak_ptr<T const> weak_from_this() const noexcept;
|
||||
`
|
||||
|
||||
[8](#8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5383)
|
||||
|
||||
*Returns*: *weak-this*[.](#8.sentence-1)
|
||||
37
cppdraft/util/smartptr/getdeleter.md
Normal file
37
cppdraft/util/smartptr/getdeleter.md
Normal file
@@ -0,0 +1,37 @@
|
||||
[util.smartptr.getdeleter]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.3 Smart pointers [[smartptr]](smartptr#util.smartptr.getdeleter)
|
||||
|
||||
### 20.3.2 Shared-ownership pointers [[util.sharedptr]](util.sharedptr#util.smartptr.getdeleter)
|
||||
|
||||
#### 20.3.2.2 Class template shared_ptr [[util.smartptr.shared]](util.smartptr.shared#util.smartptr.getdeleter)
|
||||
|
||||
#### 20.3.2.2.11 get_deleter [util.smartptr.getdeleter]
|
||||
|
||||
[ð](#lib:get_deleter,shared_ptr)
|
||||
|
||||
`template<class D, class T>
|
||||
constexpr D* get_deleter(const shared_ptr<T>& p) noexcept;
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4802)
|
||||
|
||||
*Returns*: If p owns a deleter d of type cv-unqualifiedD, returns addressof(d); otherwise returns nullptr[.](#1.sentence-1)
|
||||
|
||||
The returned
|
||||
pointer remains valid as long as there exists a shared_ptr instance
|
||||
that owns d[.](#1.sentence-2)
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
It is unspecified whether the pointer
|
||||
remains valid longer than that[.](#1.sentence-3)
|
||||
|
||||
This can happen if the implementation doesn't destroy
|
||||
the deleter until all weak_ptr instances that share ownership withp have been destroyed[.](#1.sentence-4)
|
||||
|
||||
â *end note*]
|
||||
37
cppdraft/util/smartptr/hash.md
Normal file
37
cppdraft/util/smartptr/hash.md
Normal file
@@ -0,0 +1,37 @@
|
||||
[util.smartptr.hash]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.3 Smart pointers [[smartptr]](smartptr#util.smartptr.hash)
|
||||
|
||||
### 20.3.3 Smart pointer hash support [util.smartptr.hash]
|
||||
|
||||
[ð](#lib:hash,unique_ptr)
|
||||
|
||||
`template<class T, class D> struct hash<unique_ptr<T, D>>;
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5396)
|
||||
|
||||
Letting UP be unique_ptr<T, D>,
|
||||
the specialization hash<UP> is enabled ([[unord.hash]](unord.hash "22.10.19 Class template hash"))
|
||||
if and only if hash<typename UP::pointer> is enabled[.](#1.sentence-1)
|
||||
|
||||
When enabled, for an object p of type UP,hash<UP>()(p) evaluates to
|
||||
the same value as hash<typename UP::pointer>()(p.get())[.](#1.sentence-2)
|
||||
|
||||
The member functions are not guaranteed to be noexcept[.](#1.sentence-3)
|
||||
|
||||
[ð](#lib:hash,shared_ptr)
|
||||
|
||||
`template<class T> struct hash<shared_ptr<T>>;
|
||||
`
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5412)
|
||||
|
||||
For an object p of type shared_ptr<T>,hash<shared_ptr<T>>()(p) evaluates to
|
||||
the same value as hash<typename shared_ptr<T>::element_type*>()(p.get())[.](#2.sentence-1)
|
||||
48
cppdraft/util/smartptr/owner/equal.md
Normal file
48
cppdraft/util/smartptr/owner/equal.md
Normal file
@@ -0,0 +1,48 @@
|
||||
[util.smartptr.owner.equal]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.3 Smart pointers [[smartptr]](smartptr#util.smartptr.owner.equal)
|
||||
|
||||
### 20.3.2 Shared-ownership pointers [[util.sharedptr]](util.sharedptr#util.smartptr.owner.equal)
|
||||
|
||||
#### 20.3.2.6 Struct owner_equal [util.smartptr.owner.equal]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5241)
|
||||
|
||||
The class owner_equal provides
|
||||
ownership-based mixed equality comparisons of shared and weak pointers[.](#1.sentence-1)
|
||||
|
||||
[ð](#lib:owner_equal)
|
||||
|
||||
namespace std {struct owner_equal {template<class T, class U>constexpr bool operator()(const shared_ptr<T>&, const shared_ptr<U>&) const noexcept; template<class T, class U>constexpr bool operator()(const shared_ptr<T>&, const weak_ptr<U>&) const noexcept; template<class T, class U>constexpr bool operator()(const weak_ptr<T>&, const shared_ptr<U>&) const noexcept; template<class T, class U>constexpr bool operator()(const weak_ptr<T>&, const weak_ptr<U>&) const noexcept; using is_transparent = *unspecified*; };}
|
||||
|
||||
[ð](#lib:operator(),owner_equal)
|
||||
|
||||
`template<class T, class U>
|
||||
constexpr bool operator()(const shared_ptr<T>& x, const shared_ptr<U>& y) const noexcept;
|
||||
template<class T, class U>
|
||||
constexpr bool operator()(const shared_ptr<T>& x, const weak_ptr<U>& y) const noexcept;
|
||||
template<class T, class U>
|
||||
constexpr bool operator()(const weak_ptr<T>& x, const shared_ptr<U>& y) const noexcept;
|
||||
template<class T, class U>
|
||||
constexpr bool operator()(const weak_ptr<T>& x, const weak_ptr<U>& y) const noexcept;
|
||||
`
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5276)
|
||||
|
||||
*Returns*: x.owner_equal(y)[.](#2.sentence-1)
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5280)
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
x.owner_equal(y) is true if and only if x and y share ownership or are both empty[.](#3.sentence-1)
|
||||
|
||||
â *end note*]
|
||||
43
cppdraft/util/smartptr/owner/hash.md
Normal file
43
cppdraft/util/smartptr/owner/hash.md
Normal file
@@ -0,0 +1,43 @@
|
||||
[util.smartptr.owner.hash]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.3 Smart pointers [[smartptr]](smartptr#util.smartptr.owner.hash)
|
||||
|
||||
### 20.3.2 Shared-ownership pointers [[util.sharedptr]](util.sharedptr#util.smartptr.owner.hash)
|
||||
|
||||
#### 20.3.2.5 Struct owner_hash [util.smartptr.owner.hash]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5201)
|
||||
|
||||
The class owner_hash provides ownership-based hashing[.](#1.sentence-1)
|
||||
|
||||
[ð](#lib:owner_hash)
|
||||
|
||||
namespace std {struct owner_hash {template<class T> size_t operator()(const shared_ptr<T>&) const noexcept; template<class T> size_t operator()(const weak_ptr<T>&) const noexcept; using is_transparent = *unspecified*; };}
|
||||
|
||||
[ð](#lib:operator(),owner_hash)
|
||||
|
||||
`template<class T>
|
||||
size_t operator()(const shared_ptr<T>& x) const noexcept;
|
||||
template<class T>
|
||||
size_t operator()(const weak_ptr<T>& x) const noexcept;
|
||||
`
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5228)
|
||||
|
||||
*Returns*: x.owner_hash()[.](#2.sentence-1)
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5232)
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
For any object y where x.owner_equal(y) is true,x.owner_hash() == y.owner_hash() is true[.](#3.sentence-1)
|
||||
|
||||
â *end note*]
|
||||
40
cppdraft/util/smartptr/ownerless.md
Normal file
40
cppdraft/util/smartptr/ownerless.md
Normal file
@@ -0,0 +1,40 @@
|
||||
[util.smartptr.ownerless]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.3 Smart pointers [[smartptr]](smartptr#util.smartptr.ownerless)
|
||||
|
||||
### 20.3.2 Shared-ownership pointers [[util.sharedptr]](util.sharedptr#util.smartptr.ownerless)
|
||||
|
||||
#### 20.3.2.4 Class template owner_less [util.smartptr.ownerless]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5149)
|
||||
|
||||
The class template owner_less allows ownership-based mixed comparisons of shared
|
||||
and weak pointers[.](#1.sentence-1)
|
||||
|
||||
[ð](#lib:owner_less)
|
||||
|
||||
namespace std {template<class T = void> struct owner_less; template<class T> struct owner_less<shared_ptr<T>> {constexpr bool operator()(const shared_ptr<T>&, const shared_ptr<T>&) const noexcept; constexpr bool operator()(const shared_ptr<T>&, const weak_ptr<T>&) const noexcept; constexpr bool operator()(const weak_ptr<T>&, const shared_ptr<T>&) const noexcept; }; template<class T> struct owner_less<weak_ptr<T>> {constexpr bool operator()(const weak_ptr<T>&, const weak_ptr<T>&) const noexcept; constexpr bool operator()(const shared_ptr<T>&, const weak_ptr<T>&) const noexcept; constexpr bool operator()(const weak_ptr<T>&, const shared_ptr<T>&) const noexcept; }; template<> struct owner_less<void> {template<class T, class U>constexpr bool operator()(const shared_ptr<T>&, const shared_ptr<U>&) const noexcept; template<class T, class U>constexpr bool operator()(const shared_ptr<T>&, const weak_ptr<U>&) const noexcept; template<class T, class U>constexpr bool operator()(const weak_ptr<T>&, const shared_ptr<U>&) const noexcept; template<class T, class U>constexpr bool operator()(const weak_ptr<T>&, const weak_ptr<U>&) const noexcept; using is_transparent = *unspecified*; };}
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5186)
|
||||
|
||||
operator()(x, y) returns x.owner_before(y)[.](#2.sentence-1)
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
Note that
|
||||
|
||||
- [(2.1)](#2.1)
|
||||
|
||||
operator() defines a strict weak ordering as defined in [[alg.sorting]](alg.sorting "26.8 Sorting and related operations");
|
||||
|
||||
- [(2.2)](#2.2)
|
||||
|
||||
!operator()(a, b) && !operator()(b, a) is true if and only if a.owner_equal(b) is true[.](#2.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
1411
cppdraft/util/smartptr/shared.md
Normal file
1411
cppdraft/util/smartptr/shared.md
Normal file
File diff suppressed because it is too large
Load Diff
83
cppdraft/util/smartptr/shared/assign.md
Normal file
83
cppdraft/util/smartptr/shared/assign.md
Normal file
@@ -0,0 +1,83 @@
|
||||
[util.smartptr.shared.assign]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.3 Smart pointers [[smartptr]](smartptr#util.smartptr.shared.assign)
|
||||
|
||||
### 20.3.2 Shared-ownership pointers [[util.sharedptr]](util.sharedptr#util.smartptr.shared.assign)
|
||||
|
||||
#### 20.3.2.2 Class template shared_ptr [[util.smartptr.shared]](util.smartptr.shared#assign)
|
||||
|
||||
#### 20.3.2.2.4 Assignment [util.smartptr.shared.assign]
|
||||
|
||||
[ð](#lib:operator=,shared_ptr)
|
||||
|
||||
`constexpr shared_ptr& operator=(const shared_ptr& r) noexcept;
|
||||
template<class Y> constexpr shared_ptr& operator=(const shared_ptr<Y>& r) noexcept;
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3914)
|
||||
|
||||
*Effects*: Equivalent to shared_ptr(r).swap(*this)[.](#1.sentence-1)
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3918)
|
||||
|
||||
*Returns*: *this[.](#2.sentence-1)
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3922)
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
The use count updates caused by the temporary object
|
||||
construction and destruction are not observable side
|
||||
effects, so the implementation can meet the effects (and the
|
||||
implied guarantees) via different means, without creating a
|
||||
temporary[.](#3.sentence-1)
|
||||
|
||||
In particular, in the example:shared_ptr<int> p(new int);
|
||||
shared_ptr<void> q(p);
|
||||
p = p;
|
||||
q = p; both assignments can be no-ops[.](#3.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[ð](#lib:operator=,shared_ptr_)
|
||||
|
||||
`constexpr shared_ptr& operator=(shared_ptr&& r) noexcept;
|
||||
template<class Y> constexpr shared_ptr& operator=(shared_ptr<Y>&& r) noexcept;
|
||||
`
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3946)
|
||||
|
||||
*Effects*: Equivalent to shared_ptr(std::move(r)).swap(*this)[.](#4.sentence-1)
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3950)
|
||||
|
||||
*Returns*: *this[.](#5.sentence-1)
|
||||
|
||||
[ð](#lib:operator=,shared_ptr__)
|
||||
|
||||
`template<class Y, class D> constexpr shared_ptr& operator=(unique_ptr<Y, D>&& r);
|
||||
`
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3961)
|
||||
|
||||
*Effects*: Equivalent to shared_ptr(std::move(r)).swap(*this)[.](#6.sentence-1)
|
||||
|
||||
[7](#7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3965)
|
||||
|
||||
*Returns*: *this[.](#7.sentence-1)
|
||||
152
cppdraft/util/smartptr/shared/cast.md
Normal file
152
cppdraft/util/smartptr/shared/cast.md
Normal file
@@ -0,0 +1,152 @@
|
||||
[util.smartptr.shared.cast]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.3 Smart pointers [[smartptr]](smartptr#util.smartptr.shared.cast)
|
||||
|
||||
### 20.3.2 Shared-ownership pointers [[util.sharedptr]](util.sharedptr#util.smartptr.shared.cast)
|
||||
|
||||
#### 20.3.2.2 Class template shared_ptr [[util.smartptr.shared]](util.smartptr.shared#cast)
|
||||
|
||||
#### 20.3.2.2.10 Casts [util.smartptr.shared.cast]
|
||||
|
||||
[ð](#lib:static_pointer_cast,shared_ptr)
|
||||
|
||||
`template<class T, class U>
|
||||
constexpr shared_ptr<T> static_pointer_cast(const shared_ptr<U>& r) noexcept;
|
||||
template<class T, class U>
|
||||
constexpr shared_ptr<T> static_pointer_cast(shared_ptr<U>&& r) noexcept;
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4677)
|
||||
|
||||
*Mandates*: The expression static_cast<T*>((U*)nullptr) is well-formed[.](#1.sentence-1)
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4681)
|
||||
|
||||
*Returns*: shared_ptr<T>(*R*, static_cast<typename shared_ptr<T>::element_type*>(r.get())) where *R* is r for the first overload, andstd::move(r) for the second[.](#2.sentence-1)
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4689)
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
The seemingly equivalent expressionshared_ptr<T>(static_cast<T*>(r.get())) can result in undefined behavior, attempting to delete the
|
||||
same object twice[.](#3.sentence-1)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[ð](#lib:dynamic_pointer_cast,shared_ptr)
|
||||
|
||||
`template<class T, class U>
|
||||
constexpr shared_ptr<T> dynamic_pointer_cast(const shared_ptr<U>& r) noexcept;
|
||||
template<class T, class U>
|
||||
constexpr shared_ptr<T> dynamic_pointer_cast(shared_ptr<U>&& r) noexcept;
|
||||
`
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4707)
|
||||
|
||||
*Mandates*: The expression dynamic_cast<T*>((U*)nullptr) is well-formed[.](#4.sentence-1)
|
||||
|
||||
The expression dynamic_cast<typename shared_ptr<T>::element_type*>(r.get()) is well-formed[.](#4.sentence-2)
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4712)
|
||||
|
||||
*Preconditions*: The expression dynamic_cast<typename shared_ptr<T>::element_type*>(r.get()) has well-defined behavior[.](#5.sentence-1)
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4716)
|
||||
|
||||
*Returns*:
|
||||
|
||||
- [(6.1)](#6.1)
|
||||
|
||||
When dynamic_cast<typename shared_ptr<T>::element_type*>(r.get()) returns a non-null value p, shared_ptr<T>(*R*, p),
|
||||
where *R* is r for the first overload, and std::move(r) for the second[.](#6.1.sentence-1)
|
||||
|
||||
- [(6.2)](#6.2)
|
||||
|
||||
Otherwise, shared_ptr<T>()[.](#6.2.sentence-1)
|
||||
|
||||
[7](#7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4727)
|
||||
|
||||
[*Note [2](#note-2)*:
|
||||
|
||||
The seemingly equivalent expressionshared_ptr<T>(dynamic_cast<T*>(r.get())) can result in
|
||||
undefined behavior, attempting to delete the same object twice[.](#7.sentence-1)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[ð](#lib:const_pointer_cast,shared_ptr)
|
||||
|
||||
`template<class T, class U>
|
||||
constexpr shared_ptr<T> const_pointer_cast(const shared_ptr<U>& r) noexcept;
|
||||
template<class T, class U>
|
||||
constexpr shared_ptr<T> const_pointer_cast(shared_ptr<U>&& r) noexcept;
|
||||
`
|
||||
|
||||
[8](#8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4744)
|
||||
|
||||
*Mandates*: The expression const_cast<T*>((U*)nullptr) is well-formed[.](#8.sentence-1)
|
||||
|
||||
[9](#9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4748)
|
||||
|
||||
*Returns*: shared_ptr<T>(*R*, const_cast<typename shared_ptr<T>::element_type*>(r.get())) where *R* is r for the first overload, andstd::move(r) for the second[.](#9.sentence-1)
|
||||
|
||||
[10](#10)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4756)
|
||||
|
||||
[*Note [3](#note-3)*:
|
||||
|
||||
The seemingly equivalent expressionshared_ptr<T>(const_cast<T*>(r.get())) can result in
|
||||
undefined behavior, attempting to delete the same object twice[.](#10.sentence-1)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[ð](#lib:reinterpret_pointer_cast,shared_ptr)
|
||||
|
||||
`template<class T, class U>
|
||||
shared_ptr<T> reinterpret_pointer_cast(const shared_ptr<U>& r) noexcept;
|
||||
template<class T, class U>
|
||||
shared_ptr<T> reinterpret_pointer_cast(shared_ptr<U>&& r) noexcept;
|
||||
`
|
||||
|
||||
[11](#11)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4773)
|
||||
|
||||
*Mandates*: The expression reinterpret_cast<T*>((U*)nullptr) is well-formed[.](#11.sentence-1)
|
||||
|
||||
[12](#12)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4777)
|
||||
|
||||
*Returns*: shared_ptr<T>(*R*, reinterpret_cast<typename shared_ptr<T>::element_type*>(r.get())) where *R* is r for the first overload, andstd::move(r) for the second[.](#12.sentence-1)
|
||||
|
||||
[13](#13)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4785)
|
||||
|
||||
[*Note [4](#note-4)*:
|
||||
|
||||
The seemingly equivalent expressionshared_ptr<T>(reinterpret_cast<T*>(r.get())) can result in
|
||||
undefined behavior, attempting to delete the same object twice[.](#13.sentence-1)
|
||||
|
||||
â *end note*]
|
||||
70
cppdraft/util/smartptr/shared/cmp.md
Normal file
70
cppdraft/util/smartptr/shared/cmp.md
Normal file
@@ -0,0 +1,70 @@
|
||||
[util.smartptr.shared.cmp]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.3 Smart pointers [[smartptr]](smartptr#util.smartptr.shared.cmp)
|
||||
|
||||
### 20.3.2 Shared-ownership pointers [[util.sharedptr]](util.sharedptr#util.smartptr.shared.cmp)
|
||||
|
||||
#### 20.3.2.2 Class template shared_ptr [[util.smartptr.shared]](util.smartptr.shared#cmp)
|
||||
|
||||
#### 20.3.2.2.8 Comparison [util.smartptr.shared.cmp]
|
||||
|
||||
[ð](#lib:operator==,shared_ptr)
|
||||
|
||||
`template<class T, class U>
|
||||
constexpr bool operator==(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4603)
|
||||
|
||||
*Returns*: a.get() == b.get()[.](#1.sentence-1)
|
||||
|
||||
[ð](#lib:operator==,shared_ptr_)
|
||||
|
||||
`template<class T>
|
||||
constexpr bool operator==(const shared_ptr<T>& a, nullptr_t) noexcept;
|
||||
`
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4615)
|
||||
|
||||
*Returns*: !a[.](#2.sentence-1)
|
||||
|
||||
[ð](#lib:operator%3c=%3e,shared_ptr)
|
||||
|
||||
`template<class T, class U>
|
||||
constexpr strong_ordering operator<=>(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
|
||||
`
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4627)
|
||||
|
||||
*Returns*: compare_three_way()(a.get(), b.get())[.](#3.sentence-1)
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4631)
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
Defining a comparison operator function allows shared_ptr objects
|
||||
to be used as keys in associative containers[.](#4.sentence-1)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[ð](#lib:operator%3c=%3e,shared_ptr_)
|
||||
|
||||
`template<class T>
|
||||
constexpr strong_ordering operator<=>(const shared_ptr<T>& a, nullptr_t) noexcept;
|
||||
`
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4645)
|
||||
|
||||
*Returns*: compare_three_way()(a.get(), static_cast<typename shared_ptr<T>::element_type*>(nullptr))
|
||||
309
cppdraft/util/smartptr/shared/const.md
Normal file
309
cppdraft/util/smartptr/shared/const.md
Normal file
@@ -0,0 +1,309 @@
|
||||
[util.smartptr.shared.const]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.3 Smart pointers [[smartptr]](smartptr#util.smartptr.shared.const)
|
||||
|
||||
### 20.3.2 Shared-ownership pointers [[util.sharedptr]](util.sharedptr#util.smartptr.shared.const)
|
||||
|
||||
#### 20.3.2.2 Class template shared_ptr [[util.smartptr.shared]](util.smartptr.shared#const)
|
||||
|
||||
#### 20.3.2.2.2 Constructors [util.smartptr.shared.const]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3617)
|
||||
|
||||
In the constructor definitions below,
|
||||
enables shared_from_this with p,
|
||||
for a pointer p of type Y*,
|
||||
means that if Y has an unambiguous and accessible base class
|
||||
that is a specialization of enable_shared_from_this ([[util.smartptr.enab]](util.smartptr.enab "20.3.2.7 Class template enable_shared_from_this")),
|
||||
then remove_cv_t<Y>* shall be implicitly convertible to T* and
|
||||
the constructor evaluates the statement:if (p != nullptr && p->*weak-this*.expired()) p->*weak-this* = shared_ptr<remove_cv_t<Y>>(*this, const_cast<remove_cv_t<Y>*>(p));
|
||||
|
||||
The assignment to the *weak-this* member is not atomic and
|
||||
conflicts with any potentially concurrent access to the same object ([[intro.multithread]](intro.multithread "6.10.2 Multi-threaded executions and data races"))[.](#1.sentence-2)
|
||||
|
||||
[ð](#lib:shared_ptr,constructor)
|
||||
|
||||
`constexpr shared_ptr() noexcept;
|
||||
`
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3638)
|
||||
|
||||
*Postconditions*: use_count() == 0 && get() == nullptr[.](#2.sentence-1)
|
||||
|
||||
[ð](#lib:shared_ptr,constructor_)
|
||||
|
||||
`template<class Y> constexpr explicit shared_ptr(Y* p);
|
||||
`
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3649)
|
||||
|
||||
*Constraints*: When T is an array type,
|
||||
the expression delete[] p is well-formed and eitherT is U[N] and Y(*)[N] is convertible to T*, orT is U[] and Y(*)[] is convertible to T*[.](#3.sentence-1)
|
||||
|
||||
When T is not an array type,
|
||||
the expression delete p is well-formed andY* is convertible to T*[.](#3.sentence-2)
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3659)
|
||||
|
||||
*Mandates*: Y is a complete type[.](#4.sentence-1)
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3663)
|
||||
|
||||
*Preconditions*: The expressiondelete[] p, when T is an array type, ordelete p, when T is not an array type,
|
||||
has well-defined behavior, and
|
||||
does not throw exceptions[.](#5.sentence-1)
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3671)
|
||||
|
||||
*Effects*: When T is not an array type,
|
||||
constructs a shared_ptr object
|
||||
that owns the pointer p[.](#6.sentence-1)
|
||||
|
||||
Otherwise, constructs a shared_ptr that owns p and a deleter of an
|
||||
unspecified type that calls delete[] p[.](#6.sentence-2)
|
||||
|
||||
When T is not an array type,
|
||||
enables shared_from_this with p[.](#6.sentence-3)
|
||||
|
||||
If an exception is thrown, delete p is called
|
||||
when T is not an array type, delete[] p otherwise[.](#6.sentence-4)
|
||||
|
||||
[7](#7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3684)
|
||||
|
||||
*Postconditions*: use_count() == 1 && get() == p[.](#7.sentence-1)
|
||||
|
||||
[8](#8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3688)
|
||||
|
||||
*Throws*: bad_alloc, or an implementation-defined exception when a resource other than memory cannot be obtained[.](#8.sentence-1)
|
||||
|
||||
[ð](#lib:shared_ptr,constructor__)
|
||||
|
||||
`template<class Y, class D> constexpr shared_ptr(Y* p, D d);
|
||||
template<class Y, class D, class A> constexpr shared_ptr(Y* p, D d, A a);
|
||||
template<class D> constexpr shared_ptr(nullptr_t p, D d);
|
||||
template<class D, class A> constexpr shared_ptr(nullptr_t p, D d, A a);
|
||||
`
|
||||
|
||||
[9](#9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3703)
|
||||
|
||||
*Constraints*: is_move_constructible_v<D> is true, andd(p) is a well-formed expression[.](#9.sentence-1)
|
||||
|
||||
For the first two overloads:
|
||||
|
||||
- [(9.1)](#9.1)
|
||||
|
||||
If T is an array type, then eitherT is U[N] and Y(*)[N] is convertible to T*, orT is U[] and Y(*)[] is convertible to T*[.](#9.1.sentence-1)
|
||||
|
||||
- [(9.2)](#9.2)
|
||||
|
||||
If T is not an array type, then Y* is convertible to T*[.](#9.2.sentence-1)
|
||||
|
||||
[10](#10)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3718)
|
||||
|
||||
*Preconditions*: Construction of d and a deleter of type D initialized with std::move(d) do not throw exceptions[.](#10.sentence-1)
|
||||
|
||||
The expression d(p) has well-defined behavior and does not throw exceptions[.](#10.sentence-2)
|
||||
|
||||
A meets
|
||||
the [*Cpp17Allocator*](allocator.requirements.general#:Cpp17Allocator "16.4.4.6.1 General [allocator.requirements.general]") requirements ([[allocator.requirements.general]](allocator.requirements.general "16.4.4.6.1 General"))[.](#10.sentence-3)
|
||||
|
||||
[11](#11)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3727)
|
||||
|
||||
*Effects*: Constructs a shared_ptr object that owns the
|
||||
object p and the deleter d[.](#11.sentence-1)
|
||||
|
||||
When T is not an array type,
|
||||
the first and second constructors enable shared_from_this with p[.](#11.sentence-2)
|
||||
|
||||
The second and fourth constructors shall use a copy of a to
|
||||
allocate memory for internal use[.](#11.sentence-3)
|
||||
|
||||
If an exception is thrown, d(p) is called[.](#11.sentence-4)
|
||||
|
||||
[12](#12)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3737)
|
||||
|
||||
*Postconditions*: use_count() == 1 && get() == p[.](#12.sentence-1)
|
||||
|
||||
[13](#13)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3741)
|
||||
|
||||
*Throws*: bad_alloc, or an implementation-defined exception
|
||||
when a resource other than memory cannot be obtained[.](#13.sentence-1)
|
||||
|
||||
[ð](#lib:shared_ptr,constructor___)
|
||||
|
||||
`template<class Y> constexpr shared_ptr(const shared_ptr<Y>& r, element_type* p) noexcept;
|
||||
template<class Y> constexpr shared_ptr(shared_ptr<Y>&& r, element_type* p) noexcept;
|
||||
`
|
||||
|
||||
[14](#14)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3755)
|
||||
|
||||
*Effects*: Constructs a shared_ptr instance that
|
||||
stores p and shares ownership with
|
||||
the initial value of r[.](#14.sentence-1)
|
||||
|
||||
[15](#15)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3761)
|
||||
|
||||
*Postconditions*: get() == p[.](#15.sentence-1)
|
||||
|
||||
For the second overload,r is empty and r.get() == nullptr[.](#15.sentence-2)
|
||||
|
||||
[16](#16)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3767)
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
Use of this constructor leads to a dangling pointer
|
||||
unless p remains valid
|
||||
at least until the ownership group of r is destroyed[.](#16.sentence-1)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[17](#17)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3774)
|
||||
|
||||
[*Note [2](#note-2)*:
|
||||
|
||||
This constructor allows creation of an emptyshared_ptr instance with a non-null stored pointer[.](#17.sentence-1)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[ð](#lib:shared_ptr,constructor____)
|
||||
|
||||
`constexpr shared_ptr(const shared_ptr& r) noexcept;
|
||||
template<class Y> constexpr shared_ptr(const shared_ptr<Y>& r) noexcept;
|
||||
`
|
||||
|
||||
[18](#18)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3788)
|
||||
|
||||
*Constraints*: For the second constructor, Y* is compatible with T*[.](#18.sentence-1)
|
||||
|
||||
[19](#19)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3792)
|
||||
|
||||
*Effects*: If r is empty, constructs
|
||||
an empty shared_ptr object; otherwise, constructs
|
||||
a shared_ptr object that shares ownership with r[.](#19.sentence-1)
|
||||
|
||||
[20](#20)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3798)
|
||||
|
||||
*Postconditions*: get() == r.get() && use_count() == r.use_count()[.](#20.sentence-1)
|
||||
|
||||
[ð](#lib:shared_ptr,constructor_____)
|
||||
|
||||
`constexpr shared_ptr(shared_ptr&& r) noexcept;
|
||||
template<class Y> constexpr shared_ptr(shared_ptr<Y>&& r) noexcept;
|
||||
`
|
||||
|
||||
[21](#21)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3810)
|
||||
|
||||
*Constraints*: For the second constructor, Y* is compatible with T*[.](#21.sentence-1)
|
||||
|
||||
[22](#22)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3814)
|
||||
|
||||
*Effects*: Move constructs a shared_ptr instance from r[.](#22.sentence-1)
|
||||
|
||||
[23](#23)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3818)
|
||||
|
||||
*Postconditions*: *this contains the old value ofr[.](#23.sentence-1)
|
||||
|
||||
r is empty, and r.get() == nullptr[.](#23.sentence-2)
|
||||
|
||||
[ð](#lib:shared_ptr,constructor______)
|
||||
|
||||
`template<class Y> constexpr explicit shared_ptr(const weak_ptr<Y>& r);
|
||||
`
|
||||
|
||||
[24](#24)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3831)
|
||||
|
||||
*Constraints*: Y* is compatible with T*[.](#24.sentence-1)
|
||||
|
||||
[25](#25)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3835)
|
||||
|
||||
*Effects*: Constructs a shared_ptr object that shares ownership withr and stores a copy of the pointer stored in r[.](#25.sentence-1)
|
||||
|
||||
If an exception is thrown, the constructor has no effect[.](#25.sentence-2)
|
||||
|
||||
[26](#26)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3841)
|
||||
|
||||
*Postconditions*: use_count() == r.use_count()[.](#26.sentence-1)
|
||||
|
||||
[27](#27)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3845)
|
||||
|
||||
*Throws*: bad_weak_ptr when r.expired()[.](#27.sentence-1)
|
||||
|
||||
[ð](#lib:shared_ptr,constructor_______)
|
||||
|
||||
`template<class Y, class D> constexpr shared_ptr(unique_ptr<Y, D>&& r);
|
||||
`
|
||||
|
||||
[28](#28)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3857)
|
||||
|
||||
*Constraints*: Y* is compatible with T* andunique_ptr<Y, D>::pointer is convertible to element_type*[.](#28.sentence-1)
|
||||
|
||||
[29](#29)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3862)
|
||||
|
||||
*Effects*: If r.get() == nullptr, equivalent to shared_ptr()[.](#29.sentence-1)
|
||||
|
||||
Otherwise, if D is not a reference type,
|
||||
equivalent to shared_ptr(r.release(), std::move(r.get_deleter()))[.](#29.sentence-2)
|
||||
|
||||
Otherwise, equivalent to shared_ptr(r.release(), ref(r.get_deleter()))[.](#29.sentence-3)
|
||||
|
||||
If an exception is thrown, the constructor has no effect[.](#29.sentence-4)
|
||||
379
cppdraft/util/smartptr/shared/create.md
Normal file
379
cppdraft/util/smartptr/shared/create.md
Normal file
@@ -0,0 +1,379 @@
|
||||
[util.smartptr.shared.create]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.3 Smart pointers [[smartptr]](smartptr#util.smartptr.shared.create)
|
||||
|
||||
### 20.3.2 Shared-ownership pointers [[util.sharedptr]](util.sharedptr#util.smartptr.shared.create)
|
||||
|
||||
#### 20.3.2.2 Class template shared_ptr [[util.smartptr.shared]](util.smartptr.shared#create)
|
||||
|
||||
#### 20.3.2.2.7 Creation [util.smartptr.shared.create]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4220)
|
||||
|
||||
The common requirements that apply to allmake_shared,allocate_shared,make_shared_for_overwrite, andallocate_shared_for_overwrite overloads,
|
||||
unless specified otherwise, are described below[.](#1.sentence-1)
|
||||
|
||||
[ð](#lib:make_shared)
|
||||
|
||||
`template<class T, ...>
|
||||
constexpr shared_ptr<T> make_shared(args);
|
||||
template<class T, class A, ...>
|
||||
constexpr shared_ptr<T> allocate_shared(const A& a, args);
|
||||
template<class T, ...>
|
||||
constexpr shared_ptr<T> make_shared_for_overwrite(args);
|
||||
template<class T, class A, ...>
|
||||
constexpr shared_ptr<T> allocate_shared_for_overwrite(const A& a, args);
|
||||
`
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4242)
|
||||
|
||||
*Preconditions*: A meets
|
||||
the [*Cpp17Allocator*](allocator.requirements.general#:Cpp17Allocator "16.4.4.6.1 General [allocator.requirements.general]") requirements ([[allocator.requirements.general]](allocator.requirements.general "16.4.4.6.1 General"))[.](#2.sentence-1)
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4247)
|
||||
|
||||
*Effects*: Allocates memory for an object of type T (or U[N] when T is U[],
|
||||
where N is determined from *args* as specified by the concrete overload)[.](#3.sentence-1)
|
||||
|
||||
The object is initialized from *args* as specified by the concrete overload[.](#3.sentence-2)
|
||||
|
||||
The allocate_shared and allocate_shared_for_overwrite templates
|
||||
use a copy of a (rebound for an unspecified value_type) to allocate memory[.](#3.sentence-3)
|
||||
|
||||
If an exception is thrown, the functions have no effect[.](#3.sentence-4)
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4258)
|
||||
|
||||
*Postconditions*: r.get() != nullptr && r.use_count() == 1,
|
||||
where r is the return value[.](#4.sentence-1)
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4263)
|
||||
|
||||
*Returns*: A shared_ptr instance that stores and owns the address of
|
||||
the newly constructed object[.](#5.sentence-1)
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4268)
|
||||
|
||||
*Throws*: bad_alloc, or
|
||||
an exception thrown from allocate or from the initialization of the object[.](#6.sentence-1)
|
||||
|
||||
[7](#7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4273)
|
||||
|
||||
*Remarks*:
|
||||
|
||||
- [(7.1)](#7.1)
|
||||
|
||||
Implementations should perform no more than one memory allocation[.](#7.1.sentence-1)
|
||||
[*Note [1](#note-1)*:
|
||||
This provides efficiency equivalent to an intrusive smart pointer[.](#7.1.sentence-2)
|
||||
â *end note*]
|
||||
|
||||
- [(7.2)](#7.2)
|
||||
|
||||
When an object of an array type U is specified to have
|
||||
an initial value of u (of the same type),
|
||||
this shall be interpreted to mean that
|
||||
each array element of the object has as its initial value
|
||||
the corresponding element from u[.](#7.2.sentence-1)
|
||||
|
||||
- [(7.3)](#7.3)
|
||||
|
||||
When an object of an array type is specified to have
|
||||
a default initial value,
|
||||
this shall be interpreted to mean that each array element of the object
|
||||
has a default initial value[.](#7.3.sentence-1)
|
||||
|
||||
- [(7.4)](#7.4)
|
||||
|
||||
When a (sub)object of a non-array type U is specified to have
|
||||
an initial value of v, or U(l...),
|
||||
where l... is a list of constructor arguments, make_shared shall initialize this (sub)object
|
||||
via the expression ::new(pv) U(v) or ::new(pv) U(l...) respectively,
|
||||
where pv has type void* and points to storage
|
||||
suitable to hold an object of type U[.](#7.4.sentence-1)
|
||||
|
||||
- [(7.5)](#7.5)
|
||||
|
||||
When a (sub)object of a non-array type U is specified to have
|
||||
an initial value of v, or U(l...),
|
||||
where l... is a list of constructor arguments, allocate_shared shall initialize this (sub)object
|
||||
via the expression
|
||||
* [(7.5.1)](#7.5.1)
|
||||
|
||||
allocator_traits<A2>::construct(a2, pu, v) or
|
||||
|
||||
* [(7.5.2)](#7.5.2)
|
||||
|
||||
allocator_traits<A2>::construct(a2, pu, l...)
|
||||
|
||||
respectively,
|
||||
where pu is a pointer of type remove_cv_t<U>* pointing to storage
|
||||
suitable to hold an object of type remove_cv_t<U> and a2 of type A2 is a potentially rebound copy of
|
||||
the allocator a passed to allocate_shared[.](#7.5.sentence-1)
|
||||
|
||||
- [(7.6)](#7.6)
|
||||
|
||||
When a (sub)object of non-array type U is specified to have
|
||||
a default initial value, make_shared shall initialize this (sub)object
|
||||
via the expression ::new(pv) U(),
|
||||
where pv has type void* and points to storage
|
||||
suitable to hold an object of type U[.](#7.6.sentence-1)
|
||||
|
||||
- [(7.7)](#7.7)
|
||||
|
||||
When a (sub)object of non-array type U is specified to have
|
||||
a default initial value, allocate_shared initializes this (sub)object
|
||||
via the expression allocator_traits<A2>::construct(a2, pu),
|
||||
where pu is a pointer of type remove_cv_t<U>* pointing to storage
|
||||
suitable to hold an object of type remove_cv_t<U> and a2 of type A2 is a potentially rebound copy of
|
||||
the allocator a passed to allocate_shared[.](#7.7.sentence-1)
|
||||
|
||||
- [(7.8)](#7.8)
|
||||
|
||||
When a (sub)object of non-array type U is initialized by make_shared_for_overwrite or allocate_shared_for_overwrite,
|
||||
it is initialized via the expression ::new(pv) U,
|
||||
where pv has type void* and
|
||||
points to storage suitable to hold an object of type U[.](#7.8.sentence-1)
|
||||
|
||||
- [(7.9)](#7.9)
|
||||
|
||||
Array elements are initialized in ascending order of their addresses[.](#7.9.sentence-1)
|
||||
|
||||
- [(7.10)](#7.10)
|
||||
|
||||
When the lifetime of the object managed by the return value ends, or
|
||||
when the initialization of an array element throws an exception,
|
||||
the initialized elements are destroyed in the reverse order
|
||||
of their original construction[.](#7.10.sentence-1)
|
||||
|
||||
- [(7.11)](#7.11)
|
||||
|
||||
When a (sub)object of non-array type U that was initialized by make_shared, make_shared_for_overwrite, or allocate_shared_for_overwrite is to be destroyed,
|
||||
it is destroyed via the expression pu->~U() where pu points to that object of type U[.](#7.11.sentence-1)
|
||||
|
||||
- [(7.12)](#7.12)
|
||||
|
||||
When a (sub)object of non-array type U that was initialized by allocate_shared is to be destroyed,
|
||||
it is destroyed via the expression allocator_traits<A2>::destroy(a2, pu) where pu is a pointer of type remove_cv_t<U>* pointing to that object of type remove_cv_t<U> and a2 of type A2 is a potentially rebound copy of
|
||||
the allocator a passed to allocate_shared[.](#7.12.sentence-1)
|
||||
|
||||
[*Note [2](#note-2)*:
|
||||
|
||||
These functions will typically allocate more memory than sizeof(T) to
|
||||
allow for internal bookkeeping structures such as reference counts[.](#7.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[ð](#lib:make_shared_)
|
||||
|
||||
`template<class T, class... Args>
|
||||
constexpr shared_ptr<T> make_shared(Args&&... args); // T is not array
|
||||
template<class T, class A, class... Args>
|
||||
constexpr shared_ptr<T> allocate_shared(const A& a, Args&&... args); // T is not array
|
||||
`
|
||||
|
||||
[8](#8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4380)
|
||||
|
||||
*Constraints*: T is not an array type[.](#8.sentence-1)
|
||||
|
||||
[9](#9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4384)
|
||||
|
||||
*Returns*: A shared_ptr to an object of type T with an initial value T(std::forward<Args>(args)...)[.](#9.sentence-1)
|
||||
|
||||
[10](#10)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4389)
|
||||
|
||||
*Remarks*: The shared_ptr constructors called by these functions
|
||||
enable shared_from_this with the address of the newly constructed object of type T[.](#10.sentence-1)
|
||||
|
||||
[11](#11)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4395)
|
||||
|
||||
[*Example [1](#example-1)*: shared_ptr<int> p = make_shared<int>(); // shared_ptr to int() shared_ptr<vector<int>> q = make_shared<vector<int>>(16, 1); // shared_ptr to vector of 16 elements with value 1 â *end example*]
|
||||
|
||||
[ð](#lib:make_shared__)
|
||||
|
||||
`template<class T>
|
||||
constexpr shared_ptr<T> make_shared(size_t N); // T is U[]
|
||||
template<class T, class A>
|
||||
constexpr shared_ptr<T> allocate_shared(const A& a, size_t N); // T is U[]
|
||||
`
|
||||
|
||||
[12](#12)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4415)
|
||||
|
||||
*Constraints*: T is of the form U[][.](#12.sentence-1)
|
||||
|
||||
[13](#13)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4419)
|
||||
|
||||
*Returns*: A shared_ptr to an object of type U[N] with a default initial value,
|
||||
where U is remove_extent_t<T>[.](#13.sentence-1)
|
||||
|
||||
[14](#14)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4425)
|
||||
|
||||
[*Example [2](#example-2)*: shared_ptr<double[]> p = make_shared<double[]>(1024); // shared_ptr to a value-initialized double[1024] shared_ptr<double[][2][2]> q = make_shared<double[][2][2]>(6); // shared_ptr to a value-initialized double[6][2][2] â *end example*]
|
||||
|
||||
[ð](#lib:make_shared___)
|
||||
|
||||
`template<class T>
|
||||
constexpr shared_ptr<T> make_shared(); // T is U[N]
|
||||
template<class T, class A>
|
||||
constexpr shared_ptr<T> allocate_shared(const A& a); // T is U[N]
|
||||
`
|
||||
|
||||
[15](#15)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4446)
|
||||
|
||||
*Constraints*: T is of the form U[N][.](#15.sentence-1)
|
||||
|
||||
[16](#16)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4450)
|
||||
|
||||
*Returns*: A shared_ptr to an object of type T with a default initial value[.](#16.sentence-1)
|
||||
|
||||
[17](#17)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4455)
|
||||
|
||||
[*Example [3](#example-3)*: shared_ptr<double[1024]> p = make_shared<double[1024]>(); // shared_ptr to a value-initialized double[1024] shared_ptr<double[6][2][2]> q = make_shared<double[6][2][2]>(); // shared_ptr to a value-initialized double[6][2][2] â *end example*]
|
||||
|
||||
[ð](#lib:make_shared____)
|
||||
|
||||
`template<class T>
|
||||
constexpr shared_ptr<T> make_shared(size_t N,
|
||||
const remove_extent_t<T>& u); // T is U[]
|
||||
template<class T, class A>
|
||||
constexpr shared_ptr<T> allocate_shared(const A& a, size_t N,
|
||||
const remove_extent_t<T>& u); // T is U[]
|
||||
`
|
||||
|
||||
[18](#18)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4478)
|
||||
|
||||
*Constraints*: T is of the form U[][.](#18.sentence-1)
|
||||
|
||||
[19](#19)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4482)
|
||||
|
||||
*Returns*: A shared_ptr to an object of type U[N],
|
||||
where U is remove_extent_t<T> and
|
||||
each array element has an initial value of u[.](#19.sentence-1)
|
||||
|
||||
[20](#20)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4488)
|
||||
|
||||
[*Example [4](#example-4)*: shared_ptr<double[]> p = make_shared<double[]>(1024, 1.0); // shared_ptr to a double[1024], where each element is 1.0 shared_ptr<double[][2]> q = make_shared<double[][2]>(6, {1.0, 0.0}); // shared_ptr to a double[6][2], where each double[2] element is {1.0, 0.0} shared_ptr<vector<int>[]> r = make_shared<vector<int>[]>(4, {1, 2}); // shared_ptr to a vector<int>[4], where each vector has contents {1, 2} â *end example*]
|
||||
|
||||
[ð](#lib:make_shared_____)
|
||||
|
||||
`template<class T>
|
||||
constexpr shared_ptr<T> make_shared(const remove_extent_t<T>& u); // T is U[N]
|
||||
template<class T, class A>
|
||||
constexpr shared_ptr<T> allocate_shared(const A& a,
|
||||
const remove_extent_t<T>& u); // T is U[N]
|
||||
`
|
||||
|
||||
[21](#21)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4512)
|
||||
|
||||
*Constraints*: T is of the form U[N][.](#21.sentence-1)
|
||||
|
||||
[22](#22)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4516)
|
||||
|
||||
*Returns*: A shared_ptr to an object of type T,
|
||||
where each array element of type remove_extent_t<T> has an initial value of u[.](#22.sentence-1)
|
||||
|
||||
[23](#23)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4522)
|
||||
|
||||
[*Example [5](#example-5)*: shared_ptr<double[1024]> p = make_shared<double[1024]>(1.0); // shared_ptr to a double[1024], where each element is 1.0 shared_ptr<double[6][2]> q = make_shared<double[6][2]>({1.0, 0.0}); // shared_ptr to a double[6][2], where each double[2] element is {1.0, 0.0} shared_ptr<vector<int>[4]> r = make_shared<vector<int>[4]>({1, 2}); // shared_ptr to a vector<int>[4], where each vector has contents {1, 2} â *end example*]
|
||||
|
||||
[ð](#lib:make_shared______)
|
||||
|
||||
`template<class T>
|
||||
constexpr shared_ptr<T> make_shared_for_overwrite();
|
||||
template<class T, class A>
|
||||
constexpr shared_ptr<T> allocate_shared_for_overwrite(const A& a);
|
||||
`
|
||||
|
||||
[24](#24)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4545)
|
||||
|
||||
*Constraints*: T is not an array of unknown bound[.](#24.sentence-1)
|
||||
|
||||
[25](#25)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4549)
|
||||
|
||||
*Returns*: A shared_ptr to an object of type T[.](#25.sentence-1)
|
||||
|
||||
[26](#26)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4553)
|
||||
|
||||
[*Example [6](#example-6)*: struct X { double data[1024]; };
|
||||
shared_ptr<X> p = make_shared_for_overwrite<X>(); // shared_ptr to a default-initialized X, where each element in X::data has an indeterminate value shared_ptr<double[1024]> q = make_shared_for_overwrite<double[1024]>(); // shared_ptr to a default-initialized double[1024], where each element has an indeterminate value â *end example*]
|
||||
|
||||
[ð](#lib:make_shared_______)
|
||||
|
||||
`template<class T>
|
||||
constexpr shared_ptr<T> make_shared_for_overwrite(size_t N);
|
||||
template<class T, class A>
|
||||
constexpr shared_ptr<T> allocate_shared_for_overwrite(const A& a, size_t N);
|
||||
`
|
||||
|
||||
[27](#27)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4576)
|
||||
|
||||
*Constraints*: T is an array of unknown bound[.](#27.sentence-1)
|
||||
|
||||
[28](#28)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4580)
|
||||
|
||||
*Returns*: A shared_ptr to an object of type U[N],
|
||||
where U is remove_extent_t<T>[.](#28.sentence-1)
|
||||
|
||||
[29](#29)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4585)
|
||||
|
||||
[*Example [7](#example-7)*: shared_ptr<double[]> p = make_shared_for_overwrite<double[]>(1024); // shared_ptr to a default-initialized double[1024], where each element has an indeterminate value â *end example*]
|
||||
48
cppdraft/util/smartptr/shared/dest.md
Normal file
48
cppdraft/util/smartptr/shared/dest.md
Normal file
@@ -0,0 +1,48 @@
|
||||
[util.smartptr.shared.dest]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.3 Smart pointers [[smartptr]](smartptr#util.smartptr.shared.dest)
|
||||
|
||||
### 20.3.2 Shared-ownership pointers [[util.sharedptr]](util.sharedptr#util.smartptr.shared.dest)
|
||||
|
||||
#### 20.3.2.2 Class template shared_ptr [[util.smartptr.shared]](util.smartptr.shared#dest)
|
||||
|
||||
#### 20.3.2.2.3 Destructor [util.smartptr.shared.dest]
|
||||
|
||||
[ð](#lib:shared_ptr,destructor)
|
||||
|
||||
`constexpr ~shared_ptr();
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3879)
|
||||
|
||||
*Effects*:
|
||||
|
||||
- [(1.1)](#1.1)
|
||||
|
||||
If *this is empty or shares ownership with anothershared_ptr instance (use_count() > 1), there are no side effects[.](#1.1.sentence-1)
|
||||
|
||||
- [(1.2)](#1.2)
|
||||
|
||||
Otherwise, if *this owns an objectp and a deleter d, d(p) is called[.](#1.2.sentence-1)
|
||||
|
||||
- [(1.3)](#1.3)
|
||||
|
||||
Otherwise, *this owns a pointer p,
|
||||
and delete p is called[.](#1.3.sentence-1)
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3894)
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
Since the destruction of *this decreases the number of instances that share ownership with *this by one,
|
||||
after *this has been destroyed
|
||||
all shared_ptr instances that shared ownership with*this will report a use_count() that is one less
|
||||
than its previous value[.](#2.sentence-1)
|
||||
|
||||
â *end note*]
|
||||
74
cppdraft/util/smartptr/shared/general.md
Normal file
74
cppdraft/util/smartptr/shared/general.md
Normal file
@@ -0,0 +1,74 @@
|
||||
[util.smartptr.shared.general]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.3 Smart pointers [[smartptr]](smartptr#util.smartptr.shared.general)
|
||||
|
||||
### 20.3.2 Shared-ownership pointers [[util.sharedptr]](util.sharedptr#util.smartptr.shared.general)
|
||||
|
||||
#### 20.3.2.2 Class template shared_ptr [[util.smartptr.shared]](util.smartptr.shared#general)
|
||||
|
||||
#### 20.3.2.2.1 General [util.smartptr.shared.general]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3487)
|
||||
|
||||
The shared_ptr class template stores a pointer, usually obtained
|
||||
via new[.](#1.sentence-1)
|
||||
|
||||
shared_ptr implements semantics of shared ownership;
|
||||
the last remaining owner of the pointer is responsible for destroying
|
||||
the object, or otherwise releasing the resources associated with the stored pointer[.](#1.sentence-2)
|
||||
|
||||
Ashared_ptr is said to be empty if it does not own a pointer[.](#1.sentence-3)
|
||||
|
||||
namespace std {template<class T> class shared_ptr {public:using element_type = remove_extent_t<T>; using weak_type = weak_ptr<T>; // [[util.smartptr.shared.const]](util.smartptr.shared.const "20.3.2.2.2 Constructors"), constructorsconstexpr shared_ptr() noexcept; constexpr shared_ptr(nullptr_t) noexcept : shared_ptr() { }template<class Y>constexpr explicit shared_ptr(Y* p); template<class Y, class D>constexpr shared_ptr(Y* p, D d); template<class Y, class D, class A>constexpr shared_ptr(Y* p, D d, A a); template<class D>constexpr shared_ptr(nullptr_t p, D d); template<class D, class A>constexpr shared_ptr(nullptr_t p, D d, A a); template<class Y>constexpr shared_ptr(const shared_ptr<Y>& r, element_type* p) noexcept; template<class Y>constexpr shared_ptr(shared_ptr<Y>&& r, element_type* p) noexcept; constexpr shared_ptr(const shared_ptr& r) noexcept; template<class Y>constexpr shared_ptr(const shared_ptr<Y>& r) noexcept; constexpr shared_ptr(shared_ptr&& r) noexcept; template<class Y>constexpr shared_ptr(shared_ptr<Y>&& r) noexcept; template<class Y>constexpr explicit shared_ptr(const weak_ptr<Y>& r); template<class Y, class D>constexpr shared_ptr(unique_ptr<Y, D>&& r); // [[util.smartptr.shared.dest]](util.smartptr.shared.dest "20.3.2.2.3 Destructor"), destructorconstexpr ~shared_ptr(); // [[util.smartptr.shared.assign]](util.smartptr.shared.assign "20.3.2.2.4 Assignment"), assignmentconstexpr shared_ptr& operator=(const shared_ptr& r) noexcept; template<class Y>constexpr shared_ptr& operator=(const shared_ptr<Y>& r) noexcept; constexpr shared_ptr& operator=(shared_ptr&& r) noexcept; template<class Y>constexpr shared_ptr& operator=(shared_ptr<Y>&& r) noexcept; template<class Y, class D>constexpr shared_ptr& operator=(unique_ptr<Y, D>&& r); // [[util.smartptr.shared.mod]](util.smartptr.shared.mod "20.3.2.2.5 Modifiers"), modifiersconstexpr void swap(shared_ptr& r) noexcept; constexpr void reset() noexcept; template<class Y>constexpr void reset(Y* p); template<class Y, class D>constexpr void reset(Y* p, D d); template<class Y, class D, class A>constexpr void reset(Y* p, D d, A a); // [[util.smartptr.shared.obs]](util.smartptr.shared.obs "20.3.2.2.6 Observers"), observersconstexpr element_type* get() const noexcept; constexpr T& operator*() const noexcept; constexpr T* operator->() const noexcept; constexpr element_type& operator[](ptrdiff_t i) const; constexpr long use_count() const noexcept; constexpr explicit operator bool() const noexcept; template<class U>constexpr bool owner_before(const shared_ptr<U>& b) const noexcept; template<class U>constexpr bool owner_before(const weak_ptr<U>& b) const noexcept;
|
||||
size_t owner_hash() const noexcept; template<class U>constexpr bool owner_equal(const shared_ptr<U>& b) const noexcept; template<class U>constexpr bool owner_equal(const weak_ptr<U>& b) const noexcept; }; template<class T> shared_ptr(weak_ptr<T>) -> shared_ptr<T>; template<class T, class D> shared_ptr(unique_ptr<T, D>) -> shared_ptr<T>;}
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3578)
|
||||
|
||||
Specializations of shared_ptr shall be [*Cpp17CopyConstructible*](utility.arg.requirements#:Cpp17CopyConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]"),[*Cpp17CopyAssignable*](utility.arg.requirements#:Cpp17CopyAssignable "16.4.4.2 Template argument requirements [utility.arg.requirements]"), and [*Cpp17LessThanComparable*](utility.arg.requirements#:Cpp17LessThanComparable "16.4.4.2 Template argument requirements [utility.arg.requirements]"), allowing their use in standard
|
||||
containers[.](#2.sentence-1)
|
||||
|
||||
Specializations of shared_ptr shall be
|
||||
contextually convertible to bool,
|
||||
allowing their use in boolean expressions and declarations in conditions[.](#2.sentence-2)
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3585)
|
||||
|
||||
The template parameter T of shared_ptr may be an incomplete type[.](#3.sentence-1)
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
T can be a function type[.](#3.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3592)
|
||||
|
||||
[*Example [1](#example-1)*: if (shared_ptr<X> px = dynamic_pointer_cast<X>(py)) {// do something with px} â *end example*]
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3601)
|
||||
|
||||
For purposes of determining the presence of a data race, member functions shall
|
||||
access and modify only the shared_ptr and weak_ptr objects
|
||||
themselves and not objects they refer to[.](#5.sentence-1)
|
||||
|
||||
Changes in use_count() do not
|
||||
reflect modifications that can introduce data races[.](#5.sentence-2)
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3607)
|
||||
|
||||
For the purposes of [[smartptr]](smartptr "20.3 Smart pointers"),
|
||||
a pointer type Y* is said to be[*compatible with*](#def:compatible_with,shared_ptr "20.3.2.2.1 General [util.smartptr.shared.general]") a pointer type T* when eitherY* is convertible to T* orY is U[N] and T is cv U[][.](#6.sentence-1)
|
||||
29
cppdraft/util/smartptr/shared/io.md
Normal file
29
cppdraft/util/smartptr/shared/io.md
Normal file
@@ -0,0 +1,29 @@
|
||||
[util.smartptr.shared.io]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.3 Smart pointers [[smartptr]](smartptr#util.smartptr.shared.io)
|
||||
|
||||
### 20.3.2 Shared-ownership pointers [[util.sharedptr]](util.sharedptr#util.smartptr.shared.io)
|
||||
|
||||
#### 20.3.2.2 Class template shared_ptr [[util.smartptr.shared]](util.smartptr.shared#io)
|
||||
|
||||
#### 20.3.2.2.12 I/O [util.smartptr.shared.io]
|
||||
|
||||
[ð](#lib:operator%3c%3c,shared_ptr)
|
||||
|
||||
`template<class E, class T, class Y>
|
||||
basic_ostream<E, T>& operator<<(basic_ostream<E, T>& os, const shared_ptr<Y>& p);
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4826)
|
||||
|
||||
*Effects*: As if by: os << p.get();
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4830)
|
||||
|
||||
*Returns*: os[.](#2.sentence-1)
|
||||
66
cppdraft/util/smartptr/shared/mod.md
Normal file
66
cppdraft/util/smartptr/shared/mod.md
Normal file
@@ -0,0 +1,66 @@
|
||||
[util.smartptr.shared.mod]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.3 Smart pointers [[smartptr]](smartptr#util.smartptr.shared.mod)
|
||||
|
||||
### 20.3.2 Shared-ownership pointers [[util.sharedptr]](util.sharedptr#util.smartptr.shared.mod)
|
||||
|
||||
#### 20.3.2.2 Class template shared_ptr [[util.smartptr.shared]](util.smartptr.shared#mod)
|
||||
|
||||
#### 20.3.2.2.5 Modifiers [util.smartptr.shared.mod]
|
||||
|
||||
[ð](#lib:swap,shared_ptr)
|
||||
|
||||
`constexpr void swap(shared_ptr& r) noexcept;
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3979)
|
||||
|
||||
*Effects*: Exchanges the contents of *this and r[.](#1.sentence-1)
|
||||
|
||||
[ð](#lib:reset,shared_ptr)
|
||||
|
||||
`constexpr void reset() noexcept;
|
||||
`
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3990)
|
||||
|
||||
*Effects*: Equivalent to shared_ptr().swap(*this)[.](#2.sentence-1)
|
||||
|
||||
[ð](#lib:reset,shared_ptr_)
|
||||
|
||||
`template<class Y> constexpr void reset(Y* p);
|
||||
`
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4001)
|
||||
|
||||
*Effects*: Equivalent to shared_ptr(p).swap(*this)[.](#3.sentence-1)
|
||||
|
||||
[ð](#lib:reset,shared_ptr__)
|
||||
|
||||
`template<class Y, class D> constexpr void reset(Y* p, D d);
|
||||
`
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4012)
|
||||
|
||||
*Effects*: Equivalent to shared_ptr(p, d).swap(*this)[.](#4.sentence-1)
|
||||
|
||||
[ð](#lib:reset,shared_ptr___)
|
||||
|
||||
`template<class Y, class D, class A> constexpr void reset(Y* p, D d, A a);
|
||||
`
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4023)
|
||||
|
||||
*Effects*: Equivalent to shared_ptr(p, d, a).swap(*this)[.](#5.sentence-1)
|
||||
240
cppdraft/util/smartptr/shared/obs.md
Normal file
240
cppdraft/util/smartptr/shared/obs.md
Normal file
@@ -0,0 +1,240 @@
|
||||
[util.smartptr.shared.obs]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.3 Smart pointers [[smartptr]](smartptr#util.smartptr.shared.obs)
|
||||
|
||||
### 20.3.2 Shared-ownership pointers [[util.sharedptr]](util.sharedptr#util.smartptr.shared.obs)
|
||||
|
||||
#### 20.3.2.2 Class template shared_ptr [[util.smartptr.shared]](util.smartptr.shared#obs)
|
||||
|
||||
#### 20.3.2.2.6 Observers [util.smartptr.shared.obs]
|
||||
|
||||
[ð](#lib:get,shared_ptr)
|
||||
|
||||
`constexpr element_type* get() const noexcept;
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4035)
|
||||
|
||||
*Returns*: The stored pointer[.](#1.sentence-1)
|
||||
|
||||
[ð](#lib:operator*,shared_ptr)
|
||||
|
||||
`constexpr T& operator*() const noexcept;
|
||||
`
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4046)
|
||||
|
||||
*Preconditions*: get() != nullptr[.](#2.sentence-1)
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4050)
|
||||
|
||||
*Returns*: *get()[.](#3.sentence-1)
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4054)
|
||||
|
||||
*Remarks*: When T is an array type or cv void,
|
||||
it is unspecified whether this
|
||||
member function is declared[.](#4.sentence-1)
|
||||
|
||||
If it is declared, it is unspecified what its
|
||||
return type is, except that the declaration (although not necessarily the
|
||||
definition) of the function shall be well-formed[.](#4.sentence-2)
|
||||
|
||||
[ð](#lib:operator-%3e,shared_ptr)
|
||||
|
||||
`constexpr T* operator->() const noexcept;
|
||||
`
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4069)
|
||||
|
||||
*Preconditions*: get() != nullptr[.](#5.sentence-1)
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4073)
|
||||
|
||||
*Returns*: get()[.](#6.sentence-1)
|
||||
|
||||
[7](#7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4077)
|
||||
|
||||
*Remarks*: When T is an array type,
|
||||
it is unspecified whether this member function is declared[.](#7.sentence-1)
|
||||
|
||||
If it is declared, it is unspecified what its return type is,
|
||||
except that the declaration (although not necessarily the definition)
|
||||
of the function shall be well-formed[.](#7.sentence-2)
|
||||
|
||||
[ð](#lib:operator%5b%5d,shared_ptr)
|
||||
|
||||
`constexpr element_type& operator[](ptrdiff_t i) const;
|
||||
`
|
||||
|
||||
[8](#8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4092)
|
||||
|
||||
*Preconditions*: get() != nullptr is true[.](#8.sentence-1)
|
||||
|
||||
[9](#9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4096)
|
||||
|
||||
*Hardened preconditions*: i ⥠0[.](#9.sentence-1)
|
||||
|
||||
If T is U[N], i < N[.](#9.sentence-2)
|
||||
|
||||
[10](#10)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4100)
|
||||
|
||||
*Returns*: get()[i][.](#10.sentence-1)
|
||||
|
||||
[11](#11)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4104)
|
||||
|
||||
*Throws*: Nothing[.](#11.sentence-1)
|
||||
|
||||
[12](#12)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4108)
|
||||
|
||||
*Remarks*: When T is not an array type,
|
||||
it is unspecified whether this member function is declared[.](#12.sentence-1)
|
||||
|
||||
If it is declared, it is unspecified what its return type is,
|
||||
except that the declaration (although not necessarily the definition)
|
||||
of the function shall be well-formed[.](#12.sentence-2)
|
||||
|
||||
[ð](#lib:use_count,shared_ptr)
|
||||
|
||||
`constexpr long use_count() const noexcept;
|
||||
`
|
||||
|
||||
[13](#13)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4123)
|
||||
|
||||
*Synchronization*: None[.](#13.sentence-1)
|
||||
|
||||
[14](#14)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4127)
|
||||
|
||||
*Returns*: The number of shared_ptr objects, *this included,
|
||||
that share ownership with *this, or 0 when *this is
|
||||
empty[.](#14.sentence-1)
|
||||
|
||||
[15](#15)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4133)
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
get() == nullptr does not imply a specific return value of use_count()[.](#15.sentence-1)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[16](#16)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4139)
|
||||
|
||||
[*Note [2](#note-2)*:
|
||||
|
||||
weak_ptr<T>::lock() can affect the return value of use_count()[.](#16.sentence-1)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[17](#17)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4145)
|
||||
|
||||
[*Note [3](#note-3)*:
|
||||
|
||||
When multiple threads
|
||||
might affect the return value of use_count(),
|
||||
the result is approximate[.](#17.sentence-1)
|
||||
|
||||
In particular, use_count() == 1 does not imply that accesses through
|
||||
a previously destroyed shared_ptr have in any sense completed[.](#17.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[ð](#lib:operator_bool,shared_ptr)
|
||||
|
||||
`constexpr explicit operator bool() const noexcept;
|
||||
`
|
||||
|
||||
[18](#18)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4161)
|
||||
|
||||
*Returns*: get() != nullptr[.](#18.sentence-1)
|
||||
|
||||
[ð](#lib:owner_before,shared_ptr)
|
||||
|
||||
`template<class U> constexpr bool owner_before(const shared_ptr<U>& b) const noexcept;
|
||||
template<class U> constexpr bool owner_before(const weak_ptr<U>& b) const noexcept;
|
||||
`
|
||||
|
||||
[19](#19)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4173)
|
||||
|
||||
*Returns*: An unspecified value such that
|
||||
|
||||
- [(19.1)](#19.1)
|
||||
|
||||
owner_before(b) defines a strict weak ordering as defined in [[alg.sorting]](alg.sorting "26.8 Sorting and related operations");
|
||||
|
||||
- [(19.2)](#19.2)
|
||||
|
||||
!owner_before(b) && !b.owner_before(*this) is true if and only if owner_equal(b) is true[.](#19.sentence-1)
|
||||
|
||||
[ð](#lib:owner_hash,shared_ptr)
|
||||
|
||||
`size_t owner_hash() const noexcept;
|
||||
`
|
||||
|
||||
[20](#20)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4191)
|
||||
|
||||
*Returns*: An unspecified value such that,
|
||||
for any object x where owner_equal(x) is true,owner_hash() == x.owner_hash() is true[.](#20.sentence-1)
|
||||
|
||||
[ð](#lib:owner_equal,shared_ptr)
|
||||
|
||||
`template<class U>
|
||||
constexpr bool owner_equal(const shared_ptr<U>& b) const noexcept;
|
||||
template<class U>
|
||||
constexpr bool owner_equal(const weak_ptr<U>& b) const noexcept;
|
||||
`
|
||||
|
||||
[21](#21)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4207)
|
||||
|
||||
*Returns*: true if and only if*this and b share ownership or are both empty[.](#21.sentence-1)
|
||||
|
||||
Otherwise returns false[.](#21.sentence-2)
|
||||
|
||||
[22](#22)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4213)
|
||||
|
||||
*Remarks*: owner_equal is an equivalence relation[.](#22.sentence-1)
|
||||
23
cppdraft/util/smartptr/shared/spec.md
Normal file
23
cppdraft/util/smartptr/shared/spec.md
Normal file
@@ -0,0 +1,23 @@
|
||||
[util.smartptr.shared.spec]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.3 Smart pointers [[smartptr]](smartptr#util.smartptr.shared.spec)
|
||||
|
||||
### 20.3.2 Shared-ownership pointers [[util.sharedptr]](util.sharedptr#util.smartptr.shared.spec)
|
||||
|
||||
#### 20.3.2.2 Class template shared_ptr [[util.smartptr.shared]](util.smartptr.shared#spec)
|
||||
|
||||
#### 20.3.2.2.9 Specialized algorithms [util.smartptr.shared.spec]
|
||||
|
||||
[ð](#lib:swap,shared_ptr)
|
||||
|
||||
`template<class T>
|
||||
constexpr void swap(shared_ptr<T>& a, shared_ptr<T>& b) noexcept;
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4661)
|
||||
|
||||
*Effects*: Equivalent to a.swap(b)[.](#1.sentence-1)
|
||||
297
cppdraft/util/smartptr/weak.md
Normal file
297
cppdraft/util/smartptr/weak.md
Normal file
@@ -0,0 +1,297 @@
|
||||
[util.smartptr.weak]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.3 Smart pointers [[smartptr]](smartptr#util.smartptr.weak)
|
||||
|
||||
### 20.3.2 Shared-ownership pointers [[util.sharedptr]](util.sharedptr#util.smartptr.weak)
|
||||
|
||||
#### 20.3.2.3 Class template weak_ptr [util.smartptr.weak]
|
||||
|
||||
#### [20.3.2.3.1](#general) General [[util.smartptr.weak.general]](util.smartptr.weak.general)
|
||||
|
||||
[1](#general-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4839)
|
||||
|
||||
The weak_ptr class template stores a weak reference to an object
|
||||
that is already managed by a shared_ptr[.](#general-1.sentence-1)
|
||||
|
||||
To access the object, aweak_ptr can be converted to a shared_ptr using the member
|
||||
function lock[.](#general-1.sentence-2)
|
||||
|
||||
namespace std {template<class T> class weak_ptr {public:using element_type = remove_extent_t<T>; // [[util.smartptr.weak.const]](#const "20.3.2.3.2 Constructors"), constructorsconstexpr weak_ptr() noexcept; template<class Y>constexpr weak_ptr(const shared_ptr<Y>& r) noexcept; constexpr weak_ptr(const weak_ptr& r) noexcept; template<class Y>constexpr weak_ptr(const weak_ptr<Y>& r) noexcept; constexpr weak_ptr(weak_ptr&& r) noexcept; template<class Y>constexpr weak_ptr(weak_ptr<Y>&& r) noexcept; // [[util.smartptr.weak.dest]](#dest "20.3.2.3.3 Destructor"), destructorconstexpr ~weak_ptr(); // [[util.smartptr.weak.assign]](#assign "20.3.2.3.4 Assignment"), assignmentconstexpr weak_ptr& operator=(const weak_ptr& r) noexcept; template<class Y>constexpr weak_ptr& operator=(const weak_ptr<Y>& r) noexcept; template<class Y>constexpr weak_ptr& operator=(const shared_ptr<Y>& r) noexcept; constexpr weak_ptr& operator=(weak_ptr&& r) noexcept; template<class Y>constexpr weak_ptr& operator=(weak_ptr<Y>&& r) noexcept; // [[util.smartptr.weak.mod]](#mod "20.3.2.3.5 Modifiers"), modifiersconstexpr void swap(weak_ptr& r) noexcept; constexpr void reset() noexcept; // [[util.smartptr.weak.obs]](#obs "20.3.2.3.6 Observers"), observersconstexpr long use_count() const noexcept; constexpr bool expired() const noexcept; constexpr shared_ptr<T> lock() const noexcept; template<class U>constexpr bool owner_before(const shared_ptr<U>& b) const noexcept; template<class U>constexpr bool owner_before(const weak_ptr<U>& b) const noexcept;
|
||||
size_t owner_hash() const noexcept; template<class U>constexpr bool owner_equal(const shared_ptr<U>& b) const noexcept; template<class U>constexpr bool owner_equal(const weak_ptr<U>& b) const noexcept; }; template<class T> weak_ptr(shared_ptr<T>) -> weak_ptr<T>;}
|
||||
|
||||
[2](#general-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4900)
|
||||
|
||||
Specializations of weak_ptr shall be [*Cpp17CopyConstructible*](utility.arg.requirements#:Cpp17CopyConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") and[*Cpp17CopyAssignable*](utility.arg.requirements#:Cpp17CopyAssignable "16.4.4.2 Template argument requirements [utility.arg.requirements]"), allowing their use in standard
|
||||
containers[.](#general-2.sentence-1)
|
||||
|
||||
The template parameter T of weak_ptr may be an
|
||||
incomplete type[.](#general-2.sentence-2)
|
||||
|
||||
#### [20.3.2.3.2](#const) Constructors [[util.smartptr.weak.const]](util.smartptr.weak.const)
|
||||
|
||||
[ð](#lib:weak_ptr,constructor)
|
||||
|
||||
`constexpr weak_ptr() noexcept;
|
||||
`
|
||||
|
||||
[1](#const-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4914)
|
||||
|
||||
*Effects*: Constructs an empty weak_ptr object that stores a null pointer value[.](#const-1.sentence-1)
|
||||
|
||||
[2](#const-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4918)
|
||||
|
||||
*Postconditions*: use_count() == 0[.](#const-2.sentence-1)
|
||||
|
||||
[ð](#lib:weak_ptr,constructor_)
|
||||
|
||||
`constexpr weak_ptr(const weak_ptr& r) noexcept;
|
||||
template<class Y> constexpr weak_ptr(const weak_ptr<Y>& r) noexcept;
|
||||
template<class Y> constexpr weak_ptr(const shared_ptr<Y>& r) noexcept;
|
||||
`
|
||||
|
||||
[3](#const-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4931)
|
||||
|
||||
*Constraints*: For the second and third constructors, Y* is compatible with T*[.](#const-3.sentence-1)
|
||||
|
||||
[4](#const-4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4935)
|
||||
|
||||
*Effects*: If r is empty, constructs
|
||||
an empty weak_ptr object that stores a null pointer value;
|
||||
otherwise, constructs
|
||||
a weak_ptr object that shares ownership
|
||||
with r and stores a copy of the pointer stored in r[.](#const-4.sentence-1)
|
||||
|
||||
[5](#const-5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4943)
|
||||
|
||||
*Postconditions*: use_count() == r.use_count()[.](#const-5.sentence-1)
|
||||
|
||||
[ð](#lib:weak_ptr,constructor__)
|
||||
|
||||
`constexpr weak_ptr(weak_ptr&& r) noexcept;
|
||||
template<class Y> constexpr weak_ptr(weak_ptr<Y>&& r) noexcept;
|
||||
`
|
||||
|
||||
[6](#const-6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4955)
|
||||
|
||||
*Constraints*: For the second constructor, Y* is compatible with T*[.](#const-6.sentence-1)
|
||||
|
||||
[7](#const-7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4959)
|
||||
|
||||
*Effects*: Move constructs a weak_ptr instance from r[.](#const-7.sentence-1)
|
||||
|
||||
[8](#const-8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4963)
|
||||
|
||||
*Postconditions*: *this contains the old value of r[.](#const-8.sentence-1)
|
||||
|
||||
r is empty, stores a null pointer value, and r.use_count() == 0[.](#const-8.sentence-2)
|
||||
|
||||
#### [20.3.2.3.3](#dest) Destructor [[util.smartptr.weak.dest]](util.smartptr.weak.dest)
|
||||
|
||||
[ð](#lib:weak_ptr,destructor)
|
||||
|
||||
`constexpr ~weak_ptr();
|
||||
`
|
||||
|
||||
[1](#dest-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4977)
|
||||
|
||||
*Effects*: Destroys this weak_ptr object but has no
|
||||
effect on the object its stored pointer points to[.](#dest-1.sentence-1)
|
||||
|
||||
#### [20.3.2.3.4](#assign) Assignment [[util.smartptr.weak.assign]](util.smartptr.weak.assign)
|
||||
|
||||
[ð](#lib:operator=,weak_ptr)
|
||||
|
||||
`constexpr weak_ptr& operator=(const weak_ptr& r) noexcept;
|
||||
template<class Y> constexpr weak_ptr& operator=(const weak_ptr<Y>& r) noexcept;
|
||||
template<class Y> constexpr weak_ptr& operator=(const shared_ptr<Y>& r) noexcept;
|
||||
`
|
||||
|
||||
[1](#assign-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4993)
|
||||
|
||||
*Effects*: Equivalent to weak_ptr(r).swap(*this)[.](#assign-1.sentence-1)
|
||||
|
||||
[2](#assign-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4997)
|
||||
|
||||
*Returns*: *this[.](#assign-2.sentence-1)
|
||||
|
||||
[3](#assign-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5001)
|
||||
|
||||
*Remarks*: The implementation may meet the effects (and the
|
||||
implied guarantees) via different means, without creating a temporary object[.](#assign-3.sentence-1)
|
||||
|
||||
[ð](#lib:operator=,weak_ptr_)
|
||||
|
||||
`constexpr weak_ptr& operator=(weak_ptr&& r) noexcept;
|
||||
template<class Y> constexpr weak_ptr& operator=(weak_ptr<Y>&& r) noexcept;
|
||||
`
|
||||
|
||||
[4](#assign-4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5014)
|
||||
|
||||
*Effects*: Equivalent to weak_ptr(std::move(r)).swap(*this)[.](#assign-4.sentence-1)
|
||||
|
||||
[5](#assign-5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5018)
|
||||
|
||||
*Returns*: *this[.](#assign-5.sentence-1)
|
||||
|
||||
#### [20.3.2.3.5](#mod) Modifiers [[util.smartptr.weak.mod]](util.smartptr.weak.mod)
|
||||
|
||||
[ð](#lib:swap,weak_ptr)
|
||||
|
||||
`constexpr void swap(weak_ptr& r) noexcept;
|
||||
`
|
||||
|
||||
[1](#mod-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5030)
|
||||
|
||||
*Effects*: Exchanges the contents of *this and r[.](#mod-1.sentence-1)
|
||||
|
||||
[ð](#lib:reset,weak_ptr)
|
||||
|
||||
`constexpr void reset() noexcept;
|
||||
`
|
||||
|
||||
[2](#mod-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5041)
|
||||
|
||||
*Effects*: Equivalent to weak_ptr().swap(*this)[.](#mod-2.sentence-1)
|
||||
|
||||
#### [20.3.2.3.6](#obs) Observers [[util.smartptr.weak.obs]](util.smartptr.weak.obs)
|
||||
|
||||
[ð](#lib:use_count,weak_ptr)
|
||||
|
||||
`constexpr long use_count() const noexcept;
|
||||
`
|
||||
|
||||
[1](#obs-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5053)
|
||||
|
||||
*Returns*: 0 if *this is empty;
|
||||
otherwise, the number of shared_ptr instances
|
||||
that share ownership with *this[.](#obs-1.sentence-1)
|
||||
|
||||
[ð](#lib:expired,weak_ptr)
|
||||
|
||||
`constexpr bool expired() const noexcept;
|
||||
`
|
||||
|
||||
[2](#obs-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5066)
|
||||
|
||||
*Returns*: use_count() == 0[.](#obs-2.sentence-1)
|
||||
|
||||
[ð](#lib:lock,weak_ptr)
|
||||
|
||||
`constexpr shared_ptr<T> lock() const noexcept;
|
||||
`
|
||||
|
||||
[3](#obs-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5077)
|
||||
|
||||
*Returns*: expired() ? shared_ptr<T>() : shared_ptr<T>(*this), executed atomically[.](#obs-3.sentence-1)
|
||||
|
||||
[ð](#lib:owner_before,weak_ptr)
|
||||
|
||||
`template<class U> constexpr bool owner_before(const shared_ptr<U>& b) const noexcept;
|
||||
template<class U> constexpr bool owner_before(const weak_ptr<U>& b) const noexcept;
|
||||
`
|
||||
|
||||
[4](#obs-4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5089)
|
||||
|
||||
*Returns*: An unspecified value such that
|
||||
|
||||
- [(4.1)](#obs-4.1)
|
||||
|
||||
owner_before(b) defines a strict weak ordering as defined in [[alg.sorting]](alg.sorting "26.8 Sorting and related operations");
|
||||
|
||||
- [(4.2)](#obs-4.2)
|
||||
|
||||
!owner_before(b) && !b.owner_before(*this) is true if and only if owner_equal(b) is true[.](#obs-4.sentence-1)
|
||||
|
||||
[ð](#lib:owner_hash,weak_ptr)
|
||||
|
||||
`size_t owner_hash() const noexcept;
|
||||
`
|
||||
|
||||
[5](#obs-5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5106)
|
||||
|
||||
*Returns*: An unspecified value such that,
|
||||
for any object x where owner_equal(x) is true,owner_hash() == x.owner_hash() is true[.](#obs-5.sentence-1)
|
||||
|
||||
[ð](#lib:owner_equal,weak_ptr)
|
||||
|
||||
`template<class U>
|
||||
constexpr bool owner_equal(const shared_ptr<U>& b) const noexcept;
|
||||
template<class U>
|
||||
constexpr bool owner_equal(const weak_ptr<U>& b) const noexcept;
|
||||
`
|
||||
|
||||
[6](#obs-6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5122)
|
||||
|
||||
*Returns*: true if and only if*this and b share ownership or are both empty[.](#obs-6.sentence-1)
|
||||
|
||||
Otherwise returns false[.](#obs-6.sentence-2)
|
||||
|
||||
[7](#obs-7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5128)
|
||||
|
||||
*Remarks*: owner_equal is an equivalence relation[.](#obs-7.sentence-1)
|
||||
|
||||
#### [20.3.2.3.7](#spec) Specialized algorithms [[util.smartptr.weak.spec]](util.smartptr.weak.spec)
|
||||
|
||||
[ð](#lib:swap,weak_ptr_)
|
||||
|
||||
`template<class T>
|
||||
constexpr void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept;
|
||||
`
|
||||
|
||||
[1](#spec-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5142)
|
||||
|
||||
*Effects*: Equivalent to a.swap(b)[.](#spec-1.sentence-1)
|
||||
55
cppdraft/util/smartptr/weak/assign.md
Normal file
55
cppdraft/util/smartptr/weak/assign.md
Normal file
@@ -0,0 +1,55 @@
|
||||
[util.smartptr.weak.assign]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.3 Smart pointers [[smartptr]](smartptr#util.smartptr.weak.assign)
|
||||
|
||||
### 20.3.2 Shared-ownership pointers [[util.sharedptr]](util.sharedptr#util.smartptr.weak.assign)
|
||||
|
||||
#### 20.3.2.3 Class template weak_ptr [[util.smartptr.weak]](util.smartptr.weak#assign)
|
||||
|
||||
#### 20.3.2.3.4 Assignment [util.smartptr.weak.assign]
|
||||
|
||||
[ð](#lib:operator=,weak_ptr)
|
||||
|
||||
`constexpr weak_ptr& operator=(const weak_ptr& r) noexcept;
|
||||
template<class Y> constexpr weak_ptr& operator=(const weak_ptr<Y>& r) noexcept;
|
||||
template<class Y> constexpr weak_ptr& operator=(const shared_ptr<Y>& r) noexcept;
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4993)
|
||||
|
||||
*Effects*: Equivalent to weak_ptr(r).swap(*this)[.](#1.sentence-1)
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4997)
|
||||
|
||||
*Returns*: *this[.](#2.sentence-1)
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5001)
|
||||
|
||||
*Remarks*: The implementation may meet the effects (and the
|
||||
implied guarantees) via different means, without creating a temporary object[.](#3.sentence-1)
|
||||
|
||||
[ð](#lib:operator=,weak_ptr_)
|
||||
|
||||
`constexpr weak_ptr& operator=(weak_ptr&& r) noexcept;
|
||||
template<class Y> constexpr weak_ptr& operator=(weak_ptr<Y>&& r) noexcept;
|
||||
`
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5014)
|
||||
|
||||
*Effects*: Equivalent to weak_ptr(std::move(r)).swap(*this)[.](#4.sentence-1)
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5018)
|
||||
|
||||
*Returns*: *this[.](#5.sentence-1)
|
||||
30
cppdraft/util/smartptr/weak/bad.md
Normal file
30
cppdraft/util/smartptr/weak/bad.md
Normal file
@@ -0,0 +1,30 @@
|
||||
[util.smartptr.weak.bad]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.3 Smart pointers [[smartptr]](smartptr#util.smartptr.weak.bad)
|
||||
|
||||
### 20.3.2 Shared-ownership pointers [[util.sharedptr]](util.sharedptr#util.smartptr.weak.bad)
|
||||
|
||||
#### 20.3.2.1 Class bad_weak_ptr [util.smartptr.weak.bad]
|
||||
|
||||
[ð](#lib:bad_weak_ptr)
|
||||
|
||||
namespace std {class bad_weak_ptr : public exception {public:// see [[exception]](exception "17.9.3 Class exception") for the specification of the special member functionsconstexpr const char* what() const noexcept override; };}
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3468)
|
||||
|
||||
An exception of type bad_weak_ptr is thrown by the shared_ptr constructor taking a weak_ptr[.](#1.sentence-1)
|
||||
|
||||
[ð](#lib:what,bad_weak_ptr)
|
||||
|
||||
`constexpr const char* what() const noexcept override;
|
||||
`
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3478)
|
||||
|
||||
*Returns*: An implementation-defined ntbs[.](#2.sentence-1)
|
||||
83
cppdraft/util/smartptr/weak/const.md
Normal file
83
cppdraft/util/smartptr/weak/const.md
Normal file
@@ -0,0 +1,83 @@
|
||||
[util.smartptr.weak.const]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.3 Smart pointers [[smartptr]](smartptr#util.smartptr.weak.const)
|
||||
|
||||
### 20.3.2 Shared-ownership pointers [[util.sharedptr]](util.sharedptr#util.smartptr.weak.const)
|
||||
|
||||
#### 20.3.2.3 Class template weak_ptr [[util.smartptr.weak]](util.smartptr.weak#const)
|
||||
|
||||
#### 20.3.2.3.2 Constructors [util.smartptr.weak.const]
|
||||
|
||||
[ð](#lib:weak_ptr,constructor)
|
||||
|
||||
`constexpr weak_ptr() noexcept;
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4914)
|
||||
|
||||
*Effects*: Constructs an empty weak_ptr object that stores a null pointer value[.](#1.sentence-1)
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4918)
|
||||
|
||||
*Postconditions*: use_count() == 0[.](#2.sentence-1)
|
||||
|
||||
[ð](#lib:weak_ptr,constructor_)
|
||||
|
||||
`constexpr weak_ptr(const weak_ptr& r) noexcept;
|
||||
template<class Y> constexpr weak_ptr(const weak_ptr<Y>& r) noexcept;
|
||||
template<class Y> constexpr weak_ptr(const shared_ptr<Y>& r) noexcept;
|
||||
`
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4931)
|
||||
|
||||
*Constraints*: For the second and third constructors, Y* is compatible with T*[.](#3.sentence-1)
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4935)
|
||||
|
||||
*Effects*: If r is empty, constructs
|
||||
an empty weak_ptr object that stores a null pointer value;
|
||||
otherwise, constructs
|
||||
a weak_ptr object that shares ownership
|
||||
with r and stores a copy of the pointer stored in r[.](#4.sentence-1)
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4943)
|
||||
|
||||
*Postconditions*: use_count() == r.use_count()[.](#5.sentence-1)
|
||||
|
||||
[ð](#lib:weak_ptr,constructor__)
|
||||
|
||||
`constexpr weak_ptr(weak_ptr&& r) noexcept;
|
||||
template<class Y> constexpr weak_ptr(weak_ptr<Y>&& r) noexcept;
|
||||
`
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4955)
|
||||
|
||||
*Constraints*: For the second constructor, Y* is compatible with T*[.](#6.sentence-1)
|
||||
|
||||
[7](#7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4959)
|
||||
|
||||
*Effects*: Move constructs a weak_ptr instance from r[.](#7.sentence-1)
|
||||
|
||||
[8](#8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4963)
|
||||
|
||||
*Postconditions*: *this contains the old value of r[.](#8.sentence-1)
|
||||
|
||||
r is empty, stores a null pointer value, and r.use_count() == 0[.](#8.sentence-2)
|
||||
23
cppdraft/util/smartptr/weak/dest.md
Normal file
23
cppdraft/util/smartptr/weak/dest.md
Normal file
@@ -0,0 +1,23 @@
|
||||
[util.smartptr.weak.dest]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.3 Smart pointers [[smartptr]](smartptr#util.smartptr.weak.dest)
|
||||
|
||||
### 20.3.2 Shared-ownership pointers [[util.sharedptr]](util.sharedptr#util.smartptr.weak.dest)
|
||||
|
||||
#### 20.3.2.3 Class template weak_ptr [[util.smartptr.weak]](util.smartptr.weak#dest)
|
||||
|
||||
#### 20.3.2.3.3 Destructor [util.smartptr.weak.dest]
|
||||
|
||||
[ð](#lib:weak_ptr,destructor)
|
||||
|
||||
`constexpr ~weak_ptr();
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4977)
|
||||
|
||||
*Effects*: Destroys this weak_ptr object but has no
|
||||
effect on the object its stored pointer points to[.](#1.sentence-1)
|
||||
34
cppdraft/util/smartptr/weak/general.md
Normal file
34
cppdraft/util/smartptr/weak/general.md
Normal file
@@ -0,0 +1,34 @@
|
||||
[util.smartptr.weak.general]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.3 Smart pointers [[smartptr]](smartptr#util.smartptr.weak.general)
|
||||
|
||||
### 20.3.2 Shared-ownership pointers [[util.sharedptr]](util.sharedptr#util.smartptr.weak.general)
|
||||
|
||||
#### 20.3.2.3 Class template weak_ptr [[util.smartptr.weak]](util.smartptr.weak#general)
|
||||
|
||||
#### 20.3.2.3.1 General [util.smartptr.weak.general]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4839)
|
||||
|
||||
The weak_ptr class template stores a weak reference to an object
|
||||
that is already managed by a shared_ptr[.](#1.sentence-1)
|
||||
|
||||
To access the object, aweak_ptr can be converted to a shared_ptr using the member
|
||||
function lock[.](#1.sentence-2)
|
||||
|
||||
namespace std {template<class T> class weak_ptr {public:using element_type = remove_extent_t<T>; // [[util.smartptr.weak.const]](util.smartptr.weak.const "20.3.2.3.2 Constructors"), constructorsconstexpr weak_ptr() noexcept; template<class Y>constexpr weak_ptr(const shared_ptr<Y>& r) noexcept; constexpr weak_ptr(const weak_ptr& r) noexcept; template<class Y>constexpr weak_ptr(const weak_ptr<Y>& r) noexcept; constexpr weak_ptr(weak_ptr&& r) noexcept; template<class Y>constexpr weak_ptr(weak_ptr<Y>&& r) noexcept; // [[util.smartptr.weak.dest]](util.smartptr.weak.dest "20.3.2.3.3 Destructor"), destructorconstexpr ~weak_ptr(); // [[util.smartptr.weak.assign]](util.smartptr.weak.assign "20.3.2.3.4 Assignment"), assignmentconstexpr weak_ptr& operator=(const weak_ptr& r) noexcept; template<class Y>constexpr weak_ptr& operator=(const weak_ptr<Y>& r) noexcept; template<class Y>constexpr weak_ptr& operator=(const shared_ptr<Y>& r) noexcept; constexpr weak_ptr& operator=(weak_ptr&& r) noexcept; template<class Y>constexpr weak_ptr& operator=(weak_ptr<Y>&& r) noexcept; // [[util.smartptr.weak.mod]](util.smartptr.weak.mod "20.3.2.3.5 Modifiers"), modifiersconstexpr void swap(weak_ptr& r) noexcept; constexpr void reset() noexcept; // [[util.smartptr.weak.obs]](util.smartptr.weak.obs "20.3.2.3.6 Observers"), observersconstexpr long use_count() const noexcept; constexpr bool expired() const noexcept; constexpr shared_ptr<T> lock() const noexcept; template<class U>constexpr bool owner_before(const shared_ptr<U>& b) const noexcept; template<class U>constexpr bool owner_before(const weak_ptr<U>& b) const noexcept;
|
||||
size_t owner_hash() const noexcept; template<class U>constexpr bool owner_equal(const shared_ptr<U>& b) const noexcept; template<class U>constexpr bool owner_equal(const weak_ptr<U>& b) const noexcept; }; template<class T> weak_ptr(shared_ptr<T>) -> weak_ptr<T>;}
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4900)
|
||||
|
||||
Specializations of weak_ptr shall be [*Cpp17CopyConstructible*](utility.arg.requirements#:Cpp17CopyConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") and[*Cpp17CopyAssignable*](utility.arg.requirements#:Cpp17CopyAssignable "16.4.4.2 Template argument requirements [utility.arg.requirements]"), allowing their use in standard
|
||||
containers[.](#2.sentence-1)
|
||||
|
||||
The template parameter T of weak_ptr may be an
|
||||
incomplete type[.](#2.sentence-2)
|
||||
33
cppdraft/util/smartptr/weak/mod.md
Normal file
33
cppdraft/util/smartptr/weak/mod.md
Normal file
@@ -0,0 +1,33 @@
|
||||
[util.smartptr.weak.mod]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.3 Smart pointers [[smartptr]](smartptr#util.smartptr.weak.mod)
|
||||
|
||||
### 20.3.2 Shared-ownership pointers [[util.sharedptr]](util.sharedptr#util.smartptr.weak.mod)
|
||||
|
||||
#### 20.3.2.3 Class template weak_ptr [[util.smartptr.weak]](util.smartptr.weak#mod)
|
||||
|
||||
#### 20.3.2.3.5 Modifiers [util.smartptr.weak.mod]
|
||||
|
||||
[ð](#lib:swap,weak_ptr)
|
||||
|
||||
`constexpr void swap(weak_ptr& r) noexcept;
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5030)
|
||||
|
||||
*Effects*: Exchanges the contents of *this and r[.](#1.sentence-1)
|
||||
|
||||
[ð](#lib:reset,weak_ptr)
|
||||
|
||||
`constexpr void reset() noexcept;
|
||||
`
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5041)
|
||||
|
||||
*Effects*: Equivalent to weak_ptr().swap(*this)[.](#2.sentence-1)
|
||||
100
cppdraft/util/smartptr/weak/obs.md
Normal file
100
cppdraft/util/smartptr/weak/obs.md
Normal file
@@ -0,0 +1,100 @@
|
||||
[util.smartptr.weak.obs]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.3 Smart pointers [[smartptr]](smartptr#util.smartptr.weak.obs)
|
||||
|
||||
### 20.3.2 Shared-ownership pointers [[util.sharedptr]](util.sharedptr#util.smartptr.weak.obs)
|
||||
|
||||
#### 20.3.2.3 Class template weak_ptr [[util.smartptr.weak]](util.smartptr.weak#obs)
|
||||
|
||||
#### 20.3.2.3.6 Observers [util.smartptr.weak.obs]
|
||||
|
||||
[ð](#lib:use_count,weak_ptr)
|
||||
|
||||
`constexpr long use_count() const noexcept;
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5053)
|
||||
|
||||
*Returns*: 0 if *this is empty;
|
||||
otherwise, the number of shared_ptr instances
|
||||
that share ownership with *this[.](#1.sentence-1)
|
||||
|
||||
[ð](#lib:expired,weak_ptr)
|
||||
|
||||
`constexpr bool expired() const noexcept;
|
||||
`
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5066)
|
||||
|
||||
*Returns*: use_count() == 0[.](#2.sentence-1)
|
||||
|
||||
[ð](#lib:lock,weak_ptr)
|
||||
|
||||
`constexpr shared_ptr<T> lock() const noexcept;
|
||||
`
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5077)
|
||||
|
||||
*Returns*: expired() ? shared_ptr<T>() : shared_ptr<T>(*this), executed atomically[.](#3.sentence-1)
|
||||
|
||||
[ð](#lib:owner_before,weak_ptr)
|
||||
|
||||
`template<class U> constexpr bool owner_before(const shared_ptr<U>& b) const noexcept;
|
||||
template<class U> constexpr bool owner_before(const weak_ptr<U>& b) const noexcept;
|
||||
`
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5089)
|
||||
|
||||
*Returns*: An unspecified value such that
|
||||
|
||||
- [(4.1)](#4.1)
|
||||
|
||||
owner_before(b) defines a strict weak ordering as defined in [[alg.sorting]](alg.sorting "26.8 Sorting and related operations");
|
||||
|
||||
- [(4.2)](#4.2)
|
||||
|
||||
!owner_before(b) && !b.owner_before(*this) is true if and only if owner_equal(b) is true[.](#4.sentence-1)
|
||||
|
||||
[ð](#lib:owner_hash,weak_ptr)
|
||||
|
||||
`size_t owner_hash() const noexcept;
|
||||
`
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5106)
|
||||
|
||||
*Returns*: An unspecified value such that,
|
||||
for any object x where owner_equal(x) is true,owner_hash() == x.owner_hash() is true[.](#5.sentence-1)
|
||||
|
||||
[ð](#lib:owner_equal,weak_ptr)
|
||||
|
||||
`template<class U>
|
||||
constexpr bool owner_equal(const shared_ptr<U>& b) const noexcept;
|
||||
template<class U>
|
||||
constexpr bool owner_equal(const weak_ptr<U>& b) const noexcept;
|
||||
`
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5122)
|
||||
|
||||
*Returns*: true if and only if*this and b share ownership or are both empty[.](#6.sentence-1)
|
||||
|
||||
Otherwise returns false[.](#6.sentence-2)
|
||||
|
||||
[7](#7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5128)
|
||||
|
||||
*Remarks*: owner_equal is an equivalence relation[.](#7.sentence-1)
|
||||
23
cppdraft/util/smartptr/weak/spec.md
Normal file
23
cppdraft/util/smartptr/weak/spec.md
Normal file
@@ -0,0 +1,23 @@
|
||||
[util.smartptr.weak.spec]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.3 Smart pointers [[smartptr]](smartptr#util.smartptr.weak.spec)
|
||||
|
||||
### 20.3.2 Shared-ownership pointers [[util.sharedptr]](util.sharedptr#util.smartptr.weak.spec)
|
||||
|
||||
#### 20.3.2.3 Class template weak_ptr [[util.smartptr.weak]](util.smartptr.weak#spec)
|
||||
|
||||
#### 20.3.2.3.7 Specialized algorithms [util.smartptr.weak.spec]
|
||||
|
||||
[ð](#lib:swap,weak_ptr)
|
||||
|
||||
`template<class T>
|
||||
constexpr void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept;
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5142)
|
||||
|
||||
*Effects*: Equivalent to a.swap(b)[.](#1.sentence-1)
|
||||
Reference in New Issue
Block a user