diff --git a/make_shared_array.html b/make_shared_array.html index 7059e05..2deb798 100644 --- a/make_shared_array.html +++ b/make_shared_array.html @@ -1,278 +1,365 @@ - - - - make_shared and allocate_shared for arrays - - - -

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

-

Introduction
- Synopsis
- Common Requirements
- Free Functions
- 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 - 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.

-

Synopsis

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

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

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 - allocate_shared and allocate_shared_noinit - 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 - owns the address of the newly constructed object.

-

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 - 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 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 - 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 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 - is a rebound copy of the allocator allocator passed to - 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 - 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 - 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 - copy of the allocator allocator passed to - 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 - 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 - 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.

-
-

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

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[].

-

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 type T[N].

-

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]>();
-
-
-
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 - is initialized to value.

-

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});
-
-
-
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 - initialized to value.

-

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});
-
-
-
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 type T[size].

-

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);
-
-
-
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 type T[N].

-

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]>();
-
-
-

History

-

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 - & 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 - - http://www.boost.org/LICENSE_1_0.txt.

- + + + + +allocate_shared and make_shared for arrays + + +

allocate_shared and make_shared for arrays

+ +
+

Introduction

+

+Originally the Boost function templates allocate_shared and +make_shared were for efficient allocation of shared scalar +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 utility like make_shared that +uses only a single allocation. +

+

+The header files <boost/smart_ptr/allocate_shared_array.hpp> and +<boost/smart_ptr/make_shared_array.hpp> provide function +templates, overloads of allocate_shared and +make_shared for array types, to address this need. +allocate_shared uses a user-supplied allocator for +allocation, while make_shared uses + allocate_shared with the Default Allocator. +

+
+
+

Synopsis

+
+

Header <boost/smart_ptr/allocate_shared_array.hpp>

+namespace boost { +
+template<class T, class A>
shared_ptr<T> +allocate_shared(const A& a, +std::size_t n);
+
+
+template<class T, class A>
shared_ptr<T> +allocate_shared(const A& a);
+
+
+template<class T, class A>
shared_ptr<T> +allocate_shared(const A& a, std::size_t n, +const E& v);
+
+
+template<class T, class A>
shared_ptr<T> +allocate_shared(const A& a, +const E& v);
+
+
+template<class T, class A>
shared_ptr<T> +allocate_shared_noinit(const A& a, +std::size_t n);
+
+
+template<class T, class A>
shared_ptr<T> +allocate_shared_noinit(const A& a);
+
+} +
+
+

Header <boost/smart_ptr/make_shared_array.hpp>

+namespace boost { +
+template<class T, class A>
shared_ptr<T> +make_shared(std::size_t n);
+
+
+template<class T, class A>
shared_ptr<T> +make_shared();
+
+
+template<class T, class A>
shared_ptr<T> +make_shared(std::size_t n, +const E& v);
+
+
+template<class T, class A>
shared_ptr<T> +make_shared(const E& v);
+
+
+template<class T, class A>
shared_ptr<T> +make_shared_noinit(std::size_t n);
+
+
+template<class T, class A>
shared_ptr<T> +make_shared_noinit();
+
+} +
+
+
+

Common Requirements

+

template<class T, class A>
shared_ptr<T> +allocate_shared(const A& a, +args);

+
+
Requires:
+
T is of the form E[N] or +E[]. 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 storage for an object of type E (or +E[size] when T is E[], where +size is determined from args as specified by +the concrete overload). A copy of the allocator is used to allocate +storage. The storage is initialized as specified by the concrete +overload. If an exception is thrown, the functions have no effect.
+
Returns:
+
A shared_ptr instance that stores and owns the address +of the newly allocated and constructed object.
+
Postconditions:
+
r.get() != 0 and r.use_count() == 1, +where r is the return value.
+
Throws:
+
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 smart +pointer.
  • +
  • When an object of an array type T is specified to be +initialized to a value of the same type v, this shall be +interpreted to mean that each array element of the object is initialized +to the corresponding element from v.
  • +
  • When an object of an array type T 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 scalar type S is specified to +be initialized to a value v, allocate_shared +shall perform this initialization via the expression +std::allocator_traits<A>::construct(b, p, v), where +p points to storage suitable to hold an object of type +S and b of is a copy of the allocator +a passed to allocate_shared such that its +value_type is S.
  • +
  • When a subobject of scalar type S is specified to be +value-initialized, allocate_shared shall perform this +initialization via the expression +std::allocator_traits<A>::construct(b, p), where +p points to storage suitable to hold an object +of type S and b is a copy of the allocator +a passed to allocate_shared such that its +value_type is S.
  • +
  • When a subobject of scalar type S is specified to be +default-initialized, allocate_shared_noinit shall perform +this initialization via the expression ::new(p) S, where +p has type void* and points to storage +suitable to hold an object of type S.
  • +
  • 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 the size of +sizeof(E) to allow for internal bookkeeping structures such +as the reference counts.
