forked from boostorg/smart_ptr
		
	
		
			
				
	
	
		
			274 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			274 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 | 
						|
<html>
 | 
						|
  <head>
 | 
						|
    <title>make_shared and allocate_shared for arrays</title>
 | 
						|
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
 | 
						|
  </head>
 | 
						|
  <body text="#000000" bgcolor="#ffffff" link="#0000ff" vlink="#0000ff">
 | 
						|
    <h1><img height="86" alt="boost.png (6897 bytes)" src="../../boost.png" 
 | 
						|
      width="277" align="middle" border="0">make_shared and allocate_shared 
 | 
						|
      for arrays</h1>
 | 
						|
    <p><a href="#introduction">Introduction</a><br>
 | 
						|
      <a href="#synopsis">Synopsis</a><br>
 | 
						|
      <a href="#common">Common Requirements</a><br>
 | 
						|
      <a href="#functions">Free Functions</a><br>
 | 
						|
      <a href="#history">History</a><br>
 | 
						|
      <a href="#references">References</a></p>
 | 
						|
    <h2><a name="introduction">Introduction</a></h2>
 | 
						|
    <p>Originally the Boost function templates <code>make_shared</code> and 
 | 
						|
      <code>allocate_shared</code> were for efficient allocation of shared 
 | 
						|
      objects only. There was a need to have efficient allocation of 
 | 
						|
      shared arrays. One criticism of class template <code>shared_array</code> 
 | 
						|
      was always the lack of a <a href="make_shared.html">make_shared</a> 
 | 
						|
      utility which ensures only a single allocation.</p>
 | 
						|
    <p>The header files <boost/smart_ptr/make_shared_array.hpp> and 
 | 
						|
      <boost/smart_ptr/allocate_shared_array.hpp> provide function 
 | 
						|
      templates, overloads of <code>make_shared</code> and 
 | 
						|
      <code>allocate_shared</code> for array types, to address this need. 
 | 
						|
      <code>make_shared</code> uses the global operator <code>new</code> to 
 | 
						|
      allocate memory, whereas <code>allocate_shared</code> uses an 
 | 
						|
      user-supplied allocator, allowing finer control.</p>
 | 
						|
    <h2><a name="synopsis">Synopsis</a></h2>
 | 
						|
    <pre>namespace boost {
 | 
						|
    template<class U> // U is T[]
 | 
						|
    shared_ptr<U> <a href="#functions">make_shared</a>(size_t size);
 | 
						|
 | 
						|
    template<class U, class A> // U is T[]
 | 
						|
    shared_ptr<U> <a href="#functions">allocate_shared</a>(const A& allocator, size_t size);
 | 
						|
 | 
						|
    template<class U> // U is T[N]
 | 
						|
    shared_ptr<U> <a href="#functions">make_shared</a>();
 | 
						|
 | 
						|
    template<class U, class A> // U is T[N]
 | 
						|
    shared_ptr<U> <a href="#functions">allocate_shared</a>(const A& allocator);
 | 
						|
 | 
						|
    template<class U> // U is T[]
 | 
						|
    shared_ptr<U> <a href="#functions">make_shared</a>(size_t size, const T& value);
 | 
						|
 | 
						|
    template<class U, class A>  // U is T[]
 | 
						|
    shared_ptr<U> <a href="#functions">allocate_shared</a>(const A& allocator, size_t size, const T& value);
 | 
						|
 | 
						|
    template<class U> // U is T[N]
 | 
						|
    shared_ptr<U> <a href="#functions">make_shared</a>(const T& value);
 | 
						|
 | 
						|
    template<class U, class A> // U is T[N]
 | 
						|
    shared_ptr<U> <a href="#functions">allocate_shared</a>(const A& allocator, const T& value);
 | 
						|
 | 
						|
    template<class U> // U is T[]
 | 
						|
    shared_ptr<U> <a href="#functions">make_shared_noinit</a>(size_t size);
 | 
						|
 | 
						|
    template<class U, class A> // U is T[]
 | 
						|
    shared_ptr<U> <a href="#functions">allocate_shared_noinit</a>(const A& allocator, size_t size);
 | 
						|
 | 
						|
    template<class U> // U is T[N]
 | 
						|
    shared_ptr<U> <a href="#functions">make_shared_noinit</a>();
 | 
						|
 | 
						|
    template<class U, class A> // U is T[N]
 | 
						|
    shared_ptr<U> <a href="#functions">allocate_shared_noinit</a>(const A& allocator);
 | 
						|
}</pre>
 | 
						|
    <h2><a name="common">Common Requirements</a></h2>
 | 
						|
    <pre>template<class U>
 | 
						|
    shared_ptr<U> make_shared(<em>args</em>);
 | 
						|
