Merge branch 'develop' of https://github.com/boostorg/smart_ptr into develop

This commit is contained in:
Peter Dimov
2019-03-25 19:25:44 +02:00
6 changed files with 220 additions and 141 deletions

View File

@ -78,12 +78,13 @@ namespace boost {
``` ```
intrusive_ref_counter() noexcept; intrusive_ref_counter() noexcept;
``` ```
::
``` ```
intrusive_ref_counter(const intrusive_ref_counter&) noexcept; intrusive_ref_counter(const intrusive_ref_counter&) noexcept;
``` ```
:: [none]
Postconditions::: `use_count() == 0`. * {blank}
+
Postconditions:: `use_count() == 0`.
NOTE: The pointer to the constructed object is expected to be passed to NOTE: The pointer to the constructed object is expected to be passed to
`intrusive_ptr` constructor, assignment operator or `reset` method, which `intrusive_ptr` constructor, assignment operator or `reset` method, which
@ -94,8 +95,10 @@ would increment the reference counter.
``` ```
~intrusive_ref_counter(); ~intrusive_ref_counter();
``` ```
:: [none]
Effects::: Destroys the counter object. * {blank}
+
Effects:: Destroys the counter object.
NOTE: The destructor is protected so that the object can only be destroyed NOTE: The destructor is protected so that the object can only be destroyed
through the `Derived` class. through the `Derived` class.
@ -105,16 +108,20 @@ through the `Derived` class.
``` ```
intrusive_ref_counter& operator=(const intrusive_ref_counter& v) noexcept; intrusive_ref_counter& operator=(const intrusive_ref_counter& v) noexcept;
``` ```
:: [none]
Effects::: Does nothing, reference counter is not modified. * {blank}
+
Effects:: Does nothing, reference counter is not modified.
### use_count ### use_count
``` ```
unsigned int use_count() const noexcept; unsigned int use_count() const noexcept;
``` ```
:: [none]
Returns::: The current value of the reference counter. * {blank}
+
Returns:: The current value of the reference counter.
NOTE: The returned value may not be actual in multi-threaded applications. NOTE: The returned value may not be actual in multi-threaded applications.
@ -127,8 +134,10 @@ template<class Derived, class CounterPolicy>
void intrusive_ptr_add_ref( void intrusive_ptr_add_ref(
const intrusive_ref_counter<Derived, CounterPolicy>* p) noexcept; const intrusive_ref_counter<Derived, CounterPolicy>* p) noexcept;
``` ```
:: [none]
Effects::: Increments the reference counter. * {blank}
+
Effects:: Increments the reference counter.
### intrusive_ptr_release ### intrusive_ptr_release
@ -137,6 +146,8 @@ template<class Derived, class CounterPolicy>
void intrusive_ptr_release( void intrusive_ptr_release(
const intrusive_ref_counter<Derived, CounterPolicy>* p) noexcept; const intrusive_ref_counter<Derived, CounterPolicy>* p) noexcept;
``` ```
:: [none]
Effects::: Decrements the reference counter. If the reference counter reaches * {blank}
+
Effects:: Decrements the reference counter. If the reference counter reaches
0, calls `delete static_cast<const Derived*>(p)`. 0, calls `delete static_cast<const Derived*>(p)`.

View File

@ -716,4 +716,3 @@ template<class D, class T>
* {blank} * {blank}
+ +
Returns:: If `*this` owns a `shared_ptr` instance `p`, `get_deleter<D>( p )`, otherwise 0. Returns:: If `*this` owns a `shared_ptr` instance `p`, `get_deleter<D>( p )`, otherwise 0.

View File

@ -174,17 +174,18 @@ the reference counts.
template<class T, class... Args> template<class T, class... Args>
shared_ptr<T> make_shared(Args&&... args); shared_ptr<T> make_shared(Args&&... args);
``` ```
::
``` ```
template<class T, class A, class... Args> template<class T, class A, class... Args>
shared_ptr<T> allocate_shared(const A& a, Args&&... args); shared_ptr<T> allocate_shared(const A& a, Args&&... args);
``` ```
:: [none]
Remarks::: These overloads shall only participate in overload resolution when * {blank}
+
Remarks:: These overloads shall only participate in overload resolution when
`T` is not an array type. `T` is not an array type.
Returns::: A `shared_ptr` to an object of type `T`, constructed from Returns:: A `shared_ptr` to an object of type `T`, constructed from
`args\...`. `args\...`.
Examples::: Examples::
* `auto p = make_shared<int>();` * `auto p = make_shared<int>();`
* `auto p = make_shared<std::vector<int> >(16, 1);` * `auto p = make_shared<std::vector<int> >(16, 1);`
@ -192,17 +193,18 @@ Examples:::
template<class T> template<class T>
shared_ptr<T> make_shared(std::size_t n); shared_ptr<T> make_shared(std::size_t n);
``` ```
::
``` ```
template<class T, class A> template<class T, class A>
shared_ptr<T> allocate_shared(const A& a, std::size_t n); shared_ptr<T> allocate_shared(const A& a, std::size_t n);
``` ```
:: [none]
Remarks::: These overloads shall only participate in overload resolution when * {blank}
+
Remarks:: These overloads shall only participate in overload resolution when
`T` is an array type of the form `U[]`. `T` is an array type of the form `U[]`.
Returns::: A `shared_ptr` to a sequence of `n` value-initialized objects of Returns:: A `shared_ptr` to a sequence of `n` value-initialized objects of
type `U`. type `U`.
Examples::: Examples::
* `auto p = make_shared<double[]>(1024);` * `auto p = make_shared<double[]>(1024);`
* `auto p = make_shared<double[][2][2]>(6);` * `auto p = make_shared<double[][2][2]>(6);`
@ -210,17 +212,18 @@ Examples:::
template<class T> template<class T>
shared_ptr<T> make_shared(); shared_ptr<T> make_shared();
``` ```
::
``` ```
template<class T, class A> template<class T, class A>
shared_ptr<T> allocate_shared(const A& a); shared_ptr<T> allocate_shared(const A& a);
``` ```
:: [none]
Remarks::: These overloads shall only participate in overload resolution when * {blank}
+
Remarks:: These overloads shall only participate in overload resolution when
`T` is an array type of the form `U[N]`. `T` is an array type of the form `U[N]`.
Returns::: A `shared_ptr` to a sequence of `N` value-initialized objects of Returns:: A `shared_ptr` to a sequence of `N` value-initialized objects of
type `U`. type `U`.
Examples::: Examples::
* `auto p = make_shared<double[1024]>();` * `auto p = make_shared<double[1024]>();`
* `auto p = make_shared<double[6][2][2]>();` * `auto p = make_shared<double[6][2][2]>();`
@ -228,17 +231,18 @@ Examples:::
template<class T> shared_ptr<T> template<class T> shared_ptr<T>
make_shared(std::size_t n, const remove_extent_t<T>& v); make_shared(std::size_t n, const remove_extent_t<T>& v);
``` ```
::
``` ```
template<class T, class A> shared_ptr<T> template<class T, class A> shared_ptr<T>
allocate_shared(const A& a, std::size_t n, const remove_extent_t<T>& v); allocate_shared(const A& a, std::size_t n, const remove_extent_t<T>& v);
``` ```
:: [none]
Remarks::: These overloads shall only participate in overload resolution when * {blank}
+
Remarks:: These overloads shall only participate in overload resolution when
`T` is an array type of the form `U[]`. `T` is an array type of the form `U[]`.
Returns::: A `shared_ptr` to a sequence of `n` objects of type `U`, each Returns:: A `shared_ptr` to a sequence of `n` objects of type `U`, each
initialized to `v`. initialized to `v`.
Examples::: Examples::
* `auto p = make_shared<double[]>(1024, 1.0);` * `auto p = make_shared<double[]>(1024, 1.0);`
* `auto p = make_shared<double[][2]>(6, {1.0, 0.0});` * `auto p = make_shared<double[][2]>(6, {1.0, 0.0});`
* `auto p = make_shared<std::vector<int>[]>(4, {1, 2});` * `auto p = make_shared<std::vector<int>[]>(4, {1, 2});`
@ -247,17 +251,18 @@ Examples:::
template<class T> template<class T>
shared_ptr<T> make_shared(const remove_extent_t<T>& v); shared_ptr<T> make_shared(const remove_extent_t<T>& v);
``` ```
::
``` ```
template<class T, class A> template<class T, class A>
shared_ptr<T> allocate_shared(const A& a, const remove_extent_t<T>& v); shared_ptr<T> allocate_shared(const A& a, const remove_extent_t<T>& v);
``` ```
:: [none]
Remarks::: These overloads shall only participate in overload resolution when * {blank}
+
Remarks:: These overloads shall only participate in overload resolution when
`T` is an array type of the form `U[N]`. `T` is an array type of the form `U[N]`.
Returns::: A `shared_ptr` to a sequence of `N` objects of type `U`, each Returns:: A `shared_ptr` to a sequence of `N` objects of type `U`, each
initialized to `v`. initialized to `v`.
Examples::: Examples::
* `auto p = make_shared<double[1024]>(1.0);` * `auto p = make_shared<double[1024]>(1.0);`
* `auto p = make_shared<double[6][2]>({1.0, 0.0});` * `auto p = make_shared<double[6][2]>({1.0, 0.0});`
* `auto p = make_shared<std::vector<int>[4]>({1, 2});` * `auto p = make_shared<std::vector<int>[4]>({1, 2});`
@ -266,30 +271,32 @@ Examples:::
template<class T> template<class T>
shared_ptr<T> make_shared_noinit(); shared_ptr<T> make_shared_noinit();
``` ```
::
``` ```
template<class T, class A> template<class T, class A>
shared_ptr<T> allocate_shared_noinit(const A& a); shared_ptr<T> allocate_shared_noinit(const A& a);
``` ```
:: [none]
Remarks::: These overloads shall only participate in overload resolution when * {blank}
+
Remarks:: These overloads shall only participate in overload resolution when
`T` is not an array type, or an array type of the `U[N]`. `T` is not an array type, or an array type of the `U[N]`.
Returns::: A `shared_ptr` to a default-initialized object of type `T`, or a Returns:: A `shared_ptr` to a default-initialized object of type `T`, or a
sequence of `N` default-initialized objects of type `U`, respectively. sequence of `N` default-initialized objects of type `U`, respectively.
Example::: `auto p = make_shared_noinit<double[1024]>();` Example:: `auto p = make_shared_noinit<double[1024]>();`
``` ```
template<class T> template<class T>
shared_ptr<T> make_shared_noinit(std::size_t n); shared_ptr<T> make_shared_noinit(std::size_t n);
``` ```
::
``` ```
template<class T, class A> template<class T, class A>
shared_ptr<T> allocate_shared_noinit(const A& a, std::size_t n); shared_ptr<T> allocate_shared_noinit(const A& a, std::size_t n);
``` ```
:: [none]
Remarks::: These overloads shall only participate in overload resolution when * {blank}
+
Remarks:: These overloads shall only participate in overload resolution when
`T` is an array type of the form `U[]`. `T` is an array type of the form `U[]`.
Returns::: A `shared_ptr` to a sequence of `_n_` default-initialized objects Returns:: A `shared_ptr` to a sequence of `_n_` default-initialized objects
of type `U`. of type `U`.
Example::: `auto p = make_shared_noinit<double[]>(1024);` Example:: `auto p = make_shared_noinit<double[]>(1024);`

View File

@ -68,48 +68,58 @@ namespace boost {
template<class T, class... Args> template<class T, class... Args>
std::unique_ptr<T> make_unique(Args&&... args); std::unique_ptr<T> make_unique(Args&&... args);
``` ```
:: [none]
Remarks::: These overloads shall only participate in overload resolution when * {blank}
+
Remarks:: These overloads shall only participate in overload resolution when
`T` is not an array type. `T` is not an array type.
Returns::: `std::unique_ptr<T>(new T(std::forward<Args>(args)\...)`. Returns:: `std::unique_ptr<T>(new T(std::forward<Args>(args)\...)`.
Example::: `auto p = make_unique<int>();` Example:: `auto p = make_unique<int>();`
``` ```
template<class T> template<class T>
std::unique_ptr<T> make_unique(remove_reference_t<T>&& v); std::unique_ptr<T> make_unique(remove_reference_t<T>&& v);
``` ```
:: [none]
Remarks::: These overloads shall only participate in overload resolution when * {blank}
+
Remarks:: These overloads shall only participate in overload resolution when
`T` is not an array type. `T` is not an array type.
Returns::: `std::unique_ptr<T>(new T(std::move(v))`. Returns:: `std::unique_ptr<T>(new T(std::move(v))`.
Example::: `auto p = make_unique<std::vector<int> >({1, 2});` Example:: `auto p = make_unique<std::vector<int> >({1, 2});`
``` ```
template<class T> template<class T>
std::unique_ptr<T> make_unique(std::size_t n); std::unique_ptr<T> make_unique(std::size_t n);
``` ```
:: [none]
Remarks::: These overloads shall only participate in overload resolution when * {blank}
+
Remarks:: These overloads shall only participate in overload resolution when
`T` is an array type of the form `U[]`. `T` is an array type of the form `U[]`.
Returns::: `std::unique_ptr<U[]>(new U[n]())`. Returns:: `std::unique_ptr<U[]>(new U[n]())`.
Example::: `auto p = make_unique<double[]>(1024);` Example:: `auto p = make_unique<double[]>(1024);`
``` ```
template<class T> template<class T>
std::unique_ptr<T> make_unique_noinit(); std::unique_ptr<T> make_unique_noinit();
``` ```
:: [none]
Remarks::: These overloads shall only participate in overload resolution when * {blank}
+
Remarks:: These overloads shall only participate in overload resolution when
`T` is not an array type. `T` is not an array type.
Returns::: `std::unique_ptr<T>(new T)`. Returns:: `std::unique_ptr<T>(new T)`.
Example::: `auto p = make_unique_noinit<double[1024]>();` Example:: `auto p = make_unique_noinit<double[1024]>();`
``` ```
template<class T> template<class T>
std::unique_ptr<T> make_unique_noinit(std::size_t n); std::unique_ptr<T> make_unique_noinit(std::size_t n);
``` ```
:: [none]
Remarks::: These overloads shall only participate in overload resolution when * {blank}
+
Remarks:: These overloads shall only participate in overload resolution when
`T` is an array type of the form `U[]`. `T` is an array type of the form `U[]`.
Returns::: `std::unique_ptr<U[]>(new U[n])`. Returns:: `std::unique_ptr<U[]>(new U[n])`.
Example::: `auto p = make_unique_noinit<double[]>(1024);` Example:: `auto p = make_unique_noinit<double[]>(1024);`

View File

@ -78,23 +78,29 @@ namespace boost {
``` ```
template<class T, class U> T* static_pointer_cast(U* p) noexcept; template<class T, class U> T* static_pointer_cast(U* p) noexcept;
``` ```
:: [none]
Returns::: `static_cast<T*>(p)` * {blank}
+
Returns:: `static_cast<T*>(p)`
``` ```
template<class T, class U> std::shared_ptr<T> template<class T, class U> std::shared_ptr<T>
static_pointer_cast(const std::shared_ptr<U>& p) noexcept; static_pointer_cast(const std::shared_ptr<U>& p) noexcept;
``` ```
:: [none]
Returns::: `std::static_pointer_cast<T>(p)` * {blank}
+
Returns:: `std::static_pointer_cast<T>(p)`
``` ```
template<class T, class U> std::unique_ptr<T> template<class T, class U> std::unique_ptr<T>
static_pointer_cast(std::unique_ptr<U>&& p) noexcept; static_pointer_cast(std::unique_ptr<U>&& p) noexcept;
``` ```
:: [none]
Requires::: The expression `static_cast<T*>((U*)0)` must be well-formed. * {blank}
Returns::: `std::unique_ptr<T>(static_cast<typename +
Requires:: The expression `static_cast<T*>((U*)0)` must be well-formed.
Returns:: `std::unique_ptr<T>(static_cast<typename
std::unique_ptr<T>::element_type*>(p.release()))`. std::unique_ptr<T>::element_type*>(p.release()))`.
CAUTION: The seemingly equivalent expression CAUTION: The seemingly equivalent expression
@ -106,25 +112,31 @@ undefined behavior, attempting to delete the same object twice.
``` ```
template<class T, class U> T* dynamic_pointer_cast(U* p) noexcept; template<class T, class U> T* dynamic_pointer_cast(U* p) noexcept;
``` ```
:: [none]
Returns::: `dynamic_cast<T*>(p)` * {blank}
+
Returns:: `dynamic_cast<T*>(p)`
``` ```
template<class T, class U> std::shared_ptr<T> template<class T, class U> std::shared_ptr<T>
dynamic_pointer_cast(const std::shared_ptr<U>& p) noexcept; dynamic_pointer_cast(const std::shared_ptr<U>& p) noexcept;
``` ```
:: [none]
Returns::: `std::dynamic_pointer_cast<T>(p)` * {blank}
+
Returns:: `std::dynamic_pointer_cast<T>(p)`
``` ```
template<class T, class U> std::unique_ptr<T> template<class T, class U> std::unique_ptr<T>
dynamic_pointer_cast(std::unique_ptr<U>&& p) noexcept; dynamic_pointer_cast(std::unique_ptr<U>&& p) noexcept;
``` ```
:: [none]
Requires::: * {blank}
+
Requires::
* The expression `static_cast<T*>((U*)0)` must be well-formed. * The expression `static_cast<T*>((U*)0)` must be well-formed.
* `T` must have a virtual destructor. * `T` must have a virtual destructor.
Returns::: Returns::
* When `dynamic_cast<typename std::unique_ptr<T>::element_type*>(p.get())` * When `dynamic_cast<typename std::unique_ptr<T>::element_type*>(p.get())`
returns a non-zero value, `std::unique_ptr<T>(dynamic_cast<typename returns a non-zero value, `std::unique_ptr<T>(dynamic_cast<typename
std::unique_ptr<T>::element_type*>(p.release()));`. std::unique_ptr<T>::element_type*>(p.release()));`.
@ -135,23 +147,29 @@ std::unique_ptr<T>::element_type*>(p.release()));`.
``` ```
template<class T, class U> T* const_pointer_cast(U* p) noexcept; template<class T, class U> T* const_pointer_cast(U* p) noexcept;
``` ```
:: [none]
Returns::: `const_cast<T*>(p)` * {blank}
+
Returns:: `const_cast<T*>(p)`
``` ```
template<class T, class U> std::shared_ptr<T> template<class T, class U> std::shared_ptr<T>
const_pointer_cast(const std::shared_ptr<U>& p) noexcept; const_pointer_cast(const std::shared_ptr<U>& p) noexcept;
``` ```
:: [none]
Returns::: `std::const_pointer_cast<T>(p)` * {blank}
+
Returns:: `std::const_pointer_cast<T>(p)`
``` ```
template<class T, class U> std::unique_ptr<T> template<class T, class U> std::unique_ptr<T>
const_pointer_cast(std::unique_ptr<U>&& p) noexcept; const_pointer_cast(std::unique_ptr<U>&& p) noexcept;
``` ```
:: [none]
Requires::: The expression `const_cast<T*>((U*)0)` must be well-formed. * {blank}
Returns::: `std::unique_ptr<T>(const_cast<typename +
Requires:: The expression `const_cast<T*>((U*)0)` must be well-formed.
Returns:: `std::unique_ptr<T>(const_cast<typename
std::unique_ptr<T>::element_type*>(p.release()))`. std::unique_ptr<T>::element_type*>(p.release()))`.
### reinterpret_pointer_cast ### reinterpret_pointer_cast
@ -159,23 +177,29 @@ std::unique_ptr<T>::element_type*>(p.release()))`.
``` ```
template<class T, class U> T* reinterpret_pointer_cast(U* p) noexcept; template<class T, class U> T* reinterpret_pointer_cast(U* p) noexcept;
``` ```
:: [none]
Returns::: `reinterpret_cast<T*>(p)` * {blank}
+
Returns:: `reinterpret_cast<T*>(p)`
``` ```
template<class T, class U> std::shared_ptr<T> template<class T, class U> std::shared_ptr<T>
reinterpret_pointer_cast(const std::shared_ptr<U>& p) noexcept; reinterpret_pointer_cast(const std::shared_ptr<U>& p) noexcept;
``` ```
:: [none]
Returns::: `std::reinterpret_pointer_cast<T>(p)` * {blank}
+
Returns:: `std::reinterpret_pointer_cast<T>(p)`
``` ```
template<class T, class U> std::unique_ptr<T> template<class T, class U> std::unique_ptr<T>
reinterpret_pointer_cast(std::unique_ptr<U>&& p) noexcept; reinterpret_pointer_cast(std::unique_ptr<U>&& p) noexcept;
``` ```
:: [none]
Requires::: The expression `reinterpret_cast<T*>((U*)0)` must be well-formed. * {blank}
Returns::: `std::unique_ptr<T>(reinterpret_cast<typename +
Requires:: The expression `reinterpret_cast<T*>((U*)0)` must be well-formed.
Returns:: `std::unique_ptr<T>(reinterpret_cast<typename
std::unique_ptr<T>::element_type*>(p.release()))`. std::unique_ptr<T>::element_type*>(p.release()))`.
## Example ## Example
@ -210,4 +234,4 @@ int main()
delete ptr; delete ptr;
} }
``` ```

