<!DOCTYPE html><html><head><meta charset="utf-8"><title>P0040R2</title>
<style>
ins{ color:rgb(0,128,0);}
.strike{ color:red; text-decoration: line-through; }
.sec-begin{ font-weight:bold; }
.sec-begin span{ float:right }
del{color:red;}
</style>

</head><body id="preview">
<p>LEWG, SG14: P0040R2<br>
2016-05-29<br>
Brent Friedman<br>
<a href="mailto:fourthgeek@gmail.com">fourthgeek@gmail.com</a></p>
<h1><a id="Extending_memory_management_tools_5"></a>Extending memory management tools</h1>
<blockquote>
<i>And so it is that we, as men, do not exist until we do; and then it is that we play with our world of existent things, and order and disorder them, and so it shall be that non-existence shall take us back from existence and that nameless spirituality shall return to Void, like a tired child home from a very wild circus.</i>
<footer>
— Omar Khayyam Ravenhurst and Malaclypse the Younger, Principia Discordia, pg 00058
</footer>
</blockquote>
<h2><a id="I_Motivation_7"></a>I. Motivation</h2>
<p>It is common for both the standard library and user libraries to manage memory without the use of standard-compliant allocators. They may use internal buffers (like <code>optional</code>) or use an allocator model that does not manage object lifetime <a href="https://github.com/bloomberg/bde/wiki/BDE-Allocator-model">[bde]</a> <a href="https://www.sgi.com/tech/stl/alloc.html">[sgi]</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2271.html#eastl_allocator">[eastl]</a> <a href="http://bitsquid.blogspot.fr/2010/09/custom-memory-allocation-in-c.html">[bitsquid]</a>. Such alternative allocator models are <a href="http://www.gamasutra.com/blogs/ThomasYoung/20141002/226898/Custom_Vector_Allocation.php">common</a> in efficiency-critical applications.</p>
<p>Any container-like entity will need to solve the problems of how to create, move, copy, and destroy the objects which it maintains. Optimized, exception-correct implementations of these algorithms aren't necessarily obvious however. For example, <code>destroy</code> can be optimized into a no-op for trivially destructible types and <code>uninitialized_value_construct</code> can be optimized to memset for integral types. Having a standardized implementation of these features will help the performance and correctness of libraries.</p>
<h2><a id="II_Summary_11"></a>II. Summary</h2>
<p>The function templates <code>destroy_at</code>, <code>destroy</code> and <code>destroy_n</code> call the destructor for specified elements.<br>
The function templates <code>uninitialized_move</code> and <code>uninitialized_move_n</code> perform move construction of elements over a range of memory, similar to <code>uninitialized_copy</code>.<br>
The function templates <code>uninitialized_value_construct</code> and <code>uninitialized_value_construct_n</code> perform value-initialization of objects over a range of memory.<br>
The function templates <code>uninitialized_default_construct</code> and <code>uninitialized_default_construct_n</code> perform default-initialization of objects over a range of memory.<br>
<p>Destruction order notwithstanding, these algorithms are isomorphic to existing features. The following table summarizes the relevant existing and proposed algorithms.</p>

<table  border="1"><tr><td>algorithm</td><td>feature</td></tr>
<tr><td><code>uninitialized_value_construct</code></td><td>array value-initialization</td></tr>
<tr><td><code>uninitialized_default_construct</code></td><td>array default-initialization</td></tr>
<tr><td><code>uninitialized_copy</code></td><td>std::array copy constructor</td></tr>
<tr><td><code>uninitialized_move</code></td><td>std::array move constructor</td></tr>
<tr><td><code>uninitialized_fill</code></td><td> (none?)</td></tr>
<tr><td><code>destroy</code></td><td><code> ~T[N] </code></td></tr>
<tr><td><code>destroy_at</code></td><td><code>~T</code></td></tr>
</table>
</code>
<p>Our wording for <code>destroy</code> depends on a fix for <a href="http://cplusplus.github.io/LWG/lwg-active.html#2598">LWG 2598</a>.
<p>This proposal directly contradicts <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/1995/N0639.asc">N0639</a> which removed earlier versions of these algorithms in 1995. That proposal removed <code>destroy(begin,end)</code> and <code>destroy(pointer)</code> which are identical to the destroy algorithms proposed here.
That paper advocated removing these algorithms on the following grounds:<br><blockquote>
While they may be useful
  in implementing STL and collections similar to it, they are not really
  necessary for the purposes of the Standard Library, in that they do
  not aid communication between modules, implement semantics that cannnot
  reproduced by users, or provide substantial functionality.  Furthermore,
  they are mostly subsumed by STL allocator members, which are what
  STL-conforming collections are expected to use.