template<class U, class A>
 | 
						|
    shared_ptr<U> allocate_shared(const A& allocator, <em>args</em>);
 | 
						|
template<class U>
 | 
						|
    shared_ptr<U> make_shared_noinit(<em>args</em>);
 | 
						|
template<class U, class A>
 | 
						|
    shared_ptr<U> allocate_shared_noinit(const A& allocator, <em>args</em>);</pre>
 | 
						|
    <blockquote>
 | 
						|
      <p><b>Requires:</b> <code>U</code> is of the form <code>T[]</code> or 
 | 
						|
        <code>T[N]</code>. <code>A</code> shall be an <em>Allocator</em>, as 
 | 
						|
        described in section 17.6.3.5 [<strong>Allocator 
 | 
						|
        requirements</strong>] of the C++ Standard. The copy constructor and 
 | 
						|
        destructor of <code>A</code> shall not throw exceptions.</p>
 | 
						|
      <p><b>Effects:</b> Allocates memory for an object of type <code>U</code> 
 | 
						|
        (or <code>T[size]</code> when <code>U</code> is <code>T[]</code>, 
 | 
						|
        where <code>size</code> is determined from <code><em>args</em></code> 
 | 
						|
        as specified by the concrete overload). The object is initialized as 
 | 
						|
        specified by the concrete overload. The templates 
 | 
						|
        <code>allocate_shared</code> and <code>allocate_shared_noinit</code>
 | 
						|
        use a copy of <code>allocator</code> to allocate memory. If an 
 | 
						|
        exception is thrown, the functions have no effect.</p>
 | 
						|
      <p><b>Returns:</b> A <code>shared_ptr</code> instance that stores and 
 | 
						|
        owns the address of the newly constructed object.</p>
 | 
						|
      <p><b>Postconditions:</b> <code>r.get() != 0 && 
 | 
						|
        r.use_count() == 1</code>, where <code>r</code> is the return 
 | 
						|
        value.</p>
 | 
						|
      <p><b>Throws:</b> <code>bad_alloc</code>, an exception thrown from 
 | 
						|
        <code>A::allocate</code>, or from the initialization of the 
 | 
						|
        object.</p>
 | 
						|
      <p><b>Remarks:</b></p>
 | 
						|
      <blockquote>
 | 
						|
        <p>This implementation performs no more than one memory 
 | 
						|
          allocation. This provides efficiency to equivalent to an intrusive 
 | 
						|
          smart pointer.</p>
 | 
						|
        <p>When an object of an array type <code>T</code> is specified to be 
 | 
						|
          initialized to a value of the same type <code>value</code>, this 
 | 
						|
          shall be interpreted to mean that each array element of the object 
 | 
						|
          is initialized to the corresponding element from 
 | 
						|
          <code>value</code>.</p>
 | 
						|
        <p>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.</p>
 | 
						|
        <p>Array elements are initialized in ascending order of their 
 | 
						|
          addresses.</p>
 | 
						|
        <p>When a subobject of a non-array type <code>T</code> is specified to 
 | 
						|
          be initialized to a value <code>value</code>, 
 | 
						|
          <code>make_shared</code> shall perform this initialization via the 
 | 
						|
          expression <code>::new(ptr) T(value)</code>, where <code>ptr</code> 
 | 
						|
          has type <code>void*</code> and points to storage suitable to hold 
 | 
						|
          an object of type <code>T</code>.</p>
 | 
						|
        <p>When a subobject of non-array type <code>T</code> is specified to 
 | 
						|
          be initialized to a value <code>value</code>, 
 | 
						|
          <code>allocate_shared</code> shall perform this initialization via 
 | 
						|
          the expression <code>allocator_traits<A2>::construct(a2, ptr, 
 | 
						|
          value)</code>, where <code>ptr</code> points to storage suitable to 
 | 
						|
          hold an object of type <code>T</code> and <code>a2</code> of type A2 
 | 
						|
          is a rebound copy of the allocator <code>allocator</code> passed to
 | 
						|
          <code>allocate_shared</code> such that its <code>value_type</code> 
 | 
						|
          is <code>T</code>.</p>
 | 
						|
        <p>When a subobject of non-array type <code>T</code> is specified to 
 | 
						|
          be value-initialized, <code>make_shared</code> shall perform this 
 | 
						|
          initialization via the expression <code>::new(ptr) T()</code>, where 
 | 
						|
          <code>ptr</code> has type <code>void*</code> and points to storage 
 | 
						|
          suitable to hold an object of type <code>T</code>.</p>
 | 
						|
        <p>When a subobject of non-array type <code>T</code> is specified to 
 | 
						|
          be value-initialized, <code>allocate_shared</code> shall perform 
 | 
						|
          this initialization via the expression
 | 
						|
          <code>allocator_traits<A2>::construct(a2, ptr)</code>, where 
 | 
						|
          <code>ptr</code> points to storage suitable to hold an object 
 | 
						|
          of type <code>T</code> and <code>a2</code> of type A2 is a rebound 
 | 
						|
          copy of the allocator <code>allocator</code> passed to
 | 
						|
          <code>allocate_shared</code> such that its <code>value_type</code> 
 | 
						|
          is <code>T</code>.</p>
 | 
						|
        <p>When a subobject of non-array type <code>T</code> is specified to 
 | 
						|
          be default-initialized, <code>make_shared_noinit</code> and 
 | 
						|
          <code>allocate_shared_noinit</code> shall perform this 
 | 
						|
          initialization via the expression <code>::new(ptr) T</code>, where 
 | 
						|
          <code>ptr</code> has type <code>void*</code> and points to storage 
 | 
						|
          suitable to hold an object of type <code>T</code>.</p>
 | 
						|
        <p>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.</p>
 | 
						|
      </blockquote>
 | 
						|
      <p><b>Notes:</b> These functions will typically allocate more memory 
 | 
						|
        than <code>sizeof(U)</code> to allow for internal bookkeeping 
 | 
						|
        structures such as the reference counts.</p>
 | 
						|
    </blockquote>
 | 
						|
    <h2><a name="functions">Free Functions</a></h2>
 | 
						|
    <pre>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);</pre>
 | 
						|
    <blockquote>
 | 
						|
      <p><b>Returns:</b> A <code>shared_ptr</code> to a value-initialized 
 | 
						|
        object of type <code>T[size]</code>.</p>
 | 
						|
      <p><b>Remarks:</b> These overloads shall only participate in overload 
 | 
						|
        resolution when <code>U</code> is of the form <code>T[]</code>.</p>      
 | 
						|
      <p><b>Examples:</b></p>
 | 
						|
      <blockquote>
 | 
						|
        <pre>boost::shared_ptr<int[]> a1 = boost::make_shared<int[]>(size);
 | 
						|
