<!-- markdownlint-disable MD029, MD041 -->
<h1
id="indirect-and-polymorphic-vocabulary-types-for-composite-class-design"><code>indirect</code>
and <code>polymorphic</code>: Vocabulary Types for Composite Class
Design</h1>
<p>ISO/IEC JTC1 SC22 WG21 Programming Language C++</p>
<p>P3019R13</p>
<p>Working Group: Library Evolution, Library</p>
<p>Date: 2025-02-09</p>
<p><em>Jonathan Coe &lt;<a href="mailto:jonathanbcoe@gmail.com"
class="email">jonathanbcoe@gmail.com</a>&gt;</em></p>
<p><em>Antony Peacock &lt;<a href="mailto:ant.peacock@gmail.com"
class="email">ant.peacock@gmail.com</a>&gt;</em></p>
<p><em>Sean Parent &lt;<a href="mailto:sparent@adobe.com"
class="email">sparent@adobe.com</a>&gt;</em></p>
<h1 id="abstract">Abstract</h1>
<p>We propose the addition of two new class templates to the C++
Standard Library: <code>indirect&lt;T&gt;</code> and
<code>polymorphic&lt;T&gt;</code>.</p>
<p>Specializations of these class templates have value semantics and
compose well with other standard library types (such as vector),
allowing the compiler to correctly generate special member
functions.</p>
<p>The class template <code>indirect</code> confers value-like semantics
on a dynamically-allocated object. An <code>indirect</code> may hold an
object of a class <code>T</code>. Copying the <code>indirect</code> will
copy the object <code>T</code>. When an <code>indirect&lt;T&gt;</code>
is accessed through a const access path, constness will propagate to the
owned object.</p>
<p>The class template <code>polymorphic</code> confers value-like
semantics on a dynamically-allocated object. A
<code>polymorphic&lt;T&gt;</code> may hold an object of a class publicly
derived from <code>T</code>. Copying the
<code>polymorphic&lt;T&gt;</code> will copy the object of the derived
type. When a <code>polymorphic&lt;T&gt;</code> is accessed through a
const access path, constness will propagate to the owned object.</p>
<p>This proposal is a fusion of two earlier individual proposals, P1950
and P0201. The design of the two proposed class templates is
sufficiently similar that they should not be considered in
isolation.</p>
<h1 id="history">History</h1>
<h2 id="changes-in-r13">Changes in R13</h2>
<ul>
<li><p>Remove noexcept specification from <code>operator&lt;=&gt;</code>
for <code>indirect</code>.</p></li>
<li><p>Add a second clarifying example to tagged constructors
explanatory text.</p></li>
<li><p>Remove constraint <code>is_same_v&lt;U, polymorphic&gt;</code> is
<code>false</code> on polymorphic constructors taking
<code>in_place_type_t</code> and an intializer list.</p></li>
<li><p>Order <code>polymorphic</code> constructor constraints
consistently.</p></li>
<li><p>Remove needless introduction of <code>UU</code> in
<code>indirect</code> constraints.</p></li>
<li><p>Update discussion of constraints and incomplete type support in
appendix.</p></li>
</ul>
<h2 id="changes-in-r12">Changes in R12</h2>
<ul>
<li><p>Fix <code>indirect</code> synopsis to include
<code>explicit</code> on the default constructor.</p></li>
<li><p>Replace “may only be X” with “may be X only” in specification of
<code>indirect</code> and <code>polymorphic</code>.</p></li>
<li><p>Change <em>constraints</em> on <code>T</code> where
<code>T</code> could be an incomplete type to
<em>mandates</em>.</p></li>
<li><p>Remove <em>mandates</em> that <code>T</code> is a complete type
where this is implicitly required by type_traits.</p></li>
<li><p><code>T</code> in <code>indirect</code> needs to be
copy-constructible only for the copy constructor(s).</p></li>
<li><p>Add discussion of constraints and incomplete type support in
appendix.</p></li>
<li><p>Fix specification of <code>&lt;=&gt;</code> to use
<code>synth-three-way-result</code>.</p></li>
<li><p>Change <em>constraints</em> on <code>operator==</code> for
<code>indirect</code> to <em>mandates</em>.</p></li>
<li><p>Remove constraints on <code>operator&lt;=&gt;</code> for
<code>indirect</code>.</p></li>
<li><p>Updates to non-technical specification sections to reflect design
revisions for constraints and comparison.</p></li>
</ul>
<h2 id="changes-in-r11">Changes in R11</h2>
<ul>
<li><p>Remove unnecesary <code>remove_const</code> from the
specification of hash for indirect.</p></li>
<li><p>Add a default template type parameter for single-argument
constructors for indirect and polymorphic and for indirect’s
perfect-forwarding assignment.</p></li>
<li><p>Add postconditions to say that the moved-from
<code>indirect</code> is valueless in move assigment, move constructor
and allocator-extended move construction. The same does not apply for
polymorphic which permits a small buffer optimization.</p></li>
<li><p>Add drafting note for use of italicised code font for exposition
only variables.</p></li>
<li><p>Prevent <code>T</code> from being <code>in_place_t</code> or a
specialization of <code>in_place_type_t</code> for both indirect and
polymorphic.</p></li>
<li><p>Collect <code>in_place_t</code> and <code>in_place_type_t</code>
constructors together.</p></li>
<li><p>Define <code>UU</code> as <code>remove_cvref_t&lt;U&gt;</code> to
simplify various requirements.</p></li>
<li><p>Use <code>derived_from</code> rather than
<code>is_base_of_v</code> in requirements for polymorphic.</p></li>
<li><p>Require <code>is_same_v&lt;remove_cvref_t&lt;U&gt;, U&gt;</code>
for <code>polymorphic</code> constructors taking
<code>in_place_type_t&lt;U&gt;</code>.</p></li>
<li><p>Check <code>is_same_v</code> constraints first.</p></li>
</ul>
<h2 id="changes-in-r10">Changes in R10</h2>
<ul>
<li><p>Correct naming of explicit ‘converting’ constructors to
‘single-argument’ constructors.</p></li>
<li><p>Amend naming of indirect’s ‘converting’ constructor to
‘perfect-forwarded’ assignment.</p></li>
<li><p>Correct changelog from R9.</p></li>
</ul>
<h2 id="changes-in-r9">Changes in R9</h2>
<ul>
<li><p>Move throws clauses from individual constructor specifications to
the start of constructors specification for indirect and
polymorphic.</p></li>
<li><p>Re-order constructors.</p></li>
<li><p>Add perfect-forwarded assignment operator to
<code>indirect</code>.</p></li>
<li><p>Add single-argument constructors to <code>indirect</code> and
<code>polymorphic</code>.</p></li>
<li><p>Add intializer list constructors to <code>indirect</code> and
<code>polymorphic</code>.</p></li>
<li><p>Avoid use of ‘heap’ and ‘free-store’ in favour of
‘dynamically-allocated storage’.</p></li>
</ul>
<h2 id="changes-in-r8">Changes in R8</h2>
<ul>
<li><p>Wording cleanup in parallel with independent
implementation.</p></li>
<li><p>Add more explicit wording for use of
<code>allocator_traits::construct</code> in <code>indirect</code> and
<code>polymorphic</code> constructors.</p></li>
<li><p>Prevent <code>indirect</code> and <code>polymorphic</code>
classes from being instantiated with <code>in_place_t</code> and
specializations of <code>in_place_type_t</code>.</p></li>
<li><p>Strike mandates <code>T</code> is a complete type from indirect
comparison operators and hash for consistency with reference
wrapper.</p></li>
</ul>
<h2 id="changes-in-r7">Changes in R7</h2>
<ul>
<li><p>Discuss <code>indirect</code>’s non-conditional copy constructor
in the light of implementation tricks that would enable it.</p></li>
<li><p>Improve wording for assignment operators to remove
ambiguity.</p></li>
<li><p>Add motivation for <code>valueless_after_move</code> member
function.</p></li>
</ul>
<h2 id="changes-in-r6">Changes in R6</h2>
<ul>
<li><p>Add <code>std::in_place_t</code> argument to indirect
constructors.</p></li>
<li><p>Amend wording for assignment operators to provide strong
exception guarantee.</p></li>
<li><p>Amend wording for swap to consider the valueless state.</p></li>
<li><p>Remove comparison operators for <code>indirect</code> where they
can be compiler-synthesized.</p></li>
<li><p>Rename erroneous exposition only variable <code>allocator</code>
to <code>alloc</code>.</p></li>
<li><p>Add drafting note on exception guarantees behaviour to
<code>swap</code>.</p></li>
</ul>
<h2 id="changes-in-r5">Changes in R5</h2>
<ul>
<li><p>Fix wording for assignment operators to provide strong exception
guarantee.</p></li>
<li><p>Add missing wording for valueless hash.</p></li>
</ul>
<h2 id="changes-in-r4">Changes in R4</h2>
<ul>
<li><p>Use constraints to require that the object owned by
<code>indirect</code> is copy constructible. This ensures that
<code>std::is_copy_constructible_v</code> does not give misleading
results.</p></li>
<li><p>Modify comparison of <code>indirect</code> allow comparsion of
valueless objects. Comparisons are implemented in terms of
<code>operator==</code> and <code>operator&lt;=&gt;</code> returning
<code>bool</code> and <code>auto</code>.</p></li>
<li><p>Remove <code>std::format</code> support for
<code>std::indirect</code> as it cannot handle a valueless
state.</p></li>
<li><p>Allow copy, move, assign and swap of valueless objects, discuss
similarities with variant.</p></li>
<li><p>No longer specify constructors as uses-allocator constructing
anything.</p></li>
<li><p>Require <code>T</code> to satisfy the requirements of
<code>Cpp17Destructible</code>.</p></li>
<li><p>Rename exposition only variables <code>p_</code> to
<code>p</code> and <code>allocator_</code> to
<code>alloc</code>.</p></li>
<li><p>Add discussion on incomplete types.</p></li>
<li><p>Add discussion on explicit constructors.</p></li>
<li><p>Add discussion on arithmetic operators and update change
table.</p></li>
<li><p>Remove references to
<code>std::indirect</code>/<code>std::polymorphic</code> values terms
under <code>[*.general]</code> sections.</p></li>
</ul>
<h2 id="changes-in-r3">Changes in R3</h2>
<ul>
<li><p>Add explicit to constructors.</p></li>
<li><p>Add constructor
<code>indirect(U&amp;&amp; u, Us&amp;&amp;... us)</code> overload and
requisite constraints.</p></li>
<li><p>Add constructor
<code>polymorphic(allocator_arg_t, const Allocator&amp; a)</code>
overload.</p></li>
<li><p>Add discussion on similarities and differences with
variant.</p></li>
<li><p>Add table of breaking and non-breaking changes to appendix
C.</p></li>
<li><p>Add missing comparison operators and ensure they are all
conditionally noexcept.</p></li>
<li><p>Add argument deduction guides for
<code>std::indirect</code>.</p></li>
<li><p>Address incorrect <code>std::indirect</code> usage in composite
example.</p></li>
<li><p>Additions to acknowledgements.</p></li>
<li><p>Address wording for <code>swap()</code> relating to
<code>noexcept</code>.</p></li>
<li><p>Address constraints wording for <code>std::indirect</code>
comparison operators.</p></li>
<li><p>Copy constructor now uses<br />
<code>allocator_traits::select_on_container_copy_construction</code>.</p></li>
<li><p>Ensure swap and assign with self are nops.</p></li>
<li><p>Move feature test macros to [version.syn].</p></li>
<li><p>Remove <code>std::optional</code> specializations.</p></li>
<li><p>Replace use of “erroneous” with “undefined behaviour”.</p></li>
<li><p>Strong exception guarantee for copy assignment.</p></li>
<li><p>Specify constructors as uses-allocator constructing
<code>T</code>.</p></li>
<li><p>Wording review and additions to <code>&lt;memory&gt;</code>
synopsis [memory.syn]</p></li>
</ul>
<h2 id="changes-in-r2">Changes in R2</h2>
<ul>
<li><p>Add discussion on returning <code>auto</code> for
<code>std::indirect</code> comparison operators.</p></li>
<li><p>Add discussion of <code>emplace()</code> to appendix.</p></li>
<li><p>Update wording to support allocator awareness.</p></li>
</ul>
<h2 id="changes-in-r1">Changes in R1</h2>
<ul>
<li><p>Add feature-test macros.</p></li>
<li><p>Add <code>std::format</code> support for
<code>std::indirect</code></p></li>
<li><p>Add Appendix B before and after examples.</p></li>
<li><p>Add preconditions checking for types are not valueless.</p></li>
<li><p>Add constexpr support.</p></li>
<li><p>Allow quality of implementation support for small buffer
optimization for <code>polymorphic</code>.</p></li>
<li><p>Extend wording for allocator support.</p></li>
<li><p>Change <em>constraints</em> to <em>mandates</em> to enable
support for incomplete types.</p></li>
<li><p>Change pointer usage to use <code>allocator_traits</code>
pointer.</p></li>
<li><p>Remove <code>std::uses_allocator</code> specliazations.</p></li>
<li><p>Remove <code>std::inplace_t</code> parameter in constructors for
<code>std::indirect</code>.</p></li>
<li><p>Fix <code>sizeof</code> error.</p></li>
</ul>
<h1 id="motivation">Motivation</h1>
<p>The standard library has no vocabulary type for a
dynamically-allocated object with value semantics. When designing a
composite class, we may need an object to be stored indirectly to
support incomplete types, reduce object size or support open-set
polymorphism.</p>
<p>We propose the addition of two new class templates to the standard
library to represent indirectly stored values: <code>indirect</code> and
<code>polymorphic</code>. Both class templates represent
dynamically-allocated objects with value-like semantics.
<code>polymorphic&lt;T&gt;</code> can own any object of a type publicly
derived from <code>T</code>, allowing composite classes to contain
polymorphic components. We require the addition of two classes to avoid
the cost of virtual dispatch (calling the copy constructor of a
potentially derived-type object through type erasure) when copying of
polymorphic objects is not needed.</p>
<h1 id="design-requirements">Design requirements</h1>
<p>We review the fundamental design requirements of
<code>indirect</code> and <code>polymorphic</code> that make them
suitable for composite class design.</p>
<h2 id="special-member-functions">Special member functions</h2>
<p>Both class templates are suitable for use as members of composite
classes where the compiler will generate special member functions. This
means that the class templates should provide the special member
functions where they are supported by the owned object type
<code>T</code>. As <code>T</code> may be an incomplete type, the special
member functions are unconditionally available to participate in
overload resolution but would lead to an ill-formed program if they are
called for a type that does not support them.</p>
<h2 id="deep-copies">Deep copies</h2>
<p>Copies of <code>indirect&lt;T&gt;</code> and
<code>polymorphic&lt;T&gt;</code> should own copies of the owned object
created with the copy constructor of the owned object. In the case of
<code>polymorphic&lt;T&gt;</code>, this means that the copy should own a
copy of a potentially derived type object created with the copy
constructor of the derived type object.</p>
<p>Note: Including a <code>polymorphic</code> component in a composite
class means that virtual dispatch will be used (through type erasure) in
copying the <code>polymorphic</code> member. Where a composite class
contains a polymorphic member from a known set of types, prefer
<code>std::variant</code> or <code>indirect&lt;std::variant&gt;</code>
if indirect storage is required.</p>
<h2 id="const-propagation"><code>const</code> propagation</h2>
<p>When composite objects contain <code>pointer</code>,
<code>unique_ptr</code> or <code>shared_ptr</code> members they allow
non-const access to their respective pointees when accessed through a
const access path. This prevents the compiler from eliminating a source
of const-correctness bugs and makes it difficult to reason about the
const-correctness of a composite object.</p>
<p>Accessors of unique and shared pointers do not have const and
non-const overloads:</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a>T<span class="op">*</span> unique_ptr<span class="op">&lt;</span>T<span class="op">&gt;::</span><span class="kw">operator</span><span class="op">-&gt;()</span> <span class="at">const</span><span class="op">;</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>T<span class="op">&amp;</span> unique_ptr<span class="op">&lt;</span>T<span class="op">&gt;::</span><span class="kw">operator</span><span class="op">*()</span> <span class="at">const</span><span class="op">;</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>T<span class="op">*</span> shared_ptr<span class="op">&lt;</span>T<span class="op">&gt;::</span><span class="kw">operator</span><span class="op">-&gt;()</span> <span class="at">const</span><span class="op">;</span></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a>T<span class="op">&amp;</span> shared_ptr<span class="op">&lt;</span>T<span class="op">&gt;::</span><span class="kw">operator</span><span class="op">*()</span> <span class="at">const</span><span class="op">;</span></span></code></pre></div>
<p>When a parent object contains a member of type
<code>indirect&lt;T&gt;</code> or <code>polymorphic&lt;T&gt;</code>,
access to the owned object (of type <code>T</code>) through a const
access path should be <code>const</code> qualified.</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> A <span class="op">{</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">enum</span> <span class="kw">class</span> Constness <span class="op">{</span> CONST<span class="op">,</span> NON_CONST <span class="op">};</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>    Constness foo<span class="op">()</span> <span class="op">{</span> <span class="cf">return</span> Constness<span class="op">::</span>NON_CONST<span class="op">;</span> <span class="op">}</span></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>    Constness foo<span class="op">()</span> <span class="at">const</span> <span class="op">{</span> <span class="cf">return</span> Constness<span class="op">::</span>CONST<span class="op">;</span> <span class="op">}</span></span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a><span class="op">};</span></span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> Composite <span class="op">{</span></span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a>    indirect<span class="op">&lt;</span>A<span class="op">&gt;</span> <span class="va">a_</span><span class="op">;</span></span>
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-10"><a href="#cb2-10" aria-hidden="true" tabindex="-1"></a>    Constness foo<span class="op">()</span> <span class="op">{</span> <span class="cf">return</span> <span class="va">a_</span><span class="op">-&gt;</span>foo<span class="op">();</span> <span class="op">}</span></span>
<span id="cb2-11"><a href="#cb2-11" aria-hidden="true" tabindex="-1"></a>    Constness foo<span class="op">()</span> <span class="at">const</span> <span class="op">{</span> <span class="cf">return</span> <span class="va">a_</span><span class="op">-&gt;</span>foo<span class="op">();</span> <span class="op">}</span></span>
<span id="cb2-12"><a href="#cb2-12" aria-hidden="true" tabindex="-1"></a><span class="op">};</span></span>
<span id="cb2-13"><a href="#cb2-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-14"><a href="#cb2-14" aria-hidden="true" tabindex="-1"></a><span class="dt">int</span> main<span class="op">()</span> <span class="op">{</span></span>
<span id="cb2-15"><a href="#cb2-15" aria-hidden="true" tabindex="-1"></a>    Composite c<span class="op">;</span></span>
<span id="cb2-16"><a href="#cb2-16" aria-hidden="true" tabindex="-1"></a>    <span class="ot">assert</span><span class="op">(</span>c<span class="op">.</span>foo<span class="op">()</span> <span class="op">==</span> A<span class="op">::</span>Constness<span class="op">::</span>NON_CONST<span class="op">);</span></span>
<span id="cb2-17"><a href="#cb2-17" aria-hidden="true" tabindex="-1"></a>    <span class="at">const</span> Composite<span class="op">&amp;</span> cc <span class="op">=</span> c<span class="op">;</span></span>
<span id="cb2-18"><a href="#cb2-18" aria-hidden="true" tabindex="-1"></a>    <span class="ot">assert</span><span class="op">(</span>cc<span class="op">.</span>foo<span class="op">()</span> <span class="op">==</span> A<span class="op">::</span>Constness<span class="op">::</span>CONST<span class="op">);</span></span>
<span id="cb2-19"><a href="#cb2-19" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<h2 id="value-semantics">Value semantics</h2>
<p>Both <code>indirect</code> and <code>polymorphic</code> are value
types whose owned object’s storage is managed by the specified
allocator.</p>
<p>When a value type is copied it gives rise to two independent objects
that can be modified separately.</p>
<p>The owned object is part of the logical state of
<code>indirect</code> and <code>polymorphic</code>. Operations on a
const-qualified object do not make changes to the object’s logical state
nor to the logical state of owned objects.</p>
<h2 id="the-valueless-state-and-interaction-with-stdoptional">The
valueless state and interaction with <code>std::optional</code></h2>
<p>Both <code>indirect</code> and <code>polymorphic</code> have a
valueless state that is used to implement move. The valueless state is
not intended to be observable to the user. There is no
<code>operator bool</code> or <code>has_value</code> member function.
Accessing the value of an <code>indirect</code> or
<code>polymorphic</code> after it has been moved from is undefined
behaviour. We provide a <code>valueless_after_move</code> member
function that returns <code>true</code> if an object is in a valueless
state. This allows explicit checks for the valueless state in cases
where it cannot be verified statically.</p>
<p>Without a valueless state, moving <code>indirect</code> or
<code>polymorphic</code> would require allocation and moving from the
owned object. This would be expensive and would require the owned object
to be moveable. The existence of a valueless state allows move to be
implemented cheaply without requiring the owned object to be
moveable.</p>
<p>Where a nullable <code>indirect</code> or <code>polymorphic</code> is
required, using <code>std::optional</code> is recommended. This may
become common practice since <code>indirect</code> and
<code>polymorphic</code> can replace smart pointers in composite
classes, where they are currently used to (mis)represent component
objects. Using dynamically-allocated storage for <code>T</code> should
not make it nullable. Nullability must be explicitly opted into by using
<code>std::optional&lt;indirect&lt;T&gt;&gt;</code> or
<code>std::optional&lt;polymorphic&lt;T&gt;&gt;</code>.</p>
<h2 id="allocator-support">Allocator support</h2>
<p>Both <code>indirect</code> and <code>polymorphic</code> are
allocator-aware types. They must be suitable for use in allocator-aware
composite types and containers. Existing allocator-aware types in the
standard, such as <code>vector</code> and <code>map</code>, take an
allocator type as a template parameter, provide
<code>allocator_type</code>, and have constructor overloads taking an
additional <code>allocator_type_t</code> and allocator instance as
arguments. As <code>indirect</code> and <code>polymorphic</code> need to
work with, and in the same way, as existing allocator-aware types, they
too take an allocator type as a template parameter, provide
<code>allocator_type</code>, and have constructor overloads taking an
additional <code>allocator_type_t</code> and allocator instance as
arguments.</p>
<h2 id="modelled-types">Modelled types</h2>
<p>The class templates <code>indirect</code> and
<code>polymorphic</code> have strong similarities to existing class
templates. These similarities motivate much of the design; we aim for
consistency with existing library types, not innovation.</p>
<h3 id="modelled-types-for-indirect">Modelled types for
<code>indirect</code></h3>
<p>The class template <code>indirect</code> owns an object of known
type, permits copies, propagates const and is allocator aware.</p>
<ul>
<li><p>Like <code>optional</code> and <code>unique_ptr</code>,
<code>indirect</code> can be in a valueless state; <code>indirect</code>
can get into the valueless state only after being moved from, or after
assignment or construction from a valueless state.</p></li>
<li><p><code>unique_ptr</code> and <code>optional</code> have
preconditions for <code>operator-&gt;</code> and <code>operator*</code>:
the behavior is undefined if <code>*this</code> does not contain a
value.</p></li>
<li><p><code>unique_ptr</code> and <code>optional</code> mark
<code>operator-&gt;</code> and <code>operator*</code> as noexcept:
<code>indirect</code> does the same.</p></li>
<li><p><code>optional</code> and <code>indirect</code> know the
underlying type of the owned object so can implement r-value qualified
versions of <code>operator*</code>. For <code>unique_ptr</code>, the
underlying type is not known (it could be an instance of a derived
class) so r-value qualified versions of <code>operator*</code> are not
provided.</p></li>
<li><p>Like <code>vector</code>, <code>indirect</code> owns an object
created by an allocator. The move constructor and move assignment
operator for <code>vector</code> are conditionally noexcept on
properties of the allocator. Thus for <code>indirect</code>, the move
constructor and move assignment operator are conditionally noexcept on
properties of the allocator. (Allocator instances may have different
underlying memory resources; it is not possible for an allocator with
one memory resource to delete an object in another memory resource. When
allocators have different underlying memory resources, move necessitates
the allocation of memory and cannot be marked noexcept.) Like
<code>vector</code>, <code>indirect</code> marks member and non-member
<code>swap</code> as noexcept and requires allocators to be
equal.</p></li>
<li><p>Like <code>optional</code>, <code>indirect</code> knows the type
of the owned object so it can forward comparison operators and hash to
the underlying object. A valueless <code>indirect</code>, like an empty
<code>optional</code>, hashes to an implementation-defined
value.</p></li>
</ul>
<h3 id="modelled-types-for-polymorphic">Modelled types for
<code>polymorphic</code></h3>
<p>The class template <code>polymorphic</code> owns an object of unknown
type, requires copies, propagates const and is allocator aware.</p>
<ul>
<li><p>Like <code>optional</code> and <code>unique_ptr</code>,
<code>polymorphic</code> can be in a valueless state;
<code>polymorphic</code> can get into the valueless state only after
being moved from, or after assignment or construction from a valueless
state.</p></li>
<li><p><code>unique_ptr</code> and <code>optional</code> have
preconditions for <code>operator-&gt;</code> and <code>operator*</code>:
the behavior is undefined if <code>*this</code> does not contain a
value.</p></li>
<li><p><code>unique_ptr</code> and <code>optional</code> mark
<code>operator-&gt;</code> and <code>operator*</code> as noexcept:
<code>polymorphic</code> does the same.</p></li>
<li><p>Neither <code>unique_ptr</code> nor <code>polymorphic</code> know
the underlying type of the owned object so cannot implement r-value
qualified versions of <code>operator*</code>. For <code>optional</code>,
the underlying type is known, so r-value qualified versions of
<code>operator*</code> are provided.</p></li>
<li><p>Like <code>vector</code>, <code>polymorphic</code> owns an object
created by an allocator. The move constructor and move assignment
operator for <code>vector</code> are conditionally noexcept on
properties of the allocator. Thus for <code>polymorphic</code>, the move
constructor and move assignment operator are conditionally noexcept on
properties of the allocator. Like <code>vector</code>,
<code>polymorphic</code> marks member and non-member <code>swap</code>
as noexcept and requires allocators to be equal.</p></li>
<li><p>Like <code>unique_ptr</code>, <code>polymorphic</code> does not
know the type of the owned object (it could be an instance of a derived
type). As a result, <code>polymorphic</code> cannot forward comparison
operators or hash to the owned object.</p></li>
</ul>
<h3 id="similarities-and-differences-with-variant">Similarities and
differences with variant</h3>
<p>The sum type <code>variant&lt;Ts...&gt;</code> models one of several
alternatives; <code>indirect&lt;T&gt;</code> models a single type
<code>T</code>, but with different storage constraints to
<code>T</code>.</p>
<p>Like <code>indirect</code>, a variant can get into a valueless state.
For <code>variant</code>, this valueless state is accessible when an
exception is thrown when changing the type: variant has
<code>bool valueless_by_exception()</code>. When all of the types
<code>Ts</code> are comparable, <code>variant&lt;Ts...&gt;</code>
supports comparison without preconditions: it is valid to compare
variants when they are in a valueless state. Variant comparisons can
account for the valueless state with zero cost. A variant must check
which type is the engaged type to perform comparison; valueless is one
of the possible states it can be in. For <code>indirect</code>, allowing
comparison when in a valueless state necessitates the addition of an
otherwise redundant check. After feedback from standard library
implementers, we opt to allow hash and comparison of
<code>indirect</code> in a valueless state, at cost, to avoid making
comparison or hash of <code>indirect</code> in a valueless state
undefined behaviour.</p>
<p><code>variant</code> allows valueless objects to be passed around via
copy, assignment, move and move assignment. There is no precondition on
<code>variant</code> that it must not be in a valueless state to be
copied from, moved from, assigned from or move assigned from. While the
notion that a valueless <code>indirect</code> or
<code>polymorphic</code> is toxic and must not be passed around code is
appealing, it would not interact well with generic code which may need
to handle a variety of types. Note that the standard does not require a
moved-from object to be valid for copy, move, assign or move assignment:
the restriction is only that it should be in a well-formed but
unspecified state. However, there is no precedent for standard library
types to have preconditions on move, copy, assign or move assignment. We
opt for consistency with existing standard library types (namely
<code>variant</code>, which has a valueless state) and allow copy, move,
assignment and move assignment of a valueless <code>indirect</code> and
<code>polymorphic</code>. Handling of the valueless state for
<code>indirect</code> and <code>polymorphic</code> in move operations
will not incur cost; for copy operations, the cost of handling the
valueless state will be insignificant compared to the cost of allocating
memory. Introducing preconditions for copy, move, assign and move assign
in a later revision of the C++ standard would be a silent breaking
change.</p>
<p>Like <code>variant</code>, <code>indirect</code> does not support
formatting by forwarding to the owned object. There may be no owned
object to format so we require the user to write code to determine how
to format a valueless <code>indirect</code> or to validate that the
<code>indirect</code> is not valueless before formatting <code>*i</code>
(where <code>i</code> is an instance of <code>indirect</code> for some
formattable type <code>T</code>).</p>
<h2 id="noexcept-and-narrow-contracts"><code>noexcept</code> and narrow
contracts</h2>
<p>C++ library design guidelines recommend that member functions with
narrow contracts (runtime preconditions) should not be marked
<code>noexcept</code>. This is partially motivated by a non-vendor
implementation of the C++ standard library that uses exceptions in a
debug build to check for precondition violations by throwing an
exception. The <code>noexcept</code> status of
<code>operator-&gt;</code> and <code>operator*</code> for
<code>indirect</code> and <code>polymorphic</code> is identical to that
of <code>optional</code> and <code>unique_ptr</code>. All have
preconditions (<code>*this</code> cannot be valueless), all are marked
<code>noexcept</code>. Whatever strategy was used for testing
<code>optional</code> and <code>unique_ptr</code> can be used for
<code>indirect</code> and <code>polymorphic</code>.</p>
<p>Not marking <code>operator-&gt;</code> and <code>operator*</code> as
<code>noexcept</code> for <code>indirect</code> and
<code>polymorphic</code> would make them strictly less useful than
<code>unique_ptr</code> in contexts where they would otherwise be a
valid replacement.</p>
<h2 id="tagged-constructors">Tagged constructors</h2>
<p>Constructors for <code>indirect</code> and <code>polymorphic</code>
taking an allocator or owned-object constructor arguments are tagged
with <code>allocator_arg_t</code> and <code>in_place_t</code> (or
<code>in_place_type_t</code>) respectively. This is consistent with the
standard library’s use of tagged constructors in <code>optional</code>,
<code>any</code> and <code>variant</code>.</p>
<p>Without <code>in_place_t</code> the constructor of
<code>indirect</code> would not be able to construct an owned object
using the owned object’s allocator-extended constructor.
<code>indirect(std::in_place, std::allocator_arg, alloc, args)</code>
constructs an <code>indirect</code> with a default-constructed allocator
and an owned object constructed with an allocator-extended constructor
taking an allocator <code>alloc</code> and constructor arguments
<code>args</code>.</p>
<p>For comparison,
<code>indirect(std::allocator_arg, a, std::in_place, std::allocator_arg, alloc, args)</code>
constructs an <code>indirect</code> with an allocator <code>a</code> and
an owned object constructed with an allocator-extended constructor
taking an allocator <code>alloc</code> and constructor arguments
<code>args</code>.</p>
<h2 id="single-argument-constructors">Single-argument constructors</h2>
<p>In line with <code>optional</code> and <code>variant</code>, we add
single-argument constructors to both <code>indirect</code> and
<code>polymorphic</code> so they can be constructed from single values
without the need to use <code>in_place</code> or
<code>in_place_type</code>. As <code>indirect</code> and
<code>polymorphic</code> are allocator-aware types, we also provide
allocator-extended versions of these constructors, in line with those
from <code>basic_optional</code> [2] and existing constructors from
<code>indirect</code> and <code>polymorphic</code>.</p>
<h2 id="initializer-list-constructors">Initializer-list
constructors</h2>
<p>We add initializer-list constructors to both <code>indirect</code>
and <code>polymorphic</code> in line with those in <code>optional</code>
and <code>variant</code>. As <code>indirect</code> and
<code>polymorphic</code> are allocator-aware types, we provide
allocator-extended versions of these constructors, in line with those
from <code>basic_optional</code> [2] and existing constructors from
<code>indirect</code> and <code>polymorphic</code>.</p>
<h2 id="explicit-constructors">Explicit constructors</h2>
<p>Constructors for <code>indirect</code> and <code>polymorphic</code>
are marked as explicit. This disallows “implicit conversion” from single
arguments or braced initializers. Given both <code>indirect</code> and
<code>polymorphic</code> use dynamically-allocated storage, there are no
instances where an object could be considered semantically equivalent to
its constructor arguments (unlike <code>pair</code> or
<code>variant</code>). To construct an <code>indirect</code> or
<code>polymorphic</code> object, and with it use dynamically-allocated
memory, the user must explicitly use a constructor.</p>
<p>The standard already marks multiple argument constructors as explicit
for the inplace constructors of <code>optional</code> and
<code>any</code>.</p>
<p>With some suitably compelling motivation, the <code>explicit</code>
keyword could be removed from some constructors in a later revision of
the C++ standard without rendering code ill-formed.</p>
<h2 id="perfect-forwarded-assignment">Perfect-forwarded assignment</h2>
<h3 id="perfect-forwarded-assignment-for-indirect">Perfect-forwarded
assignment for <code>indirect</code></h3>
<p>We add a perfect-forwarded assignment operator for
<code>indirect</code> in line with those from <code>optional</code> and
<code>variant</code>.</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> U<span class="op">=</span>T<span class="op">&gt;</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> optional<span class="op">&amp;</span> <span class="kw">operator</span><span class="op">=(</span>U<span class="op">&amp;&amp;</span> u<span class="op">);</span></span></code></pre></div>
<p>When assigning to an <code>indirect</code>, there is potential for
optimisation if there is an existing owned object to be assigned to:</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a>indirect<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;</span> i<span class="op">;</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>foo<span class="op">(</span>i<span class="op">);</span>  <span class="co">// could move from `i`.</span></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> <span class="op">(!</span>i<span class="op">.</span>valueless_after_move<span class="op">())</span> <span class="op">{</span></span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a>  <span class="op">*</span>i <span class="op">=</span> <span class="dv">5</span><span class="op">;</span></span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span> <span class="cf">else</span> <span class="op">{</span></span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a>  i <span class="op">=</span> indirect<span class="op">(</span><span class="dv">5</span><span class="op">);</span></span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>With perfect-forwarded assignment, handling the valueless state and
potentially creating a new indirect object is done within the
perfect-forwarded assignment. The code below is equivalent to the code
above:</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a>indirect<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;</span> i<span class="op">;</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>foo<span class="op">(</span>i<span class="op">);</span> <span class="co">// could move from `i`.</span></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>i <span class="op">=</span> <span class="dv">5</span><span class="op">;</span></span></code></pre></div>
<h3 id="perfect-forwarded-assignment-for-polymorphic">Perfect-forwarded
assignment for <code>polymorphic</code></h3>
<p>There is no perfect-forwarded assignment for <code>polymorphic</code>
as type information is erased. There is no optimisation opportunity to
be made as a new object will need creating regardless of whether the
target of assignment is valueless or not.</p>
<h2 id="the-valueless_after_move-member-function">The
<code>valueless_after_move</code> member function</h2>
<p>Both <code>indirect</code> and <code>polymorphic</code> have a
<code>valueless_after_move</code> member function that is used to query
the object state. This member function should rarely be called: it
should be clear through static analysis whether or not an object has
been moved from. The <code>valueless_after_move</code> member function
allows explicit checks for the valueless state in cases where it cannot
be verified statically or where explicit checks might be required by a
coding standard such as MISRA or High Integrity C++.</p>
<h2 id="design-for-polymorphic-types">Design for polymorphic types</h2>
<p>A type <code>PolymorphicInterface</code> used as a base class with
<code>polymorphic</code> does not need a virtual destructor. The same
mechanism that is used to call the copy constructor of a potentially
derived-type object will be used to call the destructor.</p>
<p>To allow compiler-generation of special member functions of an
abstract interface type <code>PolymorphicInterface</code> in conjunction
with <code>polymorphic</code>, <code>PolymorphicInterface</code> needs
at least a non-virtual protected destructor and a protected copy
constructor. <code>PolymorphicInterface</code> does not need to be
assignable, move constructible or move assignable for
<code>polymorphic&lt;PolymorphicInterface&gt;</code> to be assignable,
move constructible or move assignable.</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> PolymorphicInterface <span class="op">{</span></span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">protected</span><span class="op">:</span></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a>    PolymorphicInterface<span class="op">(</span><span class="at">const</span> PolymorphicInterface<span class="op">&amp;)</span> <span class="op">=</span> <span class="cf">default</span><span class="op">;</span></span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a>    <span class="op">~</span>PolymorphicInterface<span class="op">()</span> <span class="op">=</span> <span class="cf">default</span><span class="op">;</span></span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">public</span><span class="op">:</span></span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a>   <span class="co">// virtual functions</span></span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a><span class="op">};</span></span></code></pre></div>
<p>For an interface type with a public virtual destructor, users would
potentially pay the cost of virtual dispatch twice when deleting
<code>polymorphic&lt;I&gt;</code> objects containing derived-type
objects.</p>
<p>All derived types owned by a <code>polymorphic</code> must be
publicly copy constructible.</p>
<h1 id="prior-work">Prior work</h1>
<p>This proposal continues the work started in [P0201] and [P1950].</p>
<p>Previous work on a cloned pointer type [N3339] met with opposition
because of the mixing of value and pointer semantics. We believe that
the unambiguous value semantics of <code>indirect</code> and
<code>polymorphic</code> as described in this proposal address these
concerns.</p>
<h1 id="impact-on-the-standard">Impact on the standard</h1>
<p>This proposal is a pure library extension. It requires additions to
be made to the standard library header <code>&lt;memory&gt;</code>.</p>
<h1 id="technical-specifications">Technical specifications</h1>
<h2 id="header-version-synopsis-version.syn">Header
<code>&lt;version&gt;</code> synopsis [version.syn]</h2>
<p>Note to editors: Add the following macros with editor provided values
to [version.syn]</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="pp">#define __cpp_lib_indirect </span><span class="op">??????</span>L<span class="pp">    </span><span class="co">// also in &lt;memory&gt;</span></span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a><span class="pp">#define __cpp_lib_polymorphic </span><span class="op">??????</span>L<span class="pp"> </span><span class="co">// also in &lt;memory&gt;</span></span></code></pre></div>
<h2 id="header-memory-synopsis-memory">Header
<code>&lt;memory&gt;</code> synopsis [memory]</h2>
<div class="sourceCode" id="cb8"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="kw">namespace</span> std <span class="op">{</span></span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a>  <span class="co">// [inout.ptr], function template inout_ptr</span></span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> Pointer <span class="op">=</span> <span class="dt">void</span><span class="op">,</span> <span class="kw">class</span> Smart<span class="op">,</span> <span class="kw">class</span><span class="op">...</span> Args<span class="op">&gt;</span></span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">auto</span> inout_ptr<span class="op">(</span>Smart<span class="op">&amp;</span> s<span class="op">,</span> Args<span class="op">&amp;&amp;...</span> args<span class="op">);</span></span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true" tabindex="-1"></a><span class="op">&lt;</span>ins<span class="op">&gt;</span></span>
<span id="cb8-8"><a href="#cb8-8" aria-hidden="true" tabindex="-1"></a><span class="co">// DRAFTING </span><span class="al">NOTE</span><span class="co">: not sure how to typeset &lt;ins&gt; reasonably in markdown</span></span>
<span id="cb8-9"><a href="#cb8-9" aria-hidden="true" tabindex="-1"></a>  <span class="co">// [indirect], class template indirect</span></span>
<span id="cb8-10"><a href="#cb8-10" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> T<span class="op">,</span> <span class="kw">class</span> Allocator <span class="op">=</span> allocator<span class="op">&lt;</span>T<span class="op">&gt;&gt;</span></span>
<span id="cb8-11"><a href="#cb8-11" aria-hidden="true" tabindex="-1"></a>    <span class="kw">class</span> indirect<span class="op">;</span></span>
<span id="cb8-12"><a href="#cb8-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-13"><a href="#cb8-13" aria-hidden="true" tabindex="-1"></a>  <span class="co">// [indirect.hash], hash support</span></span>
<span id="cb8-14"><a href="#cb8-14" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> T<span class="op">,</span> <span class="kw">class</span> Alloc<span class="op">&gt;</span> <span class="kw">struct</span> hash<span class="op">&lt;</span>indirect<span class="op">&lt;</span>T<span class="op">,</span> Alloc<span class="op">&gt;&gt;;</span></span>
<span id="cb8-15"><a href="#cb8-15" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-16"><a href="#cb8-16" aria-hidden="true" tabindex="-1"></a>  <span class="co">// [polymorphic], class template polymorphic</span></span>
<span id="cb8-17"><a href="#cb8-17" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> T<span class="op">,</span> <span class="kw">class</span> Allocator <span class="op">=</span> allocator<span class="op">&lt;</span>T<span class="op">&gt;&gt;</span></span>
<span id="cb8-18"><a href="#cb8-18" aria-hidden="true" tabindex="-1"></a>    <span class="kw">class</span> polymorphic<span class="op">;</span></span>
<span id="cb8-19"><a href="#cb8-19" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-20"><a href="#cb8-20" aria-hidden="true" tabindex="-1"></a>  <span class="kw">namespace</span> pmr <span class="op">{</span></span>
<span id="cb8-21"><a href="#cb8-21" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-22"><a href="#cb8-22" aria-hidden="true" tabindex="-1"></a>    <span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> T<span class="op">&gt;</span> <span class="kw">using</span> indirect <span class="op">=</span></span>
<span id="cb8-23"><a href="#cb8-23" aria-hidden="true" tabindex="-1"></a>      indirect<span class="op">&lt;</span>T<span class="op">,</span> polymorphic_allocator<span class="op">&lt;</span>T<span class="op">&gt;&gt;;</span></span>
<span id="cb8-24"><a href="#cb8-24" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-25"><a href="#cb8-25" aria-hidden="true" tabindex="-1"></a>    <span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> T<span class="op">&gt;</span> <span class="kw">using</span> polymorphic <span class="op">=</span></span>
<span id="cb8-26"><a href="#cb8-26" aria-hidden="true" tabindex="-1"></a>      polymorphic<span class="op">&lt;</span>T<span class="op">,</span> polymorphic_allocator<span class="op">&lt;</span>T<span class="op">&gt;&gt;;</span></span>
<span id="cb8-27"><a href="#cb8-27" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb8-28"><a href="#cb8-28" aria-hidden="true" tabindex="-1"></a><span class="op">&lt;/</span>ins<span class="op">&gt;</span></span>
<span id="cb8-29"><a href="#cb8-29" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<h2 id="x.y-class-template-indirect-indirect">X.Y Class template
indirect [indirect]</h2>
<p>[Drafting note: The member <em><code>alloc</code></em> should be
formatted as an exposition only identifier, but limitations of the
processor used to prepare this paper means not all uses are
italicised.]</p>
<h3 id="x.y.1-class-template-indirect-general-indirect.general">X.Y.1
Class template indirect general [indirect.general]</h3>
<ol type="1">
<li><p>An indirect object manages the lifetime of an owned object. An
indirect object is <em>valueless</em> if it has no owned object. An
indirect object may become valueless only after it has been moved
from.</p></li>
<li><p>In every specialization
<code>indirect&lt;T, Allocator&gt;</code>, if the type
<code>allocator_traits&lt;Allocator&gt;::value_type</code> is not the
same type as <code>T</code>, the program is ill-formed. Every object of
type <code>indirect&lt;T, Allocator&gt;</code> uses an object of type
<code>Allocator</code> to allocate and free storage for the owned object
as needed.</p></li>
<li><p>Constructing an owned object with <code>args...</code> using the
allocator <code>a</code> means calling<br />
<code>allocator_traits&lt;Allocator&gt;::construct(a, p, args...)</code>
where <code>args</code> is an expression pack, <code>a</code> is an
allocator, and <code>p</code> is a pointer obtained by calling
<code>allocator_traits&lt;Allocator&gt;::allocate</code>.</p></li>
<li><p>The member <code>alloc</code> is used for any memory allocation
and element construction performed by member functions during the
lifetime of each indirect object. The allocator <code>alloc</code> may
be replaced only via assignment or <code>swap()</code>. Allocator
replacement is performed by copy assignment, move assignment, or
swapping of the allocator only if ([container.reqmts]):
<code>allocator_traits&lt;Allocator&gt;::propagate_on_container_copy_assignment::value</code>,
or<br />
<code>allocator_traits&lt;Allocator&gt;::propagate_on_container_move_assignment::value</code>,
or<br />
<code>allocator_traits&lt;Allocator&gt;::propagate_on_container_swap::value</code>
is <code>true</code> within the implementation of the corresponding
indirect operation.</p></li>
<li><p>A program that instantiates the definition of the template
<code>indirect&lt;T, Allocator&gt;</code> with a type for the
<code>T</code> parameter that is a non-object type, an array type,
<code>in_place_t</code>, a specialization of
<code>in_place_type_t</code>, or a cv-qualified type is
ill-formed.</p></li>
<li><p>The template parameter <code>T</code> of <code>indirect</code>
may be an incomplete type.</p></li>
<li><p>The template parameter <code>Allocator</code> of
<code>indirect</code> shall meet the <em>Cpp17Allocator</em>
requirements.</p></li>
<li><p>If a program declares an explicit or partial specialization of
<code>indirect</code>, the behavior is undefined.</p></li>
</ol>
<h3 id="x.y.2-class-template-indirect-synopsis-indirect.syn">X.Y.2 Class
template indirect synopsis [indirect.syn]</h3>
<div class="sourceCode" id="cb9"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> T<span class="op">,</span> <span class="kw">class</span> Allocator <span class="op">=</span> allocator<span class="op">&lt;</span>T<span class="op">&gt;&gt;</span></span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> indirect <span class="op">{</span></span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a> <span class="kw">public</span><span class="op">:</span></span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a>  <span class="kw">using</span> <span class="dt">value_type</span> <span class="op">=</span> T<span class="op">;</span></span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">using</span> <span class="dt">allocator_type</span> <span class="op">=</span> Allocator<span class="op">;</span></span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true" tabindex="-1"></a>  <span class="kw">using</span> pointer <span class="op">=</span> <span class="kw">typename</span> allocator_traits<span class="op">&lt;</span>Allocator<span class="op">&gt;::</span>pointer<span class="op">;</span></span>
<span id="cb9-7"><a href="#cb9-7" aria-hidden="true" tabindex="-1"></a>  <span class="kw">using</span> const_pointer <span class="op">=</span> <span class="kw">typename</span> allocator_traits<span class="op">&lt;</span>Allocator<span class="op">&gt;::</span>const_pointer<span class="op">;</span></span>
<span id="cb9-8"><a href="#cb9-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-9"><a href="#cb9-9" aria-hidden="true" tabindex="-1"></a>  <span class="kw">explicit</span> <span class="kw">constexpr</span> indirect<span class="op">();</span></span>
<span id="cb9-10"><a href="#cb9-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-11"><a href="#cb9-11" aria-hidden="true" tabindex="-1"></a>  <span class="kw">explicit</span> <span class="kw">constexpr</span> indirect<span class="op">(</span><span class="dt">allocator_arg_t</span><span class="op">,</span> <span class="at">const</span> Allocator<span class="op">&amp;</span> a<span class="op">);</span></span>
<span id="cb9-12"><a href="#cb9-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-13"><a href="#cb9-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-14"><a href="#cb9-14" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> indirect<span class="op">(</span><span class="at">const</span> indirect<span class="op">&amp;</span> other<span class="op">);</span></span>
<span id="cb9-15"><a href="#cb9-15" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-16"><a href="#cb9-16" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> indirect<span class="op">(</span><span class="dt">allocator_arg_t</span><span class="op">,</span> <span class="at">const</span> Allocator<span class="op">&amp;</span> a<span class="op">,</span></span>
<span id="cb9-17"><a href="#cb9-17" aria-hidden="true" tabindex="-1"></a>                     <span class="at">const</span> indirect<span class="op">&amp;</span> other<span class="op">);</span></span>
<span id="cb9-18"><a href="#cb9-18" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-19"><a href="#cb9-19" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> indirect<span class="op">(</span>indirect<span class="op">&amp;&amp;</span> other<span class="op">)</span> <span class="kw">noexcept</span><span class="op">;</span></span>
<span id="cb9-20"><a href="#cb9-20" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-21"><a href="#cb9-21" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> indirect<span class="op">(</span><span class="dt">allocator_arg_t</span><span class="op">,</span> <span class="at">const</span> Allocator<span class="op">&amp;</span> a<span class="op">,</span></span>
<span id="cb9-22"><a href="#cb9-22" aria-hidden="true" tabindex="-1"></a>                     indirect<span class="op">&amp;&amp;</span> other<span class="op">)</span> <span class="kw">noexcept</span><span class="op">(</span>see below<span class="op">);</span></span>
<span id="cb9-23"><a href="#cb9-23" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-24"><a href="#cb9-24" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> U<span class="op">=</span>T<span class="op">&gt;</span></span>
<span id="cb9-25"><a href="#cb9-25" aria-hidden="true" tabindex="-1"></a>  <span class="kw">explicit</span> <span class="kw">constexpr</span> indirect<span class="op">(</span>U<span class="op">&amp;&amp;</span> u<span class="op">);</span></span>
<span id="cb9-26"><a href="#cb9-26" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-27"><a href="#cb9-27" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> U<span class="op">=</span>T<span class="op">&gt;</span></span>
<span id="cb9-28"><a href="#cb9-28" aria-hidden="true" tabindex="-1"></a>  <span class="kw">explicit</span> <span class="kw">constexpr</span> indirect<span class="op">(</span><span class="dt">allocator_arg_t</span><span class="op">,</span> <span class="at">const</span> Allocator<span class="op">&amp;</span> a<span class="op">,</span> U<span class="op">&amp;&amp;</span> u<span class="op">);</span></span>
<span id="cb9-29"><a href="#cb9-29" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-30"><a href="#cb9-30" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span><span class="op">...</span> Us<span class="op">&gt;</span></span>
<span id="cb9-31"><a href="#cb9-31" aria-hidden="true" tabindex="-1"></a>  <span class="kw">explicit</span> <span class="kw">constexpr</span> indirect<span class="op">(</span><span class="dt">in_place_t</span><span class="op">,</span> Us<span class="op">&amp;&amp;...</span> us<span class="op">);</span></span>
<span id="cb9-32"><a href="#cb9-32" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-33"><a href="#cb9-33" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span><span class="op">...</span> Us<span class="op">&gt;</span></span>
<span id="cb9-34"><a href="#cb9-34" aria-hidden="true" tabindex="-1"></a>  <span class="kw">explicit</span> <span class="kw">constexpr</span> indirect<span class="op">(</span><span class="dt">allocator_arg_t</span><span class="op">,</span> <span class="at">const</span> Allocator<span class="op">&amp;</span> a<span class="op">,</span></span>
<span id="cb9-35"><a href="#cb9-35" aria-hidden="true" tabindex="-1"></a>                              <span class="dt">in_place_t</span><span class="op">,</span> Us<span class="op">&amp;&amp;...</span> us<span class="op">);</span></span>
<span id="cb9-36"><a href="#cb9-36" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-37"><a href="#cb9-37" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> I<span class="op">,</span> <span class="kw">class</span><span class="op">...</span> Us<span class="op">&gt;</span></span>
<span id="cb9-38"><a href="#cb9-38" aria-hidden="true" tabindex="-1"></a>  <span class="kw">explicit</span> <span class="kw">constexpr</span> indirect<span class="op">(</span><span class="dt">in_place_t</span><span class="op">,</span> initializer_list<span class="op">&lt;</span>I<span class="op">&gt;</span> ilist<span class="op">,</span></span>
<span id="cb9-39"><a href="#cb9-39" aria-hidden="true" tabindex="-1"></a>                              Us<span class="op">&amp;&amp;...</span> us<span class="op">);</span></span>
<span id="cb9-40"><a href="#cb9-40" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-41"><a href="#cb9-41" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> I<span class="op">,</span> <span class="kw">class</span><span class="op">...</span> Us<span class="op">&gt;</span></span>
<span id="cb9-42"><a href="#cb9-42" aria-hidden="true" tabindex="-1"></a>  <span class="kw">explicit</span> <span class="kw">constexpr</span> indirect<span class="op">(</span><span class="dt">allocator_arg_t</span><span class="op">,</span> <span class="at">const</span> Allocator<span class="op">&amp;</span> a<span class="op">,</span></span>
<span id="cb9-43"><a href="#cb9-43" aria-hidden="true" tabindex="-1"></a>                              <span class="dt">in_place_t</span><span class="op">,</span> initializer_list<span class="op">&lt;</span>I<span class="op">&gt;</span> ilist<span class="op">,</span></span>
<span id="cb9-44"><a href="#cb9-44" aria-hidden="true" tabindex="-1"></a>                              Us<span class="op">&amp;&amp;...</span> us<span class="op">);</span></span>
<span id="cb9-45"><a href="#cb9-45" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-46"><a href="#cb9-46" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> <span class="op">~</span>indirect<span class="op">();</span></span>
<span id="cb9-47"><a href="#cb9-47" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-48"><a href="#cb9-48" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> indirect<span class="op">&amp;</span> <span class="kw">operator</span><span class="op">=(</span><span class="at">const</span> indirect<span class="op">&amp;</span> other<span class="op">);</span></span>
<span id="cb9-49"><a href="#cb9-49" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-50"><a href="#cb9-50" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> indirect<span class="op">&amp;</span> <span class="kw">operator</span><span class="op">=(</span>indirect<span class="op">&amp;&amp;</span> other<span class="op">)</span> <span class="kw">noexcept</span><span class="op">(</span>see below<span class="op">);</span></span>
<span id="cb9-51"><a href="#cb9-51" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-52"><a href="#cb9-52" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> U<span class="op">=</span>T<span class="op">&gt;</span></span>
<span id="cb9-53"><a href="#cb9-53" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> indirect<span class="op">&amp;</span> <span class="kw">operator</span><span class="op">=(</span>U<span class="op">&amp;&amp;</span> u<span class="op">);</span></span>
<span id="cb9-54"><a href="#cb9-54" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-55"><a href="#cb9-55" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> <span class="at">const</span> T<span class="op">&amp;</span> <span class="kw">operator</span><span class="op">*()</span> <span class="at">const</span> <span class="op">&amp;</span> <span class="kw">noexcept</span><span class="op">;</span></span>
<span id="cb9-56"><a href="#cb9-56" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-57"><a href="#cb9-57" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> T<span class="op">&amp;</span> <span class="kw">operator</span><span class="op">*()</span> <span class="op">&amp;</span> <span class="kw">noexcept</span><span class="op">;</span></span>
<span id="cb9-58"><a href="#cb9-58" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-59"><a href="#cb9-59" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> <span class="at">const</span> T<span class="op">&amp;&amp;</span> <span class="kw">operator</span><span class="op">*()</span> <span class="at">const</span> <span class="op">&amp;&amp;</span> <span class="kw">noexcept</span><span class="op">;</span></span>
<span id="cb9-60"><a href="#cb9-60" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-61"><a href="#cb9-61" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> T<span class="op">&amp;&amp;</span> <span class="kw">operator</span><span class="op">*()</span> <span class="op">&amp;&amp;</span> <span class="kw">noexcept</span><span class="op">;</span></span>
<span id="cb9-62"><a href="#cb9-62" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-63"><a href="#cb9-63" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> const_pointer <span class="kw">operator</span><span class="op">-&gt;()</span> <span class="at">const</span> <span class="kw">noexcept</span><span class="op">;</span></span>
<span id="cb9-64"><a href="#cb9-64" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-65"><a href="#cb9-65" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> pointer <span class="kw">operator</span><span class="op">-&gt;()</span> <span class="kw">noexcept</span><span class="op">;</span></span>
<span id="cb9-66"><a href="#cb9-66" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-67"><a href="#cb9-67" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> <span class="dt">bool</span> valueless_after_move<span class="op">()</span> <span class="at">const</span> <span class="kw">noexcept</span><span class="op">;</span></span>
<span id="cb9-68"><a href="#cb9-68" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-69"><a href="#cb9-69" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> <span class="dt">allocator_type</span> get_allocator<span class="op">()</span> <span class="at">const</span> <span class="kw">noexcept</span><span class="op">;</span></span>
<span id="cb9-70"><a href="#cb9-70" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-71"><a href="#cb9-71" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> <span class="dt">void</span> swap<span class="op">(</span>indirect<span class="op">&amp;</span> other<span class="op">)</span> <span class="kw">noexcept</span><span class="op">(</span>see below<span class="op">);</span></span>
<span id="cb9-72"><a href="#cb9-72" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-73"><a href="#cb9-73" aria-hidden="true" tabindex="-1"></a>  <span class="kw">friend</span> <span class="kw">constexpr</span> <span class="dt">void</span> swap<span class="op">(</span>indirect<span class="op">&amp;</span> lhs<span class="op">,</span> indirect<span class="op">&amp;</span> rhs<span class="op">)</span> <span class="kw">noexcept</span><span class="op">(</span>see below<span class="op">);</span></span>
<span id="cb9-74"><a href="#cb9-74" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-75"><a href="#cb9-75" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> U<span class="op">,</span> <span class="kw">class</span> AA<span class="op">&gt;</span></span>
<span id="cb9-76"><a href="#cb9-76" aria-hidden="true" tabindex="-1"></a>  <span class="kw">friend</span> <span class="kw">constexpr</span> <span class="dt">bool</span> <span class="kw">operator</span><span class="op">==(</span></span>
<span id="cb9-77"><a href="#cb9-77" aria-hidden="true" tabindex="-1"></a>    <span class="at">const</span> indirect<span class="op">&amp;</span> lhs<span class="op">,</span> <span class="at">const</span> indirect<span class="op">&lt;</span>U<span class="op">,</span> AA<span class="op">&gt;&amp;</span> rhs<span class="op">)</span> <span class="kw">noexcept</span><span class="op">(</span>see below<span class="op">);</span></span>
<span id="cb9-78"><a href="#cb9-78" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-79"><a href="#cb9-79" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> U<span class="op">&gt;</span></span>
<span id="cb9-80"><a href="#cb9-80" aria-hidden="true" tabindex="-1"></a>  <span class="kw">friend</span> <span class="kw">constexpr</span> <span class="dt">bool</span> <span class="kw">operator</span><span class="op">==(</span></span>
<span id="cb9-81"><a href="#cb9-81" aria-hidden="true" tabindex="-1"></a>    <span class="at">const</span> indirect<span class="op">&amp;</span> lhs<span class="op">,</span> <span class="at">const</span> U<span class="op">&amp;</span> rhs<span class="op">)</span> <span class="kw">noexcept</span><span class="op">(</span>see below<span class="op">);</span></span>
<span id="cb9-82"><a href="#cb9-82" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-83"><a href="#cb9-83" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> U<span class="op">,</span> <span class="kw">class</span> AA<span class="op">&gt;</span></span>
<span id="cb9-84"><a href="#cb9-84" aria-hidden="true" tabindex="-1"></a>  <span class="kw">friend</span> <span class="kw">constexpr</span> <span class="kw">auto</span> <span class="kw">operator</span><span class="op">&lt;=&gt;(</span></span>
<span id="cb9-85"><a href="#cb9-85" aria-hidden="true" tabindex="-1"></a>    <span class="at">const</span> indirect<span class="op">&amp;</span> lhs<span class="op">,</span> <span class="at">const</span> indirect<span class="op">&lt;</span>U<span class="op">,</span> AA<span class="op">&gt;&amp;</span> rhs<span class="op">)</span></span>
<span id="cb9-86"><a href="#cb9-86" aria-hidden="true" tabindex="-1"></a>    <span class="op">-&gt;</span> synth<span class="op">-</span>three<span class="op">-</span>way<span class="op">-</span>result<span class="op">&lt;</span>T<span class="op">,</span> U<span class="op">&gt;;</span></span>
<span id="cb9-87"><a href="#cb9-87" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-88"><a href="#cb9-88" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> U<span class="op">&gt;</span></span>
<span id="cb9-89"><a href="#cb9-89" aria-hidden="true" tabindex="-1"></a>  <span class="kw">friend</span> <span class="kw">constexpr</span> <span class="kw">auto</span> <span class="kw">operator</span><span class="op">&lt;=&gt;(</span></span>
<span id="cb9-90"><a href="#cb9-90" aria-hidden="true" tabindex="-1"></a>    <span class="at">const</span> indirect<span class="op">&amp;</span> lhs<span class="op">,</span> <span class="at">const</span> U<span class="op">&amp;</span> rhs<span class="op">)</span></span>
<span id="cb9-91"><a href="#cb9-91" aria-hidden="true" tabindex="-1"></a>    <span class="op">-&gt;</span> synth<span class="op">-</span>three<span class="op">-</span>way<span class="op">-</span>result<span class="op">&lt;</span>T<span class="op">,</span> U<span class="op">&gt;;</span></span>
<span id="cb9-92"><a href="#cb9-92" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-93"><a href="#cb9-93" aria-hidden="true" tabindex="-1"></a><span class="kw">private</span><span class="op">:</span></span>
<span id="cb9-94"><a href="#cb9-94" aria-hidden="true" tabindex="-1"></a>  pointer p<span class="op">;</span> <span class="co">// exposition only</span></span>
<span id="cb9-95"><a href="#cb9-95" aria-hidden="true" tabindex="-1"></a>  Allocator alloc <span class="op">=</span> Allocator<span class="op">();</span> <span class="co">// exposition only</span></span>
<span id="cb9-96"><a href="#cb9-96" aria-hidden="true" tabindex="-1"></a><span class="op">};</span></span>
<span id="cb9-97"><a href="#cb9-97" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-98"><a href="#cb9-98" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> Value<span class="op">&gt;</span></span>
<span id="cb9-99"><a href="#cb9-99" aria-hidden="true" tabindex="-1"></a>indirect<span class="op">(</span>Value<span class="op">)</span> <span class="op">-&gt;</span> indirect<span class="op">&lt;</span>Value<span class="op">&gt;;</span></span>
<span id="cb9-100"><a href="#cb9-100" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-101"><a href="#cb9-101" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> Allocator<span class="op">,</span> <span class="kw">class</span> Value<span class="op">&gt;</span></span>
<span id="cb9-102"><a href="#cb9-102" aria-hidden="true" tabindex="-1"></a>indirect<span class="op">(</span><span class="dt">allocator_arg_t</span><span class="op">,</span> Allocator<span class="op">,</span> Value<span class="op">)</span> <span class="op">-&gt;</span> indirect<span class="op">&lt;</span>Value<span class="op">,</span></span>
<span id="cb9-103"><a href="#cb9-103" aria-hidden="true" tabindex="-1"></a>         <span class="kw">typename</span> allocator_traits<span class="op">&lt;</span>Allocator<span class="op">&gt;::</span><span class="kw">template</span> rebind_alloc<span class="op">&lt;</span>Value<span class="op">&gt;&gt;;</span></span></code></pre></div>
<h3 id="x.y.3-constructors-indirect.ctor">X.Y.3 Constructors
[indirect.ctor]</h3>
<p>The following element applies to all functions in
[indirect.ctor]:</p>
<p><em>Throws</em>: Nothing unless
<code>allocator_traits&lt;Allocator&gt;::allocate</code> or
<code>allocator_traits&lt;Allocator&gt;::construct</code> throws.</p>
<div class="sourceCode" id="cb10"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="kw">explicit</span> <span class="kw">constexpr</span> indirect<span class="op">();</span></span></code></pre></div>
<ol type="1">
<li><p><em>Constraints</em>:
<code>is_default_constructible_v&lt;Allocator&gt;</code> is
<code>true</code>.</p></li>
<li><p><em>Mandates</em>:
<code>is_default_constructible_v&lt;T&gt;</code> is
<code>true</code>.</p></li>
<li><p><em>Effects</em>: Constructs an owned object of type
<code>T</code> with an empty argument list, using the allocator
<code>alloc</code>.</p></li>
</ol>
<div class="sourceCode" id="cb11"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="kw">explicit</span> <span class="kw">constexpr</span> indirect<span class="op">(</span><span class="dt">allocator_arg_t</span><span class="op">,</span> <span class="at">const</span> Allocator<span class="op">&amp;</span> a<span class="op">);</span></span></code></pre></div>
<ol start="4" type="1">
<li><p><em>Mandates</em>:
<code>is_default_constructible_v&lt;T&gt;</code> is
<code>true</code>.</p></li>
<li><p><em>Effects</em>: <code>alloc</code> is
direct-non-list-initialized with <code>a</code>. Constructs an owned
object of type <code>T</code> with an empty argument list, using the
allocator <code>alloc</code>.</p></li>
</ol>
<div class="sourceCode" id="cb12"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> indirect<span class="op">(</span><span class="at">const</span> indirect<span class="op">&amp;</span> other<span class="op">);</span></span></code></pre></div>
<ol start="6" type="1">
<li><p><em>Mandates</em>: <code>is_copy_constructible_v&lt;T&gt;</code>
is <code>true</code>.</p></li>
<li><p><em>Effects</em>: <code>alloc</code> is
direct-non-list-initialized with<br />
<code>allocator_traits&lt;Allocator&gt;::select_on_container_copy_construction(other.alloc)</code>.
If <code>other</code> is valueless, <code>*this</code> is valueless.
Otherwise, constructs an owned object of type <code>T</code> with
<code>*other</code>, using the allocator <code>alloc</code>.</p></li>
</ol>
<div class="sourceCode" id="cb13"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> indirect<span class="op">(</span><span class="dt">allocator_arg_t</span><span class="op">,</span> <span class="at">const</span> Allocator<span class="op">&amp;</span> a<span class="op">,</span></span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a>                   <span class="at">const</span> indirect<span class="op">&amp;</span> other<span class="op">);</span></span></code></pre></div>
<ol start="8" type="1">
<li><p><em>Mandates</em>: <code>is_copy_constructible_v&lt;T&gt;</code>
is <code>true</code>.</p></li>
<li><p><em>Effects</em>: <code>alloc</code> is
direct-non-list-initialized with <code>a</code>. If <code>other</code>
is valueless, <code>*this</code> is valueless. Otherwise, constructs an
owned object of type <code>T</code> with <code>*other</code>, using the
allocator <code>alloc</code>.</p></li>
</ol>
<div class="sourceCode" id="cb14"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> indirect<span class="op">(</span>indirect<span class="op">&amp;&amp;</span> other<span class="op">)</span> <span class="kw">noexcept</span><span class="op">;</span></span></code></pre></div>
<ol start="10" type="1">
<li><p><em>Effects</em>: <code>alloc</code> is
direct-non-list-initialized from <code>std::move(other.alloc)</code>. If
<code>other</code> is valueless, <code>*this</code> is valueless.
Otherwise <code>*this</code> takes ownership of the owned object of
<code>other</code>.</p></li>
<li><p><em>Postconditions</em>: <code>other</code> is
valueless.</p></li>
</ol>
<div class="sourceCode" id="cb15"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> indirect<span class="op">(</span><span class="dt">allocator_arg_t</span><span class="op">,</span> <span class="at">const</span> Allocator<span class="op">&amp;</span> a<span class="op">,</span> indirect<span class="op">&amp;&amp;</span> other<span class="op">)</span></span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a>   <span class="kw">noexcept</span><span class="op">(</span>allocator_traits<span class="op">&lt;</span>Allocator<span class="op">&gt;::</span>is_always_equal<span class="op">::</span>value<span class="op">);</span></span></code></pre></div>
<ol start="12" type="1">
<li><p><em>Mandates</em>: If
<code>allocator_traits&lt;Allocator&gt;::is_always_equal::value</code>
is <code>false</code> then <code>T</code> is a complete type.</p></li>
<li><p><em>Effects</em>: <code>alloc</code> is
direct-non-list-initialized with <code>a</code>. If <code>other</code>
is valueless, <code>*this</code> is valueless. Otherwise, if
<code>alloc == other.alloc</code> is <code>true</code>, constructs an
object of type <code>indirect</code> that takes ownership of the owned
object of <code>other</code>. Otherwise, constructs an owned object of
type <code>T</code> with <code>*std::move(other)</code>, using the
allocator <code>alloc</code>.</p></li>
<li><p><em>Postconditions</em>: <code>other</code> is
valueless.</p></li>
</ol>
<div class="sourceCode" id="cb16"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> U<span class="op">=</span>T<span class="op">&gt;</span></span>
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a><span class="kw">explicit</span> <span class="kw">constexpr</span> indirect<span class="op">(</span>U<span class="op">&amp;&amp;</span> u<span class="op">);</span></span></code></pre></div>
<ol start="15" type="1">
<li><em>Constraints</em>:
<ul>
<li><code>is_same_v&lt;remove_cvref_t&lt;U&gt;, indirect&gt;</code> is
<code>false</code>,</li>
<li><code>is_same_v&lt;remove_cvref_t&lt;U&gt;, in_place_t&gt;</code> is
<code>false</code>,</li>
<li><code>is_constructible_v&lt;T, U&gt;</code> is <code>true</code>
and</li>
<li><code>is_default_constructible_v&lt;Allocator&gt;</code> is
<code>true</code>.</li>
</ul></li>
<li><em>Effects</em>: Constructs an owned object of type <code>T</code>
with <code>std​::​forward&lt;U&gt;(u)</code>, using the allocator
<code>alloc</code>.</li>
</ol>
<div class="sourceCode" id="cb17"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> U<span class="op">=</span>T<span class="op">&gt;</span></span>
<span id="cb17-2"><a href="#cb17-2" aria-hidden="true" tabindex="-1"></a><span class="kw">explicit</span> <span class="kw">constexpr</span> indirect<span class="op">(</span><span class="dt">allocator_arg_t</span><span class="op">,</span> <span class="at">const</span> Allocator<span class="op">&amp;</span> a<span class="op">,</span> U<span class="op">&amp;&amp;</span> u<span class="op">);</span></span></code></pre></div>
<ol start="17" type="1">
<li><em>Constraints</em>:
<ul>
<li><code>is_same_v&lt;remove_cvref_t&lt;U&gt;, indirect&gt;</code> is
<code>false</code>,</li>
<li><code>is_same_v&lt;remove_cvref_t&lt;U&gt;, in_place_t&gt;</code> is
<code>false</code> and</li>
<li><code>is_constructible_v&lt;T, U&gt;</code> is
<code>true</code>.</li>
</ul></li>
<li><em>Effects</em>: <code>alloc</code> is direct-non-list-initialized
with <code>a</code>. Constructs an owned object of type <code>T</code>
with <code>std​::​forward&lt;U&gt;(u)</code>, using the allocator
<code>alloc</code>.</li>
</ol>
<div class="sourceCode" id="cb18"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span><span class="op">...</span> Us<span class="op">&gt;</span></span>
<span id="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a><span class="kw">explicit</span> <span class="kw">constexpr</span> indirect<span class="op">(</span><span class="dt">in_place_t</span><span class="op">,</span> Us<span class="op">&amp;&amp;...</span> us<span class="op">);</span></span></code></pre></div>
<ol start="19" type="1">
<li><em>Constraints</em>:
<ul>
<li><code>is_constructible_v&lt;T, Us...&gt;</code> is <code>true</code>
and</li>
<li><code>is_default_constructible_v&lt;Allocator&gt;</code> is
<code>true</code>.</li>
</ul></li>
<li><em>Effects</em>: Constructs an owned object of type <code>T</code>
with <code>std​::​forward&lt;Us&gt;(us)...</code>, using the allocator
<code>alloc</code>.</li>
</ol>
<div class="sourceCode" id="cb19"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb19-1"><a href="#cb19-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span><span class="op">...</span> Us<span class="op">&gt;</span></span>
<span id="cb19-2"><a href="#cb19-2" aria-hidden="true" tabindex="-1"></a><span class="kw">explicit</span> <span class="kw">constexpr</span> indirect<span class="op">(</span><span class="dt">allocator_arg_t</span><span class="op">,</span> <span class="at">const</span> Allocator<span class="op">&amp;</span> a<span class="op">,</span></span>
<span id="cb19-3"><a href="#cb19-3" aria-hidden="true" tabindex="-1"></a>                            <span class="dt">in_place_t</span><span class="op">,</span> Us<span class="op">&amp;&amp;</span> <span class="op">...</span>us<span class="op">);</span></span></code></pre></div>
<ol start="21" type="1">
<li><p><em>Constraints</em>:
<code>is_constructible_v&lt;T, Us...&gt;</code> is
<code>true</code>.</p></li>
<li><p><em>Effects</em>: <code>alloc</code> is
direct-non-list-initialized with <code>a</code>. Constructs an owned
object of type <code>T</code> with
<code>std​::​forward&lt;Us&gt;(us)...</code>, using the allocator
<code>alloc</code>.</p></li>
</ol>
<div class="sourceCode" id="cb20"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb20-1"><a href="#cb20-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> I<span class="op">,</span> <span class="kw">class</span><span class="op">...</span> Us<span class="op">&gt;</span></span>
<span id="cb20-2"><a href="#cb20-2" aria-hidden="true" tabindex="-1"></a><span class="kw">explicit</span> <span class="kw">constexpr</span> indirect<span class="op">(</span><span class="dt">in_place_t</span><span class="op">,</span> initializer_list<span class="op">&lt;</span>I<span class="op">&gt;</span> ilist<span class="op">,</span></span>
<span id="cb20-3"><a href="#cb20-3" aria-hidden="true" tabindex="-1"></a>                            Us<span class="op">&amp;&amp;...</span> us<span class="op">);</span></span></code></pre></div>
<ol start="23" type="1">
<li><em>Constraints</em>:
<ul>
<li><code>is_constructible_v&lt;T, initializer_list&lt;I&gt;&amp;, Us...&gt;</code>
is <code>true</code>, and</li>
<li><code>is_default_constructible_v&lt;Allocator&gt;</code> is
<code>true</code>.</li>
</ul></li>
<li><em>Effects</em>: Constructs an owned object of type <code>T</code>
with the arguments <code>ilist</code>,
<code>std​::​forward&lt;Us&gt;(us)...</code>, using the allocator
<code>alloc</code>.</li>
</ol>
<div class="sourceCode" id="cb21"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb21-1"><a href="#cb21-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> I<span class="op">,</span> <span class="kw">class</span><span class="op">...</span> Us<span class="op">&gt;</span></span>
<span id="cb21-2"><a href="#cb21-2" aria-hidden="true" tabindex="-1"></a><span class="kw">explicit</span> <span class="kw">constexpr</span> indirect<span class="op">(</span><span class="dt">allocator_arg_t</span><span class="op">,</span> <span class="at">const</span> Allocator<span class="op">&amp;</span> a<span class="op">,</span></span>
<span id="cb21-3"><a href="#cb21-3" aria-hidden="true" tabindex="-1"></a>                            <span class="dt">in_place_t</span><span class="op">,</span> initializer_list<span class="op">&lt;</span>I<span class="op">&gt;</span> ilist<span class="op">,</span></span>
<span id="cb21-4"><a href="#cb21-4" aria-hidden="true" tabindex="-1"></a>                            Us<span class="op">&amp;&amp;...</span> us<span class="op">);</span></span></code></pre></div>
<ol start="25" type="1">
<li><p><em>Constraints</em>:
<code>is_constructible_v&lt;T, initializer_list&lt;I&gt;&amp;, Us...&gt;</code>
is <code>true</code>.</p></li>
<li><p><em>Effects</em>: <code>alloc</code> is
direct-non-list-initialized with <code>a</code>. Constructs an owned
object of type <code>T</code> with the arguments <code>ilist</code>,
<code>std​::​forward&lt;Us&gt;(us)...</code>, using the allocator
<code>alloc</code>.</p></li>
</ol>
<h3 id="x.y.4-destructor-indirect.dtor">X.Y.4 Destructor
[indirect.dtor]</h3>
<div class="sourceCode" id="cb22"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb22-1"><a href="#cb22-1" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> <span class="op">~</span>indirect<span class="op">();</span></span></code></pre></div>
<ol type="1">
<li><p><em>Mandates</em>: <code>T</code> is a complete type.</p></li>
<li><p><em>Effects</em>: If <code>*this</code> is not valueless,
destroys the owned object using
<code>allocator_traits&lt;Allocator&gt;::destroy</code> and then the
storage is deallocated.</p></li>
</ol>
<h3 id="x.y.5-assignment-indirect.assign">X.Y.5 Assignment
[indirect.assign]</h3>
<div class="sourceCode" id="cb23"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb23-1"><a href="#cb23-1" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> indirect<span class="op">&amp;</span> <span class="kw">operator</span><span class="op">=(</span><span class="at">const</span> indirect<span class="op">&amp;</span> other<span class="op">);</span></span></code></pre></div>
<ol type="1">
<li><p><em>Mandates</em>:</p>
<ul>
<li><code>is_copy_assignable_v&lt;T&gt;</code> is <code>true</code>
and</li>
<li><code>is_copy_constructible_v&lt;T&gt;</code> is
<code>true</code>.</li>
</ul></li>
<li><p><em>Effects</em>: If <code>addressof(other) == this</code> is
<code>true</code>, there are no effects.<br />
Otherwise:</p>
<p>2.1. The allocator needs updating if<br />
<code>allocator_traits&lt;Allocator&gt;::propagate_on_container_copy_assignment::value</code><br />
is <code>true</code>.</p>
<p>2.2. If <code>other</code> is valueless, <code>*this</code> becomes
valueless and the owned object in <code>*this</code>, if any, is
destroyed using <code>allocator_traits&lt;Allocator&gt;::destroy</code>
and then the storage is deallocated.</p>
<p>2.3. Otherwise, if <code>alloc == other.alloc</code> is
<code>true</code> and <code>*this</code> is not valueless, equivalent to
<code>**this = *other</code>.</p>
<p>2.4. Otherwise a new owned object is constructed in
<code>*this</code> using
<code>allocator_traits&lt;Allocator&gt;::construct</code> with the owned
object from <code>other</code> as the argument, using either the
allocator in <code>*this</code> or the allocator in <code>other</code>
if the allocator needs updating.</p>
<p>2.5. The previously owned object in <code>*this</code>, if any, is
destroyed using <code>allocator_traits&lt;Allocator&gt;::destroy</code>
and then the storage is deallocated.</p>
<p>2.6. If the allocator needs updating, the allocator in
<code>*this</code> is replaced with a copy of the allocator in
<code>other</code>.</p></li>
<li><p><em>Returns</em>: A reference to <code>*this</code>.</p></li>
<li><p><em>Remarks</em>: If any exception is thrown, the result of the
expression <code>this-&gt;valueless_after_move()</code> remains
unchanged. If an exception is thrown during the call to <code>T</code>’s
selected copy constructor, no effect. If an exception is thrown during
the call to <code>T</code>’s copy assignment, the state of its contained
value is as defined by the exception safety guarantee of
<code>T</code>’s copy assignment.</p></li>
</ol>
<div class="sourceCode" id="cb24"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb24-1"><a href="#cb24-1" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> indirect<span class="op">&amp;</span> <span class="kw">operator</span><span class="op">=(</span>indirect<span class="op">&amp;&amp;</span> other<span class="op">)</span> <span class="kw">noexcept</span><span class="op">(</span></span>
<span id="cb24-2"><a href="#cb24-2" aria-hidden="true" tabindex="-1"></a>    allocator_traits<span class="op">&lt;</span>Allocator<span class="op">&gt;::</span>propagate_on_container_move_assignment<span class="op">::</span>value <span class="op">||</span></span>
<span id="cb24-3"><a href="#cb24-3" aria-hidden="true" tabindex="-1"></a>    allocator_traits<span class="op">&lt;</span>Allocator<span class="op">&gt;::</span>is_always_equal<span class="op">::</span>value<span class="op">);</span></span></code></pre></div>
<ol start="5" type="1">
<li><p><em>Mandates</em>: <code>is_copy_constructible_t&lt;T&gt;</code>
is <code>true</code>.</p></li>
<li><p><em>Effects</em>: If <code>addressof(other) == this</code> is
<code>true</code>, there are no effects. Otherwise:</p>
<p>6.1. The allocator needs updating if<br />
<code>allocator_traits&lt;Allocator&gt;::propagate_on_container_move_assignment::value</code><br />
is <code>true</code>.</p>
<p>6.2. If <code>other</code> is valueless, <code>*this</code> becomes
valueless and the owned object in <code>*this</code>, if any, is
destroyed using <code>allocator_traits&lt;Allocator&gt;::destroy</code>
and then the storage is deallocated.</p>
<p>6.3. Otherwise, if <code>alloc == other.alloc</code> is
<code>true</code>, swaps the owned objects in <code>*this</code> and
<code>other</code>; the owned object in <code>other</code>, if any, is
then destroyed using
<code>allocator_traits&lt;Allocator&gt;::destroy</code> and then the
storage is deallocated.</p>
<p>6.4. Otherwise constructs a new owned object with the owned object of
<code>other</code> as the argument as an rvalue, using either the
allocator in <code>*this</code> or the allocator in <code>other</code>
if the allocator needs updating.</p>
<p>6.5. The previously owned object in <code>*this</code>, if any, is
destroyed using <code>allocator_traits&lt;Allocator&gt;::destroy</code>
and then the storage is deallocated.</p>
<p>6.6. If the allocator needs updating, the allocator in
<code>*this</code> is replaced with a copy of the allocator in
<code>other</code>.</p></li>
<li><p><em>Postconditions</em>: <code>other</code> is
valueless.</p></li>
<li><p><em>Returns</em>: A reference to <code>*this</code>.</p></li>
<li><p><em>Remarks</em>: If any exception is thrown, there are no
effects on <code>*this</code> or <code>other</code>.</p></li>
</ol>
<div class="sourceCode" id="cb25"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb25-1"><a href="#cb25-1" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> U<span class="op">=</span>T<span class="op">&gt;</span></span>
<span id="cb25-2"><a href="#cb25-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> indirect<span class="op">&amp;</span> <span class="kw">operator</span><span class="op">=(</span>U<span class="op">&amp;&amp;</span> u<span class="op">);</span></span></code></pre></div>
<ol start="10" type="1">
<li><p><em>Constraints</em>:</p>
<ul>
<li><code>is_same_v&lt;remove_cvref_t&lt;U&gt;, indirect&gt;</code> is
<code>false</code>,</li>
<li><code>is_constructible_v&lt;T, U&gt;</code> is <code>true</code>,
and</li>
<li><code>is_assignable_v&lt;T&amp;, U&gt;</code> is
<code>true</code>.</li>
</ul></li>
<li><p><em>Mandates</em>: <code>is_copy_constructible_t&lt;T&gt;</code>
is <code>true</code>.</p></li>
<li><p><em>Effects</em>: If <code>*this</code> is valueless then
equivalent to<br />
<code>*this = indirect(allocator_arg, alloc, std::forward&lt;U&gt;(u));</code>.
Otherwise, equivalent to<br />
<code>**this = std::forward&lt;U&gt;(u)</code>.</p></li>
<li><p><em>Returns</em>: A reference to <code>*this</code>.</p></li>
</ol>
<h3 id="x.y.6-observers-indirect.observers">X.Y.6 Observers
[indirect.observers]</h3>
<div class="sourceCode" id="cb26"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb26-1"><a href="#cb26-1" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> <span class="at">const</span> T<span class="op">&amp;</span> <span class="kw">operator</span><span class="op">*()</span> <span class="at">const</span> <span class="op">&amp;</span> <span class="kw">noexcept</span><span class="op">;</span></span>
<span id="cb26-2"><a href="#cb26-2" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> T<span class="op">&amp;</span> <span class="kw">operator</span><span class="op">*()</span> <span class="op">&amp;</span> <span class="kw">noexcept</span><span class="op">;</span></span></code></pre></div>
<ol type="1">
<li><p><em>Preconditions</em>: <code>*this</code> is not
valueless.</p></li>
<li><p><em>Returns</em>: <code>*p</code>.</p></li>
</ol>
<div class="sourceCode" id="cb27"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb27-1"><a href="#cb27-1" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> <span class="at">const</span> T<span class="op">&amp;&amp;</span> <span class="kw">operator</span><span class="op">*()</span> <span class="at">const</span> <span class="op">&amp;&amp;</span> <span class="kw">noexcept</span><span class="op">;</span></span>
<span id="cb27-2"><a href="#cb27-2" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> T<span class="op">&amp;&amp;</span> <span class="kw">operator</span><span class="op">*()</span> <span class="op">&amp;&amp;</span> <span class="kw">noexcept</span><span class="op">;</span></span></code></pre></div>
<ol start="3" type="1">
<li><p><em>Preconditions</em>: <code>*this</code> is not
valueless.</p></li>
<li><p><em>Returns</em>: <code>std::move(*p)</code>.</p></li>
</ol>
<div class="sourceCode" id="cb28"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb28-1"><a href="#cb28-1" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> const_pointer <span class="kw">operator</span><span class="op">-&gt;()</span> <span class="at">const</span> <span class="kw">noexcept</span><span class="op">;</span></span>
<span id="cb28-2"><a href="#cb28-2" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> pointer <span class="kw">operator</span><span class="op">-&gt;()</span> <span class="kw">noexcept</span><span class="op">;</span></span></code></pre></div>
<ol start="5" type="1">
<li><p><em>Preconditions</em>: <code>*this</code> is not
valueless.</p></li>
<li><p><em>Returns</em>: <code>p</code>.</p></li>
</ol>
<div class="sourceCode" id="cb29"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb29-1"><a href="#cb29-1" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> <span class="dt">bool</span> valueless_after_move<span class="op">()</span> <span class="at">const</span> <span class="kw">noexcept</span><span class="op">;</span></span></code></pre></div>
<ol start="7" type="1">
<li><em>Returns</em>: <code>true</code> if <code>*this</code> is
valueless, otherwise <code>false</code>.</li>
</ol>
<div class="sourceCode" id="cb30"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb30-1"><a href="#cb30-1" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> <span class="dt">allocator_type</span> get_allocator<span class="op">()</span> <span class="at">const</span> <span class="kw">noexcept</span><span class="op">;</span></span></code></pre></div>
<ol start="8" type="1">
<li><em>Returns</em>: <code>alloc</code>.</li>
</ol>
<h3 id="x.y.7-swap-indirect.swap">X.Y.7 Swap [indirect.swap]</h3>
<div class="sourceCode" id="cb31"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb31-1"><a href="#cb31-1" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> <span class="dt">void</span> swap<span class="op">(</span>indirect<span class="op">&amp;</span> other<span class="op">)</span> <span class="kw">noexcept</span><span class="op">(</span></span>
<span id="cb31-2"><a href="#cb31-2" aria-hidden="true" tabindex="-1"></a>  allocator_traits<span class="op">&lt;</span>Allocator<span class="op">&gt;::</span>propagate_on_container_swap<span class="op">::</span>value</span>
<span id="cb31-3"><a href="#cb31-3" aria-hidden="true" tabindex="-1"></a>  <span class="op">||</span> allocator_traits<span class="op">&lt;</span>Allocator<span class="op">&gt;::</span>is_always_equal<span class="op">::</span>value<span class="op">);</span></span></code></pre></div>
<ol type="1">
<li><p><em>Preconditions</em>: If<br />
<code>allocator_traits&lt;Allocator&gt;::propagate_on_container_swap::value</code><br />
is <code>true</code>, then <code>Allocator</code> meets the
<em>Cpp17Swappable</em> requirements. Otherwise
<code>get_allocator() == other.get_allocator()</code> is
<code>true</code>.</p></li>
<li><p><em>Effects</em>: Swaps the states of <code>*this</code> and
<code>other</code>, exchanging owned objects or valueless states.
If<br />
<code>allocator_traits&lt;Allocator&gt;::propagate_on_container_swap::value</code><br />
is <code>true</code>, then the allocators of <code>*this</code> and
<code>other</code> are exchanged by calling <code>swap</code> as
described in [swappable.requirements]. Otherwise, the allocators are not
swapped. <em>[Note: Does not call <code>swap</code> on the owned objects
directly. –end note]</em></p></li>
</ol>
<div class="sourceCode" id="cb32"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb32-1"><a href="#cb32-1" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> <span class="dt">void</span> swap<span class="op">(</span>indirect<span class="op">&amp;</span> lhs<span class="op">,</span> indirect<span class="op">&amp;</span> rhs<span class="op">)</span> <span class="kw">noexcept</span><span class="op">(</span></span>
<span id="cb32-2"><a href="#cb32-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">noexcept</span><span class="op">(</span>lhs<span class="op">.</span>swap<span class="op">(</span>rhs<span class="op">)));</span></span></code></pre></div>
<ol start="3" type="1">
<li><em>Effects</em>: Equivalent to <code>lhs.swap(rhs)</code>.</li>
</ol>
<h3 id="x.y.8-relational-operators-indirect.relops">X.Y.8 Relational
operators [indirect.relops]</h3>
<div class="sourceCode" id="cb33"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb33-1"><a href="#cb33-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> U<span class="op">,</span> <span class="kw">class</span> AA<span class="op">&gt;</span></span>
<span id="cb33-2"><a href="#cb33-2" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> <span class="dt">bool</span> <span class="kw">operator</span><span class="op">==(</span><span class="at">const</span> indirect<span class="op">&amp;</span> lhs<span class="op">,</span> <span class="at">const</span> indirect<span class="op">&lt;</span>U<span class="op">,</span> AA<span class="op">&gt;&amp;</span> rhs<span class="op">)</span></span>
<span id="cb33-3"><a href="#cb33-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">noexcept</span><span class="op">(</span><span class="kw">noexcept</span><span class="op">(*</span>lhs <span class="op">==</span> <span class="op">*</span>rhs<span class="op">));</span></span></code></pre></div>
<ol type="1">
<li><p><em>Mandates</em>: The expression <code>*lhs == *rhs</code> is
well-formed and its result is convertible to bool.</p></li>
<li><p><em>Returns</em>: If <code>lhs</code> is valueless or
<code>rhs</code> is valueless,<br />
<code>lhs.valueless_after_move() == rhs.valueless_after_move()</code>;
otherwise <code>*lhs == *rhs</code>.</p></li>
</ol>
<div class="sourceCode" id="cb34"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb34-1"><a href="#cb34-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> U<span class="op">,</span> <span class="kw">class</span> AA<span class="op">&gt;</span></span>
<span id="cb34-2"><a href="#cb34-2" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> synth<span class="op">-</span>three<span class="op">-</span>way<span class="op">-</span>result<span class="op">&lt;</span>T<span class="op">,</span> U<span class="op">&gt;</span> <span class="kw">operator</span><span class="op">&lt;=&gt;(</span><span class="at">const</span> indirect<span class="op">&amp;</span> lhs<span class="op">,</span></span>
<span id="cb34-3"><a href="#cb34-3" aria-hidden="true" tabindex="-1"></a>                                                <span class="at">const</span> indirect<span class="op">&lt;</span>U<span class="op">,</span> AA<span class="op">&gt;&amp;</span> rhs<span class="op">);</span></span></code></pre></div>
<ol start="3" type="1">
<li><em>Returns</em>: If <code>lhs</code> is valueless or
<code>rhs</code> is valueless,<br />
<code>!lhs.valueless_after_move() &lt;=&gt; !rhs.valueless_after_move()</code>;
otherwise<br />
<code>synth-three-way(*lhs, *rhs)</code>.</li>
</ol>
<h3 id="x.y.9-comparison-with-t-indirect.comp.with.t">X.Y.9 Comparison
with T [indirect.comp.with.t]</h3>
<div class="sourceCode" id="cb35"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb35-1"><a href="#cb35-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> U<span class="op">&gt;</span></span>
<span id="cb35-2"><a href="#cb35-2" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> <span class="dt">bool</span> <span class="kw">operator</span><span class="op">==(</span><span class="at">const</span> indirect<span class="op">&amp;</span> lhs<span class="op">,</span> <span class="at">const</span> U<span class="op">&amp;</span> rhs<span class="op">)</span></span>
<span id="cb35-3"><a href="#cb35-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">noexcept</span><span class="op">(</span><span class="kw">noexcept</span><span class="op">(*</span>lhs <span class="op">==</span> rhs<span class="op">));</span></span></code></pre></div>
<ol type="1">
<li><p><em>Mandates</em>: The expression <code>*lhs == rhs</code> is
well-formed and its result is convertible to bool.</p></li>
<li><p><em>Returns</em>: If <code>lhs</code> is valueless, false;
otherwise <code>*lhs == rhs</code>.</p></li>
</ol>
<div class="sourceCode" id="cb36"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb36-1"><a href="#cb36-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> U<span class="op">&gt;</span></span>
<span id="cb36-2"><a href="#cb36-2" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> synth<span class="op">-</span>three<span class="op">-</span>way<span class="op">-</span>result<span class="op">&lt;</span>T<span class="op">,</span> U<span class="op">&gt;</span> <span class="kw">operator</span><span class="op">&lt;=&gt;(</span><span class="at">const</span> indirect<span class="op">&amp;</span> lhs<span class="op">,</span></span>
<span id="cb36-3"><a href="#cb36-3" aria-hidden="true" tabindex="-1"></a>                                                <span class="at">const</span> U<span class="op">&amp;</span> rhs<span class="op">);</span></span></code></pre></div>
<ol start="3" type="1">
<li><em>Returns</em>: If <code>rhs</code> is valueless,
<code>false &lt; true</code>; otherwise
<code>synth-three-way(*lhs, rhs)</code>.</li>
</ol>
<h3 id="x.y.10-hash-support-indirect.hash">X.Y.10 Hash support
[indirect.hash]</h3>
<div class="sourceCode" id="cb37"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb37-1"><a href="#cb37-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> T<span class="op">,</span> <span class="kw">class</span> Allocator<span class="op">&gt;</span></span>
<span id="cb37-2"><a href="#cb37-2" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> hash<span class="op">&lt;</span>indirect<span class="op">&lt;</span>T<span class="op">,</span> Allocator<span class="op">&gt;&gt;;</span></span></code></pre></div>
<ol type="1">
<li>The specialization
<code>hash&lt;indirect&lt;T, Allocator&gt;&gt;</code> is enabled
([unord.hash]) if and only if <code>hash&lt;T&gt;</code> is enabled.
When enabled for an object <code>i</code> of type
<code>indirect&lt;T, Allocator&gt;</code>, then
<code>hash&lt;indirect&lt;T, Allocator&gt;&gt;()(i)</code> evaluates to
either the same value as <code>hash&lt;T&gt;()(*i)</code>, if
<code>i</code> is not valueless; otherwise to an implementation-defined
value. The member functions are not guaranteed to be noexcept.</li>
</ol>
<h2 id="x.z-class-template-polymorphic-polymorphic">X.Z Class template
polymorphic [polymorphic]</h2>
<p>[Drafting note: The member <em><code>alloc</code></em> should be
formatted as an exposition only identifier, but limitations of the
processor used to prepare this paper mean not all uses are
italicised.]</p>
<h3
id="x.z.1-class-template-polymorphic-general-polymorphic.general">X.Z.1
Class template polymorphic general [polymorphic.general]</h3>
<ol type="1">
<li><p>A polymorphic object manages the lifetime of an owned object. A
polymorphic object may own objects of different types at different
points in its lifetime. A polymorphic object is <em>valueless</em> if it
has no owned object. A polymorphic object may become valueless only
after it has been moved from.</p></li>
<li><p>In every specialization
<code>polymorphic&lt;T, Allocator&gt;</code>, if the type
<code>allocator_traits&lt;Allocator&gt;::value_type</code> is not the
same type as<code>T</code>, the program is ill-formed. Every object of
type <code>polymorphic&lt;T, Allocator&gt;</code> uses an object of type
<code>Allocator</code> to allocate and free storage for the owned object
as needed.</p></li>
<li><p>Constructing an owned object of type <code>U</code> with
<code>args...</code> using the allocator <code>a</code> means calling
<code>allocator_traits&lt;Allocator&gt;::construct(a, p, args...)</code>
where <code>args</code> is an expression pack, <code>a</code> is an
allocator, <code>p</code> points to storage suitable for an owned object
of type <code>U</code>.</p></li>
<li><p>The member <code>alloc</code> is used for any memory allocation
and element construction performed by member functions during the
lifetime of each polymorphic value object, or until the allocator is
replaced. The allocator may be replaced only via assignment or
<code>swap()</code>. Allocator replacement is performed by copy
assignment, move assignment, or swapping of the allocator only if (see
[container.reqmts]):<br />
<code>allocator_traits&lt;Allocator&gt;::propagate_on_container_copy_assignment::value</code>,<br />
or<br />
<code>allocator_traits&lt;Allocator&gt;::propagate_on_container_move_assignment::value</code>,<br />
or<br />
<code>allocator_traits&lt;Allocator&gt;::propagate_on_container_swap::value</code>
is true within the implementation of the corresponding polymorphic
operation.</p></li>
<li><p>A program that instantiates the definition of polymorphic for a
non-object type, an array type, <code>in_place_t</code>, a
specialization of <code>in_place_type_t</code>, or a cv-qualified type
is ill-formed.</p></li>
<li><p>The template parameter <code>T</code> of <code>polymorphic</code>
may be an incomplete type.</p></li>
<li><p>The template parameter <code>Allocator</code> of
<code>polymorphic</code> shall meet the requirements of
<em>Cpp17Allocator</em>.</p></li>
<li><p>If a program declares an explicit or partial specialization of
<code>polymorphic</code>, the behavior is undefined.</p></li>
</ol>
<h3 id="x.z.2-class-template-polymorphic-synopsis-polymorphic.syn">X.Z.2
Class template polymorphic synopsis [polymorphic.syn]</h3>
<div class="sourceCode" id="cb38"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb38-1"><a href="#cb38-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> T<span class="op">,</span> <span class="kw">class</span> Allocator <span class="op">=</span> allocator<span class="op">&lt;</span>T<span class="op">&gt;&gt;</span></span>
<span id="cb38-2"><a href="#cb38-2" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> polymorphic <span class="op">{</span></span>
<span id="cb38-3"><a href="#cb38-3" aria-hidden="true" tabindex="-1"></a> <span class="kw">public</span><span class="op">:</span></span>
<span id="cb38-4"><a href="#cb38-4" aria-hidden="true" tabindex="-1"></a>  <span class="kw">using</span> <span class="dt">value_type</span> <span class="op">=</span> T<span class="op">;</span></span>
<span id="cb38-5"><a href="#cb38-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">using</span> <span class="dt">allocator_type</span> <span class="op">=</span> Allocator<span class="op">;</span></span>
<span id="cb38-6"><a href="#cb38-6" aria-hidden="true" tabindex="-1"></a>  <span class="kw">using</span> pointer <span class="op">=</span> <span class="kw">typename</span> allocator_traits<span class="op">&lt;</span>Allocator<span class="op">&gt;::</span>pointer<span class="op">;</span></span>
<span id="cb38-7"><a href="#cb38-7" aria-hidden="true" tabindex="-1"></a>  <span class="kw">using</span> const_pointer  <span class="op">=</span> <span class="kw">typename</span> allocator_traits<span class="op">&lt;</span>Allocator<span class="op">&gt;::</span>const_pointer<span class="op">;</span></span>
<span id="cb38-8"><a href="#cb38-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb38-9"><a href="#cb38-9" aria-hidden="true" tabindex="-1"></a>  <span class="kw">explicit</span> <span class="kw">constexpr</span> polymorphic<span class="op">();</span></span>
<span id="cb38-10"><a href="#cb38-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb38-11"><a href="#cb38-11" aria-hidden="true" tabindex="-1"></a>  <span class="kw">explicit</span> <span class="kw">constexpr</span> polymorphic<span class="op">(</span><span class="dt">allocator_arg_t</span><span class="op">,</span> <span class="at">const</span> Allocator<span class="op">&amp;</span> a<span class="op">);</span></span>
<span id="cb38-12"><a href="#cb38-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb38-13"><a href="#cb38-13" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> polymorphic<span class="op">(</span><span class="at">const</span> polymorphic<span class="op">&amp;</span> other<span class="op">);</span></span>
<span id="cb38-14"><a href="#cb38-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb38-15"><a href="#cb38-15" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> polymorphic<span class="op">(</span><span class="dt">allocator_arg_t</span><span class="op">,</span> <span class="at">const</span> Allocator<span class="op">&amp;</span> a<span class="op">,</span></span>
<span id="cb38-16"><a href="#cb38-16" aria-hidden="true" tabindex="-1"></a>                        <span class="at">const</span> polymorphic<span class="op">&amp;</span> other<span class="op">);</span></span>
<span id="cb38-17"><a href="#cb38-17" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb38-18"><a href="#cb38-18" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> polymorphic<span class="op">(</span>polymorphic<span class="op">&amp;&amp;</span> other<span class="op">)</span> <span class="kw">noexcept</span><span class="op">;</span></span>
<span id="cb38-19"><a href="#cb38-19" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb38-20"><a href="#cb38-20" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> polymorphic<span class="op">(</span><span class="dt">allocator_arg_t</span><span class="op">,</span> <span class="at">const</span> Allocator<span class="op">&amp;</span> a<span class="op">,</span></span>
<span id="cb38-21"><a href="#cb38-21" aria-hidden="true" tabindex="-1"></a>                        polymorphic<span class="op">&amp;&amp;</span> other<span class="op">)</span> <span class="kw">noexcept</span><span class="op">(</span>see below<span class="op">);</span></span>
<span id="cb38-22"><a href="#cb38-22" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb38-23"><a href="#cb38-23" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> U<span class="op">=</span>T<span class="op">&gt;</span></span>
<span id="cb38-24"><a href="#cb38-24" aria-hidden="true" tabindex="-1"></a>  <span class="kw">explicit</span> <span class="kw">constexpr</span> polymorphic<span class="op">(</span>U<span class="op">&amp;&amp;</span> u<span class="op">);</span></span>
<span id="cb38-25"><a href="#cb38-25" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb38-26"><a href="#cb38-26" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> U<span class="op">=</span>T<span class="op">&gt;</span></span>
<span id="cb38-27"><a href="#cb38-27" aria-hidden="true" tabindex="-1"></a>  <span class="kw">explicit</span> <span class="kw">constexpr</span> polymorphic<span class="op">(</span><span class="dt">allocator_arg_t</span><span class="op">,</span> <span class="at">const</span> Allocator<span class="op">&amp;</span> a<span class="op">,</span></span>
<span id="cb38-28"><a href="#cb38-28" aria-hidden="true" tabindex="-1"></a>                                 U<span class="op">&amp;&amp;</span> u<span class="op">);</span></span>
<span id="cb38-29"><a href="#cb38-29" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb38-30"><a href="#cb38-30" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> U<span class="op">,</span> <span class="kw">class</span><span class="op">...</span> Ts<span class="op">&gt;</span></span>
<span id="cb38-31"><a href="#cb38-31" aria-hidden="true" tabindex="-1"></a>  <span class="kw">explicit</span> <span class="kw">constexpr</span> polymorphic<span class="op">(</span><span class="dt">in_place_type_t</span><span class="op">&lt;</span>U<span class="op">&gt;,</span> Ts<span class="op">&amp;&amp;...</span> ts<span class="op">);</span></span>
<span id="cb38-32"><a href="#cb38-32" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb38-33"><a href="#cb38-33" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> U<span class="op">,</span> <span class="kw">class</span><span class="op">...</span> Ts<span class="op">&gt;</span></span>
<span id="cb38-34"><a href="#cb38-34" aria-hidden="true" tabindex="-1"></a>  <span class="kw">explicit</span> <span class="kw">constexpr</span> polymorphic<span class="op">(</span><span class="dt">allocator_arg_t</span><span class="op">,</span> <span class="at">const</span> Allocator<span class="op">&amp;</span> a<span class="op">,</span></span>
<span id="cb38-35"><a href="#cb38-35" aria-hidden="true" tabindex="-1"></a>                                 <span class="dt">in_place_type_t</span><span class="op">&lt;</span>U<span class="op">&gt;,</span> Ts<span class="op">&amp;&amp;...</span> ts<span class="op">);</span></span>
<span id="cb38-36"><a href="#cb38-36" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb38-37"><a href="#cb38-37" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> U<span class="op">,</span> <span class="kw">class</span> I<span class="op">,</span> <span class="kw">class</span><span class="op">...</span> Us<span class="op">&gt;</span></span>
<span id="cb38-38"><a href="#cb38-38" aria-hidden="true" tabindex="-1"></a>  <span class="kw">explicit</span> <span class="kw">constexpr</span> polymorphic<span class="op">(</span><span class="dt">in_place_type_t</span><span class="op">&lt;</span>U<span class="op">&gt;,</span></span>
<span id="cb38-39"><a href="#cb38-39" aria-hidden="true" tabindex="-1"></a>                                 initializer_list<span class="op">&lt;</span>I<span class="op">&gt;</span> ilist<span class="op">,</span> Us<span class="op">&amp;&amp;...</span> us<span class="op">);</span></span>
<span id="cb38-40"><a href="#cb38-40" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb38-41"><a href="#cb38-41" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> U<span class="op">,</span> <span class="kw">class</span> I<span class="op">,</span> <span class="kw">class</span><span class="op">...</span> Us<span class="op">&gt;</span></span>
<span id="cb38-42"><a href="#cb38-42" aria-hidden="true" tabindex="-1"></a>  <span class="kw">explicit</span> <span class="kw">constexpr</span> polymorphic<span class="op">(</span><span class="dt">allocator_arg_t</span><span class="op">,</span> <span class="at">const</span> Allocator<span class="op">&amp;</span> a<span class="op">,</span></span>
<span id="cb38-43"><a href="#cb38-43" aria-hidden="true" tabindex="-1"></a>                                 <span class="dt">in_place_type_t</span><span class="op">&lt;</span>U<span class="op">&gt;,</span></span>
<span id="cb38-44"><a href="#cb38-44" aria-hidden="true" tabindex="-1"></a>                                 initializer_list<span class="op">&lt;</span>I<span class="op">&gt;</span> ilist<span class="op">,</span> Us<span class="op">&amp;&amp;...</span> us<span class="op">);</span></span>
<span id="cb38-45"><a href="#cb38-45" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb38-46"><a href="#cb38-46" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> <span class="op">~</span>polymorphic<span class="op">();</span></span>
<span id="cb38-47"><a href="#cb38-47" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb38-48"><a href="#cb38-48" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> polymorphic<span class="op">&amp;</span> <span class="kw">operator</span><span class="op">=(</span><span class="at">const</span> polymorphic<span class="op">&amp;</span> other<span class="op">);</span></span>
<span id="cb38-49"><a href="#cb38-49" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb38-50"><a href="#cb38-50" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> polymorphic<span class="op">&amp;</span> <span class="kw">operator</span><span class="op">=(</span>polymorphic<span class="op">&amp;&amp;</span> other<span class="op">)</span> <span class="kw">noexcept</span><span class="op">(</span>see below<span class="op">);</span></span>
<span id="cb38-51"><a href="#cb38-51" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb38-52"><a href="#cb38-52" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> <span class="at">const</span> T<span class="op">&amp;</span> <span class="kw">operator</span><span class="op">*()</span> <span class="at">const</span> <span class="kw">noexcept</span><span class="op">;</span></span>
<span id="cb38-53"><a href="#cb38-53" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb38-54"><a href="#cb38-54" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> T<span class="op">&amp;</span> <span class="kw">operator</span><span class="op">*()</span> <span class="kw">noexcept</span><span class="op">;</span></span>
<span id="cb38-55"><a href="#cb38-55" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb38-56"><a href="#cb38-56" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> const_pointer <span class="kw">operator</span><span class="op">-&gt;()</span> <span class="at">const</span> <span class="kw">noexcept</span><span class="op">;</span></span>
<span id="cb38-57"><a href="#cb38-57" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb38-58"><a href="#cb38-58" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> pointer <span class="kw">operator</span><span class="op">-&gt;()</span> <span class="kw">noexcept</span><span class="op">;</span></span>
<span id="cb38-59"><a href="#cb38-59" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb38-60"><a href="#cb38-60" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> <span class="dt">bool</span> valueless_after_move<span class="op">()</span> <span class="at">const</span> <span class="kw">noexcept</span><span class="op">;</span></span>
<span id="cb38-61"><a href="#cb38-61" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb38-62"><a href="#cb38-62" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> <span class="dt">allocator_type</span> get_allocator<span class="op">()</span> <span class="at">const</span> <span class="kw">noexcept</span><span class="op">;</span></span>
<span id="cb38-63"><a href="#cb38-63" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb38-64"><a href="#cb38-64" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> <span class="dt">void</span> swap<span class="op">(</span>polymorphic<span class="op">&amp;</span> other<span class="op">)</span> <span class="kw">noexcept</span><span class="op">(</span>see below<span class="op">);</span></span>
<span id="cb38-65"><a href="#cb38-65" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb38-66"><a href="#cb38-66" aria-hidden="true" tabindex="-1"></a>  <span class="kw">friend</span> <span class="kw">constexpr</span> <span class="dt">void</span> swap<span class="op">(</span>polymorphic<span class="op">&amp;</span> lhs<span class="op">,</span></span>
<span id="cb38-67"><a href="#cb38-67" aria-hidden="true" tabindex="-1"></a>                             polymorphic<span class="op">&amp;</span> rhs<span class="op">)</span> <span class="kw">noexcept</span><span class="op">(</span>see below<span class="op">);</span></span>
<span id="cb38-68"><a href="#cb38-68" aria-hidden="true" tabindex="-1"></a> <span class="kw">private</span><span class="op">:</span></span>
<span id="cb38-69"><a href="#cb38-69" aria-hidden="true" tabindex="-1"></a>  Allocator alloc <span class="op">=</span> Allocator<span class="op">();</span> <span class="co">// exposition only</span></span>
<span id="cb38-70"><a href="#cb38-70" aria-hidden="true" tabindex="-1"></a><span class="op">};</span></span></code></pre></div>
<h3 id="x.z.3-constructors-polymorphic.ctor">X.Z.3 Constructors
[polymorphic.ctor]</h3>
<p>The following element applies to all functions in
[polymorphic.ctor]:</p>
<p><em>Throws</em>: Nothing unless
<code>allocator_traits&lt;Allocator&gt;::allocate</code><br />
or <code>allocator_traits&lt;Allocator&gt;::construct</code> throws.</p>
<div class="sourceCode" id="cb39"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb39-1"><a href="#cb39-1" aria-hidden="true" tabindex="-1"></a><span class="kw">explicit</span> <span class="kw">constexpr</span> polymorphic<span class="op">();</span></span></code></pre></div>
<ol type="1">
<li><p><em>Constraints</em>:
<code>is_default_constructible_v&lt;Allocator&gt;</code> is
<code>true</code>.</p></li>
<li><p><em>Mandates</em>:</p>
<ul>
<li><code>is_default_constructible_v&lt;T&gt;</code> is
<code>true</code> and</li>
<li><code>is_copy_constructible_v&lt;T&gt;</code> is
<code>true</code>.</li>
</ul></li>
<li><p><em>Effects</em>: Constructs an owned object of type
<code>T</code> with an empty argument list using the allocator
<code>alloc</code>.</p></li>
</ol>
<div class="sourceCode" id="cb40"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb40-1"><a href="#cb40-1" aria-hidden="true" tabindex="-1"></a><span class="kw">explicit</span> <span class="kw">constexpr</span> polymorphic<span class="op">(</span><span class="dt">allocator_arg_t</span><span class="op">,</span> <span class="at">const</span> Allocator<span class="op">&amp;</span> a<span class="op">);</span></span></code></pre></div>
<ol start="4" type="1">
<li><em>Mandates</em>:
<ul>
<li><code>is_default_constructible_v&lt;T&gt;</code> is
<code>true</code> and</li>
<li><code>is_copy_constructible_v&lt;T&gt;</code> is
<code>true</code>.</li>
</ul></li>
<li><em>Effects</em>: <code>alloc</code> is direct-non-list-initialized
with <code>a</code>. Constructs an owned object of type <code>T</code>
with an empty argument list using the allocator <code>alloc</code>.</li>
</ol>
<div class="sourceCode" id="cb41"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb41-1"><a href="#cb41-1" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> polymorphic<span class="op">(</span><span class="at">const</span> polymorphic<span class="op">&amp;</span> other<span class="op">);</span></span></code></pre></div>
<ol start="6" type="1">
<li><em>Effects</em>: <code>alloc</code> is direct-non-list-initialized
with<br />
<code>allocator_traits&lt;Allocator&gt;::select_on_container_copy_construction(other.alloc)</code>.
If <code>other</code> is valueless, <code>*this</code> is valueless.
Otherwise, constructs an owned object of type <code>U</code>, where
<code>U</code> is the type of the owned object in <code>other</code>,
with the owned object in <code>other</code> using the allocator
<code>alloc</code>.</li>
</ol>
<div class="sourceCode" id="cb42"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb42-1"><a href="#cb42-1" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> polymorphic<span class="op">(</span><span class="dt">allocator_arg_t</span><span class="op">,</span> <span class="at">const</span> Allocator<span class="op">&amp;</span> a<span class="op">,</span></span>
<span id="cb42-2"><a href="#cb42-2" aria-hidden="true" tabindex="-1"></a>                      <span class="at">const</span> polymorphic<span class="op">&amp;</span> other<span class="op">);</span></span></code></pre></div>
<ol start="7" type="1">
<li><em>Effects</em>: <code>alloc</code> is direct-non-list-initialized
with <code>a</code>. If <code>other</code> is valueless,
<code>*this</code> is valueless. Otherwise, constructs an owned object
of type <code>U</code>, where <code>U</code> is the type of the owned
object in <code>other</code>, with the owned object in
<code>other</code> using the allocator <code>alloc</code>.</li>
</ol>
<div class="sourceCode" id="cb43"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb43-1"><a href="#cb43-1" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> polymorphic<span class="op">(</span>polymorphic<span class="op">&amp;&amp;</span> other<span class="op">)</span> <span class="kw">noexcept</span><span class="op">;</span></span></code></pre></div>
<ol start="8" type="1">
<li><em>Effects</em>: <code>alloc</code> is direct-non-list-initialized
with <code>std::move(other.alloc)</code>. If <code>other</code> is
valueless, <code>*this</code> is valueless. Otherwise, either
<code>*this</code> takes ownership of the owned object of
<code>other</code> or, owns an object of the same type constructed from
the owned object of <code>other</code> considering that owned object as
an rvalue, using the allocator <code>alloc</code>.</li>
</ol>
<p><em>[Drafting note: The above is intended to permit a
small-buffer-optimization and handle the case where allocators compare
equal but we do not want to swap pointers.]</em></p>
<div class="sourceCode" id="cb44"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb44-1"><a href="#cb44-1" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> polymorphic<span class="op">(</span><span class="dt">allocator_arg_t</span><span class="op">,</span> <span class="at">const</span> Allocator<span class="op">&amp;</span> a<span class="op">,</span></span>
<span id="cb44-2"><a href="#cb44-2" aria-hidden="true" tabindex="-1"></a>                      polymorphic<span class="op">&amp;&amp;</span> other<span class="op">)</span></span>
<span id="cb44-3"><a href="#cb44-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">noexcept</span><span class="op">(</span>allocator_traits<span class="op">&lt;</span>Allocator<span class="op">&gt;::</span>is_always_equal<span class="op">::</span>value<span class="op">);</span></span></code></pre></div>
<ol start="9" type="1">
<li><em>Effects</em>: <code>alloc</code> is direct-non-list-initialized
with <code>a</code>. If <code>other</code> is valueless,
<code>*this</code> is valueless. Otherwise, if
<code>alloc == other.alloc</code> is <code>true</code>, either
constructs an object of type <code>polymorphic</code> that owns the
owned object of other, making <code>other</code> valueless; or, owns an
object of the same type constructed from the owned object of
<code>other</code> considering that owned object as an rvalue.
Otherwise, if <code>alloc != other.alloc</code> is <code>true</code>,
constructs an object of type <code>polymorphic</code>, considering the
owned object in <code>other</code> as an rvalue, using the allocator
<code>alloc</code>.</li>
</ol>
<p><em>[Drafting note: The above is intended to permit a
small-buffer-optimization and handle the case where allocators compare
equal but we do not want to swap pointers.]</em></p>
<div class="sourceCode" id="cb45"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb45-1"><a href="#cb45-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> U<span class="op">=</span>T<span class="op">&gt;</span></span>
<span id="cb45-2"><a href="#cb45-2" aria-hidden="true" tabindex="-1"></a><span class="kw">explicit</span> <span class="kw">constexpr</span> polymorphic<span class="op">(</span>U<span class="op">&amp;&amp;</span> u<span class="op">);</span></span></code></pre></div>
<ol start="10" type="1">
<li><em>Constraints</em>: Where <code>UU</code> is
<code>remove_cvref_t&lt;U&gt;</code>,
<ul>
<li><code>is_same_v&lt;UU, polymorphic&gt;</code> is
<code>false</code>,</li>
<li><code>derived_from&lt;UU, T&gt;</code> is <code>true</code>,</li>
<li><code>is_constructible_v&lt;UU, U&gt;</code> is
<code>true</code>,</li>
<li><code>is_copy_constructible_v&lt;UU&gt;</code> is
<code>true</code>,</li>
<li><code>UU</code> is not a specialization of
<code>in_place_type_t</code>, and</li>
<li><code>is_default_constructible_v&lt;Allocator&gt;</code> is
<code>true</code>.</li>
</ul></li>
<li><em>Effects</em>: Constructs an owned object of type <code>U</code>
with <code>std​::​forward&lt;U&gt;(u)</code> using the allocator
<code>alloc</code>.</li>
</ol>
<div class="sourceCode" id="cb46"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb46-1"><a href="#cb46-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> U<span class="op">=</span>T<span class="op">&gt;</span></span>
<span id="cb46-2"><a href="#cb46-2" aria-hidden="true" tabindex="-1"></a><span class="kw">explicit</span> <span class="kw">constexpr</span> polymorphic<span class="op">(</span><span class="dt">allocator_arg_t</span><span class="op">,</span> <span class="at">const</span> Allocator<span class="op">&amp;</span> a<span class="op">,</span> U<span class="op">&amp;&amp;</span> u<span class="op">);</span></span></code></pre></div>
<ol start="12" type="1">
<li><em>Constraints</em>: Where <code>UU</code> is
<code>remove_cvref_t&lt;U&gt;</code>,
<ul>
<li><code>is_same_v&lt;UU, polymorphic&gt;</code> is
<code>false</code>,</li>
<li><code>derived_from&lt;UU, T&gt;</code> is <code>true</code>,</li>
<li><code>is_constructible_v&lt;UU, U&gt;</code> is
<code>true</code>,</li>
<li><code>is_copy_constructible_v&lt;UU&gt;</code> is <code>true</code>,
and</li>
<li><code>UU</code> is not a specialization of
<code>in_place_type_t</code>.</li>
</ul></li>
<li><em>Effects</em>: <code>alloc</code> is direct-non-list-initialized
with <code>a</code>. Constructs an owned object of type <code>U</code>
with <code>std​::​forward&lt;U&gt;(u)</code> using the allocator
<code>alloc</code>.</li>
</ol>
<div class="sourceCode" id="cb47"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb47-1"><a href="#cb47-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> U<span class="op">,</span> <span class="kw">class</span><span class="op">...</span> Ts<span class="op">&gt;</span></span>
<span id="cb47-2"><a href="#cb47-2" aria-hidden="true" tabindex="-1"></a><span class="kw">explicit</span> <span class="kw">constexpr</span> polymorphic<span class="op">(</span><span class="dt">in_place_type_t</span><span class="op">&lt;</span>U<span class="op">&gt;,</span> Ts<span class="op">&amp;&amp;...</span> ts<span class="op">);</span></span></code></pre></div>
<ol start="14" type="1">
<li><em>Constraints</em>:
<ul>
<li><code>is_same_v&lt;remove_cvref_t&lt;U&gt;, U&gt;</code> is
<code>true</code>,</li>
<li><code>derived_from&lt;U, T&gt;</code> is <code>true</code>,</li>
<li><code>is_constructible_v&lt;U, Ts...&gt;</code> is
<code>true</code>,</li>
<li><code>is_copy_constructible_v&lt;U&gt;</code> is <code>true</code>,
and</li>
<li><code>is_default_constructible_v&lt;Allocator&gt;</code> is
<code>true</code>.</li>
</ul></li>
<li><em>Effects</em>: Constructs an owned object of type <code>U</code>
with <code>std​::​forward&lt;Ts&gt;(ts)...</code> using the allocator
<code>alloc</code>.</li>
</ol>
<div class="sourceCode" id="cb48"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb48-1"><a href="#cb48-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> U<span class="op">,</span> <span class="kw">class</span><span class="op">...</span> Ts<span class="op">&gt;</span></span>
<span id="cb48-2"><a href="#cb48-2" aria-hidden="true" tabindex="-1"></a><span class="kw">explicit</span> <span class="kw">constexpr</span> polymorphic<span class="op">(</span><span class="dt">allocator_arg_t</span><span class="op">,</span> <span class="at">const</span> Allocator<span class="op">&amp;</span> a<span class="op">,</span></span>
<span id="cb48-3"><a href="#cb48-3" aria-hidden="true" tabindex="-1"></a>                               <span class="dt">in_place_type_t</span><span class="op">&lt;</span>U<span class="op">&gt;,</span> Ts<span class="op">&amp;&amp;...</span> ts<span class="op">);</span></span></code></pre></div>
<ol start="16" type="1">
<li><em>Constraints</em>:
<ul>
<li><code>is_same_v&lt;remove_cvref_t&lt;U&gt;, U&gt;</code> is
<code>true</code>,</li>
<li><code>derived_from&lt;U, T&gt;</code> is <code>true</code>,</li>
<li><code>is_constructible_v&lt;U, Ts...&gt;</code> is
<code>true</code>, and</li>
<li><code>is_copy_constructible_v&lt;U&gt;</code> is
<code>true</code>.</li>
</ul></li>
<li><em>Effects</em>: <code>alloc</code> is direct-non-list-initialized
with <code>a</code>. Constructs an owned object of type <code>U</code>
with <code>std​::​forward&lt;Ts&gt;(ts)...</code> using the allocator
<code>alloc</code>.</li>
</ol>
<div class="sourceCode" id="cb49"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb49-1"><a href="#cb49-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> U<span class="op">,</span> <span class="kw">class</span> I<span class="op">,</span> <span class="kw">class</span><span class="op">...</span> Us<span class="op">&gt;</span></span>
<span id="cb49-2"><a href="#cb49-2" aria-hidden="true" tabindex="-1"></a><span class="kw">explicit</span> <span class="kw">constexpr</span> polymorphic<span class="op">(</span><span class="dt">in_place_type_t</span><span class="op">&lt;</span>U<span class="op">&gt;,</span></span>
<span id="cb49-3"><a href="#cb49-3" aria-hidden="true" tabindex="-1"></a>                               initializer_list<span class="op">&lt;</span>I<span class="op">&gt;</span> ilist<span class="op">,</span> Us<span class="op">&amp;&amp;...</span> us<span class="op">);</span></span></code></pre></div>
<ol start="18" type="1">
<li><em>Constraints</em>:
<ul>
<li><code>is_same_v&lt;remove_cvref_t&lt;U&gt;, U&gt;</code> is
<code>true</code>,</li>
<li><code>derived_from&lt;U, T&gt;</code> is <code>true</code>,</li>
<li><code>is_constructible_v&lt;U, initializer_list&lt;I&gt;&amp;, Us...&gt;</code>
is <code>true</code>,</li>
<li><code>is_copy_constructible_v&lt;U&gt;</code> is <code>true</code>,
and</li>
<li><code>is_default_constructible_v&lt;Allocator&gt;</code> is
<code>true</code>.</li>
</ul></li>
<li><em>Effects</em>: Constructs an owned object of type <code>U</code>
with the arguments <code>ilist</code>,
<code>std​::​forward&lt;Us&gt;(us)...</code> using the allocator
<code>alloc</code>.</li>
</ol>
<div class="sourceCode" id="cb50"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb50-1"><a href="#cb50-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> U<span class="op">,</span> <span class="kw">class</span> I<span class="op">,</span> <span class="kw">class</span><span class="op">...</span> Us<span class="op">&gt;</span></span>
<span id="cb50-2"><a href="#cb50-2" aria-hidden="true" tabindex="-1"></a><span class="kw">explicit</span> <span class="kw">constexpr</span> polymorphic<span class="op">(</span><span class="dt">allocator_arg_t</span><span class="op">,</span> <span class="at">const</span> Allocator<span class="op">&amp;</span> a<span class="op">,</span></span>
<span id="cb50-3"><a href="#cb50-3" aria-hidden="true" tabindex="-1"></a>                               <span class="dt">in_place_type_t</span><span class="op">&lt;</span>U<span class="op">&gt;,</span></span>
<span id="cb50-4"><a href="#cb50-4" aria-hidden="true" tabindex="-1"></a>                               initializer_list<span class="op">&lt;</span>I<span class="op">&gt;</span> ilist<span class="op">,</span> Us<span class="op">&amp;&amp;...</span> us<span class="op">);</span></span></code></pre></div>
<ol start="20" type="1">
<li><em>Constraints</em>:
<ul>
<li><code>is_same_v&lt;remove_cvref_t&lt;U&gt;, U&gt;</code> is
<code>true</code>,</li>
<li><code>derived_from&lt;U, T&gt;</code> is <code>true</code>,</li>
<li><code>is_constructible_v&lt;U, initializer_list&lt;I&gt;&amp;, Us...&gt;</code>
is <code>true</code>, and</li>
<li><code>is_copy_constructible_v&lt;U&gt;</code> is
<code>true</code>.</li>
</ul></li>
<li><em>Effects</em>: <code>alloc</code> is direct-non-list-initialized
with <code>a</code>. Constructs an owned object of type <code>U</code>
with the arguments <code>ilist</code>,
<code>std​::​forward&lt;Us&gt;(us)...</code> using the allocator
<code>alloc</code>.</li>
</ol>
<h3 id="x.z.4-destructor-polymorphic.dtor">X.Z.4 Destructor
[polymorphic.dtor]</h3>
<div class="sourceCode" id="cb51"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb51-1"><a href="#cb51-1" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> <span class="op">~</span>polymorphic<span class="op">();</span></span></code></pre></div>
<ol type="1">
<li><p><em>Mandates</em>: <code>T</code> is a complete type.</p></li>
<li><p><em>Effects</em>: If <code>*this</code> is not valueless,
destroys the owned object using
<code>allocator_traits&lt;Allocator&gt;::destroy</code> and then the
storage is deallocated.</p></li>
</ol>
<h3 id="x.z.5-assignment-polymorphic.assign">X.Z.5 Assignment
[polymorphic.assign]</h3>
<div class="sourceCode" id="cb52"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb52-1"><a href="#cb52-1" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> polymorphic<span class="op">&amp;</span> <span class="kw">operator</span><span class="op">=(</span><span class="at">const</span> polymorphic<span class="op">&amp;</span> other<span class="op">);</span></span></code></pre></div>
<ol type="1">
<li><p><em>Mandates</em>: <code>T</code> is a complete type.</p></li>
<li><p><em>Effects</em>: If <code>addressof(other) == this</code> is
<code>true</code>, there are no effects. Otherwise:</p>
<p>2.1. The allocator needs updating if<br />
<code>allocator_traits&lt;Allocator&gt;::propagate_on_container_copy_assignment::value</code><br />
is <code>true</code>.</p>
<p>2.2. If <code>other</code> is not valueless, a new owned object is
constructed in <code>*this</code> using<br />
<code>allocator_traits&lt;Allocator&gt;::construct</code> with the owned
object from <code>other</code> as the argument, using either the
allocator in <code>*this</code> or the allocator in <code>other</code>
if the allocator needs updating.</p>
<p>2.3 The previously owned object in <code>*this</code>, if any, is
destroyed using <code>allocator_traits&lt;Allocator&gt;::destroy</code>
and then the storage is deallocated.</p>
<p>2.4 If the allocator needs updating, the allocator in
<code>*this</code> is replaced with a copy of the allocator in
<code>other</code>.</p></li>
<li><p><em>Returns</em>: A reference to <code>*this</code>.</p></li>
<li><p><em>Remarks</em>: If any exception is thrown, there are no
effects on <code>*this</code>.</p></li>
</ol>
<div class="sourceCode" id="cb53"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb53-1"><a href="#cb53-1" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> polymorphic<span class="op">&amp;</span> <span class="kw">operator</span><span class="op">=(</span>polymorphic<span class="op">&amp;&amp;</span> other<span class="op">)</span> <span class="kw">noexcept</span><span class="op">(</span></span>
<span id="cb53-2"><a href="#cb53-2" aria-hidden="true" tabindex="-1"></a>    allocator_traits<span class="op">&lt;</span>Allocator<span class="op">&gt;::</span>propagate_on_container_move_assignment<span class="op">::</span>value <span class="op">||</span></span>
<span id="cb53-3"><a href="#cb53-3" aria-hidden="true" tabindex="-1"></a>    allocator_traits<span class="op">&lt;</span>Allocator<span class="op">&gt;::</span>is_always_equal<span class="op">::</span>value<span class="op">);</span></span></code></pre></div>
<ol start="5" type="1">
<li><p><em>Mandates</em>: If
<code>allocator_traits&lt;Allocator&gt;::is_always_equal::value</code>
is <code>false</code>, <code>T</code> is a complete type.</p></li>
<li><p><em>Effects</em>: If <code>addressof(other) == this</code> is
<code>true</code>, there are no effects. Otherwise:</p>
<p>6.1. The allocator needs updating if<br />
<code>allocator_traits&lt;Allocator&gt;::propagate_on_container_move_assignment::value</code><br />
is <code>true</code>.</p>
<p>6.2. If <code>alloc == other.alloc</code> is <code>true</code>, swaps
the owned objects in <code>*this</code> and <code>other</code>; the
owned object in <code>other</code>, if any, is then destroyed using
<code>allocator_traits&lt;Allocator&gt;::destroy</code> and then the
storage is deallocated.</p>
<p>6.3. Otherwise, if <code>alloc != other.alloc</code> is
<code>true</code>; if <code>other</code> is not valueless, a new owned
object is constructed in <code>*this</code> using
<code>allocator_traits&lt;Allocator&gt;::construct</code> with the owned
object from <code>other</code> as the argument as an rvalue, using
either the allocator in <code>*this</code> or the allocator in
<code>other</code> if the allocator needs updating.</p>
<p>6.4. The previously owned object in <code>*this</code>, if any, is
destroyed using <code>allocator_traits&lt;Allocator&gt;::destroy</code>
and then the storage is deallocated.</p>
<p>6.5. If the allocator needs updating, the allocator in
<code>*this</code> is replaced with a copy of the allocator in
<code>other</code>.</p></li>
<li><p><em>Returns</em>: A reference to <code>*this</code>.</p></li>
<li><p><em>Remarks</em>: If any exception is thrown, there are no
effects on <code>*this</code> or <code>other</code>.</p></li>
</ol>
<h3 id="x.z.6-observers-polymorphic.observers">X.Z.6 Observers
[polymorphic.observers]</h3>
<div class="sourceCode" id="cb54"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb54-1"><a href="#cb54-1" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> <span class="at">const</span> T<span class="op">&amp;</span> <span class="kw">operator</span><span class="op">*()</span> <span class="at">const</span> <span class="kw">noexcept</span><span class="op">;</span></span>
<span id="cb54-2"><a href="#cb54-2" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> T<span class="op">&amp;</span> <span class="kw">operator</span><span class="op">*()</span> <span class="kw">noexcept</span><span class="op">;</span></span></code></pre></div>
<ol type="1">
<li><p><em>Preconditions</em>: <code>*this</code> is not
valueless.</p></li>
<li><p><em>Returns</em>: A reference to the owned object.</p></li>
</ol>
<div class="sourceCode" id="cb55"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb55-1"><a href="#cb55-1" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> const_pointer <span class="kw">operator</span><span class="op">-&gt;()</span> <span class="at">const</span> <span class="kw">noexcept</span><span class="op">;</span></span>
<span id="cb55-2"><a href="#cb55-2" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> pointer <span class="kw">operator</span><span class="op">-&gt;()</span> <span class="kw">noexcept</span><span class="op">;</span></span></code></pre></div>
<ol start="3" type="1">
<li><p><em>Preconditions</em>: <code>*this</code> is not
valueless.</p></li>
<li><p><em>Returns</em>: A pointer to the owned object.</p></li>
</ol>
<div class="sourceCode" id="cb56"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb56-1"><a href="#cb56-1" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> <span class="dt">bool</span> valueless_after_move<span class="op">()</span> <span class="at">const</span> <span class="kw">noexcept</span><span class="op">;</span></span></code></pre></div>
<ol start="5" type="1">
<li><em>Returns</em>: <code>true</code> if <code>*this</code> is
valueless, otherwise <code>false</code>.</li>
</ol>
<div class="sourceCode" id="cb57"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb57-1"><a href="#cb57-1" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> <span class="dt">allocator_type</span> get_allocator<span class="op">()</span> <span class="at">const</span> <span class="kw">noexcept</span><span class="op">;</span></span></code></pre></div>
<ol start="6" type="1">
<li><em>Returns</em>: <code>alloc</code>.</li>
</ol>
<h3 id="x.z.7-swap-polymorphic.swap">X.Z.7 Swap [polymorphic.swap]</h3>
<div class="sourceCode" id="cb58"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb58-1"><a href="#cb58-1" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> <span class="dt">void</span> swap<span class="op">(</span>polymorphic<span class="op">&amp;</span> other<span class="op">)</span> <span class="kw">noexcept</span><span class="op">(</span></span>
<span id="cb58-2"><a href="#cb58-2" aria-hidden="true" tabindex="-1"></a>  allocator_traits<span class="op">&lt;</span>Allocator<span class="op">&gt;::</span>propagate_on_container_swap<span class="op">::</span>value</span>
<span id="cb58-3"><a href="#cb58-3" aria-hidden="true" tabindex="-1"></a>  <span class="op">||</span> allocator_traits<span class="op">&lt;</span>Allocator<span class="op">&gt;::</span>is_always_equal<span class="op">::</span>value<span class="op">);</span></span></code></pre></div>
<ol type="1">
<li><p><em>Preconditions</em>: If<br />
<code>allocator_traits&lt;Allocator&gt;::propagate_on_container_swap::value</code><br />
is <code>true</code>, then <code>Allocator</code> meets the
<em>Cpp17Swappable</em> requirements. Otherwise
<code>get_allocator() == other.get_allocator()</code> is
<code>true</code>.</p></li>
<li><p><em>Effects</em>: Swaps the states of <code>*this</code> and
<code>other</code>, exchanging owned objects or valueless states.
If<br />
<code>allocator_traits&lt;Allocator&gt;::propagate_on_container_swap::value</code><br />
is <code>true</code>, then the allocators of <code>*this</code> and
<code>other</code> are exchanged by calling <code>swap</code> as
described in [swappable.requirements]. Otherwise, the allocators are not
swapped. <em>[Note: Does not call <code>swap</code> on the owned objects
directly. –end note]</em></p></li>
</ol>
<div class="sourceCode" id="cb59"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb59-1"><a href="#cb59-1" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> <span class="dt">void</span> swap<span class="op">(</span>polymorphic<span class="op">&amp;</span> lhs<span class="op">,</span> polymorphic<span class="op">&amp;</span> rhs<span class="op">)</span> <span class="kw">noexcept</span><span class="op">(</span></span>
<span id="cb59-2"><a href="#cb59-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">noexcept</span><span class="op">(</span>lhs<span class="op">.</span>swap<span class="op">(</span>rhs<span class="op">)));</span></span></code></pre></div>
<ol start="3" type="1">
<li><em>Effects</em>: Equivalent to <code>lhs.swap(rhs)</code>.</li>
</ol>
<h1 id="reference-implementation">Reference implementation</h1>
<p>A C++20 reference implementation of this proposal is available on
GitHub at <a href="https://www.github.com/jbcoe/value_types"
class="uri">https://www.github.com/jbcoe/value_types</a>.</p>
<h1 id="acknowledgements">Acknowledgements</h1>
<p>The authors would like to thank Andrew Bennieston, Bengt Gustafsson,
Casey Carter, Daniel Krugler, David Krauss, David Stone, Ed Catmur,
Geoff Romer, German Diago, Jan Moeller, Jonathan Wakely, Josh Berne,
Kilian Henneberger, LanguageLawyer, Lewis Baker, Louis Dionne, Maciej
Bogus, Malcolm Parsons, Matthew Calabrese, Nathan Myers, Neelofer
Banglawala, Nevin Liber, Nina Ranns, Patrice Roy, Roger Orr, Rostislav
Khlebnikov, Stephan T. Lavavej, Stephen Kelly, Thomas Koeppe, Thomas
Russell, Tom Hudson, Tomasz Kaminski, Tony van Eerd and Ville
Voutilainen for suggestions and useful discussion.</p>
<h1 id="references">References</h1>
<p><em>A Preliminary Proposal for a Deep-Copying Smart
Pointer</em><br />
W. E. Brown, 2012<br />
<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3339.pdf"
class="uri">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3339.pdf</a></p>
<p><em>A polymorphic value-type for C++</em><br />
J. B. Coe, S. Parent 2019<br />
<a
href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p0201r6.html"
class="uri">https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p0201r6.html</a></p>
<p><em>A Free-Store-Allocated Value Type for C++</em><br />
J. B. Coe, A. Peacock 2022<br />
<a
href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1950r2.html"
class="uri">https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1950r2.html</a></p>
<p><em>An allocator-aware optional type</em><br />
P. Halpern, N. D. Ranns, V. Voutilainen, 2024<br />
<a
href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2047r7.html"
class="uri">https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2047r7.html</a></p>
<p><em>MISRA Language Guidelines</em><br />
<a href="https://ldra.com/misra/"
class="uri">https://ldra.com/misra/</a></p>
<p><em>High Integrity C++</em><br />
<a
href="https://www.perforce.com/resources/qac/high-integrity-cpp-coding-standard"
class="uri">https://www.perforce.com/resources/qac/high-integrity-cpp-coding-standard</a></p>
<h1 id="appendix-a-detailed-design-decisions">Appendix A: Detailed
design decisions</h1>
<p>We discuss some of the decisions that were made in the design of
<code>indirect</code> and <code>polymorphic</code>. Where there are
multiple options, we discuss the advantages and disadvantages of
each.</p>
<h2 id="two-class-templates-not-one">Two class templates, not one</h2>
<p>It is conceivable that a single class template could be used as a
vocabulary type for an indirect value type supporting polymorphism.
However, implementing this would impose efficiency costs on the copy
constructor when the owned object is the same type as the template type.
When the owned object is a derived type, the copy constructor uses type
erasure to perform dynamic dispatch and call the derived type copy
constructor. The overhead of indirection and a virtual function call is
not tolerable where the owned object type and template type match.</p>
<p>One potential solution would be to use a <code>std::variant</code> to
store the owned type or the control block used to manage the owned type.
This would allow the copy constructor to be implemented efficiently when
the owned type and template type match. This would increase the object
size beyond that of a single pointer as the discriminant must be
stored.</p>
<p>For the sake of minimal size and efficiency, we opted to use two
class templates.</p>
<h2
id="copiers-deleters-pointer-constructors-and-allocator-support">Copiers,
deleters, pointer constructors, and allocator support</h2>
<p>The older types <code>indirect_value</code> and
<code>polymorphic_value</code> had constructors that take a pointer,
copier, and deleter. The copier and deleter could be used to specify how
the object should be copied and deleted. The existence of a pointer
constructor introduces undesirable properties into the design of
<code>polymorphic_value</code>, such as allowing the possibility of
object slicing on copy when the dynamic and static types of a
derived-type pointer do not match.</p>
<p>We decided to remove the copier, delete, and pointer constructor in
favour of adding allocator support. A pointer constructor and support
for custom copiers and deleters are not core to the design of either
class template; both could be added in a later revision of the standard
if required.</p>
<p>We have been advised that allocator support must be a part of the
initial implementation and cannot be added retrospectively. As
<code>indirect</code> and <code>polymorphic</code> are intended to be
used alongside other C++ standard library types, such as
<code>std::map</code> and <code>std::vector</code>, it is important that
they have allocator support in contexts where allocators are used.</p>
<h2 id="pointer-like-helper-functions">Pointer-like helper
functions</h2>
<p>Earlier revisions of <code>polymorphic_value</code> had helper
functions to get access to the underlying pointer. These were removed
under the advice of the Library Evolution Working Group as they were not
core to the design of the class template, nor were they consistent with
value-type semantics.</p>
<p>Pointer-like accessors like <code>dynamic_pointer_cast</code> and
<code>static_pointer_cast</code>, which are provided for
<code>std::shared_ptr</code>, could be added in a later revision of the
standard if required.</p>
<h2 id="constraints-and-incomplete-type-support">Constraints and
incomplete type support</h2>
<p>We decided not to conditionally enable the default constructor, copy
constructor and comparison operators for <code>indirect</code>, and not
to conditionally enable the default constructor for
<code>polymorphic</code>.</p>
<p>Both <code>indirect</code> and <code>polymorphic</code> must support
incomplete types at class instantiation time. Similar to
<code>vector</code>, they may falsely advertise support (through type
traits or concepts) for functions that would make a program ill-formed
if they were used.</p>
<div class="sourceCode" id="cb60"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb60-1"><a href="#cb60-1" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> Copyable <span class="op">{</span></span>
<span id="cb60-2"><a href="#cb60-2" aria-hidden="true" tabindex="-1"></a>  Copyable<span class="op">()</span> <span class="op">=</span> <span class="cf">default</span><span class="op">;</span></span>
<span id="cb60-3"><a href="#cb60-3" aria-hidden="true" tabindex="-1"></a>  Copyable<span class="op">(</span><span class="at">const</span> Copyable<span class="op">&amp;)</span> <span class="op">=</span> <span class="cf">default</span><span class="op">;</span></span>
<span id="cb60-4"><a href="#cb60-4" aria-hidden="true" tabindex="-1"></a><span class="op">};</span></span>
<span id="cb60-5"><a href="#cb60-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb60-6"><a href="#cb60-6" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> NonCopyable <span class="op">{</span></span>
<span id="cb60-7"><a href="#cb60-7" aria-hidden="true" tabindex="-1"></a>  NonCopyable<span class="op">()</span> <span class="op">=</span> <span class="cf">default</span><span class="op">;</span></span>
<span id="cb60-8"><a href="#cb60-8" aria-hidden="true" tabindex="-1"></a>  NonCopyable<span class="op">(</span><span class="at">const</span> NonCopyable<span class="op">&amp;)</span> <span class="op">=</span> <span class="kw">delete</span><span class="op">;</span></span>
<span id="cb60-9"><a href="#cb60-9" aria-hidden="true" tabindex="-1"></a><span class="op">};</span></span>
<span id="cb60-10"><a href="#cb60-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb60-11"><a href="#cb60-11" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> Incomplete<span class="op">;</span></span>
<span id="cb60-12"><a href="#cb60-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb60-13"><a href="#cb60-13" aria-hidden="true" tabindex="-1"></a><span class="kw">static_assert</span><span class="op">(</span><span class="bu">std::</span>is_copy_constructible_v<span class="op">&lt;</span><span class="bu">std::</span>vector<span class="op">&lt;</span>Copyable<span class="op">&gt;&gt;);</span> <span class="co">// Passes.</span></span>
<span id="cb60-14"><a href="#cb60-14" aria-hidden="true" tabindex="-1"></a><span class="kw">static_assert</span><span class="op">(</span><span class="bu">std::</span>is_copy_constructible_v<span class="op">&lt;</span><span class="bu">std::</span>vector<span class="op">&lt;</span>NonCopyable<span class="op">&gt;&gt;);</span> <span class="co">// Passes.</span></span>
<span id="cb60-15"><a href="#cb60-15" aria-hidden="true" tabindex="-1"></a><span class="kw">static_assert</span><span class="op">(</span><span class="bu">std::</span>is_copy_constructible_v<span class="op">&lt;</span><span class="bu">std::</span>vector<span class="op">&lt;</span>Incomplete<span class="op">&gt;&gt;);</span> <span class="co">// Passes.</span></span>
<span id="cb60-16"><a href="#cb60-16" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb60-17"><a href="#cb60-17" aria-hidden="true" tabindex="-1"></a><span class="kw">static_assert</span><span class="op">(</span><span class="bu">std::</span>is_copy_constructible_v<span class="op">&lt;</span>indirect<span class="op">&lt;</span>Copyable<span class="op">&gt;&gt;);</span> <span class="co">// Passes.</span></span>
<span id="cb60-18"><a href="#cb60-18" aria-hidden="true" tabindex="-1"></a><span class="kw">static_assert</span><span class="op">(</span><span class="bu">std::</span>is_copy_constructible_v<span class="op">&lt;</span>indirect<span class="op">&lt;</span>NonCopyable<span class="op">&gt;&gt;);</span> <span class="co">// Passes.</span></span>
<span id="cb60-19"><a href="#cb60-19" aria-hidden="true" tabindex="-1"></a><span class="kw">static_assert</span><span class="op">(</span><span class="bu">std::</span>is_copy_constructible_v<span class="op">&lt;</span>indirect<span class="op">&lt;</span>Incomplete<span class="op">&gt;&gt;);</span> <span class="co">// Passes.</span></span>
<span id="cb60-20"><a href="#cb60-20" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb60-21"><a href="#cb60-21" aria-hidden="true" tabindex="-1"></a><span class="kw">static_assert</span><span class="op">(</span><span class="bu">std::</span>is_copy_constructible_v<span class="op">&lt;</span>polymorphic<span class="op">&lt;</span>Copyable<span class="op">&gt;&gt;);</span> <span class="co">// Passes.</span></span>
<span id="cb60-22"><a href="#cb60-22" aria-hidden="true" tabindex="-1"></a><span class="kw">static_assert</span><span class="op">(</span><span class="bu">std::</span>is_copy_constructible_v<span class="op">&lt;</span>polymorphic<span class="op">&lt;</span>NonCopyable<span class="op">&gt;&gt;);</span> <span class="co">// Passes.</span></span>
<span id="cb60-23"><a href="#cb60-23" aria-hidden="true" tabindex="-1"></a><span class="kw">static_assert</span><span class="op">(</span><span class="bu">std::</span>is_copy_constructible_v<span class="op">&lt;</span>polymorphic<span class="op">&lt;</span>Incomplete<span class="op">&gt;&gt;);</span> <span class="co">// Passes.</span></span></code></pre></div>
<h3 id="deferred-constraints-for-incomplete-types">Deferred constraints
for incomplete types</h3>
<p>It is possible to avoid misleading type trait information by using
<em>deferred constraints</em>: constraint evaluation can be deferred to
function instantiation time by applying constraints to a deduced
template argument.</p>
<div class="sourceCode" id="cb61"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb61-1"><a href="#cb61-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> T<span class="op">&gt;</span></span>
<span id="cb61-2"><a href="#cb61-2" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> incomplete_wrapper <span class="op">{</span></span>
<span id="cb61-3"><a href="#cb61-3" aria-hidden="true" tabindex="-1"></a>  T<span class="op">*</span> t<span class="op">;</span> <span class="co">// Use a pointer for incomplete type support.</span></span>
<span id="cb61-4"><a href="#cb61-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb61-5"><a href="#cb61-5" aria-hidden="true" tabindex="-1"></a> <span class="kw">public</span><span class="op">:</span></span>
<span id="cb61-6"><a href="#cb61-6" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> TT<span class="op">=</span>T<span class="op">&gt;</span></span>
<span id="cb61-7"><a href="#cb61-7" aria-hidden="true" tabindex="-1"></a>  incomplete_wrapper<span class="op">()</span></span>
<span id="cb61-8"><a href="#cb61-8" aria-hidden="true" tabindex="-1"></a>  <span class="kw">requires</span> <span class="bu">std::</span>is_default_constructible_v<span class="op">&lt;</span>TT<span class="op">&gt;;</span></span>
<span id="cb61-9"><a href="#cb61-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb61-10"><a href="#cb61-10" aria-hidden="true" tabindex="-1"></a>  incomplete_wrapper<span class="op">(</span><span class="at">const</span> incomplete_wrapper<span class="op">&amp;)</span> <span class="kw">requires</span> <span class="kw">false</span><span class="op">;</span></span>
<span id="cb61-11"><a href="#cb61-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb61-12"><a href="#cb61-12" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> TT<span class="op">=</span>T<span class="op">&gt;</span></span>
<span id="cb61-13"><a href="#cb61-13" aria-hidden="true" tabindex="-1"></a>  incomplete_wrapper<span class="op">(</span><span class="at">const</span> incomplete_wrapper<span class="op">&amp;)</span></span>
<span id="cb61-14"><a href="#cb61-14" aria-hidden="true" tabindex="-1"></a>  <span class="kw">requires</span> <span class="bu">std::</span>is_copy_constructible_v<span class="op">&lt;</span>TT<span class="op">&gt;;</span></span>
<span id="cb61-15"><a href="#cb61-15" aria-hidden="true" tabindex="-1"></a><span class="op">};</span></span></code></pre></div>
<p>Whilst appealing, this approach is problematic when used in
composition with other types. To illustrate, consider the following
class template <code>TaggedType</code>:</p>
<div class="sourceCode" id="cb62"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb62-1"><a href="#cb62-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">typename</span> T<span class="op">&gt;</span></span>
<span id="cb62-2"><a href="#cb62-2" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> TaggedType <span class="op">{</span></span>
<span id="cb62-3"><a href="#cb62-3" aria-hidden="true" tabindex="-1"></a>  T t<span class="op">;</span></span>
<span id="cb62-4"><a href="#cb62-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb62-5"><a href="#cb62-5" aria-hidden="true" tabindex="-1"></a> <span class="kw">public</span><span class="op">:</span></span>
<span id="cb62-6"><a href="#cb62-6" aria-hidden="true" tabindex="-1"></a>  TaggedType<span class="op">()</span> <span class="kw">requires</span> <span class="bu">std::</span>is_default_constructible_v<span class="op">&lt;</span>T<span class="op">&gt;;</span></span>
<span id="cb62-7"><a href="#cb62-7" aria-hidden="true" tabindex="-1"></a>  TaggedType<span class="op">(</span><span class="at">const</span> TaggedType<span class="op">&amp;)</span> <span class="kw">requires</span> <span class="bu">std::</span>is_copy_constructible_v<span class="op">&lt;</span>T<span class="op">&gt;;</span></span>
<span id="cb62-8"><a href="#cb62-8" aria-hidden="true" tabindex="-1"></a><span class="op">};</span></span></code></pre></div>
<p>We cannot instantiate the class
<code>TaggedType&lt;incomplete_wrapper&lt;T&gt;&gt;</code> when
<code>T</code> is an incomplete type as the constraints on
<code>TaggedType</code> are evaluated at class instantiation time. This
will force the evaluation of the constraints on
<code>incomplete_wrapper&lt;T&gt;</code>, which cannot be evaluated as
<code>T</code> is incomplete.</p>
<p>To support <code>incomplete_wrapper</code> with an incomplete type,
<code>TaggedType</code> must also use deferred constraints. Any type
with constraints that might be templated on <code>TaggedType</code> must
then also use deferred constraints, and so on. The viral nature of this
requirement makes <code>incomplete_wrapper</code> unusable with other
library components if it is intended to support incomplete types.</p>
<p>We decided not to impose deferred constraints on
<code>indirect</code> and <code>polymorphic</code>, as it would make the
types unusable in composition with other types.</p>
<h3 id="mandates-not-constraints">Mandates not constraints</h3>
<p><code>indirect</code> and <code>polymorphic</code> use static
assertions (mandates clauses) which are evaluated at function
instantiation time to provide better compiler errors.</p>
<p>For example, the code sample below:</p>
<div class="sourceCode" id="cb63"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb63-1"><a href="#cb63-1" aria-hidden="true" tabindex="-1"></a>indirect<span class="op">&lt;</span>NonCopyable<span class="op">&gt;</span> copy<span class="op">(</span><span class="at">const</span> indirect<span class="op">&lt;</span>NonCopyable<span class="op">&gt;&amp;</span> i<span class="op">)</span> <span class="op">{</span></span>
<span id="cb63-2"><a href="#cb63-2" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> i<span class="op">;</span></span>
<span id="cb63-3"><a href="#cb63-3" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>gives the following errors:</p>
<div class="sourceCode" id="cb64"><pre
class="sourceCode sh"><code class="sourceCode bash"><span id="cb64-1"><a href="#cb64-1" aria-hidden="true" tabindex="-1"></a><span class="ex">indirect.h:LINE:COLUMN:</span> error: static assertion failed</span>
<span id="cb64-2"><a href="#cb64-2" aria-hidden="true" tabindex="-1"></a>  <span class="ex">LINE</span> <span class="kw">|</span>     <span class="ex">static_assert</span><span class="er">(</span><span class="ex">std::copy_constructible</span><span class="op">&lt;</span>T<span class="op">&gt;</span><span class="kw">);</span></span>
<span id="cb64-3"><a href="#cb64-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb64-4"><a href="#cb64-4" aria-hidden="true" tabindex="-1"></a><span class="ex">note:</span> in instantiation of member function <span class="st">&#39;indirect&lt;NonCopyable&gt;::indirect&#39;</span> requested here</span>
<span id="cb64-5"><a href="#cb64-5" aria-hidden="true" tabindex="-1"></a> <span class="ex">LINE</span> <span class="kw">|</span>   <span class="cf">return</span> <span class="ex">i</span><span class="kw">;</span></span></code></pre></div>
<p>Arthur O’Dwyer has written a blog post on the topic of constraints
and incomplete types <a
href="https://quuxplusone.github.io/blog/2020/02/05/vector-is-copyable-except-when-its-not"
class="uri">https://quuxplusone.github.io/blog/2020/02/05/vector-is-copyable-except-when-its-not</a>.</p>
<h2 id="implicit-conversions">Implicit conversions</h2>
<p>We decided that there should be no implicit conversion of a value
<code>T</code> to an <code>indirect&lt;T&gt;</code> or
<code>polymorphic&lt;T&gt;</code>. An implicit conversion would require
using a memory resource and memory allocation, which is best made
explicit by the user.</p>
<div class="sourceCode" id="cb65"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb65-1"><a href="#cb65-1" aria-hidden="true" tabindex="-1"></a>Rectangle r<span class="op">(</span>w<span class="op">,</span> h<span class="op">);</span></span>
<span id="cb65-2"><a href="#cb65-2" aria-hidden="true" tabindex="-1"></a>polymorphic<span class="op">&lt;</span>Shape<span class="op">&gt;</span> s <span class="op">=</span> r<span class="op">;</span> <span class="co">// error</span></span></code></pre></div>
<p>To transform a value into <code>indirect</code> or
<code>polymorphic</code>, the user must use the appropriate
constructor.</p>
<div class="sourceCode" id="cb66"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb66-1"><a href="#cb66-1" aria-hidden="true" tabindex="-1"></a>Rectangle r<span class="op">(</span>w<span class="op">,</span> h<span class="op">);</span></span>
<span id="cb66-2"><a href="#cb66-2" aria-hidden="true" tabindex="-1"></a>polymorphic<span class="op">&lt;</span>Shape<span class="op">&gt;</span> s<span class="op">(</span><span class="bu">std::</span>in_place_type<span class="op">&lt;</span>Rectangle<span class="op">&gt;,</span> r<span class="op">);</span></span>
<span id="cb66-3"><a href="#cb66-3" aria-hidden="true" tabindex="-1"></a><span class="ot">assert</span><span class="op">(</span><span class="kw">dynamic_cast</span><span class="op">&lt;</span>Rectangle<span class="op">*&gt;(&amp;*</span>s<span class="op">)</span> <span class="op">!=</span> <span class="kw">nullptr</span><span class="op">);</span></span></code></pre></div>
<h2 id="explicit-conversions">Explicit conversions</h2>
<p>The older class template <code>polymorphic_value</code> had explicit
conversions, allowing construction of a
<code>polymorphic_value&lt;T&gt;</code> from a
<code>polymorphic_value&lt;U&gt;</code>, where <code>T</code> was a base
class of <code>U</code>.</p>
<div class="sourceCode" id="cb67"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb67-1"><a href="#cb67-1" aria-hidden="true" tabindex="-1"></a>polymorphic_value<span class="op">&lt;</span>Quadrilateral<span class="op">&gt;</span> q<span class="op">(</span><span class="bu">std::</span>in_place_type<span class="op">&lt;</span>Rectangle<span class="op">&gt;,</span> w<span class="op">,</span> h<span class="op">);</span></span>
<span id="cb67-2"><a href="#cb67-2" aria-hidden="true" tabindex="-1"></a>polymorphic_value<span class="op">&lt;</span>Shape<span class="op">&gt;</span> s <span class="op">=</span> q<span class="op">;</span></span>
<span id="cb67-3"><a href="#cb67-3" aria-hidden="true" tabindex="-1"></a><span class="ot">assert</span><span class="op">(</span><span class="kw">dynamic_cast</span><span class="op">&lt;</span>Rectangle<span class="op">*&gt;(&amp;*</span>s<span class="op">)</span> <span class="op">!=</span> <span class="kw">nullptr</span><span class="op">);</span></span></code></pre></div>
<p>Similar code cannot be written with <code>polymorphic</code> as it
does not allow conversions between derived types:</p>
<div class="sourceCode" id="cb68"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb68-1"><a href="#cb68-1" aria-hidden="true" tabindex="-1"></a>polymorphic<span class="op">&lt;</span>Quadrilateral<span class="op">&gt;</span> q<span class="op">(</span><span class="bu">std::</span>in_place_type<span class="op">&lt;</span>Rectangle<span class="op">&gt;,</span> w<span class="op">,</span> h<span class="op">);</span></span>
<span id="cb68-2"><a href="#cb68-2" aria-hidden="true" tabindex="-1"></a>polymorphic<span class="op">&lt;</span>Shape<span class="op">&gt;</span> s <span class="op">=</span> q<span class="op">;</span> <span class="co">// error</span></span></code></pre></div>
<p>This is a deliberate design decision. <code>polymorphic</code> is
intended to be used for ownership of member data in composite classes
where compiler-generated special member functions will be used.</p>
<p>There is no motivating use case for explicit conversion between
derived types outside of tests.</p>
<p>A converting constructor could be added in a future version of the
C++ standard.</p>
<h2 id="comparisons-for-indirect">Comparisons for
<code>indirect</code></h2>
<p>We implement comparisons for <code>indirect</code> in terms of
<code>operator==</code> and <code>operator&lt;=&gt;</code> returning
<code>bool</code> and <code>auto</code> respectively.</p>
<p>The alternative would be to implement the full suite of comparison
operators, forwarding them to the underlying type and allowing
non-boolean return types. Support for non-boolean return types would
support unusual (non-regular) user-defined comparison operators which
could be helpful when the underlying type is part of a
domain-specific-language (DSL) that uses comparison operators for a
different purpose. However, this would be inconsistent with other
standard library types like <code>optional</code>, <code>variant</code>
and <code>reference_wrapper</code>. Moreover, we’d likely give only
partial support for a theoretical DSL which may well make use of other
operators like <code>operator+</code> and <code>operator-</code> which
are not supported for <code>indirect</code>.</p>
<h2 id="supporting-operator-operator">Supporting <code>operator()</code>
<code>operator[]</code></h2>
<p>There is no need for <code>indirect</code> or
<code>polymorphic</code> to provide a function call or an indexing
operator. Users who wish to do that can simply access the value and call
its operator. Furthermore, unlike comparisons, function calls or
indexing operators do not compose further; for example, a composite
would not be able to automatically generate a composited
<code>operator()</code> or an <code>operator[]</code>.</p>
<h2 id="supporting-arithmetic-operators">Supporting arithmetic
operators</h2>
<p>While we could provide support for arithmetic operators,
<code>+</code>, <code>-</code> ,<code>*</code>, <code>/</code>, to
<code>indirect</code> in the same way that we support comparisons, we
have chosen not to do so. The arithmetic operators would need to support
a valueless state for which there is no precedent in the standard
library.</p>
<p>Support for arithmetic operators could be added in a future version
of the C++ standard. If support for arithmetic operators for valueless
or empty objects is later added to the standard library in a coherent
way, it could be added for <code>indirect</code> at that time.</p>
<h2 id="member-function-emplace">Member function
<code>emplace</code></h2>
<p>Neither <code>indirect</code> nor <code>polymorphic</code> support
<code>emplace</code> as a member function. The member function
<code>emplace</code> could be added as :</p>
<div class="sourceCode" id="cb69"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb69-1"><a href="#cb69-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> <span class="op">...</span>Ts<span class="op">&gt;</span></span>
<span id="cb69-2"><a href="#cb69-2" aria-hidden="true" tabindex="-1"></a>indirect<span class="op">::</span>emplace<span class="op">(</span>Ts<span class="op">&amp;&amp;</span> <span class="op">...</span>ts<span class="op">);</span></span></code></pre></div>
<div class="sourceCode" id="cb70"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb70-1"><a href="#cb70-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> U<span class="op">,</span> <span class="kw">typename</span> <span class="op">...</span>Ts<span class="op">&gt;</span></span>
<span id="cb70-2"><a href="#cb70-2" aria-hidden="true" tabindex="-1"></a>polymorphic<span class="op">::</span>emplace<span class="op">(</span><span class="dt">in_place_type</span><span class="op">&lt;</span>U<span class="op">&gt;,</span> Ts<span class="op">&amp;&amp;</span> <span class="op">...</span>ts<span class="op">);</span></span></code></pre></div>
<p>This would be API noise. It offers no efficiency improvement
over:</p>
<div class="sourceCode" id="cb71"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb71-1"><a href="#cb71-1" aria-hidden="true" tabindex="-1"></a>some_indirect <span class="op">=</span> indirect<span class="op">(</span><span class="co">/* arguments */</span><span class="op">);</span></span></code></pre></div>
<div class="sourceCode" id="cb72"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb72-1"><a href="#cb72-1" aria-hidden="true" tabindex="-1"></a>some_polymorphic <span class="op">=</span> polymorphic<span class="op">(</span><span class="dt">in_place_type</span><span class="op">&lt;</span>U<span class="op">&gt;,</span> <span class="co">/* arguments */</span><span class="op">);</span></span></code></pre></div>
<p>Support for an emplace member function could be added in a future
version of the C++ standard.</p>
<h2 id="small-buffer-optimisation">Small Buffer Optimisation</h2>
<p>It is possible to implement <code>polymorphic</code> with a small
buffer optimisation, similar to that used in <code>std::function</code>.
This would allow <code>polymorphic</code> to store small objects without
allocating memory. Like <code>std::function</code>, the size of the
small buffer is left to be specified by the implementation.</p>
<p>The authors are sceptical of the value of a small buffer optimisation
for objects from a type hierarchy. If the buffer is too small, all
instances of <code>polymorphic</code> will be larger than needed. This
is because they will allocate memory in addition to having the memory
from the (empty) buffer as part of the object size. If the buffer is too
big, <code>polymorphic</code> objects will be larger than necessary,
potentially introducing the need for
<code>indirect&lt;polymorphic&lt;T&gt;&gt;</code>.</p>
<p>We could add a non-type template argument to <code>polymorphic</code>
to specify the size of the small buffer:</p>
<div class="sourceCode" id="cb73"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb73-1"><a href="#cb73-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> T<span class="op">,</span> <span class="kw">typename</span> Alloc<span class="op">,</span> <span class="dt">size_t</span> BufferSize<span class="op">&gt;</span></span>
<span id="cb73-2"><a href="#cb73-2" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> polymorphic<span class="op">;</span></span></code></pre></div>
<p>However, we opt not to do this to maintain consistency with other
standard library types. Both <code>std::function</code> and
<code>std::string</code> leave the buffer size as an implementation
detail. Including an additional template argument in a later revision of
the standard would be a breaking change. With usage experience,
implementers will be able to determine if a small buffer optimisation is
worthwhile, and what the optimal buffer size might be.</p>
<p>A small buffer optimisation makes little sense for
<code>indirect</code> as the sensible size of the buffer would be
dictated by the size of the stored object. This removes support for
incomplete types and locates storage for the object locally, defeating
the purpose of <code>indirect</code>.</p>
<h1 id="appendix-b-before-and-after-examples">Appendix B: Before and
after examples</h1>
<p>We include some minimal, illustrative examples of how
<code>indirect</code> and <code>polymorphic</code> can be used to
simplify composite class design.</p>
<h2
id="using-indirect-for-binary-compatibility-using-the-pimpl-idiom">Using
<code>indirect</code> for binary compatibility using the PIMPL
idiom</h2>
<p>Without <code>indirect</code>, we use <code>std::unique_ptr</code> to
manage the lifetime of the implementation object. All const-qualified
methods of the composite will need to be manually checked to ensure that
they are not calling non-const qualified methods of component
objects.</p>
<h3 id="before-without-using-indirect">Before, without using
<code>indirect</code></h3>
<div class="sourceCode" id="cb74"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb74-1"><a href="#cb74-1" aria-hidden="true" tabindex="-1"></a><span class="co">// Class.h</span></span>
<span id="cb74-2"><a href="#cb74-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb74-3"><a href="#cb74-3" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> Class <span class="op">{</span></span>
<span id="cb74-4"><a href="#cb74-4" aria-hidden="true" tabindex="-1"></a>  <span class="kw">class</span> Impl<span class="op">;</span></span>
<span id="cb74-5"><a href="#cb74-5" aria-hidden="true" tabindex="-1"></a>  <span class="bu">std::</span>unique_ptr<span class="op">&lt;</span>Impl<span class="op">&gt;</span> <span class="va">impl_</span><span class="op">;</span></span>
<span id="cb74-6"><a href="#cb74-6" aria-hidden="true" tabindex="-1"></a> <span class="kw">public</span><span class="op">:</span></span>
<span id="cb74-7"><a href="#cb74-7" aria-hidden="true" tabindex="-1"></a>  Class<span class="op">();</span></span>
<span id="cb74-8"><a href="#cb74-8" aria-hidden="true" tabindex="-1"></a>  <span class="op">~</span>Class<span class="op">();</span></span>
<span id="cb74-9"><a href="#cb74-9" aria-hidden="true" tabindex="-1"></a>  Class<span class="op">(</span><span class="at">const</span> Class<span class="op">&amp;);</span></span>
<span id="cb74-10"><a href="#cb74-10" aria-hidden="true" tabindex="-1"></a>  Class<span class="op">&amp;</span> <span class="kw">operator</span><span class="op">=(</span><span class="at">const</span> Class<span class="op">&amp;);</span></span>
<span id="cb74-11"><a href="#cb74-11" aria-hidden="true" tabindex="-1"></a>  Class<span class="op">(</span>Class<span class="op">&amp;&amp;)</span> <span class="kw">noexcept</span><span class="op">;</span></span>
<span id="cb74-12"><a href="#cb74-12" aria-hidden="true" tabindex="-1"></a>  Class<span class="op">&amp;</span> <span class="kw">operator</span><span class="op">=(</span>Class<span class="op">&amp;&amp;)</span> <span class="kw">noexcept</span><span class="op">;</span></span>
<span id="cb74-13"><a href="#cb74-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb74-14"><a href="#cb74-14" aria-hidden="true" tabindex="-1"></a>  <span class="dt">void</span> do_something<span class="op">();</span></span>
<span id="cb74-15"><a href="#cb74-15" aria-hidden="true" tabindex="-1"></a><span class="op">};</span></span></code></pre></div>
<div class="sourceCode" id="cb75"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb75-1"><a href="#cb75-1" aria-hidden="true" tabindex="-1"></a><span class="co">// Class.cpp</span></span>
<span id="cb75-2"><a href="#cb75-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb75-3"><a href="#cb75-3" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> Impl <span class="op">{</span></span>
<span id="cb75-4"><a href="#cb75-4" aria-hidden="true" tabindex="-1"></a> <span class="kw">public</span><span class="op">:</span></span>
<span id="cb75-5"><a href="#cb75-5" aria-hidden="true" tabindex="-1"></a>  <span class="dt">void</span> do_something<span class="op">();</span></span>
<span id="cb75-6"><a href="#cb75-6" aria-hidden="true" tabindex="-1"></a><span class="op">};</span></span>
<span id="cb75-7"><a href="#cb75-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb75-8"><a href="#cb75-8" aria-hidden="true" tabindex="-1"></a>Class<span class="op">::</span>Class<span class="op">()</span> <span class="op">:</span> <span class="va">impl_</span><span class="op">(</span><span class="bu">std::</span>make_unique<span class="op">&lt;</span>Impl<span class="op">&gt;())</span> <span class="op">{}</span></span>
<span id="cb75-9"><a href="#cb75-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb75-10"><a href="#cb75-10" aria-hidden="true" tabindex="-1"></a>Class<span class="op">::~</span>Class<span class="op">()</span> <span class="op">=</span> <span class="cf">default</span><span class="op">;</span></span>
<span id="cb75-11"><a href="#cb75-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb75-12"><a href="#cb75-12" aria-hidden="true" tabindex="-1"></a>Class<span class="op">::</span>Class<span class="op">(</span><span class="at">const</span> Class<span class="op">&amp;</span> other<span class="op">)</span> <span class="op">:</span> <span class="va">impl_</span><span class="op">(</span><span class="bu">std::</span>make_unique<span class="op">&lt;</span>Impl<span class="op">&gt;(*</span>other<span class="op">.</span><span class="va">impl_</span><span class="op">))</span> <span class="op">{}</span></span>
<span id="cb75-13"><a href="#cb75-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb75-14"><a href="#cb75-14" aria-hidden="true" tabindex="-1"></a>Class<span class="op">&amp;</span> Class<span class="op">::</span><span class="kw">operator</span><span class="op">=(</span><span class="at">const</span> Class<span class="op">&amp;</span> other<span class="op">)</span> <span class="op">{</span></span>
<span id="cb75-15"><a href="#cb75-15" aria-hidden="true" tabindex="-1"></a>  <span class="cf">if</span> <span class="op">(</span><span class="kw">this</span> <span class="op">!=</span> <span class="op">&amp;</span>other<span class="op">)</span> <span class="op">{</span></span>
<span id="cb75-16"><a href="#cb75-16" aria-hidden="true" tabindex="-1"></a>    Class tmp<span class="op">(</span>other<span class="op">);</span></span>
<span id="cb75-17"><a href="#cb75-17" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> <span class="bu">std::</span>swap<span class="op">;</span></span>
<span id="cb75-18"><a href="#cb75-18" aria-hidden="true" tabindex="-1"></a>    swap<span class="op">(*</span><span class="kw">this</span><span class="op">,</span> tmp<span class="op">);</span></span>
<span id="cb75-19"><a href="#cb75-19" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb75-20"><a href="#cb75-20" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> <span class="op">*</span><span class="kw">this</span><span class="op">;</span></span>
<span id="cb75-21"><a href="#cb75-21" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb75-22"><a href="#cb75-22" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb75-23"><a href="#cb75-23" aria-hidden="true" tabindex="-1"></a>Class<span class="op">(</span>Class<span class="op">&amp;&amp;)</span> <span class="kw">noexcept</span> <span class="op">=</span> <span class="cf">default</span><span class="op">;</span></span>
<span id="cb75-24"><a href="#cb75-24" aria-hidden="true" tabindex="-1"></a>Class<span class="op">&amp;</span> <span class="kw">operator</span><span class="op">=(</span>Class<span class="op">&amp;&amp;)</span> <span class="kw">noexcept</span> <span class="op">=</span> <span class="cf">default</span><span class="op">;</span></span>
<span id="cb75-25"><a href="#cb75-25" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb75-26"><a href="#cb75-26" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> Class<span class="op">::</span>do_something<span class="op">()</span> <span class="op">{</span></span>
<span id="cb75-27"><a href="#cb75-27" aria-hidden="true" tabindex="-1"></a>  <span class="va">impl_</span><span class="op">-&gt;</span>do_something<span class="op">();</span></span>
<span id="cb75-28"><a href="#cb75-28" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<h3 id="after-using-indirect">After, using <code>indirect</code></h3>
<div class="sourceCode" id="cb76"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb76-1"><a href="#cb76-1" aria-hidden="true" tabindex="-1"></a><span class="co">// Class.h</span></span>
<span id="cb76-2"><a href="#cb76-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb76-3"><a href="#cb76-3" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> Class <span class="op">{</span></span>
<span id="cb76-4"><a href="#cb76-4" aria-hidden="true" tabindex="-1"></a>  indirect<span class="op">&lt;</span><span class="kw">class</span> Impl<span class="op">&gt;</span> <span class="va">impl_</span><span class="op">;</span></span>
<span id="cb76-5"><a href="#cb76-5" aria-hidden="true" tabindex="-1"></a> <span class="kw">public</span><span class="op">:</span></span>
<span id="cb76-6"><a href="#cb76-6" aria-hidden="true" tabindex="-1"></a>  Class<span class="op">();</span></span>
<span id="cb76-7"><a href="#cb76-7" aria-hidden="true" tabindex="-1"></a>  <span class="op">~</span>Class<span class="op">();</span></span>
<span id="cb76-8"><a href="#cb76-8" aria-hidden="true" tabindex="-1"></a>  Class<span class="op">(</span><span class="at">const</span> Class<span class="op">&amp;);</span></span>
<span id="cb76-9"><a href="#cb76-9" aria-hidden="true" tabindex="-1"></a>  Class<span class="op">&amp;</span> <span class="kw">operator</span><span class="op">=(</span><span class="at">const</span> Class<span class="op">&amp;);</span></span>
<span id="cb76-10"><a href="#cb76-10" aria-hidden="true" tabindex="-1"></a>  Class<span class="op">(</span>Class<span class="op">&amp;&amp;)</span> <span class="kw">noexcept</span><span class="op">;</span></span>
<span id="cb76-11"><a href="#cb76-11" aria-hidden="true" tabindex="-1"></a>  Class<span class="op">&amp;</span> <span class="kw">operator</span><span class="op">=(</span>Class<span class="op">&amp;&amp;)</span> <span class="kw">noexcept</span><span class="op">;</span></span>
<span id="cb76-12"><a href="#cb76-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb76-13"><a href="#cb76-13" aria-hidden="true" tabindex="-1"></a>  <span class="dt">void</span> do_something<span class="op">();</span></span>
<span id="cb76-14"><a href="#cb76-14" aria-hidden="true" tabindex="-1"></a><span class="op">};</span></span></code></pre></div>
<div class="sourceCode" id="cb77"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb77-1"><a href="#cb77-1" aria-hidden="true" tabindex="-1"></a><span class="co">// Class.cpp</span></span>
<span id="cb77-2"><a href="#cb77-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb77-3"><a href="#cb77-3" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> Impl <span class="op">{</span></span>
<span id="cb77-4"><a href="#cb77-4" aria-hidden="true" tabindex="-1"></a> <span class="kw">public</span><span class="op">:</span></span>
<span id="cb77-5"><a href="#cb77-5" aria-hidden="true" tabindex="-1"></a>  <span class="dt">void</span> do_something<span class="op">();</span></span>
<span id="cb77-6"><a href="#cb77-6" aria-hidden="true" tabindex="-1"></a><span class="op">};</span></span>
<span id="cb77-7"><a href="#cb77-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb77-8"><a href="#cb77-8" aria-hidden="true" tabindex="-1"></a>Class<span class="op">::</span>Class<span class="op">()</span> <span class="op">:</span> <span class="va">impl_</span><span class="op">(</span>indirect<span class="op">&lt;</span>Impl<span class="op">&gt;())</span> <span class="op">{}</span></span>
<span id="cb77-9"><a href="#cb77-9" aria-hidden="true" tabindex="-1"></a>Class<span class="op">::~</span>Class<span class="op">()</span> <span class="op">=</span> <span class="cf">default</span><span class="op">;</span></span>
<span id="cb77-10"><a href="#cb77-10" aria-hidden="true" tabindex="-1"></a>Class<span class="op">::</span>Class<span class="op">(</span><span class="at">const</span> Class<span class="op">&amp;)</span> <span class="op">=</span> <span class="cf">default</span><span class="op">;</span></span>
<span id="cb77-11"><a href="#cb77-11" aria-hidden="true" tabindex="-1"></a>Class<span class="op">&amp;</span> Class<span class="op">::</span><span class="kw">operator</span><span class="op">=(</span><span class="at">const</span> Class<span class="op">&amp;)</span> <span class="op">=</span> <span class="cf">default</span><span class="op">;</span></span>
<span id="cb77-12"><a href="#cb77-12" aria-hidden="true" tabindex="-1"></a>Class<span class="op">(</span>Class<span class="op">&amp;&amp;)</span> <span class="kw">noexcept</span> <span class="op">=</span> <span class="cf">default</span><span class="op">;</span></span>
<span id="cb77-13"><a href="#cb77-13" aria-hidden="true" tabindex="-1"></a>Class<span class="op">&amp;</span> <span class="kw">operator</span><span class="op">=(</span>Class<span class="op">&amp;&amp;)</span> <span class="kw">noexcept</span> <span class="op">=</span> <span class="cf">default</span><span class="op">;</span></span>
<span id="cb77-14"><a href="#cb77-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb77-15"><a href="#cb77-15" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> Class<span class="op">::</span>do_something<span class="op">()</span> <span class="op">{</span></span>
<span id="cb77-16"><a href="#cb77-16" aria-hidden="true" tabindex="-1"></a>  <span class="va">impl_</span><span class="op">-&gt;</span>do_something<span class="op">();</span></span>
<span id="cb77-17"><a href="#cb77-17" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<h2 id="using-polymorphic-for-a-composite-class">Using
<code>polymorphic</code> for a composite class</h2>
<p>Without <code>polymorphic</code>, we use <code>std::unique_ptr</code>
to manage the lifetime of component objects. All const-qualified methods
of the composite will need to be manually checked to ensure that they
are not calling non-const qualified methods of component objects.</p>
<h3 id="before-without-using-polymorphic">Before, without using
<code>polymorphic</code></h3>
<div class="sourceCode" id="cb78"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb78-1"><a href="#cb78-1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> Canvas<span class="op">;</span></span>
<span id="cb78-2"><a href="#cb78-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb78-3"><a href="#cb78-3" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> Shape <span class="op">{</span></span>
<span id="cb78-4"><a href="#cb78-4" aria-hidden="true" tabindex="-1"></a> <span class="kw">public</span><span class="op">:</span></span>
<span id="cb78-5"><a href="#cb78-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">virtual</span> <span class="op">~</span>Shape<span class="op">()</span> <span class="op">=</span> <span class="cf">default</span><span class="op">;</span></span>
<span id="cb78-6"><a href="#cb78-6" aria-hidden="true" tabindex="-1"></a>  <span class="kw">virtual</span> <span class="bu">std::</span>unique_ptr<span class="op">&lt;</span>Shape<span class="op">&gt;</span> clone<span class="op">()</span> <span class="op">=</span> <span class="dv">0</span><span class="op">;</span></span>
<span id="cb78-7"><a href="#cb78-7" aria-hidden="true" tabindex="-1"></a>  <span class="kw">virtual</span> <span class="dt">void</span> draw<span class="op">(</span>Canvas<span class="op">&amp;)</span> <span class="at">const</span> <span class="op">=</span> <span class="dv">0</span><span class="op">;</span></span>
<span id="cb78-8"><a href="#cb78-8" aria-hidden="true" tabindex="-1"></a><span class="op">};</span></span>
<span id="cb78-9"><a href="#cb78-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb78-10"><a href="#cb78-10" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> Picture <span class="op">{</span></span>
<span id="cb78-11"><a href="#cb78-11" aria-hidden="true" tabindex="-1"></a>  <span class="bu">std::</span>vector<span class="op">&lt;</span><span class="bu">std::</span>unique_ptr<span class="op">&lt;</span>Shape<span class="op">&gt;&gt;</span> <span class="va">shapes_</span><span class="op">;</span></span>
<span id="cb78-12"><a href="#cb78-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb78-13"><a href="#cb78-13" aria-hidden="true" tabindex="-1"></a> <span class="kw">public</span><span class="op">:</span></span>
<span id="cb78-14"><a href="#cb78-14" aria-hidden="true" tabindex="-1"></a>  Picture<span class="op">(</span><span class="at">const</span> <span class="bu">std::</span>vector<span class="op">&lt;</span><span class="bu">std::</span>unique_ptr<span class="op">&lt;</span>Shape<span class="op">&gt;&gt;&amp;</span> shapes<span class="op">)</span> <span class="op">{</span></span>
<span id="cb78-15"><a href="#cb78-15" aria-hidden="true" tabindex="-1"></a>    <span class="va">shapes_</span><span class="op">.</span>reserve<span class="op">(</span>shapes<span class="op">.</span>size<span class="op">());</span></span>
<span id="cb78-16"><a href="#cb78-16" aria-hidden="true" tabindex="-1"></a>    <span class="cf">for</span> <span class="op">(</span><span class="kw">auto</span><span class="op">&amp;</span> shape <span class="op">:</span> shapes<span class="op">)</span> <span class="op">{</span></span>
<span id="cb78-17"><a href="#cb78-17" aria-hidden="true" tabindex="-1"></a>      <span class="va">shapes_</span><span class="op">.</span>push_back<span class="op">(</span>shape<span class="op">-&gt;</span>clone<span class="op">());</span></span>
<span id="cb78-18"><a href="#cb78-18" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb78-19"><a href="#cb78-19" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb78-20"><a href="#cb78-20" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb78-21"><a href="#cb78-21" aria-hidden="true" tabindex="-1"></a>  Picture<span class="op">(</span><span class="at">const</span> Picture<span class="op">&amp;</span> other<span class="op">)</span> <span class="op">{</span></span>
<span id="cb78-22"><a href="#cb78-22" aria-hidden="true" tabindex="-1"></a>    <span class="va">shapes_</span><span class="op">.</span>reserve<span class="op">(</span>other<span class="op">.</span><span class="va">shapes_</span><span class="op">.</span>size<span class="op">());</span></span>
<span id="cb78-23"><a href="#cb78-23" aria-hidden="true" tabindex="-1"></a>    <span class="cf">for</span> <span class="op">(</span><span class="kw">auto</span><span class="op">&amp;</span> shape <span class="op">:</span> other<span class="op">.</span><span class="va">shapes_</span><span class="op">)</span> <span class="op">{</span></span>
<span id="cb78-24"><a href="#cb78-24" aria-hidden="true" tabindex="-1"></a>      <span class="va">shapes_</span><span class="op">.</span>push_back<span class="op">(</span>shape<span class="op">-&gt;</span>clone<span class="op">());</span></span>
<span id="cb78-25"><a href="#cb78-25" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb78-26"><a href="#cb78-26" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb78-27"><a href="#cb78-27" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb78-28"><a href="#cb78-28" aria-hidden="true" tabindex="-1"></a>  Picture<span class="op">&amp;</span> <span class="kw">operator</span><span class="op">=(</span><span class="at">const</span> Picture<span class="op">&amp;</span> other<span class="op">)</span> <span class="op">{</span></span>
<span id="cb78-29"><a href="#cb78-29" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> <span class="op">(</span><span class="kw">this</span> <span class="op">!=</span> <span class="op">&amp;</span>other<span class="op">)</span> <span class="op">{</span></span>
<span id="cb78-30"><a href="#cb78-30" aria-hidden="true" tabindex="-1"></a>      Picture tmp<span class="op">(</span>other<span class="op">);</span></span>
<span id="cb78-31"><a href="#cb78-31" aria-hidden="true" tabindex="-1"></a>      <span class="kw">using</span> <span class="bu">std::</span>swap<span class="op">;</span></span>
<span id="cb78-32"><a href="#cb78-32" aria-hidden="true" tabindex="-1"></a>      swap<span class="op">(*</span><span class="kw">this</span><span class="op">,</span> tmp<span class="op">);</span></span>
<span id="cb78-33"><a href="#cb78-33" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb78-34"><a href="#cb78-34" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="op">*</span><span class="kw">this</span><span class="op">;</span></span>
<span id="cb78-35"><a href="#cb78-35" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb78-36"><a href="#cb78-36" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb78-37"><a href="#cb78-37" aria-hidden="true" tabindex="-1"></a>  <span class="dt">void</span> draw<span class="op">(</span>Canvas<span class="op">&amp;</span> canvas<span class="op">)</span> <span class="at">const</span><span class="op">;</span></span>
<span id="cb78-38"><a href="#cb78-38" aria-hidden="true" tabindex="-1"></a><span class="op">};</span></span></code></pre></div>
<h3 id="after-using-polymorphic">After, using
<code>polymorphic</code></h3>
<div class="sourceCode" id="cb79"><pre
class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb79-1"><a href="#cb79-1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> Canvas<span class="op">;</span></span>
<span id="cb79-2"><a href="#cb79-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb79-3"><a href="#cb79-3" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> Shape <span class="op">{</span></span>
<span id="cb79-4"><a href="#cb79-4" aria-hidden="true" tabindex="-1"></a> <span class="kw">protected</span><span class="op">:</span></span>
<span id="cb79-5"><a href="#cb79-5" aria-hidden="true" tabindex="-1"></a>  <span class="op">~</span>Shape<span class="op">()</span> <span class="op">=</span> <span class="cf">default</span><span class="op">;</span></span>
<span id="cb79-6"><a href="#cb79-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb79-7"><a href="#cb79-7" aria-hidden="true" tabindex="-1"></a> <span class="kw">public</span><span class="op">:</span></span>
<span id="cb79-8"><a href="#cb79-8" aria-hidden="true" tabindex="-1"></a>  <span class="kw">virtual</span> <span class="dt">void</span> draw<span class="op">(</span>Canvas<span class="op">&amp;)</span> <span class="at">const</span> <span class="op">=</span> <span class="dv">0</span><span class="op">;</span></span>
<span id="cb79-9"><a href="#cb79-9" aria-hidden="true" tabindex="-1"></a><span class="op">};</span></span>
<span id="cb79-10"><a href="#cb79-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb79-11"><a href="#cb79-11" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> Picture <span class="op">{</span></span>
<span id="cb79-12"><a href="#cb79-12" aria-hidden="true" tabindex="-1"></a>  <span class="bu">std::</span>vector<span class="op">&lt;</span>polymorphic<span class="op">&lt;</span>Shape<span class="op">&gt;&gt;</span> <span class="va">shapes_</span><span class="op">;</span></span>
<span id="cb79-13"><a href="#cb79-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb79-14"><a href="#cb79-14" aria-hidden="true" tabindex="-1"></a> <span class="kw">public</span><span class="op">:</span></span>
<span id="cb79-15"><a href="#cb79-15" aria-hidden="true" tabindex="-1"></a>  Picture<span class="op">(</span><span class="at">const</span> <span class="bu">std::</span>vector<span class="op">&lt;</span>polymorphic<span class="op">&lt;</span>Shape<span class="op">&gt;&gt;&amp;</span> shapes<span class="op">)</span></span>
<span id="cb79-16"><a href="#cb79-16" aria-hidden="true" tabindex="-1"></a>      <span class="op">:</span> <span class="va">shapes_</span><span class="op">(</span>shapes<span class="op">)</span> <span class="op">{}</span></span>
<span id="cb79-17"><a href="#cb79-17" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb79-18"><a href="#cb79-18" aria-hidden="true" tabindex="-1"></a>  <span class="co">// Picture(const Picture&amp; other) = default;</span></span>
<span id="cb79-19"><a href="#cb79-19" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb79-20"><a href="#cb79-20" aria-hidden="true" tabindex="-1"></a>  <span class="co">// Picture&amp; operator=(const Picture&amp; other) = default;</span></span>
<span id="cb79-21"><a href="#cb79-21" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb79-22"><a href="#cb79-22" aria-hidden="true" tabindex="-1"></a>  <span class="dt">void</span> draw<span class="op">(</span>Canvas<span class="op">&amp;</span> canvas<span class="op">)</span> <span class="at">const</span><span class="op">;</span></span>
<span id="cb79-23"><a href="#cb79-23" aria-hidden="true" tabindex="-1"></a><span class="op">};</span></span></code></pre></div>
<h1
id="appendix-c-design-choices-alternatives-and-breaking-changes">Appendix
C: Design choices, alternatives and breaking changes</h1>
<p>The table below shows the main design components considered, the key
design decisions made, and the cost and impact of alternative design
choices. As presented in this paper, the design of class templates
<code>indirect</code> and <code>polymorphic</code> has been approved by
the LEWG. The authors have until C++26 is standardized to consider
making any breaking changes; after C++26, whilst breaking changes will
still be possible, the impact of these changes on users could be
potentially significant and unwelcome.</p>
<table>
<colgroup>
<col style="width: 16%" />
<col style="width: 16%" />
<col style="width: 16%" />
<col style="width: 16%" />
<col style="width: 33%" />
</colgroup>
<thead>
<tr>
<th>Component</th>
<th>Decision</th>
<th>Alternative</th>
<th>Change impact</th>
<th style="text-align: center;">Breaking change?</th>
</tr>
</thead>
<tbody>
<tr>
<td>Member <code>emplace</code></td>
<td>No member <code>emplace</code></td>
<td>Add member <code>emplace</code></td>
<td>Pure addition</td>
<td style="text-align: center;">No</td>
</tr>
<tr>
<td><code>operator bool</code></td>
<td>No <code>operator bool</code></td>
<td>Add <code>operator bool</code></td>
<td>Changes semantics</td>
<td style="text-align: center;">No</td>
</tr>
<tr>
<td><code>indirect</code> comparsion preconditions</td>
<td>Allow comparison of valueless objects</td>
<td><code>indirect</code> must not be valueless</td>
<td>Previously valid code would invoke undefined behaviour</td>
<td style="text-align: center;">Yes</td>
</tr>
<tr>
<td><code>indirect</code> hash preconditions</td>
<td>Allow hash of valueless objects</td>
<td><code>indirect</code> must not be valueless</td>
<td>Previously valid code would invoke undefined behaviour</td>
<td style="text-align: center;">Yes</td>
</tr>
<tr>
<td>Copy and copy assign preconditions</td>
<td>Object can be valueless</td>
<td>Forbids copying of valueless objects</td>
<td>Previously valid code would invoke undefined behaviour</td>
<td style="text-align: center;">Yes</td>
</tr>
<tr>
<td>Move and move assign preconditions</td>
<td>Object can be valueless</td>
<td>Forbids moving of valueless objects</td>
<td>Previously valid code would invoke undefined behaviour</td>
<td style="text-align: center;">Yes</td>
</tr>
<tr>
<td>Requirements on <code>T</code> in
<code>polymorphic&lt;T&gt;</code></td>
<td>No requirement that <code>T</code> has virtual functions</td>
<td>Add <em>Mandates</em> to require <code>T</code> to have virtual
functions</td>
<td>Code becomes ill-formed</td>
<td style="text-align: center;">Yes</td>
</tr>
<tr>
<td>State of default-constructed object</td>
<td>Default-constructed object (where valid) has a value</td>
<td>Make default-constructed object valueless</td>
<td>Changes semantics; necessitates adding <code>operator bool</code>
and allowing move, copy and compare of valueless (empty) objects</td>
<td style="text-align: center;">Yes</td>
</tr>
<tr>
<td>Small buffer optimisation for polymorphic</td>
<td>SBO is not required, settings are hidden</td>
<td>Add buffer size and alignment as template parameters</td>
<td>Breaks ABI; forces implementers to use SBO</td>
<td style="text-align: center;">Yes</td>
</tr>
<tr>
<td><code>noexcept</code> for accessors</td>
<td>Accessors are <code>noexcept</code> like <code>unique_ptr</code> and
<code>optional</code></td>
<td>Remove <code>noexcept</code> from accessors</td>
<td>User functions marked <code>noexcept</code> could be broken</td>
<td style="text-align: center;">Yes</td>
</tr>
<tr>
<td>Specialization of optional</td>
<td>No specialization of optional</td>
<td>Specialize optional to use valueless state</td>
<td>Breaks ABI; engaged but valueless optional would become
indistinguishable from a disengaged optional</td>
<td style="text-align: center;">Yes</td>
</tr>
<tr>
<td>Permit user specialization</td>
<td>No user specialization is permitted</td>
<td>Permit specialization for user-defined types</td>
<td>Previously ill-formed code would become well-formed</td>
<td style="text-align: center;">No</td>
</tr>
<tr>
<td>Explicit constructors</td>
<td>Constructors are marked <code>explicit</code></td>
<td>Non-explicit constructors</td>
<td>Conversion for single arguments or braced initializers becomes
valid</td>
<td style="text-align: center;">No</td>
</tr>
<tr>
<td>Support comparisons for indirect</td>
<td>Comparisons are supported when the owned type supports them</td>
<td>No support for comparisons</td>
<td>Previously valid code would become ill-formed</td>
<td style="text-align: center;">Yes</td>
</tr>
<tr>
<td>Support arithmetic operations for <code>indirect</code></td>
<td>No support for arithmetic operations</td>
<td>Forward arithemtic operations to the owned type when it supports
them</td>
<td>Previously ill-formed code would become well-formed</td>
<td style="text-align: center;">No</td>
</tr>
<tr>
<td>Support <code>operator ()</code> for <code>indirect</code></td>
<td>No support for <code>operator ()</code></td>
<td>Forward <code>operator()</code> to the owned type when it is
supported</td>
<td>Previously ill-formed code would become well-formed</td>
<td style="text-align: center;">No</td>
</tr>
<tr>
<td>Support <code>operator []</code> for <code>indirect</code></td>
<td>No support for <code>operator []</code></td>
<td>Forward <code>operator[]</code> to the owned type when it is
supported</td>
<td>Previously ill-formed code would become well-formed</td>
<td style="text-align: center;">No</td>
</tr>
</tbody>
</table>
