<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC
    "-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN"
    "http://www.w3.org/2002/04/xhtml-math-svg/xhtml-math-svg.dtd">
<html xml:lang='en' xmlns:svg='http://www.w3.org/2000/svg' xmlns='http://www.w3.org/1999/xhtml'>
<head><meta content='application/xhtml+xml;charset=utf-8' http-equiv='Content-type' /><title>Minimal incomplete type support for standard containers, revision 2</title></head>
<body><!-- maruku -o incomplete.html incomplete.md --><style type='text/css'>
pre>code { display: block; margin-left: 2em; }
code { white-space: pre-wrap; }
ins { text-decoration: none; font-weight: bold; background-color: #A0FFA0 }
del { text-decoration: line-through; background-color: #FFA0A0 }
</style><table><tbody>
<tr><th>Doc. no.:</th>	<td>N4371</td></tr>
<tr><th>Date:</th>	<td>2015-02-04</td></tr>
<tr><th>Project:</th>	<td>Programming Language C++, Library Working Group</td></tr>
<tr><th>Revises:</th>	<td>N4056</td></tr>

<tr><th>Reply-to:</th>	<td>Zhihao Yuan &lt;zy at miator dot net&gt;</td></tr>
</tbody></table>
<h1 id='minimal_incomplete_type_support_for_standard_containers_revision_2'>Minimal incomplete type support for standard containers, revision 2</h1>

<h2 id='changes_since_n4056'>Changes since N4056</h2>

<ul>
<li>Wording reworked.</li>

<li>Rationale of the wording is added.</li>
</ul>

<h2 id='overview'>Overview</h2>

<p>In the original version (<a href='http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2014/n3890.html'>N3890</a>) of this paper, we explored the possibility to make all STL containers usable in the recursive data structure definitions, such as</p>

<pre><code>struct Entry
{
    std::list&lt;Entry&gt; messages;
    // ...
};</code></pre>

<p>Based on the discussion on the Issaquah meeting, we achieved the consensus to processed with the approach &#8211; &#8220;Containers of Incomplete Types&#8221;, but limit the scope to <code>std::vector</code>, <code>std::list</code>, and <code>std::forward_list</code>, as the first step.</p>

<p>The approach itself is well-known shortly after the C++98 standard being shipped<code>[1]</code>, is one of the main features provided by Boost.Container<code>[2]</code> and libstdc++, and is receiving increasing interests in libc++. By limiting the scope, MSVC STL, libstdc++, and libc++ already support the proposed solution.</p>

<h2 id='impact_on_the_standard'>Impact on the Standard</h2>

<ol>
<li>
<p>Conditionally require the targeted containers to be complete types.</p>
</li>

<li>
<p>Define &#8220;allocator completeness requirements&#8221; as a dependency of 1).</p>
</li>

<li>
<p>Require <code>std::allocator&lt;T&gt;</code> to unconditionally satisfy the &#8220;allocator completeness requirements&#8221; defined in 2).</p>
</li>
</ol>

<h2 id='wording'>Wording</h2>

<p>This wording is relative to N4296.</p>

<p>New section 17.6.3.5.1 &#91;allocator.requirements.completeness&#93;:</p>

<blockquote>
<h4 id='176351_allocator_completeness_requirements_allocatorrequirementscompleteness'>17.6.3.5.1 Allocator completeness requirements &#91;allocator.requirements.completeness&#93;</h4>

<p>If <code>X</code> is an allocator class for type <code>T</code>, <code>X</code> additionally satisfies the allocator completeness requirements if:</p>

<ul>
<li><code>T</code> may be an incomplete type, and</li>

<li><code>X</code> is a complete type, and</li>

<li>all the member types of <code>allocator_traits&lt;X&gt;</code> specified in 20.7.8.1 other than <code>value_type</code> are complete types.</li>
</ul>
</blockquote>

<p>New paragraph in 20.7.9 &#91;default.allocator&#93;, before the synopsis, as the first paragraph:</p>

<blockquote>
<p>All specializations of the default allocator satisfy the allocator completeness requirements (17.6.3.5.1).</p>
</blockquote>

<p>New paragraph in 23.3.4.1 &#91;forwardlist.overview&#93;, as paragraph 4:</p>

<blockquote>
<p>An incomplete type <code>T</code> may be used when instantiating <code>forward_list</code> if the allocator satisfies the allocator completeness requirements (17.6.3.5.1). <code>T</code> shall be complete before any member of the resulting specialization of <code>forward_list</code> is referenced.</p>
</blockquote>

<p>New paragraph in 23.3.5.1 &#91;list.overview&#93;, as paragraph 3:</p>

<blockquote>
<p>An incomplete type <code>T</code> may be used when instantiating <code>list</code> if the allocator satisfies the allocator completeness requirements (17.6.3.5.1). <code>T</code> shall be complete before any member of the resulting specialization of <code>list</code> is referenced.</p>
</blockquote>

<p>New paragraph in 23.3.6.1 &#91;vector.overview&#93;, as paragraph 3:</p>

<blockquote>
<p>An incomplete type <code>T</code> may be used when instantiating <code>vector</code> if the allocator satisfies the allocator completeness requirements (17.6.3.5.1). <code>T</code> shall be complete before any member of the resulting specialization of <code>vector</code> is referenced.</p>
</blockquote>

<h2 id='wording_rationale'>Wording Rationale</h2>

<h3 id='allocator_completeness_requirements'>Allocator completeness requirements</h3>

<p>Let <code>X</code> be an allocator type for <code>T</code>.</p>

<p>&#8221;<code>T</code> may be an incomplete type&#8221; revokes &#91;res.on.function&#93;/2.5. <code>T</code> could be a type which is not yet complete, or a type which cannot be incomplete, e.g. <code>int</code>.</p>

<p>&#8221;<code>X</code> is a complete type&#8221; is unconditional regarding to the completeness of <code>T</code>. <code>X</code> could be <code>X&lt;T&gt;</code>, <code>X&lt;T, Args...&gt;</code>, or even a non-template class <code>IntAllocator</code>. The completeness is required because a container may store an instance of the allocator.</p>

<p>&#8220;all the member types of <code>allocator_traits&lt;X&gt;</code>&#8230; other than <code>value_type</code> are complete types&#8221; allows a container to query minimal information from the allocator type to finish the class definition. For a non-template container, the class definition must not require a complete <code>T</code> if <code>T</code> could be incomplete; for a specialization the outcome of the rule is more &#8220;flexible&#8221;, since the separately-instantiated entities do not require a complete <code>T</code> when the specialization is implicitly instantiated.</p>

<h3 id='container_incomplete_type_support'>Container incomplete type support</h3>

<p>Let <code>C</code> be a sequence container.</p>

<p>&#8220;An incomplete type <code>T</code> may be used&#8230;&#8221; revokes &#91;res.on.function&#93;/2.5. The rule is unconditional regarding to the completeness of <code>T</code>. If the rule is extended to cover associative/hash containers, the rule may be unconditional regarding to the completeness of <code>K</code> and/or <code>V</code>.</p>

<p>&#8221;&#8230; if the allocator satisfies the allocator completeness requirements&#8221; ensures that the specialization can be instantiated from a user&#8217;s point of view; extra template parameters or meta-programming within the class definition must not make the instantiation ill-formed. If the rule is extended to cover associative/hash containers, the rule may be conditional regarding to the completeness requirements on other template parameters, e.g. <code>Compare</code> and <code>Hash</code>, as well.</p>

<p>&#8221;<code>T</code> shall be complete before any member of the resulting specialization&#8230; is referenced.&#8221; avoids ill-formed programs caused by instantiating separately-instantiated entities before <code>T</code> is complete. It seldom happens for a typical recursive definition use case, but if a user try the following,</p>

<pre><code>struct NT
{
    C&lt;T&gt; ct;
};</code></pre>

<p>, he/she has a chance to reference, for example, the default constructor of <code>C&lt;T&gt;</code> after the definition of <code>NT</code>, while this rule requires <code>T</code> to be completed before the default constructor is referenced.</p>

<h2 id='references'>References</h2>

<p><code>[1]</code> Austern, Matthew H. <em>The Standard Librarian: Containers of Incomplete Types</em>. <a href='http://www.drdobbs.com/the-standard-librarian-containers-of-inc/184403814'>http://www.drdobbs.com/the-standard-librarian-containers-of-inc/184403814</a></p>

<p><code>[2]</code> <em>Main features: Containers of Incomplete Types</em>. &#8220;Boost.Container&#8221; <a href='http://www.boost.org/doc/libs/1_55_0/doc/html/container/main_features.html#container.main_features.containers_of_incomplete_types'>http://www.boost.org/doc/libs/1_55_0/doc/html/container/main_features.html#container.main_features.containers_of_incomplete_types</a></p>

<h2 id='acknowledgments'>Acknowledgments</h2>

<p>Thanks to the library implementers who helped refine the idea, run my test code, and review the patches and the wording.</p>

<p>Special thanks go to Jonathan Wakely, who reviewed this paper many times, and Richard Smith, who wrote the new wording.</p>
</body></html>
