From 61de342adc5b89b2c86d228b1cbb0adeb9fb6cdc Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Thu, 15 Jun 2017 08:16:50 -0400 Subject: [PATCH] Add deprecated shared_array documentation --- doc/smart_ptr/make_shared.adoc | 10 +- doc/smart_ptr/make_unique.adoc | 8 +- doc/smart_ptr/shared_array.adoc | 249 ++++++++++++++++++++++++++++++++ 3 files changed, 258 insertions(+), 9 deletions(-) diff --git a/doc/smart_ptr/make_shared.adoc b/doc/smart_ptr/make_shared.adoc index 3f69c72..5b4366c 100644 --- a/doc/smart_ptr/make_shared.adoc +++ b/doc/smart_ptr/make_shared.adoc @@ -133,16 +133,16 @@ of the object is initialized to the corresponding element from `v`. shall be interpreted to mean that each array element of the object is value-initialized. * When a (sub)object of non-array type `U` is specified to be initialized to -a value `v`, or constructed from `args$$...$$`, `make_shared` shall perform +a value `v`, or constructed from `args\...`, `make_shared` shall perform this initialization via the expression `::new(p) U(expr)` (where -`_expr_` is `v` or `std::forward(args)$$...$$)` respectively) and `p` +`_expr_` is `v` or `std::forward(args)\...)` respectively) and `p` has type `void*` and points to storage suitable to hold an object of type `U`. * When a (sub)object of non-array type `U` is specified to be initialized to -a value `v`, or constructed from `args$$...$$`, `allocate_shared` shall +a value `v`, or constructed from `args\...`, `allocate_shared` shall perform this initialization via the expression `std::allocator_traits::construct(a2, p, expr)` (where -`_expr_` is `v` or `std::forward(args)$$...$$)` respectively), `p` +`_expr_` is `v` or `std::forward(args)\...)` respectively), `p` points to storage suitable to hold an object of type `U`, and `a2` of type `A2` is a rebound copy `a` such that its `value_type` is `U`. * When a (sub)object of non-array type `U` is specified to be @@ -183,7 +183,7 @@ template Remarks::: These overloads shall only participate in overload resolution when `T` is not an array type. Returns::: A `shared_ptr` to an object of type `T`, constructed from -`args$$...$$`. +`args\...`. Examples::: * `auto p = make_shared();` * `auto p = make_shared >(16, 1);` diff --git a/doc/smart_ptr/make_unique.adoc b/doc/smart_ptr/make_unique.adoc index f3c413c..b4e94bf 100644 --- a/doc/smart_ptr/make_unique.adoc +++ b/doc/smart_ptr/make_unique.adoc @@ -21,16 +21,16 @@ create `std::unique_ptr` objects. ## Rationale -The C$$++$$11 standard introduced `std::unique_ptr` but did not provide any +The {cpp}11 standard introduced `std::unique_ptr` but did not provide any `make_unique` utility like `std::make_shared` that provided the same exception safety and facility to avoid writing `new` expressions. Before it -was implemented by some standard library vendors (and prior to the C$$++$$14 +was implemented by some standard library vendors (and prior to the {cpp}14 standard introducing `std::make_unique`), this library provided it due to requests from users. This library also provides additional overloads of `make_unique` for default-initialization, when users do not need or want to incur the expense -of value-initialization. The C$$++$$ standard does not yet provide this +of value-initialization. The {cpp} standard does not yet provide this feature with `std::make_unique`. ## Synopsis @@ -71,7 +71,7 @@ template :: Remarks::: These overloads shall only participate in overload resolution when `T` is not an array type. -Returns::: `std::unique_ptr(new T(std::forward(args)$$...$$)`. +Returns::: `std::unique_ptr(new T(std::forward(args)\...)`. Example::: `auto p = make_unique();` ``` diff --git a/doc/smart_ptr/shared_array.adoc b/doc/smart_ptr/shared_array.adoc index aa2933f..e1da95c 100644 --- a/doc/smart_ptr/shared_array.adoc +++ b/doc/smart_ptr/shared_array.adoc @@ -14,3 +14,252 @@ http://www.boost.org/LICENSE_1_0.txt :toc-title: :idprefix: shared_array_ +NOTE: This facility is deprecated because a `shared_ptr` to `T[]` or `T[N]` +is now available, and is superior in every regard. + +## Description + +The `shared_array` class template stores a pointer to a dynamically allocated +array. (Dynamically allocated array are allocated with the C++ `new[]` +expression.) The object pointed to is guaranteed to be deleted when the last +`shared_array` pointing to it is destroyed or reset. + +Every `shared_array` meets the _CopyConstructible_ and _Assignable_ +requirements of the {cpp} Standard Library, and so can be used in standard +library containers. Comparison operators are supplied so that shared_array +works with the standard library's associative containers. + +Normally, a `shared_array` cannot correctly hold a pointer to an object that +has been allocated with the non-array form of `new`. See `shared_ptr` for that +usage. + +Because the implementation uses reference counting, cycles of `shared_array` +instances will not be reclaimed. For example, if `main` holds a shared_array +to `A`, which directly or indirectly holds a shared_array back to `A`, the use +count of `A` will be 2. Destruction of the original `shared_array` will leave +`A` dangling with a use count of 1. + +A `shared_ptr` to a `std::vector` is an alternative to a `shared_array` that +is a bit heavier duty but far more flexible. + +The class template is parameterized on `T`, the type of the object pointed to. +`shared_array` and most of its member functions place no requirements on `T`; +it is allowed to be an incomplete type, or `void`. Member functions that do +place additional requirements (constructors, reset) are explicitly documented +below. + +## Synopsis + +``` +namespace boost { + template class shared_array { + public: + typedef T element_type; + + explicit shared_array(T* p = 0); + template shared_array(T* p, D d); + shared_array(const shared_array& v) noexcept; + + ~shared_array() noexcept; + + shared_array& operator=(const shared_array& v) noexcept; + + void reset(T* p = 0); + template void reset(T* p, D d); + + T& operator[](std::ptrdiff_t n) const noexcept; + T* get() const noexcept; + + bool unique() const noexcept; + long use_count() const noexcept; + + explicit operator bool() const noexcept; + + void swap(shared_array& v) noexcept; + }; + + template bool + operator==(const shared_array& a, const shared_array& b) noexcept; + template bool + operator!=(const shared_array& a, const shared_array& b) noexcept; + template bool + operator<(const shared_array& a, const shared_array& b) noexcept; + + template + void swap(shared_array& a, shared_array& b) noexcept; +} +``` + +## Members + +### element_type + +``` +typedef T element_type; +``` +Type:: Provides the type of the stored pointer. + +### Constructors + +``` +explicit shared_array(T* p = 0); +``` +:: +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. +Afterwards, the use count is 1 (even if `p == 0`; see `~shared_array`). +Requires::: `T` is a complete type. +Throws::: `std::bad_alloc`. If an exception is thrown, `delete[] p` is called. + +``` +template shared_array(T* p, D d); +``` +:: +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 +pointed to by `p`, the object `d` is used in the statement `d(p)`. +Requires::: +* `T` is a complete type. +* The copy constructor and destructor of `D` 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. + +``` +shared_array(const shared_array& v) noexcept; +``` +:: +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 +initial use count. +Requires::: `T` is a complete type. + +### Destructor + +``` +~shared_array() noexcept; +``` +:: +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 +a value of 0 is harmless. + +### Assignment + +``` +shared_array& operator=(const shared_array& v) noexcept; +``` +:: +Effects::: Constructs a new `shared_array` as described above, then replaces +this `shared_array` with the new one, destroying the replaced object. +Requires::: `T` is a complete type. +Returns::: `*this`. + +### reset + +``` +void reset(T* p = 0); +``` +:: +Effects::: Constructs a new `shared_array` as described above, then replaces +this `shared_array` with the new one, destroying the replaced object. +Requires::: `T` is a complete type. +Throws::: `std::bad_alloc`. If an exception is thrown, `delete[] p` is called. + +``` +template void reset(T* p, D d); +``` +:: +Effects::: Constructs a new `shared_array` as described above, then replaces +this `shared_array` with the new one, destroying the replaced object. +Requires::: +* `T` is a complete type. +* The copy constructor of `D` must not throw. +Throws::: `std::bad_alloc`. If an exception is thrown, `d(p)` is called. + +### Indexing + +``` +T& operator[](std::ptrdiff_t n) const noexcept; +``` +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 is 0, or if `n` is less than 0 or is greater than or equal to the +number of elements in the array. +Requires::: `T` is a complete type. + +### get + +``` +T* get() const noexcept; +``` +:: +Returns::: The stored pointer. + +### unique + +``` +bool unique() const noexcept; +``` +:: +Returns::: `true` if no other `shared_array` is sharing ownership of the +stored pointer, `false` otherwise. + +### use_count + +``` +long use_count() const noexcept; +``` +:: +Returns::: The number of `shared_array` objects sharing ownership of the +stored pointer. + +### Conversions + +``` +explicit operator bool() const noexcept; +``` +:: +Returns::: `get() != 0`. +Requires::: `T` is a complete type. + +### swap + +``` +void swap(shared_array& b) noexcept; +``` +:: +Effects::: Exchanges the contents of the two smart pointers. + +## Free Functions + +### Comparison + +``` +template bool + operator==(const shared_array& a, const shared_array& b) noexcept; +template bool + operator!=(const shared_array& a, const shared_array& b) noexcept; +template bool + operator<(const shared_array& a, const shared_array& b) noexcept; +``` +:: +Returns::: The result of comparing the stored pointers of the two smart +pointers. + +NOTE: The `operator<` overload is provided to define an ordering so that +`shared_array` objects can be used in associative containers such as +`std::map`. The implementation uses `std::less` to perform the comparison. +This ensures that the comparison is handled correctly, since the standard +mandates that relational operations on pointers are unspecified (5.9 +[expr.rel] paragraph 2) but `std::less` on pointers is well-defined (20.3.3 +[lib.comparisons] paragraph 8). + +### swap + +``` +template + void swap(shared_array& a, shared_array& b) noexcept; +``` +:: +Returns::: `a.swap(b)` +Requires::: `T` is a complete type. \ No newline at end of file