make_shared and allocate_shared
for arraysIntroduction
Synopsis
Common Requirements
Free Functions
History
References
Originally the Boost function templates make_shared and
allocate_shared were for efficient allocation of shared
objects only. There was a need to have efficient allocation of
shared arrays. One criticism of class template shared_array
was always the lack of a make_shared
utility which ensures only a single allocation.
The header files <boost/smart_ptr/make_shared_array.hpp> and
<boost/smart_ptr/allocate_shared_array.hpp> provide function
templates, overloads of make_shared and
allocate_shared for array types, to address this need.
make_shared uses the global operator new to
allocate memory, whereas allocate_shared uses an
user-supplied allocator, allowing finer control.
namespace boost {
template<class U> // U is T[]
shared_ptr<U> make_shared(size_t size);
template<class U, class A> // U is T[]
shared_ptr<U> allocate_shared(const A& allocator, size_t size);
template<class U> // U is T[N]
shared_ptr<U> make_shared();
template<class U, class A> // U is T[N]
shared_ptr<U> allocate_shared(const A& allocator);
template<class U> // U is T[]
shared_ptr<U> make_shared(size_t size, const T& value);
template<class U, class A> // U is T[]
shared_ptr<U> allocate_shared(const A& allocator, size_t size, const T& value);
template<class U> // U is T[N]
shared_ptr<U> make_shared(const T& value);
template<class U, class A> // U is T[N]
shared_ptr<U> allocate_shared(const A& allocator, const T& value);
template<class U> // U is T[]
shared_ptr<U> make_shared_noinit(size_t size);
template<class U, class A> // U is T[]
shared_ptr<U> allocate_shared_noinit(const A& allocator, size_t size);
template<class U> // U is T[N]
shared_ptr<U> make_shared_noinit();
template<class U, class A> // U is T[N]
shared_ptr<U> allocate_shared_noinit(const A& allocator);
}
template<class U>
shared_ptr<U> make_shared(args);
template<class U, class A>
shared_ptr<U> allocate_shared(const A& allocator, args);
template<class U>
shared_ptr<U> make_shared_noinit(args);
template<class U, class A>
shared_ptr<U> allocate_shared_noinit(const A& allocator, args);
Requires:
Uis of the formT[]orT[N].Ashall be an Allocator, as described in section 17.6.3.5 [Allocator requirements] of the C++ Standard. The copy constructor and destructor ofAshall not throw exceptions.Effects: Allocates memory for an object of type
U(orT[size]whenUisT[], wheresizeis determined fromargsas specified by the concrete overload). The object is initialized as specified by the concrete overload. The templatesallocate_sharedandallocate_shared_noinituse a copy ofallocatorto allocate memory. If an exception is thrown, the functions have no effect.Returns: A
shared_ptrinstance that stores and owns the address of the newly constructed object.Postconditions:
r.get() != 0 && r.use_count() == 1, whereris the return value.Throws:
bad_alloc, an exception thrown fromA::allocate, or from the initialization of the object.Remarks:
This implementation performs no more than one memory allocation. This provides efficiency to equivalent to an intrusive smart pointer.
When an object of an array type
Tis specified to be initialized to a value of the same typevalue, this shall be interpreted to mean that each array element of the object is initialized to the corresponding element fromvalue.When an object of an array type is specified to be value-initialized, this shall be interpreted to mean that each array element of the object is value-initialized.
Array elements are initialized in ascending order of their addresses.
When a subobject of a non-array type
Tis specified to be initialized to a valuevalue,make_sharedshall perform this initialization via the expression::new(ptr) T(value), whereptrhas typevoid*and points to storage suitable to hold an object of typeT.When a subobject of non-array type
Tis specified to be initialized to a valuevalue,allocate_sharedshall perform this initialization via the expressionallocator_traits<A2>::construct(a2, ptr, value), whereptrpoints to storage suitable to hold an object of typeTanda2of type A2 is a rebound copy of the allocatorallocatorpassed toallocate_sharedsuch that itsvalue_typeisT.When a subobject of non-array type
Tis specified to be value-initialized,make_sharedshall perform this initialization via the expression::new(ptr) T(), whereptrhas typevoid*and points to storage suitable to hold an object of typeT.When a subobject of non-array type
Tis specified to be value-initialized,allocate_sharedshall perform this initialization via the expressionallocator_traits<A2>::construct(a2, ptr), whereptrpoints to storage suitable to hold an object of typeTanda2of type A2 is a rebound copy of the allocatorallocatorpassed toallocate_sharedsuch that itsvalue_typeisT.When a subobject of non-array type
Tis specified to be default-initialized,make_shared_noinitandallocate_shared_noinitshall perform this initialization via the expression::new(ptr) T, whereptrhas typevoid*and points to storage suitable to hold an object of typeT.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 should be destroyed in the reverse order of their construction.
Notes: These functions will typically allocate more memory than
sizeof(U)to allow for internal bookkeeping structures such as the reference counts.
template<class U>
shared_ptr<U> make_shared(size_t size);
template<class U, class A>
shared_ptr<U> allocate_shared(const A& allocator, size_t size);
Returns: A
shared_ptrto a value-initialized object of typeT[size].Remarks: These overloads shall only participate in overload resolution when
Uis of the formT[].Examples:
boost::shared_ptr<int[]> a1 = boost::make_shared<int[]>(size); boost::shared_ptr<int[][2]> a2 = boost::make_shared<int[][2]>(size);
template<class U>
shared_ptr<U> make_shared();
template<class U, class A>
shared_ptr<U> allocate_shared(const A& allocator);
Returns: A
shared_ptrto a value-initialized object of typeT[N].Remarks: These overloads shall only participate in overload resolution when
Uis of the formT[N].Examples:
boost::shared_ptr<int[8]> a1 = boost::make_shared<int[8]>(); boost::shared_ptr<int[4][2]> a2 = boost::make_shared<int[4][2]>();
template<class U>
shared_ptr<U> make_shared(size_t size, const T& value);
template<class U, class A>
shared_ptr<U> allocate_shared(const A& allocator, size_t size, const T& value);
Returns: A
shared_ptrto an object of typeT[size], where each array element of typeTis initialized tovalue.Remarks: These overloads shall only participate in overload resolution when
Uis of the formT[].Examples:
boost::shared_ptr<int[]> a1 = boost::make_shared<int[]>(size, 1); boost::shared_ptr<int[][2]> a2 = boost::make_shared<int[][2]>(size, {1, 2});
template<class U>
shared_ptr<U> make_shared(const T& value);
template<class U, class A>
shared_ptr<U> allocate_shared(const A& allocator, const T& value);
Returns: A
shared_ptrto an object of typeT[N], where each array element of typeTis initialized tovalue.Remarks: These overloads shall only participate in overload resolution when
Uis of the formT[N].Examples:
boost::shared_ptr<int[8]> a1 = boost::make_shared<int[8]>(1); boost::shared_ptr<int[4][2]> a2 = boost::make_shared<int[4][2]>({1, 2});
template<class U>
shared_ptr<U> make_shared_noinit(size_t size);
template<class U, class A>
shared_ptr<U> allocate_shared_noinit(const A& allocator, size_t size);
Returns: A
shared_ptrto a default-initialized object of typeT[size].Remarks: These overloads shall only participate in overload resolution when
Uis of the formT[].Examples:
boost::shared_ptr<int[]> a1 = boost::make_shared_noinit<int[]>(size); boost::shared_ptr<int[][2]> a2 = boost::make_shared_noinit<int[][2]>(size);
template<class U>
shared_ptr<U> make_shared_noinit();
template<class U, class A>
shared_ptr<U> allocate_shared_noinit(const A& allocator);
Returns: A
shared_ptrto a default-initialized object of typeT[N].Remarks: These overloads shall only participate in overload resolution when
Uis of the formT[N].Examples:
boost::shared_ptr<int[8]> a1 = boost::make_shared_noinit<int[8]>(); boost::shared_ptr<int[4][2]> a2 = boost::make_shared_noinit<int[4][2]>();
February 2014. Glen Fernandes updated overloads of make_shared and allocate_shared to conform to the specification in C++ standard paper N3870, including resolving C++ standard library defect report 2070, and reduced the spatial overhead of the internal bookkeeping structures.
November 2012. Glen Fernandes contributed implementations of make_shared and allocate_shared for arrays.
N3870, Extending make_shared to Support Arrays, Revision 1, Peter Dimov & Glen Fernandes, January, 2014.
$Date$
Copyright 2012-2014 Glen Fernandes. 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.