</blockquote><br>
It seems to this author fairly self-evident that this reasoning would not likely hold water if it were made today. Many important library features (like <code>move</code>) constitute simple but vital contributrions to the vocabulary. Our analysis show that this decision has forced user libraries and standard library implementations to re-invent the wheel.</p> 
<h2><a id="III_Discussion_18"></a>III. Discussion</h2>
<h3> Organization </h3>
<p> Each following section begins with a table. These tables represent an informal survey of existing practice, made mostly by searching github and the Visual Studio standard library implementation. They are by no means complete or scientific.<br>
Many standard library implementations already contain our algorithms, except in that they take an additional allocator parameter and forward memory management operations into that allocator object. This paper does not propose adding such algorithms. However, for completeness, those algorithms are included in the survey as "<quote>+ allocator</quote>"</p>
<p>In addition to these surveys, Creative Assembly has noted that they also have internal implementations of these algorithms.</p>
<h3><code>destroy</code></h3>
<table border="1">
<tr><td>P0040</td><td>destroy_at</td><td>destroy</td><td>+ allocator</td></tr>
<tr><td>VC++</td><td>_Destroy</td><td>~_Temp_iterator<br>valarray::_Tidy</td><td>_Destroy_range</td></tr>
<tr><td>libstdcxx</td><td><a href="https://github.com/gcc-mirror/gcc/blob/7aea4e7cdcd40d7bd47c64e76325a62191887d1b/libstdc%2B%2B-v3/include/bits/stl_construct.h#L87">_Destroy</a></td><td><a href="https://github.com/gcc-mirror/gcc/blob/7aea4e7cdcd40d7bd47c64e76325a62191887d1b/libstdc%2B%2B-v3/include/bits/stl_construct.h">_Destroy(first,last)</a></td><td></td></tr>
<tr><td>libcxx</td><td></td><td>see <a href="https://github.com/llvm-mirror/libcxx/blob/master/include/valarray#L3698">valarray::resize</a><br><a href="https://github.com/llvm-mirror/libcxx/blob/8f1e73dfd2581000748652489c33198b312a78bb/include/memory#L3531">__destruct_n::__process</a><br> </td><td><a href="https://github.com/llvm-mirror/libcxx/blob/master/include/vector#L419">vector::__destruct_at_end</a></td></tr>
<tr><td>EASTL</td><td><a href="https://github.com/electronicarts/EASTL/blob/5a1f0ffcd10d524062bc727e636a5de8630d92f4/include/EASTL/memory.h#L1218">destruct</a></td><td><a href="https://github.com/electronicarts/EASTL/blob/5a1f0ffcd10d524062bc727e636a5de8630d92f4/include/EASTL/memory.h#L1218">destruct(first,last)</a></td><td></td></tr>
<tr><td>folly</td><td></td><td>see <A href="https://github.com/facebook/folly/blob/26d9f3f3cc34d30f7e73a6f12a3bae5102c7512e/folly/small_vector.h">~small_vector</a></td><td><a href="https://github.com/facebook/folly/blob/dee8a5180aa542d98d1b71c74f83a006e4627952/folly/FBVector.h#L357">S_destroy_range_a</a></td></tr>
<tr><td>concrt</td><td></td><td>see concurrent_vector::_Destroy_array</td><td></td></tr>
<tr><td>hpx</td><td></td><td><a href="https://github.com/STEllAR-GROUP/hpx/blob/9deeea16b7d5bb491d5e35a10b4c62f0b8d6dbfa/hpx/util/reinitializable_static.hpp#L77">reinitializable_static::destruct</a></td><td></td></tr>
<tr><td>bsl</td><td></td><td><a href="https://github.com/bloomberg/bde/blob/28dd726641d09746e6d9cca6e4aa0ea319fa3595/groups/bsl/bslalg/bslalg_arraydestructionprimitives.h#L192">ArrayDestructionPrimitives::destroy</a></td><td></td></tr>
</table>
<p>A design decision must be made regarding the order of destruction in <code>destroy</code>. Should bidirectional iterators destroy objects in reverse order? We argue no, for the following reasons:
<ul>
<li>Order of construction and destruction is a property of the container, not a property of the iterator category. Not all containers with bidirectional iterators necessarily imply reverse-order destruction.</li>
<li>It would be a very strange API which requires users to provide reverse iterators in order to destroy in forward order</li>
<li>Reverse-order destruction can be provided by explicitly providing a reverse iterator (or, if truly desired, a <code>destroy_reverse</code> algorithm). Explicitness is the key here.</li>
<li>The semantics of an algorithm should not change based on the iterator category. This could lead to suprises during code maintenance.</li>
<li>Leaving the order as implementation-defined will likely damage its usefulness</li>
</ul>
<p>It is conceivable that always destroying in forward order would be seen as suprising behavior to some. However, this is at least a consistent behavior which can be accounted for once understood. If we choose to change the behavior based on iterator category, we create a situation which is difficult for users to control.</p>
<p>A good implementation of <code>destroy</code> should not accept cases where expression <code>*first</code> resolves to an rvalue. For example, dereferencing an iterator could return <code>int</code> or <code>int&amp;&amp;</code> instead of <code>int&amp;</code>. Returning an <code>int</code> is forbidden by our use of <code>ForwardIterator</code> but without Concepts we are as yet unable to enforce this, so an alternative error checking mechanism is needed. 
With appropriate reslolution of <a href="http://cplusplus.github.io/LWG/lwg-active.html#2598">LWG 2598</a>, the expression <code>addressof(*first)</code> will produce an error if <code>*first</code> returns an rvalue.</p>
<p>The specification of <code>destroy_at</code> may seem odd and restrictive in how it requires a non-null pointer rather than a reference or arbitrary iterator type. This design is chosen for the following reasons:</p>
<ul>
<li>It matches existing practice in various libraries (see table)</li>
<li>It is conceptually compatible with <code>allocator::destroy</code> which operates on the allocator's pointer type</li>
<li>By requiring a pointer, the API makes it difficult to call on a temporary object. If the algorithm operated on a reference or iterator, we would need to do extra work to exclude <code>const T&amp;&amp;</code>s</li>
<li>The restrictive API makes it somewhat less likely to be called incorrectly. If the API accepted a reference, users might pass in a pointer and the pointer would be destroyed rather than the value to which it points.</li>
</ul> 
<p>All implementations of the standard library which were surveyed have some equivalent of the logic for <code>destroy</code> implemented in the exception handling block of the existing <code>uninitialized_*</code> algorithms.</p>
<p>The author wanted <code>destroy</code> to use <code>InputIterator</code> instead of <code>ForwardIterator</code>. As destroy is a single-pass algorithm, many of the features of <code>ForwardIterator</code> provide more guarantees than are strictly needed. Conversations on std-proposals and in private with Stepanov indicate broad disapproval for using <code>InputIterator</code> in this algorithm, so it has been restricted to the more conservative <code>ForwardIterator</code>. Objections revolved around questions regarding exception handling on iterator operations and a lack of compelling use cases</code>.
<h3><code>uninitialized_move</code></h3>
<table border="1">
<tr>
<tr><td>P0040</td> <td>uninitialized_move </td><td>+ allocator</td></tr>
<tr><td>VC++</td><td>see vector::_Assign_rv (_Construct w/ move iterator)  </td><td>_Uninitialized_move</td></tr>
<tr><td>libstdcxx</td><td> </td><td><a href="https://github.com/gcc-mirror/gcc/blob/edd716b6b1caa1a5cb320a8cd7f626f30198e098/libstdc%2B%2B-v3/include/bits/stl_uninitialized.h#L283">__uninitialized_move_a</a> </td></tr>
<tr><td>EASTL</td><td><a href="https://github.com/electronicarts/EASTL/blob/5a1f0ffcd10d524062bc727e636a5de8630d92f4/include/EASTL/memory.h#L784">uninitialized_move</a></td><td></td></tr>
<tr><td>folly</td><td><a href="https://github.com/facebook/folly/blob/26d9f3f3cc34d30f7e73a6f12a3bae5102c7512e/folly/small_vector.h">moveToUninitialized</a></td><td></td></tr>
</table>
<p>Some concern is raised about exception handling with respect to <code>uninitialized_move</code>. If a move-constructor throws, the source object may have been irreparably damaged. As there is no solution to this problem, we implement the natural and expected semantics of destroying all fully constructed objects in the destination buffer and propagating the exception. This matches the behavior of <code>uninitialized_copy</code> as closely as possible.<br>
An additional algorithm, <code>uninitialized_move_if_noexcept</code>, could be considered as a resolution to this concern. Such an algorithm was found already implemented in <a href="https://github.com/gcc-mirror/gcc/blob/edd716b6b1caa1a5cb320a8cd7f626f30198e098/libstdc%2B%2B-v3/include/bits/stl_uninitialized.h#L283">libstdc++</a> using a move_if_noexcept iterator. Given that there is currently no range-based <code>move_if_noexcept</code> algorithm, such a solution is not considered here. It seems clear that such a feature is readily possible, however.</p>
<p><a href="http://cplusplus.github.io/LWG/lwg-active.html#2242">LWG 2242</a> reports a defect in <code>copy_n</code> and <code>uninitialized_copy_n</code>. We make no attempt to resolve the existing issue in <code>uninitialized_copy_n</code>, and replicate its flaws in <code>uninitialized_move_n</code>.<br>
During implementation research, it was found that libstdc++ implements a variation of <code>uninitialized_move</code> by combining <code>move_iterator</code> with <code>uninitialized_copy</code>. Although this implementation would provide us with a clever and simple wording, it makes resolution of <a href="http://cplusplus.github.io/LWG/lwg-active.html#2242">LWG 2242</a> more difficult in the future, and so is not used.
</p>