boost::shared_ptr<int[][2]> a2 = boost::make_shared<int[][2]>(size);</pre>
 | 
						|
      </blockquote>
 | 
						|
    </blockquote>
 | 
						|
    <pre>template<class U> 
 | 
						|
    shared_ptr<U> make_shared();
 | 
						|
template<class U, class A> 
 | 
						|
    shared_ptr<U> allocate_shared(const A& allocator);</pre>
 | 
						|
    <blockquote>
 | 
						|
      <p><b>Returns:</b> A <code>shared_ptr</code> to a value-initialized 
 | 
						|
        object of type <code>T[N]</code>.</p>
 | 
						|
      <p><b>Remarks:</b> These overloads shall only participate in overload 
 | 
						|
        resolution when <code>U</code> is of the form <code>T[N]</code>.</p>
 | 
						|
      <p><b>Examples:</b></p>
 | 
						|
      <blockquote>
 | 
						|
        <pre>boost::shared_ptr<int[8]> a1 = boost::make_shared<int[8]>();
 | 
						|
boost::shared_ptr<int[4][2]> a2 = boost::make_shared<int[4][2]>();</pre>
 | 
						|
      </blockquote>
 | 
						|
    </blockquote>
 | 
						|
    <pre>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);</pre>
 | 
						|
    <blockquote>
 | 
						|
      <p><b>Returns:</b> A <code>shared_ptr</code> to an object of type 
 | 
						|
        <code>T[size]</code>, where each array element of type <code>T</code> 
 | 
						|
        is initialized to <code>value</code>.</p>
 | 
						|
      <p><b>Remarks:</b> These overloads shall only participate in overload 
 | 
						|
        resolution when <code>U</code> is of the form <code>T[]</code>.</p>
 | 
						|
      <p><b>Examples:</b></p>
 | 
						|
      <blockquote>
 | 
						|
        <pre>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});</pre>
 | 
						|
      </blockquote>
 | 
						|
    </blockquote>
 | 
						|
    <pre>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);</pre>
 | 
						|
    <blockquote>
 | 
						|
      <p><b>Returns:</b> A <code>shared_ptr</code> to an object of type 
 | 
						|
        <code>T[N]</code>, where each array element of type <code>T</code> is 
 | 
						|
        initialized to <code>value</code>.</p>
 | 
						|
      <p><b>Remarks:</b> These overloads shall only participate in overload 
 | 
						|
        resolution when <code>U</code> is of the form <code>T[N]</code>.</p>
 | 
						|
      <p><b>Examples:</b></p>
 | 
						|
      <blockquote>
 | 
						|
        <pre>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});</pre>
 | 
						|
      </blockquote>
 | 
						|
    </blockquote>
 | 
						|
    <pre>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);</pre>
 | 
						|
    <blockquote>
 | 
						|
      <p><b>Returns:</b> A <code>shared_ptr</code> to a default-initialized 
 | 
						|
        object of type <code>T[size]</code>.</p>
 | 
						|
      <p><b>Remarks:</b> These overloads shall only participate in overload 
 | 
						|
        resolution when <code>U</code> is of the form <code>T[]</code>.</p>
 | 
						|
      <p><b>Examples:</b></p>
 | 
						|
      <blockquote>
 | 
						|
        <pre>boost::shared_ptr<int[]> a1 = boost::make_shared_noinit<int[]>(size);
 | 
						|
