make_shared and allocate_shared
for arraysIntroduction
Synopsis
Free Functions
Example
History
Originally the Boost function templates make_shared and
allocate_shared were for efficient allocation of single
objects only. There was a need to have efficient, single, allocation of
arrays. One criticism of shared_array was
always the lack of a make_shared utility
which ensures only a single allocation for an array.
The header files <boost/smart_ptr/make_shared_array.hpp> and
<boost/smart_ptr/allocate_shared_array.hpp> provide new function
templates, make_shared and allocate_shared,
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<typename T>
shared_ptr<T[]> make_shared(size_t size);
template<typename T, typename A>
shared_ptr<T[]> allocate_shared(const A& allocator, size_t size);
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template<typename T, typename... Args>
shared_ptr<T[]> make_shared(size_t size, Args&&... args);
template<typename T, typename... Args>
shared_ptr<T[N]> make_shared(Args&&... args);
template<typename T, typename A, typename... Args>
shared_ptr<T[]> allocate_shared(const A& allocator, size_t size, Args&&... args);
template<typename T, typename A, typename... Args>
shared_ptr<T[N]> allocate_shared(const A& allocator, Args&&... args);
#endif
#if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX)
template<typename T, typename... Args>
shared_ptr<T[N]> make_shared(const T (&list)[N]);
template<typename T, typename... Args>
shared_ptr<T[][N]> make_shared(size_t size, const T (&list)[N]);
template<typename T, typename... Args>
shared_ptr<T[M][N]> make_shared(const T (&list)[N]);
template<typename T, typename A, typename... Args>
shared_ptr<T[N]> allocate_shared(const A& allocator, const T (&list)[N]);
template<typename T, typename A, typename... Args>
shared_ptr<T[][N]> allocate_shared(const A& allocator, size_t size, const T (&list)[N]);
template<typename T, typename A, typename... Args>
shared_ptr<T[M][N]> allocate_shared(const A& allocator, const T (&list)[N]);
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
template<typename T, typename... Args>
shared_ptr<T[]> make_shared(initializer_list<T> list);
template<typename T, typename A, typename... Args>
shared_ptr<T[]> allocate_shared(const A& allocator, initializer_list<T> list);
#endif
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template<typename T>
shared_ptr<T[]> make_shared(size_t size, T&& value);
template<typename T>
shared_ptr<T[N]> make_shared(T&& value);
template<typename T, typename A>
shared_ptr<T[]> allocate_shared(const A& allocator, size_t size, T&& value);
template<typename T, typename A>
shared_ptr<T[N]> allocate_shared(const A& allocator, T&& value);
#endif
#endif
template<typename T>
shared_ptr<T[]> make_shared_noinit(size_t size);
template<typename T>
shared_ptr<T[N]> make_shared_noinit();
template<typename T, typename A>
shared_ptr<T[]> allocate_shared_noinit(const A& allocator, size_t size);
template<typename T, typename A>
shared_ptr<T[N]> allocate_shared_noinit(const A& allocator);
}
template<typename T, typename... Args>
shared_ptr<T[]> make_shared(size_t size, Args&&... args);
template<typename T, typename A, typename... Args>
shared_ptr<T[]> allocate_shared(const A& allocator, size_t size, Args&&... args);
Requires: The expression
new(pointer) T(forward<Args>(args)...), wherepointeris avoid*pointing to storage suitable to hold an object of typeT, shall be well-formed.Ashall be an Allocator, as described in section 20.1.5 (Allocator requirements) of the C++ Standard. The copy constructor and destructor ofAshall not throw.Effects: Allocates memory suitable for an array of type
Tand sizesizeand constructs an array of objects in it via the placement new expressionnew(pointer) T()ornew(pointer) T(forward<Args>(args)...).allocate_shareduses a copy ofallocatorto allocate memory. If an exception is thrown, has no effect.Returns: A
shared_ptrinstance that stores and owns the address of the newly constructed array of typeTand sizesize.Postconditions:
get() != 0 && use_count() == 1.Throws:
bad_alloc, or an exception thrown fromA::allocateor the constructor ofT.Notes: This implementation allocates the memory required for the returned
shared_ptrand an array of typeTof sizesizein a single allocation. This provides efficiency to equivalent to an intrusive smart array pointer.The prototypes shown above are used if your compiler supports r-value references and variadic templates. They perfectly forward the
argsparameters to the constructors ofTfor each array element.Otherwise, you can use the overloads which take only the array size (and the allocator in case of
allocate_shared) and do not take any constructor arguments. These overloads invoke the default constructor ofTfor each array element.
template<typename T, typename... Args>
shared_ptr<T[N]> make_shared(Args&&... args);
template<typename T, typename A, typename... Args>
shared_ptr<T[N]> allocate_shared(const A& allocator, Args&&... args);
Description: These overloads of the utilities above are for a fixed size array.
template<typename T, typename... Args>
shared_ptr<T[]> make_shared(initializer_list<T> list);
template<typename T, typename A, typename... Args>
shared_ptr<T[]> allocate_shared(const A& allocator, initializer_list<T> list);
Description: These overloads initialize the array elements from the initializer list.
template<typename T, typename... Args>
shared_ptr<T[N]> make_shared(const T (&list)[N]);
template<typename T, typename A, typename... Args>
shared_ptr<T[N]> allocate_shared(const A& allocator, const T (&list)[N]);
Description: These overloads of the utilities above are for a fixed size array.
template<typename T, typename... Args>
shared_ptr<T[][N]> make_shared(size_t size, const T (&list)[N]);
template<typename T, typename A, typename... Args>
shared_ptr<T[][N]> allocate_shared(const A& allocator, size_t size, const T (&list)[N]);
Description: These overloads initialize inner array elements from the initializer list.
template<typename T, typename... Args>
shared_ptr<T[M][N]> make_shared(const T (&list)[N]);
template<typename T, typename A, typename... Args>
shared_ptr<T[M][N]> allocate_shared(const A& allocator, const T (&list)[N]);
Description: These overloads of the utilities above are for a fixed size array.
template<typename T>
shared_ptr<T[]> make_shared(size_t size, T&& value);
template<typename T, typename A>
shared_ptr<T[]> allocate_shared(const A& allocator, size_t size, T&& value);
Description: These overloads initialize array elements with the given value.
template<typename T>
shared_ptr<T[N]> make_shared(T&& value);
template<typename T, typename A>
shared_ptr<T[N]> allocate_shared(const A& allocator, T&& value);
Description: These overloads of the utilities above are for a fixed size array.
template<typename T>
shared_ptr<T[]> make_shared_noinit(size_t size);
template<typename T, typename A>
shared_ptr<T[]> allocate_shared_noinit(const A& allocator, size_t size);
Description: These overloads do not perform any value initialization of elements.
template<typename T>
shared_ptr<T[N]> make_shared_noinit();
template<typename T, typename A>
shared_ptr<T[N]> allocate_shared_noinit(const A& allocator);
Description: These overloads of the utilities above are for a fixed size array.
An example of each overload of make_shared for arrays:
boost::shared_ptr<point[]> a1 = boost::make_shared<point[]>(size);
boost::shared_ptr<point[]> a2 = boost::make_shared<point[]>(size, x, y);
boost::shared_ptr<point[5]> a3 = boost::make_shared<point[5]>(x, y);
boost::shared_ptr<int[]> a4 = boost::make_shared<int[]>({1, 2, 3});
boost::shared_ptr<int[3]> a5 = boost::make_shared<int[3]>({1, 2, 3});
boost::shared_ptr<int[][3]> a6 = boost::make_shared<int[][3]>(size, {1, 2, 3});
boost::shared_ptr<int[5][3]> a7 = boost::make_shared<int[5][3]>({1, 2, 3});
boost::shared_ptr<point[]> a8 = boost::make_shared<point[]>(size, {x, y});
boost::shared_ptr<point[5]> a9 = boost::make_shared<point[5]>({x, y});
boost::shared_ptr<int[]> a10 = boost::make_shared_noinit<int[]>(size);
boost::shared_ptr<int[5]> a11 = boost::make_shared_noinit<int[5]>();
November 2012. Glen Fernandes contributed implementations of make_shared and allocate_shared for arrays.
$Date: 2012-10-30 10:12:25 -0800 (Tue, 30 Oct 2012) $
Copyright 2012 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.