View File

@ -105,42 +105,50 @@ Type:: Provides the type of the stored pointer.
``` ```
explicit shared_array(T* p = 0); explicit shared_array(T* p = 0);
``` ```
:: [none]
Effects::: Constructs a `shared_array`, storing a copy of `p`, which must be a * {blank}
+
Effects:: Constructs a `shared_array`, storing a copy of `p`, which must be a
pointer to an array that was allocated via a C++ `new[]` expression or be 0. pointer to an array that was allocated via a C++ `new[]` expression or be 0.
Afterwards, the use count is 1 (even if `p == 0`; see `~shared_array`). Afterwards, the use count is 1 (even if `p == 0`; see `~shared_array`).
Requires::: `T` is a complete type. Requires:: `T` is a complete type.
Throws::: `std::bad_alloc`. If an exception is thrown, `delete[] p` is called. Throws:: `std::bad_alloc`. If an exception is thrown, `delete[] p` is called.
``` ```
template<class D> shared_array(T* p, D d); template<class D> shared_array(T* p, D d);
``` ```
:: [none]
Effects::: Constructs a `shared_array`, storing a copy of `p` and of `d`. * {blank}
+
Effects:: Constructs a `shared_array`, storing a copy of `p` and of `d`.
Afterwards, the use count is 1. When the the time comes to delete the array Afterwards, the use count is 1. When the the time comes to delete the array
pointed to by `p`, the object `d` is used in the statement `d(p)`. pointed to by `p`, the object `d` is used in the statement `d(p)`.
Requires::: Requires::
* `T` is a complete type. * `T` is a complete type.
* The copy constructor and destructor of `D` must not throw. * The copy constructor and destructor of `D` must not throw.
* Invoking the object `d` with parameter `p` must not throw. * Invoking the object `d` with parameter `p` must not throw.
Throws::: `std::bad_alloc`. If an exception is thrown, `d(p)` is called. Throws:: `std::bad_alloc`. If an exception is thrown, `d(p)` is called.
``` ```
shared_array(const shared_array& v) noexcept; shared_array(const shared_array& v) noexcept;
``` ```
:: [none]
Effects::: Constructs a `shared_array`, as if by storing a copy of the pointer * {blank}
+
Effects:: Constructs a `shared_array`, as if by storing a copy of the pointer
stored in `v`. Afterwards, the use count for all copies is 1 more than the stored in `v`. Afterwards, the use count for all copies is 1 more than the
initial use count. initial use count.
Requires::: `T` is a complete type. Requires:: `T` is a complete type.
### Destructor ### Destructor
``` ```
~shared_array() noexcept; ~shared_array() noexcept;
``` ```
:: [none]
Effects::: Decrements the use count. Then, if the use count is 0, deletes the * {blank}
+
Effects:: Decrements the use count. Then, if the use count is 0, deletes the
array pointed to by the stored pointer. Note that `delete[]` on a pointer with array pointed to by the stored pointer. Note that `delete[]` on a pointer with
a value of 0 is harmless. a value of 0 is harmless.
@ -149,60 +157,70 @@ a value of 0 is harmless.
``` ```
shared_array& operator=(const shared_array& v) noexcept; shared_array& operator=(const shared_array& v) noexcept;
``` ```
:: [none]
Effects::: Constructs a new `shared_array` as described above, then replaces * {blank}
+
Effects:: Constructs a new `shared_array` as described above, then replaces
this `shared_array` with the new one, destroying the replaced object. this `shared_array` with the new one, destroying the replaced object.
Requires::: `T` is a complete type. Requires:: `T` is a complete type.
Returns::: `*this`. Returns:: `*this`.
### reset ### reset
``` ```
void reset(T* p = 0); void reset(T* p = 0);
``` ```
:: [none]
Effects::: Constructs a new `shared_array` as described above, then replaces * {blank}
+
Effects:: Constructs a new `shared_array` as described above, then replaces
this `shared_array` with the new one, destroying the replaced object. this `shared_array` with the new one, destroying the replaced object.
Requires::: `T` is a complete type. Requires:: `T` is a complete type.
Throws::: `std::bad_alloc`. If an exception is thrown, `delete[] p` is called. Throws:: `std::bad_alloc`. If an exception is thrown, `delete[] p` is called.
``` ```
template<class D> void reset(T* p, D d); template<class D> void reset(T* p, D d);
``` ```
:: [none]
Effects::: Constructs a new `shared_array` as described above, then replaces * {blank}
+
Effects:: Constructs a new `shared_array` as described above, then replaces
this `shared_array` with the new one, destroying the replaced object. this `shared_array` with the new one, destroying the replaced object.
Requires::: Requires::
* `T` is a complete type. * `T` is a complete type.
* The copy constructor of `D` must not throw. * The copy constructor of `D` must not throw.
Throws::: `std::bad_alloc`. If an exception is thrown, `d(p)` is called. Throws:: `std::bad_alloc`. If an exception is thrown, `d(p)` is called.
### Indexing ### Indexing
``` ```
T& operator[](std::ptrdiff_t n) const noexcept; T& operator[](std::ptrdiff_t n) const noexcept;
``` ```
Returns::: A reference to element `n` of the array pointed to by the stored Returns:: A reference to element `n` of the array pointed to by the stored
pointer. Behavior is undefined and almost certainly undesirable if the stored pointer. Behavior is undefined and almost certainly undesirable if the stored
pointer is 0, or if `n` is less than 0 or is greater than or equal to the pointer is 0, or if `n` is less than 0 or is greater than or equal to the
number of elements in the array. number of elements in the array.
Requires::: `T` is a complete type. Requires:: `T` is a complete type.
### get ### get
``` ```
T* get() const noexcept; T* get() const noexcept;
``` ```
:: [none]
Returns::: The stored pointer. * {blank}
+
Returns:: The stored pointer.
### unique ### unique
``` ```
bool unique() const noexcept; bool unique() const noexcept;
``` ```
:: [none]
Returns::: `true` if no other `shared_array` is sharing ownership of the * {blank}
+
Returns:: `true` if no other `shared_array` is sharing ownership of the
stored pointer, `false` otherwise. stored pointer, `false` otherwise.
### use_count ### use_count
@ -210,8 +228,10 @@ stored pointer, `false` otherwise.
``` ```
long use_count() const noexcept; long use_count() const noexcept;
``` ```
:: [none]
Returns::: The number of `shared_array` objects sharing ownership of the * {blank}
+
Returns:: The number of `shared_array` objects sharing ownership of the
stored pointer. stored pointer.
### Conversions ### Conversions
@ -219,17 +239,21 @@ stored pointer.
``` ```
explicit operator bool() const noexcept; explicit operator bool() const noexcept;
``` ```
:: [none]
Returns::: `get() != 0`. * {blank}
Requires::: `T` is a complete type. +
Returns:: `get() != 0`.
Requires:: `T` is a complete type.
### swap ### swap
``` ```
void swap(shared_array<T>& b) noexcept; void swap(shared_array<T>& b) noexcept;
``` ```
:: [none]
Effects::: Exchanges the contents of the two smart pointers. * {blank}
+
Effects:: Exchanges the contents of the two smart pointers.
## Free Functions ## Free Functions
@ -247,8 +271,10 @@ template<class T> bool
template<class T> bool template<class T> bool
operator<(const shared_array<T>& a, const shared_array<T>& b) noexcept; operator<(const shared_array<T>& a, const shared_array<T>& b) noexcept;
``` ```
:: [none]
Returns::: The result of comparing the stored pointers of the two smart * {blank}
+
Returns:: The result of comparing the stored pointers of the two smart
pointers. pointers.
NOTE: The `operator<` overload is provided to define an ordering so that NOTE: The `operator<` overload is provided to define an ordering so that
@ -265,6 +291,8 @@ mandates that relational operations on pointers are unspecified (5.9
template<class T> template<class T>
void swap(shared_array<T>& a, shared_array<T>& b) noexcept; void swap(shared_array<T>& a, shared_array<T>& b) noexcept;
``` ```
:: [none]
Returns::: `a.swap(b)`. * {blank}
Requires::: `T` is a complete type. +
Returns:: `a.swap(b)`.
Requires:: `T` is a complete type.