<h3><code>uninitialized_value_construct; uninitialized_default_construct</code></h3>
<table border="1">
<tr><td>P0040</td><td>uninitialized_value_construct</td><td>+ allocator</td></tr>
<tr><td>VC++</td><td>_Construct</td><td>_Uninitialized_default_fill_n (deque, vector, internal_concurrent_hash)</td></tr>
<tr><td>libstdcxx</td><td><a href="https://github.com/gcc-mirror/gcc/blob/edd716b6b1caa1a5cb320a8cd7f626f30198e098/libstdc%2B%2B-v3/include/bits/stl_uninitialized.h#L544">__uninitialized_default</a></td><td>__uninitialized_default_a</td></tr>
<tr><td>libcxx</td><td></td><td><a href="https://github.com/llvm-mirror/libcxx/blob/master/include/vector#L970">vector::__construct_at_end</a></td> </tr>
<tr><td>EASTL</td><td><a href="https://github.com/electronicarts/EASTL/blob/6a62b754180376f5fdacb0842c3aa9409b35566b/include/EASTL/memory.h#L864">uninitialized_default_fill</a></td><td></td></tr>
<tr><td>folly</td><td>see <a href="https://github.com/facebook/folly/blob/26d9f3f3cc34d30f7e73a6f12a3bae5102c7512e/folly/futures/Barrier.cpp">Barrier::allocateControlBlock</a></td><td></td></tr>
<tr><td>concrt</td><td>_Internal_loop_guide::_Init</td><td></td></tr>
<tr><td>hpx</td><td><a href="https://github.com/STEllAR-GROUP/hpx/blob/9deeea16b7d5bb491d5e35a10b4c62f0b8d6dbfa/hpx/util/reinitializable_static.hpp#L64">reinitializable_static::default_construct</a></td><td></td></tr>
</table>
<p>The names <code>uninitialized_value_construct</code> and <code>uninitialized_default_construct</code> were the originally proposed names, and were approved by ballot at Kona. Since that time, this author has grown to prefer the names <code>default_initialize</code> and <code>value_initialize</code> as they more clearly reflect the terminology used in the standard. The words "construct" and "initialize" already imply operating on uninitialized memory so the repetition seems redundant. In respect for Kona's decision, however, the names have been left as per their vote.</p>
<p>The table demonstrates that many libraries use the word "default" to refer to value-initialization. This is likely a historical artifact from a time before the distinction between default-initialization and value-initialization. It may also be caused simply by the fact that allocators provide no mechanism for containers to request one form of initialization over another. We seek to support multiple forms of initialization, so the distinction is important to make clearly.</p>
<p>The solution of using <code>uninitialized_fill</code> to fill a range with a default-initialized or value-initialized object is suboptimal, making this algorithm useful. Using fill presents the following issues:
<ul>
<li>Requires unnecessary copy-construction which is not possible for move-only types</li>
<li>May incur additional overhead</li>
</ul>
</p>
<p>No algorithms equivalent to <code>uninitialized_default_construct</code> were found in our (very incomplete) search. The author believes that the Standard Library would be remiss to support only one form.</p>
<h2><a id="IV_Proposed_Text_31"></a>IV. Proposed Text</h2>
<p>This document is written as a set of changes against n4582.</p>
<p>The existing structure of [specialized.algorithms] made amendments difficult, especially with respect to exception behavior. As such, the proposed wording applies a conservative refactoring in order to make the section more flexible. This wording is copied almost verbatim from 25.1 [algorithms.general]</p>
<p>A minor inconsistency was noted in that <code>uninitialized_copy</code> and <code>uninitialized_copy_n</code> are in the same section, but <code>uninitialized_fill</code> and <code>uninitialized_fill_n</code> are in separate sections. The fill algorithms are combined into one section as part of this wording.
<p><b>Amend the <code>&lt;memory&gt;</code> header synposis in 20.9.2 [memory.syn]</b> </p>
<p>
The header &lt;memory&gt; defines several types and function templates that describe properties of pointers
and pointer-like types, manage memory for containers and other template types, <ins>destroy objects</ins>, and construct multiple
objects in uninitialized memory buffers (20.9.3–20.9.12).
<pre>
// 20.9.12, specialized algorithms:
...
template &lt;class ExecutionPolicy, class ForwardIterator, class Size, class T&gt;
ForwardIterator uninitialized_fill_n(ExecutionPolicy&amp;&amp; exec, // see 25.2.5
ForwardIterator first, Size n, const T&amp; x);