boost::shared_ptr<int[][2]> a2 = boost::make_shared_noinit<int[][2]>(size);</pre>
 | 
						|
      </blockquote>
 | 
						|
    </blockquote>
 | 
						|
    <pre>template<class U> 
 | 
						|
    shared_ptr<U> make_shared_noinit();
 | 
						|
template<class U, class A> 
 | 
						|
    shared_ptr<U> allocate_shared_noinit(const A& allocator);</pre>
 | 
						|
    <blockquote>
 | 
						|
      <p><b>Returns:</b> A <code>shared_ptr</code> to a default-initialized 
 | 
						|
        object of type <code>T[N]</code>.</p>
 | 
						|
      <p><b>Remarks:</b> These overloads shall only participate in overload 
 | 
						|
        resolution when <code>U</code> is of the form <code>T[N]</code>.</p>
 | 
						|
      <p><b>Examples:</b></p>
 | 
						|
      <blockquote>
 | 
						|
        <pre>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]>();</pre>
 | 
						|
      </blockquote>
 | 
						|
    </blockquote>
 | 
						|
    <h2><a name="history">History</a></h2>
 | 
						|
    <p>February 2014. Glen Fernandes updated overloads of make_shared and 
 | 
						|
      allocate_shared to conform to the specification in C++ standard paper 
 | 
						|
      <a href="#N3870">N3870</a>, including resolving C++ standard library 
 | 
						|
      defect report 2070, and reduced the spatial overhead of the internal
 | 
						|
      bookkeeping structures.</p>
 | 
						|
    <p>November 2012. Glen Fernandes contributed implementations of 
 | 
						|
      make_shared and allocate_shared for arrays.</p>
 | 
						|
    <h2><a name="references">References</a></h2>
 | 
						|
    <p><a name="N3870">N3870</a>,
 | 
						|
      <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3870.html">
 | 
						|
      Extending make_shared to Support Arrays, Revision 1</a>, Peter Dimov 
 | 
						|
      & Glen Fernandes, January, 2014.</p>
 | 
						|
    <hr>
 | 
						|
    <p>$Date$</p>
 | 
						|
    <p><small>Copyright 2012-2014 Glen Fernandes. Distributed under the 
 | 
						|
      Boost Software License, Version 1.0. See accompanying file 
 | 
						|
      <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy at 
 | 
						|
      <a href="http://www.boost.org/LICENSE_1_0.txt">
 | 
						|
      http://www.boost.org/LICENSE_1_0.txt</a>.</small></p>
 | 
						|
  </body>
 | 
						|
</html>
 |