+
+
+
+

Free Functions

+
+

template<class T, class A>
shared_ptr<T> +allocate_shared(const A& a, std::size_t n);

+
+
Returns:
+
A shared_ptr to a value-initialized object of type +E[size].
+
Remarks:
+
This overload shall only participate in overload resolution when +T is of the form E[].
+
+
+
+

template<class T, class A>
shared_ptr<T> +allocate_shared(const A& a);

+
+
Returns:
+
A shared_ptr to a value-initialized object of type +E[N].
+
Remarks:
+
This overload shall only participate in overload resolution when +T is of the form E[N].
+
+
+
+

template<class T, class A>
shared_ptr<T> +allocate_shared(const A& a, std::size_t n, +const E& v);

+
+
Returns:
+
A shared_ptr to an object of type +E[size], where each array element of type E is +initialized to v.
+
Remarks:
+
This overload shall only participate in overload resolution when +T is of the form E[].
+
+
+
+

template<class T, class A>
shared_ptr<T> +allocate_shared(const A& a, const E& v);

+
+
Returns:
+
A shared_ptr to an object of type E[N], +where each array element of type E is initialized to +v.
+
Remarks:
+
This overload shall only participate in overload resolution when +T is of the form E[N].
+
+
+
+

template<class T, class A>
shared_ptr<T> +allocate_shared_noinit(const A& a, std::size_t n);

+
+
Returns:
+
A shared_ptr to a default-initialized object of type +E[size].
+
Remarks:
+
This overload shall only participate in overload resolution when +T is of the form E[].
+
+
+
+

template<class T, class A>
shared_ptr<T> +allocate_shared_noinit(const A& a);

+
+
Returns:
+
A shared_ptr to a default-initialized object of type +E[N].
+
Remarks:
+
This overload shall only participate in overload resolution when +T is of the form E[N].
+
+
+
+

template<class T>
shared_ptr<T> +make_shared(std::size_t n);

+
+
Returns:
+
allocate_shared<T>(std::allocator<S>(), n);
+
Remarks:
+
This overload shall only participate in overload resolution when +T is of the form E[].
+
+
+
+

template<class T>
shared_ptr<T> +make_shared();

+
+
Returns:
+
allocate_shared<T>(std::allocator<S>());
+
Remarks:
+
This overload shall only participate in overload resolution when +T is of the form E[N].
+
+
+
+

template<class T>
shared_ptr<T> +make_shared(std::size_t n, const E& v);

+
+
Returns:
+
allocate_shared<T>(std::allocator<S>(), n, v);
+
Remarks:
+
This overload shall only participate in overload resolution when +T is of the form E[].
+
+
+
+

template<class T>
shared_ptr<T> +make_shared(const E& v);

+
+
Returns:
+
allocate_shared<T>(std::allocator<S>(), v);
+
Remarks:
+
This overload shall only participate in overload resolution when +T is of the form E[N].
+
+
+
+

template<class T>
shared_ptr<T> +make_shared_noinit(std::size_t n);

+
+
Returns:
+
allocate_shared_noinit<T>(std::allocator<S>(), n);
+
Remarks:
+
This overload shall only participate in overload resolution when +T is of the form E[].
+
+
+
+

template<class T>
shared_ptr<T> +make_shared_noinit();

+
+
Returns:
+
allocate_shared_noinit<T>(std::allocator<S>());
+
Remarks:
+
This overload shall only participate in overload resolution when +T is of the form E[N].
+
+
+
+
+

History

+
+
Boost 1.64
+
Glen Fernandes rewrote allocate_shared and make_shared for a more +optimal and more maintainable implementation.
+
Boost 1.56
+
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 DR 2070.
+
Boost 1.53
+
Glen Fernandes contributed implementations of make_shared and +allocate_shared for arrays.
+
+
+
+

References

+
    +
  1. N3870, +Extending make_shared to Support Arrays, Revision 1, Peter Dimov +& Glen Fernandes, January, 2014.
  2. +
  3. DR 2070, + +allocate_shared should use allocator_traits<A>::construct, +Jonathan Wakely, July, 2011.
  4. +
+
+
+Copyright 2012-2017 Glen Fernandes. Distributed under the +Boost Software License, +Version 1.0. +