<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>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<p>ISO/IEC JTC1 SC22 WG21 Programming Language C++</p>
<p>P3019R9</p>
<p>Working Group: Library Evolution, Library</p>
<p>Date: 2024-09-15</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>
<h2 id="abstract">Abstract</h2>
<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>
<h2 id="history">History</h2>
<h3 id="changes-in-r9">Changes in R9</h3>
<ul>
<li><p>Re-order constructors.</p></li>
<li><p>Add converting assignment operator to <code>indirect</code>.</p></li>
<li><p>Add converting 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>
<h3 id="changes-in-r8">Changes in R8</h3>
<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>
<h3 id="changes-in-r7">Changes in R7</h3>
<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>
<h3 id="changes-in-r6">Changes in R6</h3>
<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>
<h3 id="changes-in-r5">Changes in R5</h3>
<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>
<h3 id="changes-in-r4">Changes in R4</h3>
<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>
<h3 id="changes-in-r3">Changes in R3</h3>
<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 <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>
<h3 id="changes-in-r2">Changes in R2</h3>
<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>
<h3 id="changes-in-r1">Changes in R1</h3>
<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>
<h2 id="motivation">Motivation</h2>
<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>
<h2 id="design-requirements">Design requirements</h2>
<p>We review the fundamental design requirements of <code>indirect</code> and <code>polymorphic</code> that make them suitable for composite class design.</p>
<h3 id="special-member-functions">Special member functions</h3>
<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>.</p>
<ul>
<li><p><code>indirect&lt;T, Alloc&gt;</code> and <code>polymorphic&lt;T, Alloc&gt;</code> are default constructible in cases where <code>T</code> is default constructible.</p></li>
<li><p><code>indirect&lt;T, Alloc&gt;</code> and <code>polymorphic&lt;T, Alloc&gt;</code> are unconditionally copy constructible and assignable, move constructible and move assignable.</p></li>
<li><p><code>indirect&lt;T, Alloc&gt;</code> and <code>polymorphic&lt;T, Alloc&gt;</code> destroy the owned object in their destructors.</p></li>
</ul>
<h3 id="deep-copies">Deep copies</h3>
<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>
<h3 id="const-propagation"><code>const</code> propagation</h3>
<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"></a>T* unique_ptr&lt;T&gt;::<span class="kw">operator</span>-&gt;() <span class="at">const</span>;</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true"></a>T&amp; unique_ptr&lt;T&gt;::<span class="kw">operator</span>*() <span class="at">const</span>;</span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true"></a></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true"></a>T* shared_ptr&lt;T&gt;::<span class="kw">operator</span>-&gt;() <span class="at">const</span>;</span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true"></a>T&amp; shared_ptr&lt;T&gt;::<span class="kw">operator</span>*() <span class="at">const</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"></a><span class="kw">struct</span> A {</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true"></a>    <span class="kw">enum</span> <span class="kw">class</span> Constness { CONST, NON_CONST };</span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true"></a>    Constness foo() { <span class="cf">return</span> Constness::NON_CONST; }</span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true"></a>    Constness foo() <span class="at">const</span> { <span class="cf">return</span> Constness::CONST; };</span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true"></a>};</span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true"></a></span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true"></a><span class="kw">class</span> Composite {</span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true"></a>    indirect&lt;A&gt; <span class="va">a_</span>;</span>
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true"></a></span>
<span id="cb2-10"><a href="#cb2-10" aria-hidden="true"></a>    Constness foo() { <span class="cf">return</span> <span class="va">a_</span>-&gt;foo(); }</span>
<span id="cb2-11"><a href="#cb2-11" aria-hidden="true"></a>    Constness foo() <span class="at">const</span> { <span class="cf">return</span> <span class="va">a_</span>-&gt;foo(); };</span>
<span id="cb2-12"><a href="#cb2-12" aria-hidden="true"></a>};</span>
<span id="cb2-13"><a href="#cb2-13" aria-hidden="true"></a></span>
<span id="cb2-14"><a href="#cb2-14" aria-hidden="true"></a><span class="dt">int</span> main() {</span>
<span id="cb2-15"><a href="#cb2-15" aria-hidden="true"></a>    Composite c;</span>
<span id="cb2-16"><a href="#cb2-16" aria-hidden="true"></a>    <span class="ot">assert</span>(c.foo() == A::Constness::NON_CONST);</span>
<span id="cb2-17"><a href="#cb2-17" aria-hidden="true"></a>    <span class="at">const</span> Composite&amp; cc = c;</span>
<span id="cb2-18"><a href="#cb2-18" aria-hidden="true"></a>    <span class="ot">assert</span>(cc.foo() == A::Constness::CONST);</span>
<span id="cb2-19"><a href="#cb2-19" aria-hidden="true"></a>}</span></code></pre></div>
<h3 id="value-semantics">Value semantics</h3>
<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>
<p><code>indirect&lt;T&gt;</code> and <code>polymorphic&lt;T&gt;</code> are default constructible in cases where <code>T</code> is default constructible. Moving a value type into dynamically-allocated storage should not add or remove the ability to be default constructed.</p>
<h3 id="the-valueless-state-and-interaction-with-stdoptional">The valueless state and interaction with <code>std::optional</code></h3>
<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>
<h3 id="allocator-support">Allocator support</h3>
<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>
<h3 id="modelled-types">Modelled types</h3>
<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>
<h4 id="modelled-types-for-indirect">Modelled types for <code>indirect</code></h4>
<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 only get into the valueless state after being moved from, or 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>
<h4 id="modelled-types-for-polymorphic">Modelled types for <code>polymorphic</code></h4>
<p>The class template <code>polymorphic</code> owns an object of known 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 only get into the valueless state after being moved from, or 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>
<h4 id="similarities-and-differences-with-variant">Similarities and differences with variant</h4>
<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 rendering the 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 only restriction is 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>
<h3 id="noexcept-and-narrow-contracts"><code>noexcept</code> and narrow contracts</h3>
<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>
<h3 id="tagged-constructors">Tagged constructors</h3>
<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> unambiguously 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>
<h3 id="converting-constructors">Converting constructors</h3>
<p>In line with <code>optional</code> and <code>variant</code>, we add converting 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>
<h3 id="initializer-list-constructors">Initializer-list constructors</h3>
<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>
<h3 id="explicit-constructors">Explicit constructors</h3>
<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>
<h3 id="converting-assignment">Converting assignment</h3>
<h4 id="converting-assignment-for-indirect">Converting assignment for <code>indirect</code></h4>
<p>We add a converting assignment for <code>indirect</code> in line with the converting assignment operators 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"></a><span class="kw">template</span> &lt;<span class="kw">class</span> U = T&gt;</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true"></a><span class="kw">constexpr</span> optional&amp; <span class="kw">operator</span>=(U&amp;&amp; u);</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"></a>indirect&lt;<span class="dt">int</span>&gt; i;</span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true"></a>foo(i);  <span class="co">// could move from `i`.</span></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true"></a><span class="cf">if</span> (!i.valueless_after_move()) {</span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true"></a>  *i = <span class="dv">5</span>;</span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true"></a>} <span class="cf">else</span> {</span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true"></a>  i = indirect(<span class="dv">5</span>);</span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true"></a>}</span></code></pre></div>
<p>With converting assignment, handling the valueless state and potentially creating a new indirect object is done within the converting 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"></a>indirect&lt;<span class="dt">int</span>&gt; i;</span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true"></a>foo(i); <span class="co">// could move from `i`.</span></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true"></a>i = <span class="dv">5</span>;</span></code></pre></div>
<h4 id="converting-assignment-for-polymorphic">Converting assignment for <code>polymorphic</code></h4>
<p>There is no converting 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>
<h3 id="the-valueless_after_move-member-function">The <code>valueless_after_move</code> member function</h3>
<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 normally 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>
<h3 id="design-for-polymorphic-types">Design for polymorphic types</h3>
<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"></a><span class="kw">class</span> PolymorphicInterface {</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true"></a>  <span class="kw">protected</span>:</span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true"></a>    PolymorphicInterface(<span class="at">const</span> PolymorphicInterface&amp;) = <span class="cf">default</span>;</span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true"></a>    ~PolymorphicInterface() = <span class="cf">default</span>;</span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true"></a>  <span class="kw">public</span>:</span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true"></a>   <span class="co">// virtual functions</span></span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true"></a>};</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>
<h2 id="prior-work">Prior work</h2>
<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>
<h2 id="impact-on-the-standard">Impact on the standard</h2>
<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>
<h2 id="technical-specifications">Technical specifications</h2>
<h3 id="header-version-synopsis-version.syn">Header <code>&lt;version&gt;</code> synopsis [version.syn]</h3>
<p>Note to editors: Add the following macros with editor provided values to [version.syn]</p>
<pre><code>#define __cpp_lib_indirect ??????L    // also in &lt;memory&gt;
#define __cpp_lib_polymorphic ??????L // also in &lt;memory&gt;</code></pre>
<h3 id="header-memory-synopsis-memory">Header <code>&lt;memory&gt;</code> synopsis [memory]</h3>
<div class="sourceCode" id="cb8"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true"></a><span class="kw">namespace</span> std {</span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true"></a></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true"></a>  <span class="co">// [inout.ptr], function template inout_ptr</span></span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true"></a>  <span class="kw">template</span>&lt;<span class="kw">class</span> Pointer = <span class="dt">void</span>, <span class="kw">class</span> Smart, <span class="kw">class</span>... Args&gt;</span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true"></a>    <span class="kw">auto</span> inout_ptr(Smart&amp; s, Args&amp;&amp;... args);</span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true"></a></span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true"></a>&lt;ins&gt; <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-8"><a href="#cb8-8" aria-hidden="true"></a>  <span class="co">// [indirect], class template indirect</span></span>
<span id="cb8-9"><a href="#cb8-9" aria-hidden="true"></a>  <span class="kw">template</span>&lt;<span class="kw">class</span> T, <span class="kw">class</span> Allocator = allocator&lt;T&gt;&gt;</span>
<span id="cb8-10"><a href="#cb8-10" aria-hidden="true"></a>    <span class="kw">class</span> indirect;</span>
<span id="cb8-11"><a href="#cb8-11" aria-hidden="true"></a></span>
<span id="cb8-12"><a href="#cb8-12" aria-hidden="true"></a>  <span class="co">// [indirect.hash], hash support</span></span>
<span id="cb8-13"><a href="#cb8-13" aria-hidden="true"></a>  <span class="kw">template</span> &lt;<span class="kw">class</span> T, <span class="kw">class</span> Alloc&gt; <span class="kw">struct</span> hash&lt;indirect&lt;T, Alloc&gt;&gt;;</span>
<span id="cb8-14"><a href="#cb8-14" aria-hidden="true"></a></span>
<span id="cb8-15"><a href="#cb8-15" aria-hidden="true"></a>  <span class="co">// [polymorphic], class template polymorphic</span></span>
<span id="cb8-16"><a href="#cb8-16" aria-hidden="true"></a>  <span class="kw">template</span> &lt;<span class="kw">class</span> T, <span class="kw">class</span> Allocator = allocator&lt;T&gt;&gt;</span>
<span id="cb8-17"><a href="#cb8-17" aria-hidden="true"></a>    <span class="kw">class</span> polymorphic;</span>
<span id="cb8-18"><a href="#cb8-18" aria-hidden="true"></a></span>
<span id="cb8-19"><a href="#cb8-19" aria-hidden="true"></a>  <span class="kw">namespace</span> pmr {</span>
<span id="cb8-20"><a href="#cb8-20" aria-hidden="true"></a></span>
<span id="cb8-21"><a href="#cb8-21" aria-hidden="true"></a>    <span class="kw">template</span>&lt;<span class="kw">class</span> T&gt; <span class="kw">using</span> indirect =</span>
<span id="cb8-22"><a href="#cb8-22" aria-hidden="true"></a>      indirect&lt;T, polymorphic_allocator&lt;T&gt;&gt;;</span>
<span id="cb8-23"><a href="#cb8-23" aria-hidden="true"></a></span>
<span id="cb8-24"><a href="#cb8-24" aria-hidden="true"></a>    <span class="kw">template</span>&lt;<span class="kw">class</span> T&gt; <span class="kw">using</span> polymorphic =</span>
<span id="cb8-25"><a href="#cb8-25" aria-hidden="true"></a>      polymorphic&lt;T, polymorphic_allocator&lt;T&gt;&gt;;</span>
<span id="cb8-26"><a href="#cb8-26" aria-hidden="true"></a>  }</span>
<span id="cb8-27"><a href="#cb8-27" aria-hidden="true"></a></span>
<span id="cb8-28"><a href="#cb8-28" aria-hidden="true"></a>&lt;/ins&gt;</span>
<span id="cb8-29"><a href="#cb8-29" aria-hidden="true"></a>}</span></code></pre></div>
<h3 id="x.y-class-template-indirect-indirect">X.Y Class template indirect [indirect]</h3>
<h4 id="x.y.1-class-template-indirect-general-indirect.general">X.Y.1 Class template indirect general [indirect.general]</h4>
<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 only become valueless 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 arguments <code>args...</code> using an allocator <code>al</code> means calling <code>allocator_traits&lt;allocator_type&gt;::construct(al, p, args...)</code> where <code>p</code> is a pointer obtained by calling <code>allocator_traits&lt;allocator_type&gt;::allocate</code>.</p></li>
<li><p>Copy constructors for an indirect type obtain an allocator by calling <code>allocator_traits&lt;allocator_type&gt;::select_on_container_copy_construction</code> on the allocator belonging to the indirect object being copied. Move constructors obtain an allocator by move construction from the allocator belonging to the indirect object being moved. All other constructors for this type take a <code>const allocator_type&amp; argument</code>. <em>[Note: If an invocation of a constructor uses the default value of an optional allocator argument, then the allocator type must support value-initialization. –end note]</em> A copy of this allocator is used for any memory allocation and element construction performed by these constructors and by all member functions during the lifetime of each indirect 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 ([container.reqmts]):</p>
<p>(64.1) <code>allocator_traits&lt;allocator_type&gt;::propagate_on_container_copy_assignment::value</code>,</p>
<p>(64.2) <code>allocator_traits&lt;allocator_type&gt;::propagate_on_container_move_assignment::value</code>,</p>
<p>(64.3) <code>allocator_traits&lt;allocator_type&gt;::propagate_on_container_swap::value</code></p>
<p>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>, 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>
<h4 id="x.y.2-class-template-indirect-synopsis-indirect.syn">X.Y.2 Class template indirect synopsis [indirect.syn]</h4>
<div class="sourceCode" id="cb9"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true"></a><span class="kw">template</span> &lt;<span class="kw">class</span> T, <span class="kw">class</span> Allocator = allocator&lt;T&gt;&gt;</span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true"></a><span class="kw">class</span> indirect {</span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true"></a> <span class="kw">public</span>:</span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true"></a>  <span class="kw">using</span> <span class="dt">value_type</span> = T;</span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true"></a>  <span class="kw">using</span> <span class="dt">allocator_type</span> = Allocator;</span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true"></a>  <span class="kw">using</span> pointer = <span class="kw">typename</span> allocator_traits&lt;Allocator&gt;::pointer;</span>
<span id="cb9-7"><a href="#cb9-7" aria-hidden="true"></a>  <span class="kw">using</span> const_pointer = <span class="kw">typename</span> allocator_traits&lt;Allocator&gt;::const_pointer;</span>
<span id="cb9-8"><a href="#cb9-8" aria-hidden="true"></a></span>
<span id="cb9-9"><a href="#cb9-9" aria-hidden="true"></a>  <span class="kw">constexpr</span> indirect();</span>
<span id="cb9-10"><a href="#cb9-10" aria-hidden="true"></a></span>
<span id="cb9-11"><a href="#cb9-11" aria-hidden="true"></a>  <span class="kw">explicit</span> <span class="kw">constexpr</span> indirect(<span class="dt">allocator_arg_t</span>, <span class="at">const</span> Allocator&amp; a);</span>
<span id="cb9-12"><a href="#cb9-12" aria-hidden="true"></a></span>
<span id="cb9-13"><a href="#cb9-13" aria-hidden="true"></a></span>
<span id="cb9-14"><a href="#cb9-14" aria-hidden="true"></a>  <span class="kw">constexpr</span> indirect(<span class="at">const</span> indirect&amp; other);</span>
<span id="cb9-15"><a href="#cb9-15" aria-hidden="true"></a></span>
<span id="cb9-16"><a href="#cb9-16" aria-hidden="true"></a>  <span class="kw">constexpr</span> indirect(<span class="dt">allocator_arg_t</span>, <span class="at">const</span> Allocator&amp; a,</span>
<span id="cb9-17"><a href="#cb9-17" aria-hidden="true"></a>                     <span class="at">const</span> indirect&amp; other);</span>
<span id="cb9-18"><a href="#cb9-18" aria-hidden="true"></a></span>
<span id="cb9-19"><a href="#cb9-19" aria-hidden="true"></a>  <span class="kw">constexpr</span> indirect(indirect&amp;&amp; other) <span class="kw">noexcept</span>;</span>
<span id="cb9-20"><a href="#cb9-20" aria-hidden="true"></a></span>
<span id="cb9-21"><a href="#cb9-21" aria-hidden="true"></a>  <span class="kw">constexpr</span> indirect(<span class="dt">allocator_arg_t</span>, <span class="at">const</span> Allocator&amp; a,</span>
<span id="cb9-22"><a href="#cb9-22" aria-hidden="true"></a>                     indirect&amp;&amp; other) <span class="kw">noexcept</span>(see below);</span>
<span id="cb9-23"><a href="#cb9-23" aria-hidden="true"></a></span>
<span id="cb9-24"><a href="#cb9-24" aria-hidden="true"></a>  <span class="kw">template</span> &lt;<span class="kw">class</span>... Us&gt;</span>
<span id="cb9-25"><a href="#cb9-25" aria-hidden="true"></a>  <span class="kw">explicit</span> <span class="kw">constexpr</span> indirect(<span class="dt">in_place_t</span>, Us&amp;&amp;... us);</span>
<span id="cb9-26"><a href="#cb9-26" aria-hidden="true"></a></span>
<span id="cb9-27"><a href="#cb9-27" aria-hidden="true"></a>  <span class="kw">template</span> &lt;<span class="kw">class</span>... Us&gt;</span>
<span id="cb9-28"><a href="#cb9-28" aria-hidden="true"></a>  <span class="kw">explicit</span> <span class="kw">constexpr</span> indirect(<span class="dt">allocator_arg_t</span>, <span class="at">const</span> Allocator&amp; a,</span>
<span id="cb9-29"><a href="#cb9-29" aria-hidden="true"></a>                              <span class="dt">in_place_t</span>, Us&amp;&amp;... us);</span>
<span id="cb9-30"><a href="#cb9-30" aria-hidden="true"></a></span>
<span id="cb9-31"><a href="#cb9-31" aria-hidden="true"></a>  <span class="kw">template</span> &lt;<span class="kw">class</span> U&gt;</span>
<span id="cb9-32"><a href="#cb9-32" aria-hidden="true"></a>  <span class="kw">explicit</span> <span class="kw">constexpr</span> indirect(U&amp;&amp; u);</span>
<span id="cb9-33"><a href="#cb9-33" aria-hidden="true"></a></span>
<span id="cb9-34"><a href="#cb9-34" aria-hidden="true"></a>  <span class="kw">template</span> &lt;<span class="kw">class</span> U&gt;</span>
<span id="cb9-35"><a href="#cb9-35" aria-hidden="true"></a>  <span class="kw">explicit</span> <span class="kw">constexpr</span> indirect(<span class="dt">allocator_arg_t</span>, <span class="at">const</span> Allocator&amp; a, U&amp;&amp; u);</span>
<span id="cb9-36"><a href="#cb9-36" aria-hidden="true"></a></span>
<span id="cb9-37"><a href="#cb9-37" aria-hidden="true"></a>  <span class="kw">template</span>&lt;<span class="kw">class</span> U, <span class="kw">class</span>... Us&gt;</span>
<span id="cb9-38"><a href="#cb9-38" aria-hidden="true"></a>  <span class="kw">explicit</span> <span class="kw">constexpr</span> indirect(<span class="dt">in_place_t</span>, initializer_list&lt;U&gt; ilist,</span>
<span id="cb9-39"><a href="#cb9-39" aria-hidden="true"></a>                              Us&amp;&amp;... us);</span>
<span id="cb9-40"><a href="#cb9-40" aria-hidden="true"></a></span>
<span id="cb9-41"><a href="#cb9-41" aria-hidden="true"></a>  <span class="kw">template</span>&lt;<span class="kw">class</span> U, <span class="kw">class</span>... Us&gt;</span>
<span id="cb9-42"><a href="#cb9-42" aria-hidden="true"></a>  <span class="kw">explicit</span> <span class="kw">constexpr</span> indirect(<span class="dt">allocator_arg_t</span>, <span class="at">const</span> Allocator&amp; a,</span>
<span id="cb9-43"><a href="#cb9-43" aria-hidden="true"></a>                              <span class="dt">in_place_t</span>, initializer_list&lt;U&gt; ilist,</span>
<span id="cb9-44"><a href="#cb9-44" aria-hidden="true"></a>                              Us&amp;&amp;... us);</span>
<span id="cb9-45"><a href="#cb9-45" aria-hidden="true"></a></span>
<span id="cb9-46"><a href="#cb9-46" aria-hidden="true"></a>  <span class="kw">constexpr</span> ~indirect();</span>
<span id="cb9-47"><a href="#cb9-47" aria-hidden="true"></a></span>
<span id="cb9-48"><a href="#cb9-48" aria-hidden="true"></a>  <span class="kw">constexpr</span> indirect&amp; <span class="kw">operator</span>=(<span class="at">const</span> indirect&amp; other);</span>
<span id="cb9-49"><a href="#cb9-49" aria-hidden="true"></a></span>
<span id="cb9-50"><a href="#cb9-50" aria-hidden="true"></a>  <span class="kw">constexpr</span> indirect&amp; <span class="kw">operator</span>=(indirect&amp;&amp; other) <span class="kw">noexcept</span>(see below);</span>
<span id="cb9-51"><a href="#cb9-51" aria-hidden="true"></a></span>
<span id="cb9-52"><a href="#cb9-52" aria-hidden="true"></a>  <span class="kw">template</span> &lt;<span class="kw">class</span> U&gt;</span>
<span id="cb9-53"><a href="#cb9-53" aria-hidden="true"></a>  <span class="kw">constexpr</span> indirect&amp; <span class="kw">operator</span>=(U&amp;&amp; u);</span>
<span id="cb9-54"><a href="#cb9-54" aria-hidden="true"></a></span>
<span id="cb9-55"><a href="#cb9-55" aria-hidden="true"></a>  <span class="kw">constexpr</span> <span class="at">const</span> T&amp; <span class="kw">operator</span>*() <span class="at">const</span> &amp; <span class="kw">noexcept</span>;</span>
<span id="cb9-56"><a href="#cb9-56" aria-hidden="true"></a></span>
<span id="cb9-57"><a href="#cb9-57" aria-hidden="true"></a>  <span class="kw">constexpr</span> T&amp; <span class="kw">operator</span>*() &amp; <span class="kw">noexcept</span>;</span>
<span id="cb9-58"><a href="#cb9-58" aria-hidden="true"></a></span>
<span id="cb9-59"><a href="#cb9-59" aria-hidden="true"></a>  <span class="kw">constexpr</span> <span class="at">const</span> T&amp;&amp; <span class="kw">operator</span>*() <span class="at">const</span> &amp;&amp; <span class="kw">noexcept</span>;</span>
<span id="cb9-60"><a href="#cb9-60" aria-hidden="true"></a></span>
<span id="cb9-61"><a href="#cb9-61" aria-hidden="true"></a>  <span class="kw">constexpr</span> T&amp;&amp; <span class="kw">operator</span>*() &amp;&amp; <span class="kw">noexcept</span>;</span>
<span id="cb9-62"><a href="#cb9-62" aria-hidden="true"></a></span>
<span id="cb9-63"><a href="#cb9-63" aria-hidden="true"></a>  <span class="kw">constexpr</span> const_pointer <span class="kw">operator</span>-&gt;() <span class="at">const</span> <span class="kw">noexcept</span>;</span>
<span id="cb9-64"><a href="#cb9-64" aria-hidden="true"></a></span>
<span id="cb9-65"><a href="#cb9-65" aria-hidden="true"></a>  <span class="kw">constexpr</span> pointer <span class="kw">operator</span>-&gt;() <span class="kw">noexcept</span>;</span>
<span id="cb9-66"><a href="#cb9-66" aria-hidden="true"></a></span>
<span id="cb9-67"><a href="#cb9-67" aria-hidden="true"></a>  <span class="kw">constexpr</span> <span class="dt">bool</span> valueless_after_move() <span class="at">const</span> <span class="kw">noexcept</span>;</span>
<span id="cb9-68"><a href="#cb9-68" aria-hidden="true"></a></span>
<span id="cb9-69"><a href="#cb9-69" aria-hidden="true"></a>  <span class="kw">constexpr</span> <span class="dt">allocator_type</span> get_allocator() <span class="at">const</span> <span class="kw">noexcept</span>;</span>
<span id="cb9-70"><a href="#cb9-70" aria-hidden="true"></a></span>
<span id="cb9-71"><a href="#cb9-71" aria-hidden="true"></a>  <span class="kw">constexpr</span> <span class="dt">void</span> swap(indirect&amp; other) <span class="kw">noexcept</span>(see below);</span>
<span id="cb9-72"><a href="#cb9-72" aria-hidden="true"></a></span>
<span id="cb9-73"><a href="#cb9-73" aria-hidden="true"></a>  <span class="kw">friend</span> <span class="kw">constexpr</span> <span class="dt">void</span> swap(indirect&amp; lhs, indirect&amp; rhs) <span class="kw">noexcept</span>(see below);</span>
<span id="cb9-74"><a href="#cb9-74" aria-hidden="true"></a></span>
<span id="cb9-75"><a href="#cb9-75" aria-hidden="true"></a>  <span class="kw">template</span> &lt;<span class="kw">class</span> U, <span class="kw">class</span> AA&gt;</span>
<span id="cb9-76"><a href="#cb9-76" aria-hidden="true"></a>  <span class="kw">friend</span> <span class="kw">constexpr</span> <span class="dt">bool</span> <span class="kw">operator</span>==(</span>
<span id="cb9-77"><a href="#cb9-77" aria-hidden="true"></a>    <span class="at">const</span> indirect&amp; lhs, <span class="at">const</span> indirect&lt;U, AA&gt;&amp; rhs) <span class="kw">noexcept</span>(see below);</span>
<span id="cb9-78"><a href="#cb9-78" aria-hidden="true"></a></span>
<span id="cb9-79"><a href="#cb9-79" aria-hidden="true"></a>  <span class="kw">template</span> &lt;<span class="kw">class</span> U&gt;</span>
<span id="cb9-80"><a href="#cb9-80" aria-hidden="true"></a>  <span class="kw">friend</span> <span class="kw">constexpr</span> <span class="dt">bool</span> <span class="kw">operator</span>==(</span>
<span id="cb9-81"><a href="#cb9-81" aria-hidden="true"></a>    <span class="at">const</span> indirect&amp; lhs, <span class="at">const</span> U&amp; rhs) <span class="kw">noexcept</span>(see below);</span>
<span id="cb9-82"><a href="#cb9-82" aria-hidden="true"></a></span>
<span id="cb9-83"><a href="#cb9-83" aria-hidden="true"></a>  <span class="kw">template</span> &lt;<span class="kw">class</span> U, <span class="kw">class</span> AA&gt;</span>
<span id="cb9-84"><a href="#cb9-84" aria-hidden="true"></a>  <span class="kw">friend</span> <span class="kw">constexpr</span> <span class="kw">auto</span> <span class="kw">operator</span>&lt;=&gt;(</span>
<span id="cb9-85"><a href="#cb9-85" aria-hidden="true"></a>    <span class="at">const</span> indirect&amp; lhs, <span class="at">const</span> indirect&lt;U, AA&gt;&amp; rhs) <span class="kw">noexcept</span>(see below)</span>
<span id="cb9-86"><a href="#cb9-86" aria-hidden="true"></a>    -&gt; <span class="dt">compare_three_way_result_t</span>&lt;T, U&gt;;</span>
<span id="cb9-87"><a href="#cb9-87" aria-hidden="true"></a></span>
<span id="cb9-88"><a href="#cb9-88" aria-hidden="true"></a>  <span class="kw">template</span> &lt;<span class="kw">class</span> U&gt;</span>
<span id="cb9-89"><a href="#cb9-89" aria-hidden="true"></a>  <span class="kw">friend</span> <span class="kw">constexpr</span> <span class="kw">auto</span> <span class="kw">operator</span>&lt;=&gt;(</span>
<span id="cb9-90"><a href="#cb9-90" aria-hidden="true"></a>    <span class="at">const</span> indirect&amp; lhs, <span class="at">const</span> U&amp; rhs) <span class="kw">noexcept</span>(see below)</span>
<span id="cb9-91"><a href="#cb9-91" aria-hidden="true"></a>    -&gt; <span class="dt">compare_three_way_result_t</span>&lt;T, U&gt;;</span>
<span id="cb9-92"><a href="#cb9-92" aria-hidden="true"></a></span>
<span id="cb9-93"><a href="#cb9-93" aria-hidden="true"></a><span class="kw">private</span>:</span>
<span id="cb9-94"><a href="#cb9-94" aria-hidden="true"></a>  pointer p; <span class="co">// exposition only</span></span>
<span id="cb9-95"><a href="#cb9-95" aria-hidden="true"></a>  Allocator alloc = Allocator(); <span class="co">// exposition only</span></span>
<span id="cb9-96"><a href="#cb9-96" aria-hidden="true"></a>};</span>
<span id="cb9-97"><a href="#cb9-97" aria-hidden="true"></a></span>
<span id="cb9-98"><a href="#cb9-98" aria-hidden="true"></a><span class="kw">template</span> &lt;<span class="kw">class</span> Value&gt;</span>
<span id="cb9-99"><a href="#cb9-99" aria-hidden="true"></a>indirect(Value) -&gt; indirect&lt;Value&gt;;</span>
<span id="cb9-100"><a href="#cb9-100" aria-hidden="true"></a></span>
<span id="cb9-101"><a href="#cb9-101" aria-hidden="true"></a><span class="kw">template</span> &lt;<span class="kw">class</span> Alloc, <span class="kw">class</span> Value&gt;</span>
<span id="cb9-102"><a href="#cb9-102" aria-hidden="true"></a>indirect(<span class="dt">allocator_arg_t</span>, Alloc, Value) -&gt; indirect&lt;</span>
<span id="cb9-103"><a href="#cb9-103" aria-hidden="true"></a>         Value, <span class="kw">typename</span> allocator_traits&lt;Alloc&gt;::<span class="kw">template</span> rebind_alloc&lt;Value&gt;&gt;;</span></code></pre></div>
<h4 id="x.y.3-constructors-indirect.ctor">X.Y.3 Constructors [indirect.ctor]</h4>
<p>The following element applies to all functions in [indirect.ctor]:</p>
<p><em>Throws</em>: Nothing unless <code>allocator_traits&lt;allocator_type&gt;::allocate</code> or <code>allocator_traits&lt;allocator_type&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"></a><span class="kw">explicit</span> <span class="kw">constexpr</span> indirect()</span></code></pre></div>
<ol type="1">
<li><p><em>Constraints</em>: <code>is_default_constructible_v&lt;T&gt;</code> is <code>true</code>. <code>is_copy_constructible_v&lt;T&gt;</code> is <code>true</code>. <code>is_default_constructible_v&lt;allocator_type&gt;</code> is <code>true</code>.</p></li>
<li><p><em>Mandates</em>: <code>T</code> is a complete type.</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>
<li><p><em>Postconditions</em>: <code>*this</code> is not valueless.</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"></a><span class="kw">explicit</span> <span class="kw">constexpr</span> indirect(<span class="dt">allocator_arg_t</span>, <span class="at">const</span> Allocator&amp; a);</span></code></pre></div>
<ol start="5" type="1">
<li><p><em>Constraints</em>: <code>is_default_constructible_v&lt;T&gt;</code> is <code>true</code>. <code>is_copy_constructible_v&lt;T&gt;</code> is <code>true</code>.</p></li>
<li><p><em>Mandates</em>: <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>. Constructs an owned object of type <code>T</code> with an empty argument list, using the allocator <code>alloc</code>.</p></li>
<li><p><em>Postconditions</em>: <code>*this</code> is not valueless.</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"></a><span class="kw">constexpr</span> indirect(<span class="at">const</span> indirect&amp; other);</span></code></pre></div>
<ol start="9" type="1">
<li><p><em>Mandates</em>: <code>T</code> is a complete type.</p></li>
<li><p><em>Effects</em>: 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"></a><span class="kw">constexpr</span> indirect(<span class="dt">allocator_arg_t</span>, <span class="at">const</span> Allocator&amp; a,</span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true"></a>                   <span class="at">const</span> indirect&amp; other);</span></code></pre></div>
<ol start="11" type="1">
<li><p><em>Mandates</em>: <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, 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"></a><span class="kw">constexpr</span> indirect(indirect&amp;&amp; other) <span class="kw">noexcept</span>;</span></code></pre></div>
<ol start="13" type="1">
<li><p><em>Mandates</em>: If <code>allocator_traits&lt;allocator_type&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>: 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 owns the owned object of <code>other</code>; <code>other</code> is valueless. Otherwise, constructs an owned object of type <code>T</code> with <code>*std::move(other)</code>, using the allocator <code>alloc</code>.</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"></a><span class="kw">constexpr</span> indirect(<span class="dt">allocator_arg_t</span>, <span class="at">const</span> Allocator&amp; a, indirect&amp;&amp; other)</span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true"></a>   <span class="kw">noexcept</span>(allocator_traits&lt;Allocator&gt;::is_always_equal::value);</span></code></pre></div>
<ol start="15" type="1">
<li><p><em>Mandates</em>: If <code>allocator_traits&lt;allocator_type&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 owns the owned object of <code>other</code>; <code>other</code> is valueless. Otherwise, constructs an owned object of type <code>T</code> with <code>*std::move(other)</code>, using the allocator <code>alloc</code>.</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"></a><span class="kw">template</span> &lt;<span class="kw">class</span>... Us&gt;</span>
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true"></a><span class="kw">explicit</span> <span class="kw">constexpr</span> indirect(<span class="dt">in_place_t</span>, Us&amp;&amp;... us);</span></code></pre></div>
<ol start="17" type="1">
<li><p><em>Constraints</em>: <code>is_constructible_v&lt;T, Us...&gt;</code> is <code>true</code>. <code>is_copy_constructible_v&lt;T&gt;</code> is <code>true</code>. <code>is_default_constructible_v&lt;allocator_type&gt;</code> is <code>true</code>.</p></li>
<li><p><em>Mandates</em>: <code>T</code> is a complete type.</p></li>
<li><p><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>.</p></li>
<li><p><em>Postconditions</em>: <code>*this</code> is not valueless.</p></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"></a><span class="kw">template</span> &lt;<span class="kw">class</span>... Us&gt;</span>
<span id="cb17-2"><a href="#cb17-2" aria-hidden="true"></a><span class="kw">explicit</span> <span class="kw">constexpr</span> indirect(<span class="dt">allocator_arg_t</span>, <span class="at">const</span> Allocator&amp; a, <span class="dt">in_place_t</span>, Us&amp;&amp; ...us);</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>. <code>is_copy_constructible_v&lt;T&gt;</code> is <code>true</code>.</p></li>
<li><p><em>Mandates</em>: <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>. 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="cb18"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true"></a><span class="kw">template</span> &lt;<span class="kw">class</span> U&gt;</span>
<span id="cb18-2"><a href="#cb18-2" aria-hidden="true"></a><span class="kw">explicit</span> <span class="kw">constexpr</span> indirect(U&amp;&amp; u);</span></code></pre></div>
<ol start="24" type="1">
<li><p><em>Constraints</em>: <code>is_constructible_v&lt;T, U&gt;</code> is <code>true</code>. <code>is_copy_constructible_v&lt;T&gt;</code> is <code>true</code>. <code>is_default_constructible_v&lt;allocator_type&gt;</code> is <code>true</code>. <code>is_same_v&lt;remove_cvref_t&lt;U&gt;, in_place_t&gt;</code> is <code>false</code>. <code>is_same_v&lt;remove_cvref_t&lt;U&gt;, indirect&gt;</code> is <code>false</code>.</p></li>
<li><p><em>Mandates</em>: <code>T</code> is a complete type.</p></li>
<li><p><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>.</p></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"></a><span class="kw">template</span> &lt;<span class="kw">class</span> U&gt;</span>
<span id="cb19-2"><a href="#cb19-2" aria-hidden="true"></a><span class="kw">explicit</span> <span class="kw">constexpr</span> indirect(<span class="dt">allocator_arg_t</span>, <span class="at">const</span> Allocator&amp; a, U&amp;&amp; u);</span></code></pre></div>
<ol start="27" type="1">
<li><p><em>Constraints</em>: <code>is_constructible_v&lt;T, U&gt;</code> is <code>true</code>. <code>is_copy_constructible_v&lt;T&gt;</code> is <code>true</code>. <code>is_same_v&lt;remove_cvref_t&lt;U&gt;, in_place_t&gt;</code> is <code>false</code>. <code>is_same_v&lt;remove_cvref_t&lt;U&gt;, indirect&gt;</code> is <code>false</code>.</p></li>
<li><p><em>Mandates</em>: <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>. Constructs an owned object of type <code>T</code> with <code>std​::​forward&lt;U&gt;(u)</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"></a><span class="kw">template</span>&lt;<span class="kw">class</span> U, <span class="kw">class</span>... Us&gt;</span>
<span id="cb20-2"><a href="#cb20-2" aria-hidden="true"></a><span class="kw">explicit</span> <span class="kw">constexpr</span> indirect(<span class="dt">in_place_t</span>, initializer_list&lt;U&gt; ilist,</span>
<span id="cb20-3"><a href="#cb20-3" aria-hidden="true"></a>                            Us&amp;&amp;... us);</span></code></pre></div>
<ol start="30" type="1">
<li><p><em>Constraints</em>: <code>is_copy_constructible_v&lt;T&gt;</code> is <code>true</code>. <code>is_constructible_v&lt;T, initializer_list&lt;I&gt;, Us...&gt;</code> is <code>true</code>. <code>is_default_constructible_v&lt;allocator_type&gt;</code> is <code>true</code>.</p></li>
<li><p><em>Mandates</em>: <code>T</code> is a complete type.</p></li>
<li><p><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>.</p></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"></a><span class="kw">template</span>&lt;<span class="kw">class</span> U, <span class="kw">class</span>... Us&gt;</span>
<span id="cb21-2"><a href="#cb21-2" aria-hidden="true"></a><span class="kw">explicit</span> <span class="kw">constexpr</span> indirect(<span class="dt">allocator_arg_t</span>, <span class="at">const</span> Allocator&amp; a,</span>
<span id="cb21-3"><a href="#cb21-3" aria-hidden="true"></a>                            <span class="dt">in_place_t</span>, initializer_list&lt;U&gt; ilist,</span>
<span id="cb21-4"><a href="#cb21-4" aria-hidden="true"></a>                            Us&amp;&amp;... us);</span></code></pre></div>
<ol start="33" type="1">
<li><p><em>Constraints</em>: <code>is_copy_constructible_v&lt;T&gt;</code> is <code>true</code>. <code>is_constructible_v&lt;T, initializer_list&lt;I&gt;, Us...&gt;</code> is <code>true</code>.</p></li>
<li><p><em>Mandates</em>: <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>. 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>
<h4 id="x.y.4-destructor-indirect.dtor">X.Y.4 Destructor [indirect.dtor]</h4>
<div class="sourceCode" id="cb22"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb22-1"><a href="#cb22-1" aria-hidden="true"></a><span class="kw">constexpr</span> ~indirect();</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_type&gt;::destroy</code> and then the storage is deallocated.</p></li>
</ol>
<h4 id="x.y.5-assignment-indirect.assign">X.Y.5 Assignment [indirect.assign]</h4>
<div class="sourceCode" id="cb23"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb23-1"><a href="#cb23-1" aria-hidden="true"></a><span class="kw">constexpr</span> indirect&amp; <span class="kw">operator</span>=(<span class="at">const</span> indirect&amp; other);</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.</p></li>
</ol>
<p>If <code>allocator_traits&lt;allocator_type&gt;::propagate_on_container_copy_assignment</code> is <code>true</code> then the allocator needs updating.</p>
<p>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_type&gt;::destroy</code> and then the storage is deallocated.</p>
<p>Otherwise, if <code>alloc == other.alloc</code> is <code>true</code> and <code>*this</code> is not valueless, <code>*other</code> is assigned to the owned object.</p>
<p>Otherwise a new owned object is constructed in <code>*this</code> using <code>allocator_traits&lt;allocator_type&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. The previously owned object in <code>*this</code>, if any, is destroyed using <code>allocator_traits&lt;allocator_type&gt;::destroy</code> and then the storage is deallocated.</p>
<p>If the allocator needs updating, the allocator in <code>*this</code> is replaced with a copy of the allocator in <code>other</code>.</p>
<ol start="3" type="1">
<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"></a><span class="kw">constexpr</span> indirect&amp; <span class="kw">operator</span>=(indirect&amp;&amp; other) <span class="kw">noexcept</span>(</span>
<span id="cb24-2"><a href="#cb24-2" aria-hidden="true"></a>    allocator_traits&lt;Allocator&gt;::propagate_on_container_move_assignment::value ||</span>
<span id="cb24-3"><a href="#cb24-3" aria-hidden="true"></a>    allocator_traits&lt;Allocator&gt;::is_always_equal::value);</span></code></pre></div>
<ol start="5" type="1">
<li><p><em>Mandates</em>: If <code>allocator_traits&lt;allocator_type&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>: If <code>addressof(other) == this</code> is <code>true</code>, there are no effects.</p></li>
</ol>
<p>If<code>allocator_traits&lt;allocator_type&gt;::propagate_on_container_move_assignment</code> is <code>true</code> then the allocator needs updating.</p>
<p>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_type&gt;::destroy</code> and then the storage is deallocated.</p>
<p>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_type&gt;::destroy</code> and then the storage is deallocated.</p>
<p>Otherwise constructs a new owned object with the owned object <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. The previous owned object in <code>*this</code>, if any, is destroyed using <code>allocator_traits&lt;allocator_type&gt;::destroy</code> and then the storage is deallocated.</p>
<p>If the allocator needs updating, the allocator in <code>*this</code> is replaced with a copy of the allocator in <code>other</code>.</p>
<ol start="7" type="1">
<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"></a>  <span class="kw">template</span> &lt;<span class="kw">class</span> U&gt;</span>
<span id="cb25-2"><a href="#cb25-2" aria-hidden="true"></a>  <span class="kw">constexpr</span> indirect&amp; <span class="kw">operator</span>=(U&amp;&amp; u);</span></code></pre></div>
<ol start="10" type="1">
<li><p><em>Constraints</em>: <code>is_constructible_v&lt;T, U&gt;</code> is <code>true</code>. <code>is_assignable_v&lt;T&amp;,U&gt;</code> is <code>true</code>. <code>is_same_v&lt;remove_cvref_t&lt;U&gt;, indirect&gt;</code> is <code>false</code>.</p></li>
<li><p><em>Mandates</em>: <code>T</code> is a complete type.</p></li>
<li><p><em>Effects</em>: If <code>*this</code> is valueless then equivalent to <code>*this = indirect(allocator_arg, alloc, std::forward&lt;U&gt;(u));</code>. Otherwise, equivalent to <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>
<h4 id="x.y.6-observers-indirect.observers">X.Y.6 Observers [indirect.observers]</h4>
<div class="sourceCode" id="cb26"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb26-1"><a href="#cb26-1" aria-hidden="true"></a><span class="kw">constexpr</span> <span class="at">const</span> T&amp; <span class="kw">operator</span>*() <span class="at">const</span> &amp; <span class="kw">noexcept</span>;</span>
<span id="cb26-2"><a href="#cb26-2" aria-hidden="true"></a><span class="kw">constexpr</span> T&amp; <span class="kw">operator</span>*() &amp; <span class="kw">noexcept</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"></a><span class="kw">constexpr</span> <span class="at">const</span> T&amp;&amp; <span class="kw">operator</span>*() <span class="at">const</span> &amp;&amp; <span class="kw">noexcept</span>;</span>
<span id="cb27-2"><a href="#cb27-2" aria-hidden="true"></a><span class="kw">constexpr</span> T&amp;&amp; <span class="kw">operator</span>*() &amp;&amp; <span class="kw">noexcept</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"></a><span class="kw">constexpr</span> const_pointer <span class="kw">operator</span>-&gt;() <span class="at">const</span> <span class="kw">noexcept</span>;</span>
<span id="cb28-2"><a href="#cb28-2" aria-hidden="true"></a><span class="kw">constexpr</span> pointer <span class="kw">operator</span>-&gt;() <span class="kw">noexcept</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"></a><span class="kw">constexpr</span> <span class="dt">bool</span> valueless_after_move() <span class="at">const</span> <span class="kw">noexcept</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"></a><span class="kw">constexpr</span> <span class="dt">allocator_type</span> get_allocator() <span class="at">const</span> <span class="kw">noexcept</span>;</span></code></pre></div>
<ol start="8" type="1">
<li><em>Returns</em>: <code>alloc</code>.</li>
</ol>
<h4 id="x.y.7-swap-indirect.swap">X.Y.7 Swap [indirect.swap]</h4>
<div class="sourceCode" id="cb31"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb31-1"><a href="#cb31-1" aria-hidden="true"></a><span class="kw">constexpr</span> <span class="dt">void</span> swap(indirect&amp; other) <span class="kw">noexcept</span>(</span>
<span id="cb31-2"><a href="#cb31-2" aria-hidden="true"></a>  allocator_traits::propagate_on_container_swap::value</span>
<span id="cb31-3"><a href="#cb31-3" aria-hidden="true"></a>  || allocator_traits&lt;Allocator&gt;::is_always_equal::value);</span></code></pre></div>
<ol type="1">
<li><em>Effects</em>: Swaps <code>p</code> and <code>other.p</code>. If <code>allocator_traits&lt;allocator_type&gt;::propagate_on_container_swap::value</code> is <code>true</code>, then <code>allocator_type</code> shall meet the <em>Cpp17Swappable</em> requirements and 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, and the behavior is undefined unless <code>(*this).get_allocator() ==   other.get_allocator()</code> is <code>true</code>.</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"></a><span class="kw">constexpr</span> <span class="dt">void</span> swap(indirect&amp; lhs, indirect&amp; rhs) <span class="kw">noexcept</span>(</span>
<span id="cb32-2"><a href="#cb32-2" aria-hidden="true"></a>  <span class="kw">noexcept</span>(lhs.swap(rhs)));</span></code></pre></div>
<ol start="2" type="1">
<li><em>Effects</em>: Equivalent to <code>lhs.swap(rhs)</code>.</li>
</ol>
<h4 id="x.y.8-relational-operators-indirect.relops">X.Y.8 Relational operators [indirect.relops]</h4>
<div class="sourceCode" id="cb33"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb33-1"><a href="#cb33-1" aria-hidden="true"></a><span class="kw">template</span> &lt;<span class="kw">class</span> U, <span class="kw">class</span> AA&gt;</span>
<span id="cb33-2"><a href="#cb33-2" aria-hidden="true"></a><span class="kw">constexpr</span> <span class="dt">bool</span> <span class="kw">operator</span>==(<span class="at">const</span> indirect&amp; lhs, <span class="at">const</span> indirect&lt;U, AA&gt;&amp; rhs)</span>
<span id="cb33-3"><a href="#cb33-3" aria-hidden="true"></a>  <span class="kw">noexcept</span>(<span class="kw">noexcept</span>(*lhs == *rhs));</span></code></pre></div>
<ol type="1">
<li><p><em>Constraints</em>: <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, <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"></a><span class="kw">template</span> &lt;<span class="kw">class</span> U, <span class="kw">class</span> AA&gt;</span>
<span id="cb34-2"><a href="#cb34-2" aria-hidden="true"></a><span class="kw">constexpr</span> synth-three-way-result&lt;T&gt; <span class="kw">operator</span>&lt;=&gt;(<span class="at">const</span> indirect&amp; lhs, <span class="at">const</span> indirect&lt;U, AA&gt;&amp; rhs)</span>
<span id="cb34-3"><a href="#cb34-3" aria-hidden="true"></a>  <span class="kw">noexcept</span>(<span class="kw">noexcept</span>(synth-three-way(*lhs, *rhs)));</span></code></pre></div>
<ol start="3" type="1">
<li><p><em>Constraints</em>: <code>*lhs &lt;=&gt; *rhs</code> is well-formed.</p></li>
<li><p><em>Returns</em>: If <code>lhs</code> is valueless or <code>rhs</code> is valueless, <code>!lhs.valueless_after_move() &lt;=&gt; !rhs.valueless_after_move()</code>; otherwise <code>synth-three-way(*lhs, *rhs)</code>.</p></li>
</ol>
<h4 id="x.y.9-comparison-with-t-indirect.comp.with.t">X.Y.9 Comparison with T [indirect.comp.with.t]</h4>
<div class="sourceCode" id="cb35"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb35-1"><a href="#cb35-1" aria-hidden="true"></a><span class="kw">template</span> &lt;<span class="kw">class</span> U&gt;</span>
<span id="cb35-2"><a href="#cb35-2" aria-hidden="true"></a><span class="kw">constexpr</span> <span class="dt">bool</span> <span class="kw">operator</span>==(<span class="at">const</span> indirect&amp; lhs, <span class="at">const</span> U&amp; rhs)</span>
<span id="cb35-3"><a href="#cb35-3" aria-hidden="true"></a>  <span class="kw">noexcept</span>(<span class="kw">noexcept</span>(*lhs == rhs));</span></code></pre></div>
<ol type="1">
<li><p><em>Constraints</em>: <code>*lhs == rhs</code> is well-formed.</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"></a><span class="kw">template</span> &lt;<span class="kw">class</span> U&gt;</span>
<span id="cb36-2"><a href="#cb36-2" aria-hidden="true"></a><span class="kw">constexpr</span> synth-three-way-result&lt;T&gt; <span class="kw">operator</span>&lt;=&gt;(<span class="at">const</span> indirect&amp; lhs, <span class="at">const</span> U&amp; rhs)</span>
<span id="cb36-3"><a href="#cb36-3" aria-hidden="true"></a>  <span class="kw">noexcept</span>(<span class="kw">noexcept</span>(synth-three-way(*lhs, rhs)));</span></code></pre></div>
<ol start="3" type="1">
<li><p><em>Constraints</em>: <code>*lhs &lt;=&gt; rhs</code> is well-formed.</p></li>
<li><p><em>Returns</em>: If <code>rhs</code> is valueless, <code>false &lt; true</code>; otherwise <code>synth-three-way(*lhs, rhs)</code>.</p></li>
</ol>
<h4 id="x.y.10-hash-support-indirect.hash">X.Y.10 Hash support [indirect.hash]</h4>
<div class="sourceCode" id="cb37"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb37-1"><a href="#cb37-1" aria-hidden="true"></a><span class="kw">template</span> &lt;<span class="kw">class</span> T, <span class="kw">class</span> Alloc&gt;</span>
<span id="cb37-2"><a href="#cb37-2" aria-hidden="true"></a><span class="kw">struct</span> hash&lt;indirect&lt;T, Alloc&gt;&gt;;</span></code></pre></div>
<ol type="1">
<li>The specialization <code>hash&lt;indirect&lt;T, Alloc&gt;&gt;</code> is enabled ([unord.hash]) if and only if <code>hash&lt;remove_const_t&lt;T&gt;&gt;</code> is enabled. When enabled for an object <code>i</code> of type <code>indirect&lt;T, Alloc&gt;</code>, then <code>hash&lt;indirect&lt;T, Alloc&gt;&gt;()(i)</code> evaluates to either the same value as <code>hash&lt;remove_const_t&lt;T&gt;&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>
<h3 id="x.z-class-template-polymorphic-polymorphic">X.Z Class template polymorphic [polymorphic]</h3>
<h4 id="x.z.1-class-template-polymorphic-general-polymorphic.general">X.Z.1 Class template polymorphic general [polymorphic.general]</h4>
<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 only become valueless 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 with arguments <code>args...</code> using an allocator <code>a</code> means calling <code>allocator_traits&lt;allocator_type&gt;::rebind_traits&lt;U&gt;::construct(a, p, args...)</code> where <code>p</code> is a pointer obtained by calling <code>allocator_traits&lt;allocator_type&gt;::rebind_traits&lt;U&gt;::allocate</code> and <code>U</code> is either <code>allocator_type::value_type</code> or an internal type used by the polymorphic value.</p></li>
<li><p>Copy constructors for a polymorphic type obtain an allocator by calling <code>allocator_traits&lt;allocator_type&gt;::select_on_container_copy_construction</code> on the allocator belonging to the polymorphic object being copied. Move constructors obtain an allocator by move construction from the allocator belonging to the object being moved. All other constructors for this type take a <code>const allocator_type&amp; argument</code>. <em>[Note 3: If an invocation of a constructor uses the default value of an optional allocator argument, then the allocator type must support value-initialization. –end note]</em> A copy of this allocator is used for any memory allocation and element construction performed by these constructors and by all 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]):</p></li>
</ol>
<p>(64.1) <code>allocator_traits&lt;allocator_type&gt;::propagate_on_container_copy_assignment::value</code>,</p>
<p>(64.2) <code>allocator_traits&lt;allocator_type&gt;::propagate_on_container_move_assignment::value</code>, or</p>
<p>(64.3) <code>allocator_traits&lt;allocator_type&gt;::propagate_on_container_swap::value</code> is true within the implementation of the corresponding polymorphic value operation.</p>
<ol start="5" type="1">
<li><p>A program that instantiates the definition of polymorphic for a non-object type, an array type, 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>
<h4 id="x.z.2-class-template-polymorphic-synopsis-polymorphic.syn">X.Z.2 Class template polymorphic synopsis [polymorphic.syn]</h4>
<div class="sourceCode" id="cb38"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb38-1"><a href="#cb38-1" aria-hidden="true"></a><span class="kw">template</span> &lt;<span class="kw">class</span> T, <span class="kw">class</span> Allocator = allocator&lt;T&gt;&gt;</span>
<span id="cb38-2"><a href="#cb38-2" aria-hidden="true"></a><span class="kw">class</span> polymorphic {</span>
<span id="cb38-3"><a href="#cb38-3" aria-hidden="true"></a> <span class="kw">public</span>:</span>
<span id="cb38-4"><a href="#cb38-4" aria-hidden="true"></a>  <span class="kw">using</span> <span class="dt">value_type</span> = T;</span>
<span id="cb38-5"><a href="#cb38-5" aria-hidden="true"></a>  <span class="kw">using</span> <span class="dt">allocator_type</span> = Allocator;</span>
<span id="cb38-6"><a href="#cb38-6" aria-hidden="true"></a>  <span class="kw">using</span> pointer = <span class="kw">typename</span> allocator_traits&lt;Allocator&gt;::pointer;</span>
<span id="cb38-7"><a href="#cb38-7" aria-hidden="true"></a>  <span class="kw">using</span> const_pointer  = <span class="kw">typename</span> allocator_traits&lt;Allocator&gt;::const_pointer;</span>
<span id="cb38-8"><a href="#cb38-8" aria-hidden="true"></a></span>
<span id="cb38-9"><a href="#cb38-9" aria-hidden="true"></a>  <span class="kw">explicit</span> <span class="kw">constexpr</span> polymorphic();</span>
<span id="cb38-10"><a href="#cb38-10" aria-hidden="true"></a></span>
<span id="cb38-11"><a href="#cb38-11" aria-hidden="true"></a>  <span class="kw">explicit</span> <span class="kw">constexpr</span> polymorphic(<span class="dt">allocator_arg_t</span>, <span class="at">const</span> Allocator&amp; a);</span>
<span id="cb38-12"><a href="#cb38-12" aria-hidden="true"></a></span>
<span id="cb38-13"><a href="#cb38-13" aria-hidden="true"></a>  <span class="kw">constexpr</span> polymorphic(<span class="at">const</span> polymorphic&amp; other);</span>
<span id="cb38-14"><a href="#cb38-14" aria-hidden="true"></a></span>
<span id="cb38-15"><a href="#cb38-15" aria-hidden="true"></a>  <span class="kw">constexpr</span> polymorphic(<span class="dt">allocator_arg_t</span>, <span class="at">const</span> Allocator&amp; a,</span>
<span id="cb38-16"><a href="#cb38-16" aria-hidden="true"></a>                        <span class="at">const</span> polymorphic&amp; other);</span>
<span id="cb38-17"><a href="#cb38-17" aria-hidden="true"></a></span>
<span id="cb38-18"><a href="#cb38-18" aria-hidden="true"></a>  <span class="kw">constexpr</span> polymorphic(polymorphic&amp;&amp; other) <span class="kw">noexcept</span>;</span>
<span id="cb38-19"><a href="#cb38-19" aria-hidden="true"></a></span>
<span id="cb38-20"><a href="#cb38-20" aria-hidden="true"></a>  <span class="kw">constexpr</span> polymorphic(<span class="dt">allocator_arg_t</span>, <span class="at">const</span> Allocator&amp; a,</span>
<span id="cb38-21"><a href="#cb38-21" aria-hidden="true"></a>                        polymorphic&amp;&amp; other) <span class="kw">noexcept</span>(see below);</span>
<span id="cb38-22"><a href="#cb38-22" aria-hidden="true"></a></span>
<span id="cb38-23"><a href="#cb38-23" aria-hidden="true"></a>  <span class="kw">template</span> &lt;<span class="kw">class</span> U, <span class="kw">class</span>... Ts&gt;</span>
<span id="cb38-24"><a href="#cb38-24" aria-hidden="true"></a>  <span class="kw">explicit</span> <span class="kw">constexpr</span> polymorphic(<span class="dt">in_place_type_t</span>&lt;U&gt;, Ts&amp;&amp;... ts);</span>
<span id="cb38-25"><a href="#cb38-25" aria-hidden="true"></a></span>
<span id="cb38-26"><a href="#cb38-26" aria-hidden="true"></a>  <span class="kw">template</span> &lt;<span class="kw">class</span> U, <span class="kw">class</span>... Ts&gt;</span>
<span id="cb38-27"><a href="#cb38-27" aria-hidden="true"></a>  <span class="kw">explicit</span> <span class="kw">constexpr</span> polymorphic(<span class="dt">allocator_arg_t</span>, <span class="at">const</span> Allocator&amp; a,</span>
<span id="cb38-28"><a href="#cb38-28" aria-hidden="true"></a>                                 <span class="dt">in_place_type_t</span>&lt;U&gt;, Ts&amp;&amp;... ts);</span>
<span id="cb38-29"><a href="#cb38-29" aria-hidden="true"></a></span>
<span id="cb38-30"><a href="#cb38-30" aria-hidden="true"></a>  <span class="kw">template</span> &lt;<span class="kw">class</span> U&gt;</span>
<span id="cb38-31"><a href="#cb38-31" aria-hidden="true"></a>  <span class="kw">explicit</span> <span class="kw">constexpr</span> polymorphic(U&amp;&amp; u);</span>
<span id="cb38-32"><a href="#cb38-32" aria-hidden="true"></a></span>
<span id="cb38-33"><a href="#cb38-33" aria-hidden="true"></a>  <span class="kw">template</span> &lt;<span class="kw">class</span> U&gt;</span>
<span id="cb38-34"><a href="#cb38-34" aria-hidden="true"></a>  <span class="kw">explicit</span> <span class="kw">constexpr</span> polymorphic(<span class="dt">allocator_arg_t</span>, <span class="at">const</span> Allocator&amp; a, U&amp;&amp; u);</span>
<span id="cb38-35"><a href="#cb38-35" aria-hidden="true"></a></span>
<span id="cb38-36"><a href="#cb38-36" aria-hidden="true"></a>  <span class="kw">template</span> &lt;<span class="kw">class</span> U, <span class="kw">class</span> I, <span class="kw">class</span>... Us&gt;</span>
<span id="cb38-37"><a href="#cb38-37" aria-hidden="true"></a>  <span class="kw">explicit</span> <span class="kw">constexpr</span> polymorphic(<span class="dt">in_place_type_t</span>&lt;U&gt;,</span>
<span id="cb38-38"><a href="#cb38-38" aria-hidden="true"></a>                                 initializer_list&lt;I&gt; ilist, Us&amp;&amp;... us)</span>
<span id="cb38-39"><a href="#cb38-39" aria-hidden="true"></a></span>
<span id="cb38-40"><a href="#cb38-40" aria-hidden="true"></a>  <span class="kw">template</span> &lt;<span class="kw">class</span> U, <span class="kw">class</span> I, <span class="kw">class</span>... Us&gt;</span>
<span id="cb38-41"><a href="#cb38-41" aria-hidden="true"></a>  <span class="kw">explicit</span> <span class="kw">constexpr</span> polymorphic(<span class="dt">allocator_arg_t</span>, <span class="at">const</span> Allocator&amp; a,</span>
<span id="cb38-42"><a href="#cb38-42" aria-hidden="true"></a>                                 <span class="dt">in_place_type_t</span>&lt;U&gt;,</span>
<span id="cb38-43"><a href="#cb38-43" aria-hidden="true"></a>                                 initializer_list&lt;I&gt; ilist, Us&amp;&amp;... us)</span>
<span id="cb38-44"><a href="#cb38-44" aria-hidden="true"></a></span>
<span id="cb38-45"><a href="#cb38-45" aria-hidden="true"></a>  <span class="kw">constexpr</span> ~polymorphic();</span>
<span id="cb38-46"><a href="#cb38-46" aria-hidden="true"></a></span>
<span id="cb38-47"><a href="#cb38-47" aria-hidden="true"></a>  <span class="kw">constexpr</span> polymorphic&amp; <span class="kw">operator</span>=(<span class="at">const</span> polymorphic&amp; other);</span>
<span id="cb38-48"><a href="#cb38-48" aria-hidden="true"></a></span>
<span id="cb38-49"><a href="#cb38-49" aria-hidden="true"></a>  <span class="kw">constexpr</span> polymorphic&amp; <span class="kw">operator</span>=(polymorphic&amp;&amp; other) <span class="kw">noexcept</span>(see below);</span>
<span id="cb38-50"><a href="#cb38-50" aria-hidden="true"></a></span>
<span id="cb38-51"><a href="#cb38-51" aria-hidden="true"></a>  <span class="kw">constexpr</span> <span class="at">const</span> T&amp; <span class="kw">operator</span>*() <span class="at">const</span> <span class="kw">noexcept</span>;</span>
<span id="cb38-52"><a href="#cb38-52" aria-hidden="true"></a></span>
<span id="cb38-53"><a href="#cb38-53" aria-hidden="true"></a>  <span class="kw">constexpr</span> T&amp; <span class="kw">operator</span>*() <span class="kw">noexcept</span>;</span>
<span id="cb38-54"><a href="#cb38-54" aria-hidden="true"></a></span>
<span id="cb38-55"><a href="#cb38-55" aria-hidden="true"></a>  <span class="kw">constexpr</span> const_pointer <span class="kw">operator</span>-&gt;() <span class="at">const</span> <span class="kw">noexcept</span>;</span>
<span id="cb38-56"><a href="#cb38-56" aria-hidden="true"></a></span>
<span id="cb38-57"><a href="#cb38-57" aria-hidden="true"></a>  <span class="kw">constexpr</span> pointer <span class="kw">operator</span>-&gt;() <span class="kw">noexcept</span>;</span>
<span id="cb38-58"><a href="#cb38-58" aria-hidden="true"></a></span>
<span id="cb38-59"><a href="#cb38-59" aria-hidden="true"></a>  <span class="kw">constexpr</span> <span class="dt">bool</span> valueless_after_move() <span class="at">const</span> <span class="kw">noexcept</span>;</span>
<span id="cb38-60"><a href="#cb38-60" aria-hidden="true"></a></span>
<span id="cb38-61"><a href="#cb38-61" aria-hidden="true"></a>  <span class="kw">constexpr</span> <span class="dt">allocator_type</span> get_allocator() <span class="at">const</span> <span class="kw">noexcept</span>;</span>
<span id="cb38-62"><a href="#cb38-62" aria-hidden="true"></a></span>
<span id="cb38-63"><a href="#cb38-63" aria-hidden="true"></a>  <span class="kw">constexpr</span> <span class="dt">void</span> swap(polymorphic&amp; other) <span class="kw">noexcept</span>(see below);</span>
<span id="cb38-64"><a href="#cb38-64" aria-hidden="true"></a></span>
<span id="cb38-65"><a href="#cb38-65" aria-hidden="true"></a>  <span class="kw">friend</span> <span class="kw">constexpr</span> <span class="dt">void</span> swap(polymorphic&amp; lhs,</span>
<span id="cb38-66"><a href="#cb38-66" aria-hidden="true"></a>                             polymorphic&amp; rhs) <span class="kw">noexcept</span>(see below);</span>
<span id="cb38-67"><a href="#cb38-67" aria-hidden="true"></a> <span class="kw">private</span>:</span>
<span id="cb38-68"><a href="#cb38-68" aria-hidden="true"></a>  Allocator alloc = Alloc(); <span class="co">// exposition only</span></span>
<span id="cb38-69"><a href="#cb38-69" aria-hidden="true"></a>};</span></code></pre></div>
<h4 id="x.z.3-constructors-polymorphic.ctor">X.Z.3 Constructors [polymorphic.ctor]</h4>
<p>The following element applies to all functions in [polymorphic.ctor]:</p>
<p><em>Throws</em>: Nothing unless <code>allocator_traits&lt;allocator_type&gt;::allocate</code> or <code>allocator_traits&lt;allocator_type&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"></a><span class="kw">explicit</span> <span class="kw">constexpr</span> polymorphic()</span></code></pre></div>
<ol type="1">
<li><p><em>Constraints</em>: <code>is_default_constructible_v&lt;T&gt;</code> is <code>true</code>, <code>is_copy_constructible_v&lt;T&gt;</code> is <code>true</code>. <code>is_default_constructible_v&lt;allocator_type&gt;</code> is <code>true</code>.</p></li>
<li><p><em>Mandates</em>: <code>T</code> is a complete type.</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>
<li><p><em>Postconditions</em>: <code>*this</code> is not valueless.</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"></a><span class="kw">explicit</span> <span class="kw">constexpr</span> polymorphic(<span class="dt">allocator_arg_t</span>, <span class="at">const</span> Allocator&amp; a);</span></code></pre></div>
<ol start="5" type="1">
<li><p><em>Constraints</em>: <code>is_default_constructible_v&lt;T&gt;</code> is <code>true</code>, <code>is_copy_constructible_v&lt;T&gt;</code> is <code>true</code>.</p></li>
<li><p><em>Mandates</em>: <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>. Constructs an owned object of type <code>T</code> with an empty argument list using the allocator <code>alloc</code>.</p></li>
<li><p><em>Postconditions</em>: <code>*this</code> is not valueless.</p></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"></a><span class="kw">constexpr</span> polymorphic(<span class="at">const</span> polymorphic&amp; other);</span></code></pre></div>
<ol start="9" type="1">
<li><p><em>Mandates</em>: <code>T</code> is a complete type.</p></li>
<li><p><em>Effects</em>: 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>.</p></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"></a><span class="kw">constexpr</span> polymorphic(<span class="dt">allocator_arg_t</span>, <span class="at">const</span> Allocator&amp; a,</span>
<span id="cb42-2"><a href="#cb42-2" aria-hidden="true"></a>                      <span class="at">const</span> polymorphic&amp; other);</span></code></pre></div>
<ol start="11" type="1">
<li><p><em>Mandates</em>: <code>T</code> is a complete type.</p></li>
<li><p><em>Effects</em>: <code>alloc</code> is direct-non-list-initialized with <code>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>.</p></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"></a><span class="kw">constexpr</span> polymorphic(polymorphic&amp;&amp; other) <span class="kw">noexcept</span>;</span></code></pre></div>
<ol start="13" type="1">
<li><p><em>Mandates</em>: If <code>allocator_traits&lt;allocator_type&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>: 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>.</p></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"></a><span class="kw">constexpr</span> polymorphic(<span class="dt">allocator_arg_t</span>, <span class="at">const</span> Allocator&amp; a,</span>
<span id="cb44-2"><a href="#cb44-2" aria-hidden="true"></a>                      polymorphic&amp;&amp; other) <span class="kw">noexcept</span>(allocator_traits&lt;Allocator&gt;::is_always_equal::value);</span></code></pre></div>
<ol start="15" type="1">
<li><p><em>Mandates</em>: If <code>allocator_traits&lt;allocator_type&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>, 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>.</p></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"></a><span class="kw">template</span> &lt;<span class="kw">class</span> U, <span class="kw">class</span>... Ts&gt;</span>
<span id="cb45-2"><a href="#cb45-2" aria-hidden="true"></a><span class="kw">explicit</span> <span class="kw">constexpr</span> polymorphic(<span class="dt">in_place_type_t</span>&lt;U&gt;, Ts&amp;&amp;... ts);</span></code></pre></div>
<ol start="17" type="1">
<li><p><em>Constraints</em>: <code>is_base_of_v&lt;T, U&gt;</code> is <code>true</code>. <code>is_constructible_v&lt;U,   Ts...&gt;</code> is <code>true</code>. <code>is_copy_constructible_v&lt;U&gt;</code> is <code>true</code>. <code>is_default_constructible_v&lt;allocator_type&gt;</code> is <code>true</code>.</p></li>
<li><p><em>Mandates</em>: <code>T</code> is a complete type.</p></li>
<li><p><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>.</p></li>
<li><p><em>Postconditions</em>: <code>*this</code> is not valueless.</p></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"></a><span class="kw">template</span> &lt;<span class="kw">class</span> U, <span class="kw">class</span>... Ts&gt;</span>
<span id="cb46-2"><a href="#cb46-2" aria-hidden="true"></a><span class="kw">explicit</span> <span class="kw">constexpr</span> polymorphic(<span class="dt">allocator_arg_t</span>, <span class="at">const</span> Allocator&amp; a,</span>
<span id="cb46-3"><a href="#cb46-3" aria-hidden="true"></a>                               <span class="dt">in_place_type_t</span>&lt;U&gt;, Ts&amp;&amp;... ts);</span></code></pre></div>
<ol start="21" type="1">
<li><p><em>Constraints</em>: <code>is_base_of_v&lt;T, U&gt;</code> is <code>true</code> and <code>is_constructible_v&lt;U,   Ts...&gt;</code> is <code>true</code> and <code>is_copy_constructible_v&lt;U&gt;</code> is <code>true</code>.</p></li>
<li><p><em>Mandates</em>: <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>. Constructs an owned object of type <code>U</code> with <code>std​::​forward&lt;Ts&gt;(ts)...</code> using the allocator <code>alloc</code>.</p></li>
<li><p><em>Postconditions</em>: <code>*this</code> is not valueless.</p></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"></a><span class="kw">template</span> &lt;<span class="kw">class</span> U&gt;</span>
<span id="cb47-2"><a href="#cb47-2" aria-hidden="true"></a><span class="kw">explicit</span> <span class="kw">constexpr</span> polymorphic(U&amp;&amp; u);</span></code></pre></div>
<ol start="25" type="1">
<li><p><em>Constraints</em>: <code>is_base_of_v&lt;T, remove_cvref_t&lt;U&gt;&gt;</code> is <code>true</code>. <code>is_copy_constructible_v&lt;remove_cvref_t&lt;U&gt;&gt;</code> is <code>true</code>. <code>is_constructible_v&lt;remove_cvref_t&lt;U&gt;, U&gt;</code> is <code>true</code>. <code>is_same_v&lt;remove_cvref_t&lt;U&gt;, polymorphic&gt;</code> is <code>false</code>. <code>is_default_constructible_v&lt;allocator_type&gt;</code> is <code>true</code>. <code>remove_cvref_t&lt;U&gt;</code> is not a specialization of <code>in_place_type_t</code>.</p></li>
<li><p><em>Mandates</em>: <code>T</code> is a complete type.</p></li>
<li><p><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>.</p></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"></a><span class="kw">template</span> &lt;<span class="kw">class</span> U&gt;</span>
<span id="cb48-2"><a href="#cb48-2" aria-hidden="true"></a><span class="kw">explicit</span> <span class="kw">constexpr</span> polymorphic(<span class="dt">allocator_arg_t</span>, <span class="at">const</span> Allocator&amp; a, U&amp;&amp; u);</span></code></pre></div>
<ol start="28" type="1">
<li><p><em>Constraints</em>: <code>is_base_of_v&lt;T, remove_cvref_t&lt;U&gt;&gt;</code> is <code>true</code>. <code>is_copy_constructible_v&lt;remove_cvref_t&lt;U&gt;&gt;</code> is <code>true</code>. <code>is_constructible_v&lt;remove_cvref_t&lt;U&gt;, U&gt;</code> is <code>true</code>. <code>is_same_v&lt;remove_cvref_t&lt;U&gt;, polymorphic&gt;</code> is <code>false</code>. <code>is_default_constructible_v&lt;allocator_type&gt;</code> is <code>true</code>. <code>remove_cvref_t&lt;U&gt;</code> is not a specialization of <code>in_place_type_t</code>.</p></li>
<li><p><em>Mandates</em>: <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>. Constructs an owned object of type <code>U</code> with <code>std​::​forward&lt;U&gt;(u)</code> using the allocator <code>alloc</code>.</p></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"></a><span class="kw">template</span> &lt;<span class="kw">class</span> U, <span class="kw">class</span> I, <span class="kw">class</span>... Us&gt;</span>
<span id="cb49-2"><a href="#cb49-2" aria-hidden="true"></a><span class="kw">explicit</span> <span class="kw">constexpr</span> polymorphic(<span class="dt">in_place_type_t</span>&lt;U&gt;,</span>
<span id="cb49-3"><a href="#cb49-3" aria-hidden="true"></a>                               initializer_list&lt;I&gt; ilist, Us&amp;&amp;... us)</span></code></pre></div>
<ol start="31" type="1">
<li><p><em>Constraints</em>: <code>is_base_of_v&lt;T, remove_cvref_t&lt;U&gt;&gt;</code> is <code>true</code>. <code>is_copy_constructible_v&lt;remove_cvref_t&lt;U&gt;&gt;</code> is <code>true</code>. <code>is_constructible_v&lt;remove_cvref_t&lt;U&gt;, U&gt;</code> is <code>true</code>. <code>is_same_v&lt;remove_cvref_t&lt;U&gt;, polymorphic&gt;</code> is <code>false</code>. <code>remove_cvref_t&lt;U&gt;</code> is not a specialization of <code>in_place_type_t</code>.</p></li>
<li><p><em>Mandates</em>: <code>T</code> is a complete type.</p></li>
<li><p><em>Effects</em>: Constructs an owned object of type <code>U</code> with the arguments <code>ilist</code>, <code>std​::​forward&lt;U&gt;(u)</code> using the allocator <code>alloc</code>.</p></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"></a><span class="kw">template</span> &lt;<span class="kw">class</span> U, <span class="kw">class</span> I, <span class="kw">class</span>... Us&gt;</span>
<span id="cb50-2"><a href="#cb50-2" aria-hidden="true"></a><span class="kw">explicit</span> <span class="kw">constexpr</span> polymorphic(<span class="dt">allocator_arg_t</span>, <span class="at">const</span> Allocator&amp; a,</span>
<span id="cb50-3"><a href="#cb50-3" aria-hidden="true"></a>                               <span class="dt">in_place_type_t</span>&lt;U&gt;,</span>
<span id="cb50-4"><a href="#cb50-4" aria-hidden="true"></a>                               initializer_list&lt;I&gt; ilist, Us&amp;&amp;... us)</span></code></pre></div>
<ol start="34" type="1">
<li><p><em>Constraints</em>: <code>is_base_of_v&lt;T, remove_cvref_t&lt;U&gt;&gt;</code> is <code>true</code>. <code>is_copy_constructible_v&lt;remove_cvref_t&lt;U&gt;&gt;</code> is <code>true</code>. <code>is_constructible_v&lt;remove_cvref_t&lt;U&gt;, U&gt;</code> is <code>true</code>. <code>is_same_v&lt;remove_cvref_t&lt;U&gt;, polymorphic&gt;</code> is <code>false</code>. <code>remove_cvref_t&lt;U&gt;</code> is not a specialization of <code>in_place_type_t</code>.</p></li>
<li><p><em>Mandates</em>: <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>. Constructs an owned object of type <code>U</code> with the arguments <code>ilist</code>, <code>std​::​forward&lt;U&gt;(u)</code> using the allocator <code>alloc</code>.</p></li>
</ol>
<h4 id="x.z.4-destructor-polymorphic.dtor">X.Z.4 Destructor [polymorphic.dtor]</h4>
<div class="sourceCode" id="cb51"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb51-1"><a href="#cb51-1" aria-hidden="true"></a><span class="kw">constexpr</span> ~polymorphic();</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_type&gt;::destroy</code> and then the storage is deallocated.</p></li>
</ol>
<h4 id="x.z.5-assignment-polymorphic.assign">X.Z.5 Assignment [polymorphic.assign]</h4>
<div class="sourceCode" id="cb52"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb52-1"><a href="#cb52-1" aria-hidden="true"></a><span class="kw">constexpr</span> polymorphic&amp; <span class="kw">operator</span>=(<span class="at">const</span> polymorphic&amp; other);</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.</p></li>
</ol>
<p>If <code>allocator_traits&lt;alloctor_type&gt;::propagate_on_container_copy_assignment</code> is <code>true</code> then the allocator needs updating.</p>
<p>If <code>other</code> is not valueless, a new owned object is constructed in <code>*this</code> using <code>allocator_traits&lt;allocator_type&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>The previous owned object in <code>*this</code>, if any, is destroyed using <code>allocator_traits&lt;allocator_type&gt;::destroy</code> and then the storage is deallocated.</p>
<p>If the allocator needs updating, the allocator in <code>*this</code> is replaced with a copy of the allocator in <code>other</code>.</p>
<ol start="3" type="1">
<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"></a><span class="kw">constexpr</span> polymorphic&amp; <span class="kw">operator</span>=(polymorphic&amp;&amp; other) <span class="kw">noexcept</span>(</span>
<span id="cb53-2"><a href="#cb53-2" aria-hidden="true"></a>    allocator_traits&lt;Allocator&gt;::propagate_on_container_move_assignment::value ||</span>
<span id="cb53-3"><a href="#cb53-3" aria-hidden="true"></a>    allocator_traits&lt;Allocator&gt;::is_always_equal::value);</span></code></pre></div>
<ol start="5" type="1">
<li><p><em>Mandates</em>: If <code>allocator_traits&lt;allocator_type&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.</p></li>
</ol>
<p>If <code>allocator_traits&lt;allocator_type&gt;::propagate_on_container_move_assignment</code> is <code>true</code> then the allocator needs updating.</p>
<p>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_type&gt;::destroy</code> and then the storage is deallocated.</p>
<p>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_type&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. The previous owned object in <code>*this</code>, if any, is destroyed using <code>allocator_traits&lt;allocator_type&gt;::destroy</code> and then the storage is deallocated.</p>
<p>If the allocator needs updating, the allocator in <code>*this</code> is replaced with a copy of the allocator in <code>other</code>.</p>
<ol start="7" type="1">
<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>
<h4 id="x.z.6-observers-polymorphic.observers">X.Z.6 Observers [polymorphic.observers]</h4>
<div class="sourceCode" id="cb54"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb54-1"><a href="#cb54-1" aria-hidden="true"></a><span class="kw">constexpr</span> <span class="at">const</span> T&amp; <span class="kw">operator</span>*() <span class="at">const</span> <span class="kw">noexcept</span>;</span>
<span id="cb54-2"><a href="#cb54-2" aria-hidden="true"></a><span class="kw">constexpr</span> T&amp; <span class="kw">operator</span>*() <span class="kw">noexcept</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"></a><span class="kw">constexpr</span> const_pointer <span class="kw">operator</span>-&gt;() <span class="at">const</span> <span class="kw">noexcept</span>;</span>
<span id="cb55-2"><a href="#cb55-2" aria-hidden="true"></a><span class="kw">constexpr</span> pointer <span class="kw">operator</span>-&gt;() <span class="kw">noexcept</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"></a><span class="kw">constexpr</span> <span class="dt">bool</span> valueless_after_move() <span class="at">const</span> <span class="kw">noexcept</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"></a><span class="kw">constexpr</span> <span class="dt">allocator_type</span> get_allocator() <span class="at">const</span> <span class="kw">noexcept</span>;</span></code></pre></div>
<ol start="6" type="1">
<li><em>Returns</em>: <code>alloc</code>.</li>
</ol>
<h4 id="x.z.7-swap-polymorphic.swap">X.Z.7 Swap [polymorphic.swap]</h4>
<div class="sourceCode" id="cb58"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb58-1"><a href="#cb58-1" aria-hidden="true"></a><span class="kw">constexpr</span> <span class="dt">void</span> swap(polymorphic&amp; other) <span class="kw">noexcept</span>(</span>
<span id="cb58-2"><a href="#cb58-2" aria-hidden="true"></a>  allocator_traits::propagate_on_container_swap::value</span>
<span id="cb58-3"><a href="#cb58-3" aria-hidden="true"></a>  || allocator_traits::is_always_equal::value);</span></code></pre></div>
<ol type="1">
<li><em>Effects</em>: Swaps the states of <code>*this</code> and <code>other</code>, exchanging owned objects or valueless states. If <code>allocator_traits&lt;allocator_type&gt;::propagate_on_container_swap::value</code> is <code>true</code>, then <code>allocator_type</code> shall meet the <em>Cpp17Swappable</em> requirements and 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, and the behavior is undefined unless <code>(*this).get_allocator() ==   other.get_allocator()</code>.<br />
<em>[Note: Does not call <code>swap</code> on the owned objects directly. –end note]</em></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"></a><span class="kw">constexpr</span> <span class="dt">void</span> swap(polymorphic&amp; lhs, polymorphic&amp; rhs) <span class="kw">noexcept</span>(</span>
<span id="cb59-2"><a href="#cb59-2" aria-hidden="true"></a>  <span class="kw">noexcept</span>(lhs.swap(rhs)));</span></code></pre></div>
<ol start="2" type="1">
<li><em>Effects</em>: Equivalent to <code>lhs.swap(rhs)</code>.</li>
</ol>
<h2 id="reference-implementation">Reference implementation</h2>
<p>A C++20 reference implementation of this proposal is available on GitHub at [https://www.github.com/jbcoe/value_types].</p>
<h2 id="acknowledgements">Acknowledgements</h2>
<p>The authors would like to thank Lewis Baker, Andrew Bennieston, Josh Berne, Bengt Gustafsson, Casey Carter, Rostislav Khlebnikov, Daniel Krugler, David Krauss, David Stone, Ed Catmur, Geoff Romer, German Diago, Jonathan Wakely, Kilian Henneberger, LanguageLawyer, Louis Dionne, Maciej Bogus, Malcolm Parsons, Matthew Calabrese, Nathan Myers, Neelofer Banglawala, Nevin Liber, Nina Ranns, Patrice Roy, Roger Orr, 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>
<h2 id="references">References</h2>
<p><em>A Preliminary Proposal for a Deep-Copying Smart Pointer</em>, W. E. Brown, 2012<br />
[http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3339.pdf]</p>
<p><em>A polymorphic value-type for C++</em>, J. B. Coe, S. Parent 2019<br />
[https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p0201r6.html]</p>
<p><em>A Free-Store-Allocated Value Type for C++</em>, J. B. Coe, A. Peacock 2022<br />
[https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1950r2.html]</p>
<p><em>An allocator-aware optional type</em>,<br />
P. Halpern, N. D. Ranns, V. Voutilainen, 2024<br />
[https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2047r7.html]</p>
<p><em>MISRA Language Guidelines</em><br />
[https://ldra.com/misra/]</p>
<p><em>High Integrity C++</em><br />
[https://www.perforce.com/resources/qac/high-integrity-cpp-coding-standard]</p>
<h2 id="appendix-a-detailed-design-decisions">Appendix A: Detailed design decisions</h2>
<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>
<h3 id="two-class-templates-not-one">Two class templates, not one</h3>
<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>
<h3 id="copiers-deleters-pointer-constructors-and-allocator-support">Copiers, deleters, pointer constructors, and allocator support</h3>
<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>
<h3 id="pointer-like-helper-functions">Pointer-like helper functions</h3>
<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>
<h3 id="constraints-on-incomplete-types-and-conditional-constructors">Constraints on incomplete types and conditional constructors</h3>
<p>Both <code>indirect</code> and <code>polymorphic</code> support incomplete types. Support for an incomplete type requires deferring the instantiation of functions with requirements until they are used.</p>
<p>The default constructor of <code>indirect</code> requires that <code>T</code> is default constructible. We cannot write this constraint as a requirement on <code>T</code> because that would require <code>T</code> to be a complete type at class instantiation time. Instead we write the constraint as a requirement on a deduced type <code>TT</code> to defer evaluation of the constraint until the default constructor is instantiated.</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"></a><span class="kw">template</span> &lt;<span class="kw">typename</span> TT = T&gt;</span>
<span id="cb60-2"><a href="#cb60-2" aria-hidden="true"></a>indirect() <span class="kw">requires</span> is_default_constructible_v&lt;TT&gt;;</span></code></pre></div>
<p>We can use this technique to write constraints on the default constructor of <code>indirect</code> and <code>polymorphic</code>. Both <code>indirect</code> and <code>polymorphic</code> are conditionally default constructible.</p>
<p>The same technique cannot be used for the copy or move constructor of <code>polymorphic</code> because that would require type information on an open set of erased types, which is not possible: a <code>polymorphic</code> object can contain any type that is derived from <code>T</code>, we cannot write a constraint that requires that all such types are copy constructible. We make <code>polymorphic</code> unconditionally copy and move constructible. The authors do not envisage that this could be relaxed in a future version of the C++ standard.</p>
<p>While a copy constructor cannot be a template, in C++20 and later we can conditionally constrain copy construction of <code>indirect</code> by defining:</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"></a>indirect(<span class="at">const</span> indirect&amp; other) <span class="kw">requires</span> <span class="kw">false</span> = <span class="kw">delete</span>;</span>
<span id="cb61-2"><a href="#cb61-2" aria-hidden="true"></a></span>
<span id="cb61-3"><a href="#cb61-3" aria-hidden="true"></a><span class="kw">template</span> &lt;<span class="kw">typename</span> TT = T&gt;</span>
<span id="cb61-4"><a href="#cb61-4" aria-hidden="true"></a>indirect(<span class="at">const</span> indirect&amp; other) <span class="kw">requires</span> is_copy_constructible_v&lt;TT&gt;;</span></code></pre></div>
<p>An instantiation of the function template with <code>TT = T</code> is added to the overload set when <code>indirect</code> is copy-constructed and will be selected if the owned object type <code>T</code> is copy constructible. This would make copy construction conditional for <code>indirect</code> but not for <code>polymorphic</code>. We opt for consistency and make copy construction unconditional for both <code>indirect</code> and <code>polymorphic</code>. Making <code>indirect</code> conditionally copy constructible in a future version of the C++ standard would require adding a template function as above and would be an ABI break. It might be simpler to add new types for non-copyable <code>indirect</code> and <code>polymorphic</code> objects, although we do not propose the addition of such types in this draft.</p>
<h3 id="implicit-conversions">Implicit conversions</h3>
<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="cb62"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb62-1"><a href="#cb62-1" aria-hidden="true"></a>Rectangle r(w, h);</span>
<span id="cb62-2"><a href="#cb62-2" aria-hidden="true"></a>polymorphic&lt;Shape&gt; s = r; <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="cb63"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb63-1"><a href="#cb63-1" aria-hidden="true"></a>Rectangle r(w, h);</span>
<span id="cb63-2"><a href="#cb63-2" aria-hidden="true"></a>polymorphic&lt;Shape&gt; s(<span class="bu">std::</span>in_place_type&lt;Rectangle&gt;, r);</span>
<span id="cb63-3"><a href="#cb63-3" aria-hidden="true"></a><span class="ot">assert</span>(<span class="kw">dynamic_cast</span>&lt;Rectangle*&gt;(&amp;*s) != <span class="kw">nullptr</span>);</span></code></pre></div>
<h3 id="explicit-conversions">Explicit conversions</h3>
<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="cb64"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb64-1"><a href="#cb64-1" aria-hidden="true"></a>polymorphic_value&lt;Quadrilateral&gt; q(<span class="bu">std::</span>in_place_type&lt;Rectangle&gt;, w, h);</span>
<span id="cb64-2"><a href="#cb64-2" aria-hidden="true"></a>polymorphic_value&lt;Shape&gt; s = q;</span>
<span id="cb64-3"><a href="#cb64-3" aria-hidden="true"></a><span class="ot">assert</span>(<span class="kw">dynamic_cast</span>&lt;Rectangle*&gt;(&amp;*s) != <span class="kw">nullptr</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="cb65"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb65-1"><a href="#cb65-1" aria-hidden="true"></a>polymorphic&lt;Quadrilateral&gt; q(<span class="bu">std::</span>in_place_type&lt;Rectangle&gt;, w, h);</span>
<span id="cb65-2"><a href="#cb65-2" aria-hidden="true"></a>polymorphic&lt;Shape&gt; s = q; <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>
<h3 id="comparisons-for-indirect">Comparisons for <code>indirect</code></h3>
<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 only give 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>
<h3 id="supporting-operator-operator">Supporting <code>operator()</code> <code>operator[]</code></h3>
<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>
<h3 id="supporting-arithmetic-operators">Supporting arithmetic operators</h3>
<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 which there is no precedent for 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>
<h3 id="member-function-emplace">Member function <code>emplace</code></h3>
<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="cb66"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb66-1"><a href="#cb66-1" aria-hidden="true"></a><span class="kw">template</span> &lt;<span class="kw">typename</span> ...Ts&gt;</span>
<span id="cb66-2"><a href="#cb66-2" aria-hidden="true"></a>indirect::emplace(Ts&amp;&amp; ...ts);</span></code></pre></div>
<div class="sourceCode" id="cb67"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb67-1"><a href="#cb67-1" aria-hidden="true"></a><span class="kw">template</span> &lt;<span class="kw">typename</span> U, <span class="kw">typename</span> ...Ts&gt;</span>
<span id="cb67-2"><a href="#cb67-2" aria-hidden="true"></a>polymorphic::emplace(<span class="dt">in_place_type</span>&lt;U&gt;, Ts&amp;&amp; ...ts);</span></code></pre></div>
<p>This would be API noise. It offers no efficiency improvement over:</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"></a>some_indirect = indirect(<span class="co">/* arguments */</span>);</span></code></pre></div>
<div class="sourceCode" id="cb69"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb69-1"><a href="#cb69-1" aria-hidden="true"></a>some_polymorphic = polymorphic(<span class="dt">in_place_type</span>&lt;U&gt;, <span class="co">/* arguments */</span>);</span></code></pre></div>
<p>Support for an emplace member function could be added in a future version of the C++ standard.</p>
<h3 id="small-buffer-optimisation">Small Buffer Optimisation</h3>
<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="cb70"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb70-1"><a href="#cb70-1" aria-hidden="true"></a><span class="kw">template</span> &lt;<span class="kw">typename</span> T, <span class="kw">typename</span> Alloc, <span class="dt">size_t</span> BufferSize&gt;</span>
<span id="cb70-2"><a href="#cb70-2" aria-hidden="true"></a><span class="kw">class</span> polymorphic;</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>
<h2 id="appendix-b-before-and-after-examples">Appendix B: Before and after examples</h2>
<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>
<h3 id="using-indirect-for-binary-compatibility-using-the-pimpl-idiom">Using <code>indirect</code> for binary compatibility using the PIMPL idiom</h3>
<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>
<h4 id="before-without-using-indirect">Before, without using <code>indirect</code></h4>
<div class="sourceCode" id="cb71"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb71-1"><a href="#cb71-1" aria-hidden="true"></a><span class="co">// Class.h</span></span>
<span id="cb71-2"><a href="#cb71-2" aria-hidden="true"></a></span>
<span id="cb71-3"><a href="#cb71-3" aria-hidden="true"></a><span class="kw">class</span> Class {</span>
<span id="cb71-4"><a href="#cb71-4" aria-hidden="true"></a>  <span class="kw">class</span> Impl;</span>
<span id="cb71-5"><a href="#cb71-5" aria-hidden="true"></a>  <span class="bu">std::</span>unique_ptr&lt;Impl&gt; <span class="va">impl_</span>;</span>
<span id="cb71-6"><a href="#cb71-6" aria-hidden="true"></a> <span class="kw">public</span>:</span>
<span id="cb71-7"><a href="#cb71-7" aria-hidden="true"></a>  Class();</span>
<span id="cb71-8"><a href="#cb71-8" aria-hidden="true"></a>  ~Class();</span>
<span id="cb71-9"><a href="#cb71-9" aria-hidden="true"></a>  Class(<span class="at">const</span> Class&amp;);</span>
<span id="cb71-10"><a href="#cb71-10" aria-hidden="true"></a>  Class&amp; <span class="kw">operator</span>=(<span class="at">const</span> Class&amp;);</span>
<span id="cb71-11"><a href="#cb71-11" aria-hidden="true"></a>  Class(Class&amp;&amp;) <span class="kw">noexcept</span>;</span>
<span id="cb71-12"><a href="#cb71-12" aria-hidden="true"></a>  Class&amp; <span class="kw">operator</span>=(Class&amp;&amp;) <span class="kw">noexcept</span>;</span>
<span id="cb71-13"><a href="#cb71-13" aria-hidden="true"></a></span>
<span id="cb71-14"><a href="#cb71-14" aria-hidden="true"></a>  <span class="dt">void</span> do_something();</span>
<span id="cb71-15"><a href="#cb71-15" aria-hidden="true"></a>};</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"></a><span class="co">// Class.cpp</span></span>
<span id="cb72-2"><a href="#cb72-2" aria-hidden="true"></a></span>
<span id="cb72-3"><a href="#cb72-3" aria-hidden="true"></a><span class="kw">class</span> Impl {</span>
<span id="cb72-4"><a href="#cb72-4" aria-hidden="true"></a> <span class="kw">public</span>:</span>
<span id="cb72-5"><a href="#cb72-5" aria-hidden="true"></a>  <span class="dt">void</span> do_something();</span>
<span id="cb72-6"><a href="#cb72-6" aria-hidden="true"></a>};</span>
<span id="cb72-7"><a href="#cb72-7" aria-hidden="true"></a></span>
<span id="cb72-8"><a href="#cb72-8" aria-hidden="true"></a>Class::Class() : <span class="va">impl_</span>(<span class="bu">std::</span>make_unique&lt;Impl&gt;()) {}</span>
<span id="cb72-9"><a href="#cb72-9" aria-hidden="true"></a></span>
<span id="cb72-10"><a href="#cb72-10" aria-hidden="true"></a>Class::~Class() = <span class="cf">default</span>;</span>
<span id="cb72-11"><a href="#cb72-11" aria-hidden="true"></a></span>
<span id="cb72-12"><a href="#cb72-12" aria-hidden="true"></a>Class::Class(<span class="at">const</span> Class&amp; other) : <span class="va">impl_</span>(<span class="bu">std::</span>make_unique&lt;Impl&gt;(*other.<span class="va">impl_</span>)) {}</span>
<span id="cb72-13"><a href="#cb72-13" aria-hidden="true"></a></span>
<span id="cb72-14"><a href="#cb72-14" aria-hidden="true"></a>Class&amp; Class::<span class="kw">operator</span>=(<span class="at">const</span> Class&amp; other) {</span>
<span id="cb72-15"><a href="#cb72-15" aria-hidden="true"></a>  <span class="cf">if</span> (<span class="kw">this</span> != &amp;other) {</span>
<span id="cb72-16"><a href="#cb72-16" aria-hidden="true"></a>    Class tmp(other);</span>
<span id="cb72-17"><a href="#cb72-17" aria-hidden="true"></a>    <span class="kw">using</span> <span class="bu">std::</span>swap;</span>
<span id="cb72-18"><a href="#cb72-18" aria-hidden="true"></a>    swap(*<span class="kw">this</span>, tmp);</span>
<span id="cb72-19"><a href="#cb72-19" aria-hidden="true"></a>  }</span>
<span id="cb72-20"><a href="#cb72-20" aria-hidden="true"></a>  <span class="cf">return</span> *<span class="kw">this</span>;</span>
<span id="cb72-21"><a href="#cb72-21" aria-hidden="true"></a>}</span>
<span id="cb72-22"><a href="#cb72-22" aria-hidden="true"></a></span>
<span id="cb72-23"><a href="#cb72-23" aria-hidden="true"></a>Class(Class&amp;&amp;) <span class="kw">noexcept</span> = <span class="cf">default</span>;</span>
<span id="cb72-24"><a href="#cb72-24" aria-hidden="true"></a>Class&amp; <span class="kw">operator</span>=(Class&amp;&amp;) <span class="kw">noexcept</span> = <span class="cf">default</span>;</span>
<span id="cb72-25"><a href="#cb72-25" aria-hidden="true"></a></span>
<span id="cb72-26"><a href="#cb72-26" aria-hidden="true"></a><span class="dt">void</span> Class::do_something() {</span>
<span id="cb72-27"><a href="#cb72-27" aria-hidden="true"></a>  <span class="va">impl_</span>-&gt;do_something();</span>
<span id="cb72-28"><a href="#cb72-28" aria-hidden="true"></a>}</span></code></pre></div>
<h4 id="after-using-indirect">After, using <code>indirect</code></h4>
<div class="sourceCode" id="cb73"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb73-1"><a href="#cb73-1" aria-hidden="true"></a><span class="co">// Class.h</span></span>
<span id="cb73-2"><a href="#cb73-2" aria-hidden="true"></a></span>
<span id="cb73-3"><a href="#cb73-3" aria-hidden="true"></a><span class="kw">class</span> Class {</span>
<span id="cb73-4"><a href="#cb73-4" aria-hidden="true"></a>  indirect&lt;<span class="kw">class</span> Impl&gt; <span class="va">impl_</span>;</span>
<span id="cb73-5"><a href="#cb73-5" aria-hidden="true"></a> <span class="kw">public</span>:</span>
<span id="cb73-6"><a href="#cb73-6" aria-hidden="true"></a>  Class();</span>
<span id="cb73-7"><a href="#cb73-7" aria-hidden="true"></a>  ~Class();</span>
<span id="cb73-8"><a href="#cb73-8" aria-hidden="true"></a>  Class(<span class="at">const</span> Class&amp;);</span>
<span id="cb73-9"><a href="#cb73-9" aria-hidden="true"></a>  Class&amp; <span class="kw">operator</span>=(<span class="at">const</span> Class&amp;);</span>
<span id="cb73-10"><a href="#cb73-10" aria-hidden="true"></a>  Class(Class&amp;&amp;) <span class="kw">noexcept</span>;</span>
<span id="cb73-11"><a href="#cb73-11" aria-hidden="true"></a>  Class&amp; <span class="kw">operator</span>=(Class&amp;&amp;) <span class="kw">noexcept</span>;</span>
<span id="cb73-12"><a href="#cb73-12" aria-hidden="true"></a></span>
<span id="cb73-13"><a href="#cb73-13" aria-hidden="true"></a>  <span class="dt">void</span> do_something();</span>
<span id="cb73-14"><a href="#cb73-14" aria-hidden="true"></a>};</span></code></pre></div>
<div class="sourceCode" id="cb74"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb74-1"><a href="#cb74-1" aria-hidden="true"></a><span class="co">// Class.cpp</span></span>
<span id="cb74-2"><a href="#cb74-2" aria-hidden="true"></a></span>
<span id="cb74-3"><a href="#cb74-3" aria-hidden="true"></a><span class="kw">class</span> Impl {</span>
<span id="cb74-4"><a href="#cb74-4" aria-hidden="true"></a> <span class="kw">public</span>:</span>
<span id="cb74-5"><a href="#cb74-5" aria-hidden="true"></a>  <span class="dt">void</span> do_something();</span>
<span id="cb74-6"><a href="#cb74-6" aria-hidden="true"></a>};</span>
<span id="cb74-7"><a href="#cb74-7" aria-hidden="true"></a></span>
<span id="cb74-8"><a href="#cb74-8" aria-hidden="true"></a>Class::Class() : <span class="va">impl_</span>(indirect&lt;Impl&gt;()) {}</span>
<span id="cb74-9"><a href="#cb74-9" aria-hidden="true"></a>Class::~Class() = <span class="cf">default</span>;</span>
<span id="cb74-10"><a href="#cb74-10" aria-hidden="true"></a>Class::Class(<span class="at">const</span> Class&amp;) = <span class="cf">default</span>;</span>
<span id="cb74-11"><a href="#cb74-11" aria-hidden="true"></a>Class&amp; Class::<span class="kw">operator</span>=(<span class="at">const</span> Class&amp;) = <span class="cf">default</span>;</span>
<span id="cb74-12"><a href="#cb74-12" aria-hidden="true"></a>Class(Class&amp;&amp;) <span class="kw">noexcept</span> = <span class="cf">default</span>;</span>
<span id="cb74-13"><a href="#cb74-13" aria-hidden="true"></a>Class&amp; <span class="kw">operator</span>=(Class&amp;&amp;) <span class="kw">noexcept</span> = <span class="cf">default</span>;</span>
<span id="cb74-14"><a href="#cb74-14" aria-hidden="true"></a></span>
<span id="cb74-15"><a href="#cb74-15" aria-hidden="true"></a><span class="dt">void</span> Class::do_something() {</span>
<span id="cb74-16"><a href="#cb74-16" aria-hidden="true"></a>  <span class="va">impl_</span>-&gt;do_something();</span>
<span id="cb74-17"><a href="#cb74-17" aria-hidden="true"></a>}</span></code></pre></div>
<h3 id="using-polymorphic-for-a-composite-class">Using <code>polymorphic</code> for a composite class</h3>
<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>
<h4 id="before-without-using-polymorphic">Before, without using <code>polymorphic</code></h4>
<div class="sourceCode" id="cb75"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb75-1"><a href="#cb75-1" aria-hidden="true"></a><span class="kw">class</span> Canvas;</span>
<span id="cb75-2"><a href="#cb75-2" aria-hidden="true"></a></span>
<span id="cb75-3"><a href="#cb75-3" aria-hidden="true"></a><span class="kw">class</span> Shape {</span>
<span id="cb75-4"><a href="#cb75-4" aria-hidden="true"></a> <span class="kw">public</span>:</span>
<span id="cb75-5"><a href="#cb75-5" aria-hidden="true"></a>  <span class="kw">virtual</span> ~Shape() = <span class="cf">default</span>;</span>
<span id="cb75-6"><a href="#cb75-6" aria-hidden="true"></a>  <span class="kw">virtual</span> <span class="bu">std::</span>unique_ptr&lt;Shape&gt; clone() = <span class="dv">0</span>;</span>
<span id="cb75-7"><a href="#cb75-7" aria-hidden="true"></a>  <span class="kw">virtual</span> <span class="dt">void</span> draw(Canvas&amp;) <span class="at">const</span> = <span class="dv">0</span>;</span>
<span id="cb75-8"><a href="#cb75-8" aria-hidden="true"></a>};</span>
<span id="cb75-9"><a href="#cb75-9" aria-hidden="true"></a></span>
<span id="cb75-10"><a href="#cb75-10" aria-hidden="true"></a><span class="kw">class</span> Picture {</span>
<span id="cb75-11"><a href="#cb75-11" aria-hidden="true"></a>  <span class="bu">std::</span>vector&lt;<span class="bu">std::</span>unique_ptr&lt;Shape&gt;&gt; <span class="va">shapes_</span>;</span>
<span id="cb75-12"><a href="#cb75-12" aria-hidden="true"></a></span>
<span id="cb75-13"><a href="#cb75-13" aria-hidden="true"></a> <span class="kw">public</span>:</span>
<span id="cb75-14"><a href="#cb75-14" aria-hidden="true"></a>  Picture(<span class="at">const</span> <span class="bu">std::</span>vector&lt;<span class="bu">std::</span>unique_ptr&lt;Shape&gt;&gt;&amp; shapes) {</span>
<span id="cb75-15"><a href="#cb75-15" aria-hidden="true"></a>    <span class="va">shapes_</span>.reserve(shapes.size());</span>
<span id="cb75-16"><a href="#cb75-16" aria-hidden="true"></a>    <span class="cf">for</span> (<span class="kw">auto</span>&amp; shape : shapes) {</span>
<span id="cb75-17"><a href="#cb75-17" aria-hidden="true"></a>      <span class="va">shapes_</span>.push_back(shape-&gt;clone());</span>
<span id="cb75-18"><a href="#cb75-18" aria-hidden="true"></a>    }</span>
<span id="cb75-19"><a href="#cb75-19" aria-hidden="true"></a>  }</span>
<span id="cb75-20"><a href="#cb75-20" aria-hidden="true"></a></span>
<span id="cb75-21"><a href="#cb75-21" aria-hidden="true"></a>  Picture(<span class="at">const</span> Picture&amp; other) {</span>
<span id="cb75-22"><a href="#cb75-22" aria-hidden="true"></a>    <span class="va">shapes_</span>.reserve(other.<span class="va">shapes_</span>.size());</span>
<span id="cb75-23"><a href="#cb75-23" aria-hidden="true"></a>    <span class="cf">for</span> (<span class="kw">auto</span>&amp; shape : other.<span class="va">shapes_</span>) {</span>
<span id="cb75-24"><a href="#cb75-24" aria-hidden="true"></a>      <span class="va">shapes_</span>.push_back(shape-&gt;clone());</span>
<span id="cb75-25"><a href="#cb75-25" aria-hidden="true"></a>    }</span>
<span id="cb75-26"><a href="#cb75-26" aria-hidden="true"></a>  }</span>
<span id="cb75-27"><a href="#cb75-27" aria-hidden="true"></a></span>
<span id="cb75-28"><a href="#cb75-28" aria-hidden="true"></a>  Picture&amp; <span class="kw">operator</span>=(<span class="at">const</span> Picture&amp; other) {</span>
<span id="cb75-29"><a href="#cb75-29" aria-hidden="true"></a>    <span class="cf">if</span> (<span class="kw">this</span> != &amp;other) {</span>
<span id="cb75-30"><a href="#cb75-30" aria-hidden="true"></a>      Picture tmp(other);</span>
<span id="cb75-31"><a href="#cb75-31" aria-hidden="true"></a>      <span class="kw">using</span> <span class="bu">std::</span>swap;</span>
<span id="cb75-32"><a href="#cb75-32" aria-hidden="true"></a>      swap(*<span class="kw">this</span>, tmp);</span>
<span id="cb75-33"><a href="#cb75-33" aria-hidden="true"></a>    }</span>
<span id="cb75-34"><a href="#cb75-34" aria-hidden="true"></a>    <span class="cf">return</span> *<span class="kw">this</span>;</span>
<span id="cb75-35"><a href="#cb75-35" aria-hidden="true"></a>  }</span>
<span id="cb75-36"><a href="#cb75-36" aria-hidden="true"></a></span>
<span id="cb75-37"><a href="#cb75-37" aria-hidden="true"></a>  <span class="dt">void</span> draw(Canvas&amp; canvas) <span class="at">const</span>;</span>
<span id="cb75-38"><a href="#cb75-38" aria-hidden="true"></a>};</span></code></pre></div>
<h4 id="after-using-polymorphic">After, using <code>polymorphic</code></h4>
<div class="sourceCode" id="cb76"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb76-1"><a href="#cb76-1" aria-hidden="true"></a><span class="kw">class</span> Canvas;</span>
<span id="cb76-2"><a href="#cb76-2" aria-hidden="true"></a></span>
<span id="cb76-3"><a href="#cb76-3" aria-hidden="true"></a><span class="kw">class</span> Shape {</span>
<span id="cb76-4"><a href="#cb76-4" aria-hidden="true"></a> <span class="kw">protected</span>:</span>
<span id="cb76-5"><a href="#cb76-5" aria-hidden="true"></a>  ~Shape() = <span class="cf">default</span>;</span>
<span id="cb76-6"><a href="#cb76-6" aria-hidden="true"></a></span>
<span id="cb76-7"><a href="#cb76-7" aria-hidden="true"></a> <span class="kw">public</span>:</span>
<span id="cb76-8"><a href="#cb76-8" aria-hidden="true"></a>  <span class="kw">virtual</span> <span class="dt">void</span> draw(Canvas&amp;) <span class="at">const</span> = <span class="dv">0</span>;</span>
<span id="cb76-9"><a href="#cb76-9" aria-hidden="true"></a>};</span>
<span id="cb76-10"><a href="#cb76-10" aria-hidden="true"></a></span>
<span id="cb76-11"><a href="#cb76-11" aria-hidden="true"></a><span class="kw">class</span> Picture {</span>
<span id="cb76-12"><a href="#cb76-12" aria-hidden="true"></a>  <span class="bu">std::</span>vector&lt;polymorphic&lt;Shape&gt;&gt; <span class="va">shapes_</span>;</span>
<span id="cb76-13"><a href="#cb76-13" aria-hidden="true"></a></span>
<span id="cb76-14"><a href="#cb76-14" aria-hidden="true"></a> <span class="kw">public</span>:</span>
<span id="cb76-15"><a href="#cb76-15" aria-hidden="true"></a>  Picture(<span class="at">const</span> <span class="bu">std::</span>vector&lt;polymorphic&lt;Shape&gt;&gt;&amp; shapes)</span>
<span id="cb76-16"><a href="#cb76-16" aria-hidden="true"></a>      : <span class="va">shapes_</span>(shapes) {}</span>
<span id="cb76-17"><a href="#cb76-17" aria-hidden="true"></a></span>
<span id="cb76-18"><a href="#cb76-18" aria-hidden="true"></a>  <span class="co">// Picture(const Picture&amp; other) = default;</span></span>
<span id="cb76-19"><a href="#cb76-19" aria-hidden="true"></a></span>
<span id="cb76-20"><a href="#cb76-20" aria-hidden="true"></a>  <span class="co">// Picture&amp; operator=(const Picture&amp; other) = default;</span></span>
<span id="cb76-21"><a href="#cb76-21" aria-hidden="true"></a></span>
<span id="cb76-22"><a href="#cb76-22" aria-hidden="true"></a>  <span class="dt">void</span> draw(Canvas&amp; canvas) <span class="at">const</span>;</span>
<span id="cb76-23"><a href="#cb76-23" aria-hidden="true"></a>};</span></code></pre></div>
<h2 id="appendix-c-design-choices-alternatives-and-breaking-changes">Appendix C: Design choices, alternatives and breaking changes</h2>
<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 class="header">
<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 class="odd">
<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 class="even">
<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 class="odd">
<td><code>indirect</code> comparsion preconditions</td>
<td><code>indirect</code> must not be valueless</td>
<td>Allows comparison of valueless objects</td>
<td>Runtime cost</td>
<td style="text-align: center;">No</td>
</tr>
<tr class="even">
<td><code>indirect</code> hash preconditions</td>
<td><code>indirect</code> must not be valueless</td>
<td>Allows hash of valueless objects</td>
<td>Runtime cost</td>
<td style="text-align: center;">No</td>
</tr>
<tr class="odd">
<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 class="even">
<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 class="odd">
<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> or <em>Constraints</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 class="even">
<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 class="odd">
<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 class="even">
<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 class="odd">
<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 class="even">
<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 class="odd">
<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 class="even">
<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 class="odd">
<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 class="even">
<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 class="odd">
<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>