<ins>
template &lt;class T&gt;
 void destroy_at(T* location); 
 
template &lt;class ExecutionPolicy, class ForwardIterator&gt;
 void destroy(ExecutionPolicy&amp;&amp; exec, //see 25.2.5
 ForwardIterator begin, ForwardIterator end);
 template &lt;class ForwardIterator&gt;
 void destroy(ForwardIterator begin, ForwardIterator end);

template &lt;class ForwardIterator, class Size&gt;
 ForwardIterator destroy_n(ForwardIterator begin, Size n);
template &lt;class ExecutionPolicy&amp;&amp; exec, //see 25.2.5
class ForwardIterator, class Size&gt;
 ForwardIterator destroy_n(ForwardIterator begin, Size n);
 
template &lt;class ExecutionPolicy, class InputIterator, class ForwardIterator&gt;
 ForwardIterator uninitialized_move(ExecutionPolicy&amp;&amp; exec,//see 25.2.5
 InputIterator first, InputIterator last, ForwardIterator result);
 template &lt;class InputIterator, class ForwardIterator&gt;
 ForwardIterator uninitialized_move(InputIterator first, InputIterator last, ForwardIterator result);
 
template &lt;class ExecutionPolicy, class InputIterator, class Size, class ForwardIterator&gt;
 ForwardIterator uninitialized_move_n(ExecutionPolicy&amp;&amp; exec, //see 25.2.5
 InputIterator first, Size n, ForwardIterator result);
