<?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 xmlns="http://www.w3.org/1999/xhtml" xmlns:svg="http://www.w3.org/2000/svg" xml:lang="en">
<head><meta http-equiv="Content-type" content="application/xhtml+xml;charset=utf-8" /><title>Minimal incomplete type support for standard containers, revision 4</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>N4510</td></tr>
<tr><th>Date:</th>	<td>2015-05-05</td></tr>
<tr><th>Project:</th>	<td>Programming Language C++, Library Working Group</td></tr>
<tr><th>Revises:</th>	<td>N4390</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_4">Minimal incomplete type support for standard containers, revision 4</h1>

<h2 id="changes_since_n4390">Changes since N4390</h2>

<ul>
<li>Cross-reference section 20.7.8.</li>
</ul>

<h2 id="changes_since_n4371">Changes since N4371</h2>

<ul>
<li>Reword a permission within requirements.</li>

<li>Relocate the per-container new paragraphs.</li>
</ul>

<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 – “Containers of Incomplete Types”, 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 “allocator completeness requirements” as a dependency of 1).</p>
</li>

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

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

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

<p>New section 17.6.3.5.1 [allocator.requirements.completeness]:</p>

<blockquote>
<h4 id="176351_allocator_completeness_requirements_allocatorrequirementscompleteness">17.6.3.5.1 Allocator completeness requirements [allocator.requirements.completeness]</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, whether or not <code>T</code> is a complete type:</p>

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

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

<p>New paragraph in 20.7.9 [default.allocator], 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 [forwardlist.overview], as paragraph 4, after the synopsis:</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 [list.overview], as paragraph 3, after the synopsis:</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 [vector.overview], as paragraph 3, after the synopsis:</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>“whether or not <code>T</code> is a complete type… <code>X</code> is a complete type” is unconditional regarding to the completeness of <code>T</code>, which could be a type which is not yet complete, or a type which cannot be incomplete, e.g. <code>int</code>, while <code>X</code> may 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 of <code>X</code> is required because a container may store an instance of the allocator.</p>

<p>“all the member types of <code>allocator_traits&lt;X&gt;</code>… other than <code>value_type</code> are complete types” 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 “flexible”, 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>“An incomplete type <code>T</code> may be used…” revokes [res.on.function]/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>“… if the allocator satisfies the allocator completeness requirements” ensures that the specialization can be instantiated from a user’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>“<code>T</code> shall be complete before any member of the resulting specialization… is referenced.” 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>. “Boost.Container” <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>
