diff --git a/make_shared_array.html b/make_shared_array.html index ebfaeda..7059e05 100644 --- a/make_shared_array.html +++ b/make_shared_array.html @@ -5,8 +5,8 @@ -

boost.png (6897 bytes)make_shared and allocate_shared +

boost.png (6897 bytes)make_shared and allocate_shared for arrays

Introduction
Synopsis
@@ -15,18 +15,18 @@ History
References

Introduction

-

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 +

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 +

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.

Synopsis

namespace boost {
@@ -68,205 +68,210 @@
 }

Common Requirements

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);
+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 form T[] or - T[N]. A shall be an Allocator, as - described in section 17.6.3.5 [Allocator - requirements] of the C++ Standard. The copy constructor and +

Requires: U is of the form T[] or + T[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 of A shall not throw exceptions.

-

Effects: Allocates memory for an object of type U - (or T[size] when U is T[], - where size is determined from args - as specified by the concrete overload). The object is initialized as - specified by the concrete overload. The templates +

Effects: Allocates memory for an object of type U + (or T[size] when U is T[], + where size is determined from args + as specified by the concrete overload). The object is initialized as + specified by the concrete overload. The templates allocate_shared and allocate_shared_noinit - use a copy of allocator to allocate memory. If an + use a copy of allocator to allocate memory. If an exception is thrown, the functions have no effect.

-

Returns: A shared_ptr instance that stores and +

Returns: A shared_ptr instance that stores and owns the address of the newly constructed object.

-

Postconditions: r.get() != 0 && - r.use_count() == 1, where r is the return +

Postconditions: r.get() != 0 && + r.use_count() == 1, where r is the return value.

-

Throws: bad_alloc, an exception thrown from - A::allocate, or from the initialization of the +

Throws: bad_alloc, an exception thrown from + A::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 +

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 type value, this - shall be interpreted to mean that each array element of the object - is initialized to the corresponding element from +

When an object of an array type T is specified to be + initialized to a value of the same type value, this + shall be interpreted to mean that each array element of the object + is initialized to the corresponding element from value.

-

When an object of an array type is specified to be - value-initialized, this shall be interpreted to mean that each +

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 +

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 value value, - make_shared shall perform this initialization via the - expression ::new(ptr) T(value), where ptr - has type void* and points to storage suitable to hold +

When a subobject of a non-array type T is specified to + be initialized to a value value, + make_shared shall perform this initialization via the + expression ::new(ptr) T(value), where ptr + has type void* and points to storage suitable to hold an object of type T.

-

When a subobject of non-array type T is specified to - be initialized to a value value, - allocate_shared shall perform this initialization via - the expression allocator_traits<A2>::construct(a2, ptr, - value), where ptr points to storage suitable to - hold an object of type T and a2 of type A2 +

When a subobject of non-array type T is specified to + be initialized to a value value, + allocate_shared shall perform this initialization via + the expression allocator_traits<A2>::construct(a2, ptr, + value), where ptr points to storage suitable to + hold an object of type T and a2 of type A2 is a rebound copy of the allocator allocator passed to - allocate_shared such that its value_type + allocate_shared such that its value_type is T.

-

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(), where - ptr has type void* and points to storage +

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(), where + ptr has type void* and points to storage suitable to hold an object of type T.

-

When a subobject of non-array type T is specified to - be value-initialized, allocate_shared shall perform +

When a subobject of non-array type T is specified to + be value-initialized, allocate_shared shall perform this initialization via the expression - allocator_traits<A2>::construct(a2, ptr), where - ptr points to storage suitable to hold an object - of type T and a2 of type A2 is a rebound + allocator_traits<A2>::construct(a2, ptr), where + ptr points to storage suitable to hold an object + of type T and a2 of type A2 is a rebound copy of the allocator allocator passed to - allocate_shared such that its value_type + allocate_shared such that its value_type is T.

-

When a subobject of non-array type T is specified to - be default-initialized, make_shared_noinit and - allocate_shared_noinit shall perform this - initialization via the expression ::new(ptr) T, where - ptr has type void* and points to storage +

When a subobject of non-array type T is specified to + be default-initialized, make_shared_noinit and + allocate_shared_noinit shall perform this + initialization via the expression ::new(ptr) T, where + ptr has type void* and points to storage suitable to hold an object of type T.

-

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 +

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 +

Notes: These functions will typically allocate more memory + than sizeof(U) to allow for internal bookkeeping structures such as the reference counts.

Free Functions

-
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);
+
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 +

Returns: A shared_ptr to a value-initialized object of type T[size].

-

Remarks: These overloads shall only participate in overload - resolution when U is of the form T[].

+

Remarks: These overloads shall only participate in overload + resolution when U is of the form T[].

Examples:

-
boost::shared_ptr<int[]> a1 = boost::make_shared<int[]>(size);
-boost::shared_ptr<int[][2]> a2 = boost::make_shared<int[][2]>(size);
+
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);
+
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 +

Returns: A shared_ptr to a value-initialized object of type T[N].

-

Remarks: These overloads shall only participate in overload +

Remarks: These overloads shall only participate in overload resolution when U is of the form T[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]>();
+
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);
+
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 type - T[size], where each array element of type T +

Returns: A shared_ptr to an object of type + T[size], where each array element of type T is initialized to value.

-

Remarks: These overloads shall only participate in overload +

Remarks: These overloads shall only participate in overload resolution when U is of the form T[].

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});
+
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);
+
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 type - T[N], where each array element of type T is +

Returns: A shared_ptr to an object of type + T[N], where each array element of type T is initialized to value.

-

Remarks: These overloads shall only participate in overload +

Remarks: These overloads shall only participate in overload resolution when U is of the form T[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});
+
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);
+
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 +

Returns: A shared_ptr to a default-initialized object of type T[size].

-

Remarks: These overloads shall only participate in overload +

Remarks: These overloads shall only participate in overload resolution when U is of the form T[].

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);
+
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);
+
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 +

Returns: A shared_ptr to a default-initialized object of type T[N].

-

Remarks: These overloads shall only participate in overload +

Remarks: These overloads shall only participate in overload resolution when U is of the form T[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]>();
+
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]>();

History

-

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 +

February 2017. Glen Fernandes rewrote allocate_shared and make_shared + for a more optimal and more maintainable implementation.

+

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 DR2070.

+

November 2012. Glen Fernandes contributed implementations of make_shared and allocate_shared for arrays.

References

N3870, - Extending make_shared to Support Arrays, Revision 1, Peter Dimov + Extending make_shared to Support Arrays, Revision 1, Peter Dimov & Glen Fernandes, January, 2014.

+

DR2070, + + allocate_shared should use allocator_traits<A>::construct, + Jonathan Wakely, July, 2011.


$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 +

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.

diff --git a/smart_ptr.htm b/smart_ptr.htm index fab9dd6..0388cc7 100644 --- a/smart_ptr.htm +++ b/smart_ptr.htm @@ -136,6 +136,9 @@

Functions which destroy objects of the pointed to type are prohibited from throwing exceptions by the common requirements.

History and Acknowledgements

+

February 2017. Glen Fernandes rewrote allocate_shared + and make_shared for arrays for a more optimal and more + maintainable implementation.

February 2014. Glen Fernandes updated overloads of make_shared and allocate_shared to conform to the specification in C++ standard paper [D&F-14], and implemented make_unique for