template &lt;class InputIterator, class Size, class ForwardIterator&gt;
 ForwardIterator uninitialized_move_n(InputIterator first, Size n, ForwardIterator result);

template &lt;class ExecutionPolity, class ForwardIterator&gt;
 void uninitialized_value_construct(ExecutionPolicy&amp;&amp; exec, //see 25.2.5
 ForwardIterator first, ForwardIterator last);
template &lt;class ForwardIterator&gt;
 void uninitialized_value_construct(ForwardIterator first, ForwardIterator last);
 
template &lt;class ExecutionPolicy, class ForwardIterator, class Size&gt;
 ForwardIterator uninitialized_value_construct_n(ExecutionPolicy&amp;&amp; exec, //see 25.2.5
 ForwardIterator first, Size n);
template &lt;class ForwardIterator, class Size&gt;
 ForwardIterator uninitialized_value_construct_n(ForwardIterator first, Size n);

 template &lt;class ExecutionPolicy, class ForwardIterator&gt;
 void uninitialized_default_construct(ExecutionPolity&amp;&amp; exec, //see 25.2.5
 ForwardIterator first, ForwardIterator last); 
 template &lt;class ForwardIterator&gt;
 void uninitialized_default_construct(ForwardIterator first, ForwardIterator last);
 
 template &lt;class ExecutionPolicy, class ForwardIterator, class Size&gt;
 ForwardIterator uninitialized_default_construct_n(ExecutionPolicy&amp;&amp; exec, //see 25.2.5
 ForwardIterator first, Size n);
 template &lt;class ForwardIterator, class Size&gt;
 ForwardIterator uninitialized_default_construct_n(ForwardIterator first, Size n);
