//// Copyright 2017 Peter Dimov Distributed under the Boost Software License, Version 1.0. See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt //// [[shared_array]] [appendix] # shared_array (deprecated) :toc: :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); ``` [none] * {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. 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); ``` [none] * {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 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; ``` [none] * {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 initial use count. Requires:: `T` is a complete type. ### Destructor ``` ~shared_array() noexcept; ``` [none] * {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 a value of 0 is harmless. ### Assignment ``` shared_array& operator=(const shared_array& v) noexcept; ``` [none] * {blank} + 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); ``` [none] * {blank} + 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); ``` [none] * {blank} + 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; ``` [none] * {blank} + Returns:: The stored pointer. ### unique ``` bool unique() const noexcept; ``` [none] * {blank} + Returns:: `true` if no other `shared_array` is sharing ownership of the stored pointer, `false` otherwise. ### use_count ``` long use_count() const noexcept; ``` [none] * {blank} + Returns:: The number of `shared_array` objects sharing ownership of the stored pointer. ### Conversions ``` explicit operator bool() const noexcept; ``` [none] * {blank} + Returns:: `get() != 0`. Requires:: `T` is a complete type. ### swap ``` void swap(shared_array& b) noexcept; ``` [none] * {blank} + 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; ``` [none] * {blank} + 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; ``` [none] * {blank} + Returns:: `a.swap(b)`. Requires:: `T` is a complete type.