Introduction
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:
U
is of the formT[]
orT[N]
.A
shall be an Allocator, as described in section 17.6.3.5 [Allocator requirements] of the C++ Standard. The copy constructor and destructor ofA
shall not throw exceptions.Effects: Allocates memory for an object of type
U
(orT[size]
whenU
isT[]
, wheresize
is determined fromargs
as specified by the concrete overload). The object is initialized as specified by the concrete overload. The templatesallocate_shared
andallocate_shared_noinit
use a copy ofallocator
to allocate memory. If an exception is thrown, the functions have no effect.Returns: A
shared_ptr
instance that stores and owns the address of the newly constructed object.Postconditions:
r.get() != 0 && r.use_count() == 1
, wherer
is 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
T
is 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
T
is specified to be initialized to a valuevalue
,make_shared
shall perform this initialization via the expression::new(ptr) T(value)
, whereptr
has typevoid*
and points to storage suitable to hold an object of typeT
.When a subobject of non-array type
T
is specified to be initialized to a valuevalue
,allocate_shared
shall perform this initialization via the expressionallocator_traits<A2>::construct(a2, ptr, value)
, whereptr
points to storage suitable to hold an object of typeT
anda2
of type A2 is a rebound copy of the allocatorallocator
passed toallocate_shared
such that itsvalue_type
isT
.When a subobject of non-array type
T
is specified to be value-initialized,make_shared
shall perform this initialization via the expression::new(ptr) T()
, or::new(ptr) T(hdl)
, where ptr has typevoid*
and points to storage suitable to hold an object of typeT
, andhdl
is an instace ofshared_handle
.When a subobject of non-array type
T
is specified to be value-initialized,allocate_shared
shall perform this initialization via the expressionallocator_traits<A2>::construct(a2, ptr)
or,allocator_traits<A2>::construct(a2, hdl, ptr)
whereptr
points to storage suitable to hold an object of typeT
anda2
of type A2 is a rebound copy of the allocatorallocator
passed toallocate_shared
such that itsvalue_type
isT
.When a subobject of non-array type
T
is specified to be default-initialized,make_shared_noinit
andallocate_shared_noinit
shall perform this initialization via the expression::new(ptr) T
, whereptr
has 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_ptr
to a value-initialized object of typeT[size]
.Remarks: These overloads shall only participate in overload resolution when
U
is 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_ptr
to a value-initialized object of typeT[N]
.Remarks: These overloads shall only participate in overload resolution when
U
is 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_ptr
to an object of typeT[size]
, where each array element of typeT
is initialized tovalue
.Remarks: These overloads shall only participate in overload resolution when
U
is 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_ptr
to an object of typeT[N]
, where each array element of typeT
is initialized tovalue
.Remarks: These overloads shall only participate in overload resolution when
U
is 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_ptr
to a default-initialized object of typeT[size]
.Remarks: These overloads shall only participate in overload resolution when
U
is 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_ptr
to a default-initialized object of typeT[N]
.Remarks: These overloads shall only participate in overload resolution when
U
is 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.