</ins> 
...
</pre>
</p>

<p><b>Amend [specialized.algorithms] in 20.9.12:</b></p>

<p class="sec-begin">20.9.12 Specialized algorithms <span>[specialized.algorithms]</span></p>
<p>
</p>
<p>
<del>In the algorithm uninitialized_copy, the template parameter InputIterator is required to satisfy the
requirements of an input iterator (24.2.3). In all of the following algorithms, the template parameter
ForwardIterator is required to satisfy the requirements of a forward iterator (24.2.5), and is required
to have the property that no exceptions are thrown from increment, assignment, comparison, or indirection
through valid iterators.</del><br>
<ins>Throughout this Clause, the names of template parameters are used to express type requirements.</ins>
<ul>
 <li> <ins>If an algorithm's template parameter is named InputIterator, the template argument shall satisfy the requirements of an input iterator (24.2.3).</ins></li>
 <li> <ins>If an algorithm's template parameter is named ForwardIterator, the template argument shall satisfy the requirements of a forward iterator (24.2.5), and is required to have the property that no exceptions are thrown from increment, assignment, comparison, or indirection through valid iterators.</ins></li>
</ul>
<p><ins>In the descriptions of the algorithms operator <code>+</code> and <code>-</code> observe the same rules as &sect;25.1.12.</ins></p>
<del>In the following algorithms, if an exception is thrown there are no effects.</del>
</p>
<p class="sec-begin">20.9.12.1 <code>addressof</code> <span>[specialized.addressof]</span></p>
<pre><code>
template &lt;class T&gt; T* addressof(T&amp; r) noexcept;</code>
<p>    <i>Returns:</i> The actual address of the object or function referenced by <code>r</code>, even in the presence of an overloaded operator&amp;.</p></pre>
<p class="sec-begin">20.9.12.2 <code>uninitialized_copy</code> <span>[uninitialized.copy]</span></p>
<pre><code>
template &lt;class InputIterator, class ForwardIterator&gt;
ForwardIterator uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator result);
</code>
    <i>Effects:</i>
<code>
        for (; first != last; ++result, (void) ++first)
            ::new (static_cast&lt;void*&gt;(addressof(*result)))
             typename iterator_traits&lt;ForwardIterator&gt;::value_type(*first);
</code>
    <i>Returns:</i> <code>result</code>
    <ins><i>Remarks:</i> If an exception is thrown there are no effects.</ins>
<code>
template &lt;class InputIterator, class Size, class ForwardIterator&gt;
ForwardIterator uninitialized_copy_n(InputIterator first, Size n, ForwardIterator result);
</code>
    <i>Effects:</i>
<code>
        for ( ; n > 0; ++result, (void) ++first, --n) {
            ::new (static_cast&lt;void*&gt;(addressof(*result)))
            typename iterator_traits&lt;ForwardIterator&gt;::value_type(*first);
        }
</code>
    <i>Returns:</i> <code>result</code>
    <ins><i>Remarks:</i> If an exception is thrown there are no effects.</ins>
</pre>
<p class="sec-begin">20.9.12.3 <code>uninitialized_fill</code> <span>[uninitialized.fill]</span></p>
<pre><code>
template &lt;class ForwardIterator, class T&gt;
void uninitialized_fill(ForwardIterator first, ForwardIterator last, const T&amp; x);
</code>
    <i>Effects:</i>
<code>
        for (; first != last; ++first)
            ::new (static_cast&lt;void*&gt;(addressof(*first))) typename iterator_traits&lt;ForwardIterator&gt;::value_type(x);
</code>
    <ins><i>Remarks:</i> If an exception is thrown there are no effects.</ins>
</pre>
<del><p class="sec-begin">20.9.12.4 <code>uninitialized_fill_n</code> <span>[uninitialized.fill]</span></p></del>
<pre><code>
template &lt;class ForwardIterator, class Size, class T&gt;
ForwardIterator uninitialized_fill_n(ForwardIterator first, Size n, const T& x);
</code>
    <i>Effects:</i>
<code>
        for (; n--; ++first)
            ::new (static_cast&lt;void*&gt;(addressof(*first))) typename iterator_traits&lt;ForwardIterator&gt;::value_type(x);
</code>
    <i>Returns:</i> <code>first</code>
    <ins><i>Remarks:</i> If an exception is thrown there are no effects.</ins>
</pre>
<ins>
<p class="sec-begin">20.9.12.4 <code>destroy</code>    <span>[specialized.destroy]</span></p>
<pre><code>
template &lt;class ForwardIterator&gt;
void destroy(ForwardIterator first, ForwardIterator last);</code>   
    <i>Effects:</i> <code>
            for(;first!=last;++first)
                destroy_at(addressof(*first));
     </code>

<code>template &lt;class ForwardIterator, class Size&gt;
ForwardIterator destroy_n(ForwardIterator first, Size n);</code>
    <i>Effects:</i> <code>
            for ( ; n > 0; (void)++first, --n)
                  destroy_at(addressof(*first));
    </code>
    <i>Returns:</i> <code>first</code>
			
<code>template &lt;class T&gt;
void destroy_at(T* location);</code>    
    <i>Effects:</i> <code>
            location->~T();
    </code>
</pre>

<p class="sec-begin">20.9.12.5    <code>uninitialized_move</code>     <span>[uninitialized.move]</span></p>
<pre><code>
template &lt;class InputIterator, class ForwardIterator&gt;
ForwardIterator uninitialized_move(InputIterator first, InputIterator last, ForwardIterator result);
</code>
    <i>Effects:</i>
<code>
        for (; first != last; ++result, (void) ++first)
            ::new (static_cast&lt;void*&gt;(addressof(*result)))
             typename iterator_traits<ForwardIterator>::value_type(move(*first));
</code>
    <i>Returns:</i> <code>result</code>
    <i>Remarks:</i> If an exception is thrown, there are no effects on objects in the range [result,result+(last-first)).
<code>		
template &lt;class InputIterator, class Size, class ForwardIterator&gt;
ForwardIterator uninitialized_move_n(InputIterator first, Size n, ForwardIterator result);    
</code>
    <i>Effects:</i>
<code>
        for ( ; n > 0; ++result, (void) ++first, --n) {
            ::new (static_cast&lt;void*&gt;(addressof(*result)))
            typename iterator_traits&lt;ForwardIterator&gt;::value_type(move(*first));
        }
</code>
    <i>Returns:</i> <code>result</code>
    <i>Remarks:</i> If an exception is thrown, there are no effects on objects in the range [result,result+n).
</pre>		
<p class="sec-begin"> 20.9.12.6   <code>uninitialized_value_construct</code>   <span>[uninitialized.construct.value]</span></p>
 <pre><code>
template&lt;class ForwardIterator&gt;
void uninitialized_value_construct(ForwardIterator first, ForwardIterator last);
</code>    
    <i>Effects:</i> 
	<code>for (; first != last; ++first)
          ::new (static_cast&lt;void*&gt;(addressof(*first)))
            typename iterator_traits&lt;ForwardIterator&gt;::value_type();
    </code>
    <i>Remarks:</i> If an exception is thrown there are no effects.
</pre>
 <pre><code>
template&lt;class ForwardIterator, class Size&gt;
ForwardIterator uninitialized_value_construct_n(ForwardIterator first, Size n);
</code>    
    <i>Effects:</i> 
	<code>for (; n>0; (void)++first, --n)
          ::new (static_cast&lt;void*&gt;(addressof(*first)))
            typename iterator_traits&lt;ForwardIterator&gt;::value_type();
    </code>
    <i>Returns:</i> <code>first</code>
    <i>Remarks:</i> If an exception is thrown there are no effects.
</pre>
 <p class="sec-begin">20.9.12.7  <code>uninitialized_default_construct</code>   <span>[uninitialized.construct.default]</span></p>
 <pre><code>
template&lt;class ForwardIterator&gt;
void uninitialized_default_construct(ForwardIterator first, ForwardIterator last);
</code>    
    <i>Effects:</i> 
	<code>for (; first != last; ++first)
          ::new (static_cast&lt;void*&gt;(addressof(*first)))
            typename iterator_traits&lt;ForwardIterator&gt;::value_type;
    </code>
    <i>Remarks:</i> If an exception is thrown there are no effects.
<code>
template&lt;class ForwardIterator, class Size&gt;
ForwardIterator uninitialized_default_construct_n(ForwardIterator first, Size n);
</code>    
    <i>Effects:</i> 
	<code>for (; n>0; (void)++first, --n)
          ::new (static_cast&lt;void*&gt;(addressof(*first)))
            typename iterator_traits&lt;ForwardIterator&gt;::value_type;
    </code>
    <i>Returns:</i> <code>first</code>
    <i>Remarks:</i> If an exception is thrown there are no effects.
</pre>
</ins>
<h2> V. Revision history</h2>
<p> <b>R2</b></p>
<ul>
<li> Added <code>destroy_n</code>, <code>uninitialized_value_construct_n</code>, <code>uninitialized_default_construct_n</code> for symmetry with existing algorithms.</li>
<li> Tweaks to iterator categories and return values for better correctness </li>
<li> Added <code>destroy_at</code>, which makes <code>destroy</code> both simpler and safer.</li>
<li> Refactored [specialized.algorithm] for simpler wording</li>
<li> Refactored discussions and surveys </li>
<li> Rejected alternative wording for <code>uninitialized_move</code></li>
<li> Added references to LWG 2422 and 2598</li>
<li> Added recommendation that we change the name of uninitialized_*_construct algorithms</li>
<li> Made wording normative against n4582 </li>
<li> Reference and discussion of N0639</li>
<li> Added cross-reference to 25.1.12</li>
<li> Improved formatting</li>
<li> Added amendments to <code>memory.syn</code> </li>
<li> Added revision history </li>
</ul> 
<p> <b>R1</b></p>
<ul>
<li> Added surveys of existing code</li>
<li> Added discussion about order of destruction in <code>destroy</code></li>
<li> Added alternative wording for <code>uninitialized_move</code></li>
<li> Exempted <code>destroy</code> and <code>uninitialized_move</code> from no-effects policy</li>
</ul>
<p> <b>R0</b></p>
<ul> <li> Initial revision </li></ul>
<h2>VI. Credits</h2>
<p>Special thanks is given to Billy Baker and Patrice Roy for feedback and championship. Thanks to Michael Wong for helping to organize this effort. Thanks to Howard Hinnant for feedback regarding <code>uninitialized_move</code>. Thanks to Alexander Stepanov for consultations regarding <code>destroy</code>.</p>
</body></html>