<h1 id="indirect-and-polymorphic-vocabulary-types-for-composite-class-design"><code>indirect</code> and <code>polymorphic</code>: Vocabulary Types for Composite Class Design</h1>
<p>ISO/IEC JTC1 SC22 WG21 Programming Language C++</p>
<p>P3019R3</p>
<p>Working Group: Library Evolution, Library</p>
<p>Date: 2023-11-20</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 free-store-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 a parent object contains a member of type <code>indirect&lt;T&gt;</code> and is accessed through a const access path, <code>const</code>ness will propagate from the parent object to the instance of <code>T</code> owned by the <code>indirect</code> member.</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. A const <code>polymorphic&lt;T&gt;</code> propagates the constness to the owned <code>T</code>.</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-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; alloc)</code> overload.</p></li>
<li><p>Add discussion on similarities and dissimilarities 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 <memory> 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> is copy constructible where <code>T</code> is copy constructible and assignable.</p></li>
<li><p><code>polymorphic&lt;T, Alloc&gt;</code> is unconditionally copy constructible and assignable.</p></li>
<li><p><code>indirect&lt;T, Alloc&gt;</code> and <code>polymorphic&lt;T, Alloc&gt;</code> are unconditionally move constructible and 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 is dynamically-allocated (or some other memory resource controlled 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 other 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 onto the free store should not add or remove the ability to be default constructed.</p>
<p>Note that due to the requirement to support incomplete <code>T</code> types, the <code>indirect&lt;T&gt;</code> and <code>polymorphic&lt;T&gt;</code> types unconditionally have a default constructor (according to <code>std::is_default_constructible_v&lt;indirect&lt;T&gt;&gt;</code>). However, if <code>T</code> is not default constructible then attempting to odr-use the <code>indirect&lt;T&gt;</code> default constructor will be ill-formed.</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. Putting <code>T</code> onto the free store 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>
<p>We invite implementers to optimise their implementation of <code>optional&lt;indirect&gt;</code> and <code>optional&lt;polymorphic&gt;</code> to exploit the non-observable nature of the valueless state and minimise the size of an <code>optional&lt;indirect&gt;</code> or <code>optional&lt;polymorphic&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 move.</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 forwards comparison operators and hash to the underlying object.</p></li>
<li><p>Unlike <code>optional</code>, <code>indirect</code> is not observably valueless: use after move is undefined behaviour. Formatting is supported by <code>indirect</code> by forwarding to the owned object.</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 move.</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, hash or formatting 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.</p>
<p>Like <code>indirect</code>, a variant can get into a valueless state. For variant, 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 would necessitate the addition of an otherwise redundant check. Accessing a valueless <code>indirect</code> is undefined behaviour, so we make it a precondition for comparison and hash that the instance of <code>indirect</code> is not valueless.</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="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="cb3"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true"></a><span class="kw">class</span> PolymorphicInterface {</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true"></a>  <span class="kw">protected</span>:</span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true"></a>    PolymorphicInterface(<span class="at">const</span> PolymorphicInterface&amp;) = <span class="cf">default</span>;</span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true"></a>    ~PolymorphicInterface() = <span class="cf">default</span>;</span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true"></a>  <span class="kw">public</span>:</span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true"></a>   <span class="co">// virtual functions</span></span>
<span id="cb3-7"><a href="#cb3-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.syn">Header <code>&lt;memory&gt;</code> synopsis [memory.syn]</h3>
<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>  <span class="co">// [inout.ptr], function template inout_ptr</span></span>
<span id="cb5-2"><a href="#cb5-2" 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="cb5-3"><a href="#cb5-3" aria-hidden="true"></a>    <span class="kw">auto</span> inout_ptr(Smart&amp; s, Args&amp;&amp;... args);</span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true"></a></span>
<span id="cb5-5"><a href="#cb5-5" 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="cb5-6"><a href="#cb5-6" aria-hidden="true"></a>  <span class="co">// [indirect], class template indirect</span></span>
<span id="cb5-7"><a href="#cb5-7" 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="cb5-8"><a href="#cb5-8" aria-hidden="true"></a>    <span class="kw">class</span> indirect;</span>
<span id="cb5-9"><a href="#cb5-9" aria-hidden="true"></a></span>
<span id="cb5-10"><a href="#cb5-10" aria-hidden="true"></a>  <span class="co">// [indirect.hash], hash support</span></span>
<span id="cb5-11"><a href="#cb5-11" 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="cb5-12"><a href="#cb5-12" aria-hidden="true"></a></span>
<span id="cb5-13"><a href="#cb5-13" aria-hidden="true"></a>  <span class="co">// [indirect.format], formatting</span></span>
<span id="cb5-14"><a href="#cb5-14" aria-hidden="true"></a>  <span class="kw">template</span> &lt;<span class="kw">class</span> T, <span class="kw">class</span> Alloc, <span class="kw">class</span> charT&gt;</span>
<span id="cb5-15"><a href="#cb5-15" aria-hidden="true"></a>    <span class="kw">struct</span> formatter&lt;indirect&lt;T, Alloc&gt;, charT&gt;;</span>
<span id="cb5-16"><a href="#cb5-16" aria-hidden="true"></a></span>
<span id="cb5-17"><a href="#cb5-17" aria-hidden="true"></a>  <span class="co">// [polymorphic], class template polymorphic</span></span>
<span id="cb5-18"><a href="#cb5-18" 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="cb5-19"><a href="#cb5-19" aria-hidden="true"></a>    <span class="kw">class</span> polymorphic;</span>
<span id="cb5-20"><a href="#cb5-20" aria-hidden="true"></a></span>
<span id="cb5-21"><a href="#cb5-21" aria-hidden="true"></a>&lt;/ins&gt;</span>
<span id="cb5-22"><a href="#cb5-22" 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 <em>indirect value</em> is an object that manages the lifetime of an owned object. An indirect value object is <em>valueless</em> if it has no owned object. An indirect value may only become valueless after it has been moved from.</p></li>
<li><p>In every specialization <code>indirect&lt;T, Allocator&gt;</code>, the type <code>allocator_traits&lt;Allocator&gt;::value_type</code> shall be the same type as <code>T</code>. 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. The owned object is constructed using the function <code>allocator_traits&lt;allocator_type&gt;::rebind_traits&lt;U&gt;::construct</code> and destroyed using the function <code>allocator_traits&lt;allocator_type&gt;::rebind_traits&lt;U&gt;::destroy</code>, where <code>U</code> is either <code>allocator_type::value_type</code> or an internal type used by the indirect value.</p></li>
</ol>
<p>// DRAFTING NOTE: [indirect.general]#3 modeled on [container.reqmts]#64</p>
<ol start="3" type="1">
<li><p>Copy constructors for an indirect value 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 value being copied. Move constructors obtain an allocator by move construction from the allocator belonging to the container being moved. Such move construction of the allocator shall not exit via an exception. All other constructors for these container types 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 indirect 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</p>
<p>(3.1) <code>allocator_traits&lt;allocator_type&gt;::propagate_on_container_copy_assignment::value</code>,</p>
<p>(3.2) <code>allocator_traits&lt;allocator_type&gt;::propagate_on_container_move_assignment::value</code>,</p>
<p>(3.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 value operation.</p></li>
<li><p>The template parameter <code>T</code> of <code>indirect</code> shall be a non-union class type.</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="cb6"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb6-1"><a href="#cb6-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="cb6-2"><a href="#cb6-2" aria-hidden="true"></a><span class="kw">class</span> indirect {</span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true"></a>  pointer <span class="va">p_</span>; <span class="co">// exposition only</span></span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true"></a>  Allocator <span class="va">allocator_</span>; <span class="co">// exposition only</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="kw">using</span> <span class="dt">value_type</span> = T;</span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true"></a>  <span class="kw">using</span> <span class="dt">allocator_type</span> = Allocator;</span>
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true"></a>  <span class="kw">using</span> pointer = <span class="kw">typename</span> allocator_traits&lt;Allocator&gt;::pointer;</span>
<span id="cb6-9"><a href="#cb6-9" 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="cb6-10"><a href="#cb6-10" aria-hidden="true"></a></span>
<span id="cb6-11"><a href="#cb6-11" aria-hidden="true"></a>  <span class="kw">constexpr</span> indirect();</span>
<span id="cb6-12"><a href="#cb6-12" aria-hidden="true"></a></span>
<span id="cb6-13"><a href="#cb6-13" 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; alloc);</span>
<span id="cb6-14"><a href="#cb6-14" aria-hidden="true"></a></span>
<span id="cb6-15"><a href="#cb6-15" 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="cb6-16"><a href="#cb6-16" aria-hidden="true"></a>  <span class="kw">explicit</span> <span class="kw">constexpr</span> indirect(U&amp;&amp; u, Us&amp;&amp;... us);</span>
<span id="cb6-17"><a href="#cb6-17" aria-hidden="true"></a></span>
<span id="cb6-18"><a href="#cb6-18" 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="cb6-19"><a href="#cb6-19" 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; alloc,</span>
<span id="cb6-20"><a href="#cb6-20" aria-hidden="true"></a>                     U&amp;&amp; u, Us&amp;&amp;... us);</span>
<span id="cb6-21"><a href="#cb6-21" aria-hidden="true"></a></span>
<span id="cb6-22"><a href="#cb6-22" aria-hidden="true"></a>  <span class="kw">constexpr</span> indirect(<span class="at">const</span> indirect&amp; other);</span>
<span id="cb6-23"><a href="#cb6-23" aria-hidden="true"></a></span>
<span id="cb6-24"><a href="#cb6-24" aria-hidden="true"></a>  <span class="kw">constexpr</span> indirect(<span class="dt">allocator_arg_t</span>, <span class="at">const</span> Allocator&amp; alloc,</span>
<span id="cb6-25"><a href="#cb6-25" aria-hidden="true"></a>                     <span class="at">const</span> indirect&amp; other);</span>
<span id="cb6-26"><a href="#cb6-26" aria-hidden="true"></a></span>
<span id="cb6-27"><a href="#cb6-27" aria-hidden="true"></a>  <span class="kw">constexpr</span> indirect(indirect&amp;&amp; other) <span class="kw">noexcept</span>(see below);</span>
<span id="cb6-28"><a href="#cb6-28" aria-hidden="true"></a></span>
<span id="cb6-29"><a href="#cb6-29" aria-hidden="true"></a>  <span class="kw">constexpr</span> indirect(<span class="dt">allocator_arg_t</span>, <span class="at">const</span> Allocator&amp; alloc,</span>
<span id="cb6-30"><a href="#cb6-30" aria-hidden="true"></a>                     indirect&amp;&amp; other) <span class="kw">noexcept</span>(see below);</span>
<span id="cb6-31"><a href="#cb6-31" aria-hidden="true"></a></span>
<span id="cb6-32"><a href="#cb6-32" aria-hidden="true"></a>  <span class="kw">constexpr</span> ~indirect();</span>
<span id="cb6-33"><a href="#cb6-33" aria-hidden="true"></a></span>
<span id="cb6-34"><a href="#cb6-34" 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="cb6-35"><a href="#cb6-35" aria-hidden="true"></a></span>
<span id="cb6-36"><a href="#cb6-36" 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="cb6-37"><a href="#cb6-37" aria-hidden="true"></a></span>
<span id="cb6-38"><a href="#cb6-38" 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="cb6-39"><a href="#cb6-39" aria-hidden="true"></a></span>
<span id="cb6-40"><a href="#cb6-40" 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="cb6-41"><a href="#cb6-41" aria-hidden="true"></a></span>
<span id="cb6-42"><a href="#cb6-42" 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="cb6-43"><a href="#cb6-43" aria-hidden="true"></a></span>
<span id="cb6-44"><a href="#cb6-44" 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="cb6-45"><a href="#cb6-45" aria-hidden="true"></a></span>
<span id="cb6-46"><a href="#cb6-46" 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="cb6-47"><a href="#cb6-47" aria-hidden="true"></a></span>
<span id="cb6-48"><a href="#cb6-48" aria-hidden="true"></a>  <span class="kw">constexpr</span> pointer <span class="kw">operator</span>-&gt;() <span class="kw">noexcept</span>;</span>
<span id="cb6-49"><a href="#cb6-49" aria-hidden="true"></a></span>
<span id="cb6-50"><a href="#cb6-50" 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="cb6-51"><a href="#cb6-51" aria-hidden="true"></a></span>
<span id="cb6-52"><a href="#cb6-52" 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="cb6-53"><a href="#cb6-53" aria-hidden="true"></a></span>
<span id="cb6-54"><a href="#cb6-54" 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="cb6-55"><a href="#cb6-55" aria-hidden="true"></a></span>
<span id="cb6-56"><a href="#cb6-56" 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="cb6-57"><a href="#cb6-57" aria-hidden="true"></a></span>
<span id="cb6-58"><a href="#cb6-58" 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="cb6-59"><a href="#cb6-59" aria-hidden="true"></a>  <span class="kw">friend</span> <span class="kw">constexpr</span> <span class="kw">auto</span> <span class="kw">operator</span>==(</span>
<span id="cb6-60"><a href="#cb6-60" 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="cb6-61"><a href="#cb6-61" aria-hidden="true"></a></span>
<span id="cb6-62"><a href="#cb6-62" 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="cb6-63"><a href="#cb6-63" aria-hidden="true"></a>  <span class="kw">friend</span> <span class="kw">constexpr</span> <span class="kw">auto</span> <span class="kw">operator</span>!=(</span>
<span id="cb6-64"><a href="#cb6-64" 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="cb6-65"><a href="#cb6-65" aria-hidden="true"></a></span>
<span id="cb6-66"><a href="#cb6-66" 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="cb6-67"><a href="#cb6-67" 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;(</span>
<span id="cb6-68"><a href="#cb6-68" 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="cb6-69"><a href="#cb6-69" aria-hidden="true"></a></span>
<span id="cb6-70"><a href="#cb6-70" 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="cb6-71"><a href="#cb6-71" 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;=(</span>
<span id="cb6-72"><a href="#cb6-72" 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="cb6-73"><a href="#cb6-73" aria-hidden="true"></a></span>
<span id="cb6-74"><a href="#cb6-74" 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="cb6-75"><a href="#cb6-75" aria-hidden="true"></a>  <span class="kw">friend</span> <span class="kw">constexpr</span> <span class="kw">auto</span> <span class="kw">operator</span>&gt;(</span>
<span id="cb6-76"><a href="#cb6-76" 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="cb6-77"><a href="#cb6-77" aria-hidden="true"></a></span>
<span id="cb6-78"><a href="#cb6-78" 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="cb6-79"><a href="#cb6-79" aria-hidden="true"></a>  <span class="kw">friend</span> <span class="kw">constexpr</span> <span class="kw">auto</span> <span class="kw">operator</span>&gt;=(</span>
<span id="cb6-80"><a href="#cb6-80" 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="cb6-81"><a href="#cb6-81" aria-hidden="true"></a></span>
<span id="cb6-82"><a href="#cb6-82" 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="cb6-83"><a href="#cb6-83" 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="cb6-84"><a href="#cb6-84" 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="cb6-85"><a href="#cb6-85" aria-hidden="true"></a></span>
<span id="cb6-86"><a href="#cb6-86" aria-hidden="true"></a>  <span class="kw">template</span> &lt;<span class="kw">class</span> U&gt;</span>
<span id="cb6-87"><a href="#cb6-87" aria-hidden="true"></a>  <span class="kw">friend</span> <span class="kw">constexpr</span> <span class="kw">auto</span> <span class="kw">operator</span>==(</span>
<span id="cb6-88"><a href="#cb6-88" 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="cb6-89"><a href="#cb6-89" aria-hidden="true"></a></span>
<span id="cb6-90"><a href="#cb6-90" aria-hidden="true"></a>  <span class="kw">template</span> &lt;<span class="kw">class</span> U&gt;</span>
<span id="cb6-91"><a href="#cb6-91" aria-hidden="true"></a>  <span class="kw">friend</span> <span class="kw">constexpr</span> <span class="kw">auto</span> <span class="kw">operator</span>==(</span>
<span id="cb6-92"><a href="#cb6-92" aria-hidden="true"></a>    <span class="at">const</span> U&amp; lhs, <span class="at">const</span> indirect&amp; rhs) <span class="kw">noexcept</span>(see below);</span>
<span id="cb6-93"><a href="#cb6-93" aria-hidden="true"></a></span>
<span id="cb6-94"><a href="#cb6-94" aria-hidden="true"></a>  <span class="kw">template</span> &lt;<span class="kw">class</span> U&gt;</span>
<span id="cb6-95"><a href="#cb6-95" aria-hidden="true"></a>  <span class="kw">friend</span> <span class="kw">constexpr</span> <span class="kw">auto</span> <span class="kw">operator</span>!=(</span>
<span id="cb6-96"><a href="#cb6-96" 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="cb6-97"><a href="#cb6-97" aria-hidden="true"></a></span>
<span id="cb6-98"><a href="#cb6-98" aria-hidden="true"></a>  <span class="kw">template</span> &lt;<span class="kw">class</span> U&gt;</span>
<span id="cb6-99"><a href="#cb6-99" aria-hidden="true"></a>  <span class="kw">friend</span> <span class="kw">constexpr</span> <span class="kw">auto</span> <span class="kw">operator</span>!=(</span>
<span id="cb6-100"><a href="#cb6-100" aria-hidden="true"></a>    <span class="at">const</span> U&amp; lhs, <span class="at">const</span> indirect&amp; rhs) <span class="kw">noexcept</span>(see below);</span>
<span id="cb6-101"><a href="#cb6-101" aria-hidden="true"></a></span>
<span id="cb6-102"><a href="#cb6-102" aria-hidden="true"></a>  <span class="kw">template</span> &lt;<span class="kw">class</span> U&gt;</span>
<span id="cb6-103"><a href="#cb6-103" 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;(</span>
<span id="cb6-104"><a href="#cb6-104" 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="cb6-105"><a href="#cb6-105" aria-hidden="true"></a></span>
<span id="cb6-106"><a href="#cb6-106" aria-hidden="true"></a>  <span class="kw">template</span> &lt;<span class="kw">class</span> U&gt;</span>
<span id="cb6-107"><a href="#cb6-107" 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;(</span>
<span id="cb6-108"><a href="#cb6-108" aria-hidden="true"></a>    <span class="at">const</span> U&amp; lhs, <span class="at">const</span> indirect&amp; rhs) <span class="kw">noexcept</span>(see below);</span>
<span id="cb6-109"><a href="#cb6-109" aria-hidden="true"></a></span>
<span id="cb6-110"><a href="#cb6-110" aria-hidden="true"></a>  <span class="kw">template</span> &lt;<span class="kw">class</span> U&gt;</span>
<span id="cb6-111"><a href="#cb6-111" 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;=(</span>
<span id="cb6-112"><a href="#cb6-112" 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="cb6-113"><a href="#cb6-113" aria-hidden="true"></a></span>
<span id="cb6-114"><a href="#cb6-114" aria-hidden="true"></a>  <span class="kw">template</span> &lt;<span class="kw">class</span> U&gt;</span>
<span id="cb6-115"><a href="#cb6-115" 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;=(</span>
<span id="cb6-116"><a href="#cb6-116" aria-hidden="true"></a>    <span class="at">const</span> U&amp; lhs, <span class="at">const</span> indirect&amp; rhs) <span class="kw">noexcept</span>(see below);</span>
<span id="cb6-117"><a href="#cb6-117" aria-hidden="true"></a></span>
<span id="cb6-118"><a href="#cb6-118" aria-hidden="true"></a>  <span class="kw">template</span> &lt;<span class="kw">class</span> U&gt;</span>
<span id="cb6-119"><a href="#cb6-119" aria-hidden="true"></a>  <span class="kw">friend</span> <span class="kw">constexpr</span> <span class="kw">auto</span> <span class="kw">operator</span>&gt;(</span>
<span id="cb6-120"><a href="#cb6-120" 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="cb6-121"><a href="#cb6-121" aria-hidden="true"></a></span>
<span id="cb6-122"><a href="#cb6-122" aria-hidden="true"></a>  <span class="kw">template</span> &lt;<span class="kw">class</span> U&gt;</span>
<span id="cb6-123"><a href="#cb6-123" aria-hidden="true"></a>  <span class="kw">friend</span> <span class="kw">constexpr</span> <span class="kw">auto</span> <span class="kw">operator</span>&gt;(</span>
<span id="cb6-124"><a href="#cb6-124" aria-hidden="true"></a>    <span class="at">const</span> U&amp; lhs, <span class="at">const</span> indirect&amp; rhs) <span class="kw">noexcept</span>(see below);</span>
<span id="cb6-125"><a href="#cb6-125" aria-hidden="true"></a></span>
<span id="cb6-126"><a href="#cb6-126" aria-hidden="true"></a>  <span class="kw">template</span> &lt;<span class="kw">class</span> U&gt;</span>
<span id="cb6-127"><a href="#cb6-127" aria-hidden="true"></a>  <span class="kw">friend</span> <span class="kw">constexpr</span> <span class="kw">auto</span> <span class="kw">operator</span>&gt;=(</span>
<span id="cb6-128"><a href="#cb6-128" 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="cb6-129"><a href="#cb6-129" aria-hidden="true"></a></span>
<span id="cb6-130"><a href="#cb6-130" aria-hidden="true"></a>  <span class="kw">template</span> &lt;<span class="kw">class</span> U&gt;</span>
<span id="cb6-131"><a href="#cb6-131" aria-hidden="true"></a>  <span class="kw">friend</span> <span class="kw">constexpr</span> <span class="kw">auto</span> <span class="kw">operator</span>&gt;=(</span>
<span id="cb6-132"><a href="#cb6-132" aria-hidden="true"></a>    <span class="at">const</span> U&amp; lhs, <span class="at">const</span> indirect&amp; rhs) <span class="kw">noexcept</span>(see below);</span>
<span id="cb6-133"><a href="#cb6-133" aria-hidden="true"></a></span>
<span id="cb6-134"><a href="#cb6-134" aria-hidden="true"></a>  <span class="kw">template</span> &lt;<span class="kw">class</span> U&gt;</span>
<span id="cb6-135"><a href="#cb6-135" 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="cb6-136"><a href="#cb6-136" 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="cb6-137"><a href="#cb6-137" aria-hidden="true"></a></span>
<span id="cb6-138"><a href="#cb6-138" aria-hidden="true"></a>  <span class="kw">template</span> &lt;<span class="kw">class</span> U&gt;</span>
<span id="cb6-139"><a href="#cb6-139" 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="cb6-140"><a href="#cb6-140" aria-hidden="true"></a>    <span class="at">const</span> U&amp; lhs, <span class="at">const</span> indirect&amp; rhs) <span class="kw">noexcept</span>(see below);</span>
<span id="cb6-141"><a href="#cb6-141" aria-hidden="true"></a>};</span>
<span id="cb6-142"><a href="#cb6-142" aria-hidden="true"></a></span>
<span id="cb6-143"><a href="#cb6-143" aria-hidden="true"></a><span class="kw">template</span> &lt;<span class="kw">typename</span> Value&gt;</span>
<span id="cb6-144"><a href="#cb6-144" aria-hidden="true"></a>indirect(Value) -&gt; indirect&lt;Value&gt;;</span>
<span id="cb6-145"><a href="#cb6-145" aria-hidden="true"></a></span>
<span id="cb6-146"><a href="#cb6-146" aria-hidden="true"></a><span class="kw">template</span> &lt;<span class="kw">typename</span> Alloc, <span class="kw">typename</span> Value&gt;</span>
<span id="cb6-147"><a href="#cb6-147" aria-hidden="true"></a>indirect(<span class="bu">std::</span>allocator_arg_t, Alloc, Value) -&gt; indirect&lt;</span>
<span id="cb6-148"><a href="#cb6-148" aria-hidden="true"></a>    Value, <span class="kw">typename</span> <span class="bu">std::</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>
<div class="sourceCode" id="cb7"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb7-1"><a href="#cb7-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>Mandates</em>: <code>is_default_constructible_v&lt;T&gt;</code> is true.</p></li>
<li><p><em>Effects</em>: Constructs an <code>indirect</code> owning a uses-allocator constructed <code>T</code> and stores the address in <code>p_</code>. <code>allocator_</code> is default constructed.</p></li>
<li><p><em>Postconditions</em>: <code>*this</code> is not valueless.</p></li>
<li><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></li>
</ol>
<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">explicit</span> <span class="kw">constexpr</span> indirect(<span class="dt">allocator_arg_t</span>, <span class="at">const</span> Allocator&amp; alloc);</span></code></pre></div>
<ol start="5" type="1">
<li><p><em>Mandates</em>: <code>is_default_constructible_v&lt;T&gt;</code> is <code>true</code>.</p></li>
<li><p><em>Effects</em>: Constructs an <code>indirect</code> owning a uses-allocator constructed <code>T</code> and stores the address in <code>p_</code>. <code>allocator_</code> is direct-non-list-initialized with <code>alloc</code>.</p></li>
<li><p><em>Postconditions</em>: <code>*this</code> is not valueless.</p></li>
<li><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></li>
</ol>
<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> U, <span class="kw">class</span>... Us&gt;</span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true"></a><span class="kw">explicit</span> <span class="kw">constexpr</span> indirect(U&amp;&amp; u, Us&amp;&amp;... us);</span></code></pre></div>
<ol start="9" type="1">
<li><p><em>Constraints</em>: <code>is_constructible_v&lt;T, U, Us...&gt;</code> is <code>true</code>. <code>is_same_v&lt;remove_cvref_t&lt;U&gt;, allocator_arg&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>Effects</em>: Equivalent to <code>indirect(allocator_arg_t{}, Allocator(), std::forward&lt;U&gt;(u), std::forward&lt;Us&gt;(us)...)</code>.</p></li>
</ol>
<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">template</span> &lt;<span class="kw">class</span> U, <span class="kw">class</span>... Us&gt;</span>
<span id="cb10-2"><a href="#cb10-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; alloc, U&amp;&amp; u, Us&amp;&amp; ...us);</span></code></pre></div>
<ol start="11" type="1">
<li><p><em>Constraints</em>: <code>is_constructible_v&lt;T, U, Us...&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>Effects</em>: <code>allocator_</code> is direct-non-list-initialized with <code>alloc</code>.</p>
<p>DRAFTING NOTE: based on https://eel.is/c++draft/func.wrap#func.con-6</p></li>
<li><p><em>Postconditions</em>: <code>*this</code> is not valueless. <code>p_</code> targets an object of type <code>T</code> uses-allocator constructed with <code>std::forward&lt;U&gt;(u)</code>, <code>std::forward&lt;Us&gt;(us)...</code>.</p></li>
</ol>
<div class="sourceCode" id="cb11"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true"></a><span class="kw">constexpr</span> indirect(<span class="at">const</span> indirect&amp; other);</span></code></pre></div>
<ol start="14" type="1">
<li><p><em>Mandates</em>: <code>is_copy_constructible_v&lt;T&gt;</code> is <code>true</code>.</p></li>
<li><p><em>Preconditions</em>: <code>other</code> is not valueless.</p></li>
<li><p><em>Effects</em>: Equivalent to <code>indirect(allocator_arg, allocator_traits&lt;allocator_type&gt;::select_on_container_copy_construction(other.get_allocator()), *other)</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="dt">allocator_arg_t</span>, <span class="at">const</span> Allocator&amp; alloc,</span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true"></a>                   <span class="at">const</span> indirect&amp; other);</span></code></pre></div>
<ol start="18" type="1">
<li><p><em>Mandates</em>: <code>is_copy_constructible_v&lt;T&gt;</code> is <code>true</code>.</p></li>
<li><p><em>Preconditions</em>: <code>other</code> is not valueless.</p></li>
<li><p><em>Effects</em>: Equivalent to <code>indirect(allocator_arg, alloc, *other)</code>.</p></li>
<li><p><em>Postconditions</em>: <code>*this</code> is not valueless.</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(indirect&amp;&amp; other) <span class="kw">noexcept</span>;</span></code></pre></div>
<ol start="22" type="1">
<li><p><em>Preconditions</em>: <code>other</code> is not valueless. <em>[Note: This constructor does not require that <code>is_move_constructible_v&lt;T&gt;</code> is <code>true</code> –end note]</em></p></li>
<li><p><em>Effects</em>: Constructs an <code>indirect</code> that takes ownership of the <code>other</code>’s owned object and stores the address in <code>p_</code>. <code>allocator_</code> is initialized by construction from <code>other.allocator_</code>.</p></li>
<li><p><em>Postconditions</em>: <code>other</code> is valueless.</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(<span class="dt">allocator_arg_t</span>, <span class="at">const</span> Allocator&amp; alloc, indirect&amp;&amp; other)</span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true"></a>  <span class="kw">noexcept</span>(allocator_traits&lt;Allocator&gt;::is_always_equal);</span></code></pre></div>
<ol start="25" type="1">
<li><p><em>Preconditions</em>: <code>other</code> is not valueless. <em>[Note: This constructor does not require that <code>is_move_constructible_v&lt;T&gt;</code> is <code>true</code> –end note]</em></p></li>
<li><p><em>Effects</em>: If <code>alloc == other.get_allocator()</code> is <code>true</code> then equivalent to <code>indirect(std::move(other))</code>, otherwise, equivalent to <code>indirect(allocator_arg, alloc, *std::move(other))</code>.</p></li>
<li><p><em>Postconditions</em>: <code>other</code> is valueless.</p></li>
</ol>
<h4 id="x.y.4-destructor-indirect.dtor">X.Y.4 Destructor [indirect.dtor]</h4>
<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></code></pre></div>
<ol type="1">
<li><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 deallocates the storage using <code>allocator_traits&lt;allocator_type&gt;::deallocate</code>.</li>
</ol>
<h4 id="x.y.5-assignment-indirect.assign">X.Y.5 Assignment [indirect.assign]</h4>
<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">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>is_copy_constructible_v&lt;T&gt;</code> is <code>true</code>.</p></li>
<li><p><em>Preconditions</em>: <code>other</code> is not valueless.</p></li>
<li><p><em>Effects</em>: If <code>this == &amp;other</code> is <code>true</code>, then has no effects. Otherwise, if either:</p></li>
</ol>
<ul>
<li><code>is_copy_assignable_v&lt;T&gt;</code> is <code>false</code> and <code>is_nothrow_copy_constructible_v&lt;T&gt;</code> is <code>false</code>, or</li>
<li><code>allocator_traits&lt;allocator_type&gt;::propagate_on_container_copy_assignment::value</code> is <code>true</code> and <code>allocator_ == other.allocator_</code> is <code>false</code>, or</li>
<li><code>*this</code> is valueless then, equivalent to <code>*this = indirect(allocator_arg, allocator_traits&lt;allocator_type&gt;::propagate_on_container_copy_assignment::value ? other.allocator_ : allocator_, *other)</code> Otherwise, if <code>is_copy_assignable_v&lt;T&gt;</code> is <code>true</code>, then equivalent to <code>**this = *other</code>, Otherwise, equivalent to:</li>
<li><code>(allocator_traits&lt;allocator_type&gt;::destruct(alloc_, p_), allocator_traits&lt;allocator_type&gt;::construct(alloc_, p_, *other))</code></li>
</ul>
<ol start="4" type="1">
<li><p><em>Postconditions</em>: <code>*this</code> is not valueless.</p></li>
<li><p><em>Returns</em>: A reference to <code>*this</code>.</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">constexpr</span> indirect&amp; <span class="kw">operator</span>=(indirect&amp;&amp; other) <span class="kw">noexcept</span>(</span>
<span id="cb17-2"><a href="#cb17-2" aria-hidden="true"></a>    allocator_traits&lt;Allocator&gt;::propagate_on_container_move_assignment::value ||</span>
<span id="cb17-3"><a href="#cb17-3" aria-hidden="true"></a>    allocator_traits&lt;Allocator&gt;::is_always_equal::value);</span></code></pre></div>
<p><em>Mandates</em>: <code>is_move_constructible_v&lt;T&gt;</code> is <code>true</code>.</p>
<ol start="6" type="1">
<li><p><em>Preconditions</em>: <code>other</code> is not valueless.</p></li>
<li><p><em>Effects</em>: If <code>&amp;other == this</code>, then has no effects. Otherwise, if <code>allocator_traits&lt;allocator_type&gt;::propagate_on_container_move_assignment::value   == true</code>, <code>allocator_</code> is set to the allocator of <code>other</code>. If allocator is propagated or is equal to the allocator of <code>other</code>, destroys the owned object, if any, then takes ownership of the object owned by <code>other</code>. Otherwise, destroys the owned object if any, then move constructs an object from the object owned by <code>other</code>.</p></li>
<li><p><em>Postconditions</em>: <code>*this</code> is not valueless. <code>other</code> is valueless.</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="cb18"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb18-1"><a href="#cb18-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="cb18-2"><a href="#cb18-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="cb19"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb19-1"><a href="#cb19-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="cb19-2"><a href="#cb19-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="cb20"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb20-1"><a href="#cb20-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="cb20-2"><a href="#cb20-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="cb21"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb21-1"><a href="#cb21-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="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> <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>: A copy of the <code>Allocator</code> object used to construct the owned object.</li>
</ol>
<h4 id="x.y.7-swap-indirect.swap">X.Y.7 Swap [indirect.swap]</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> <span class="dt">void</span> swap(indirect&amp; other) <span class="kw">noexcept</span>(</span>
<span id="cb23-2"><a href="#cb23-2" aria-hidden="true"></a>  allocator_traits::propagate_on_container_swap::value</span>
<span id="cb23-3"><a href="#cb23-3" aria-hidden="true"></a>  || allocator_traits::is_always_equal::value);</span></code></pre></div>
<ol type="1">
<li><p><em>Preconditions</em>: <code>*this</code> is not valueless, <code>other</code> is not valueless.</p></li>
<li><p><em>Effects</em>: Swaps the objects owned by <code>*this</code> and <code>other</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>. <em>[Note: Does not call <code>swap</code> on the owned objects directly. –end note]</em></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> <span class="dt">void</span> swap(indirect&amp; lhs, indirect&amp; rhs) <span class="kw">noexcept</span>(</span>
<span id="cb24-2"><a href="#cb24-2" aria-hidden="true"></a>  <span class="kw">noexcept</span>(lhs.swap(rhs)));</span></code></pre></div>
<ol start="4" type="1">
<li><em>Effects</em>: Equivalent to <code>lhs.swap(rhs)</code>.</li>
</ol>
<h4 id="x.y.8-relational-operators-indirect.rel">X.Y.8 Relational operators [indirect.rel]</h4>
<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, <span class="kw">class</span> AA&gt;</span>
<span id="cb25-2"><a href="#cb25-2" aria-hidden="true"></a><span class="kw">constexpr</span> <span class="kw">auto</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="cb25-3"><a href="#cb25-3" aria-hidden="true"></a>  <span class="kw">noexcept</span>(<span class="kw">noexcept</span>(*lhs == *rhs));</span></code></pre></div>
<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">template</span> &lt;<span class="kw">class</span> U, <span class="kw">class</span> AA&gt;</span>
<span id="cb26-2"><a href="#cb26-2" aria-hidden="true"></a><span class="kw">constexpr</span> <span class="kw">auto</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="cb26-3"><a href="#cb26-3" aria-hidden="true"></a>  <span class="kw">noexcept</span>(<span class="kw">noexcept</span>(*lhs != *rhs));</span></code></pre></div>
<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">template</span> &lt;<span class="kw">class</span> U, <span class="kw">class</span> AA&gt;</span>
<span id="cb27-2"><a href="#cb27-2" aria-hidden="true"></a><span class="kw">constexpr</span> <span class="kw">auto</span> <span class="kw">operator</span>&lt;(<span class="at">const</span> indirect&amp; lhs, <span class="at">const</span> indirect&lt;U, AA&gt;&amp; rhs)</span>
<span id="cb27-3"><a href="#cb27-3" aria-hidden="true"></a>  <span class="kw">noexcept</span>(<span class="kw">noexcept</span>(*lhs &lt; *rhs));</span></code></pre></div>
<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">template</span> &lt;<span class="kw">class</span> U, <span class="kw">class</span> AA&gt;</span>
<span id="cb28-2"><a href="#cb28-2" aria-hidden="true"></a><span class="kw">constexpr</span> <span class="kw">auto</span> <span class="kw">operator</span>&lt;=(<span class="at">const</span> indirect&amp; lhs, <span class="at">const</span> indirect&lt;U, AA&gt;&amp; rhs)</span>
<span id="cb28-3"><a href="#cb28-3" aria-hidden="true"></a>  <span class="kw">noexcept</span>(<span class="kw">noexcept</span>(*lhs &lt;= *rhs));</span></code></pre></div>
<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">template</span> &lt;<span class="kw">class</span> U, <span class="kw">class</span> AA&gt;</span>
<span id="cb29-2"><a href="#cb29-2" aria-hidden="true"></a><span class="kw">constexpr</span> <span class="kw">auto</span> <span class="kw">operator</span>&gt;(<span class="at">const</span> indirect&amp; lhs, <span class="at">const</span> indirect&lt;U, AA&gt;&amp; rhs)</span>
<span id="cb29-3"><a href="#cb29-3" aria-hidden="true"></a>  <span class="kw">noexcept</span>(<span class="kw">noexcept</span>(*lhs &gt; *rhs));</span></code></pre></div>
<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">template</span> &lt;<span class="kw">class</span> U, <span class="kw">class</span> AA&gt;</span>
<span id="cb30-2"><a href="#cb30-2" aria-hidden="true"></a><span class="kw">constexpr</span> <span class="kw">auto</span> <span class="kw">operator</span>&gt;=(<span class="at">const</span> indirect&amp; lhs, <span class="at">const</span> indirect&lt;U, AA&gt;&amp; rhs)</span>
<span id="cb30-3"><a href="#cb30-3" aria-hidden="true"></a>  <span class="kw">noexcept</span>(<span class="kw">noexcept</span>(*lhs &gt;= *rhs));</span></code></pre></div>
<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">template</span> &lt;<span class="kw">class</span> U, <span class="kw">class</span> AA&gt;</span>
<span id="cb31-2"><a href="#cb31-2" aria-hidden="true"></a><span class="kw">constexpr</span> <span class="kw">auto</span> <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="cb31-3"><a href="#cb31-3" aria-hidden="true"></a>  <span class="kw">noexcept</span>(<span class="kw">noexcept</span>(*lhs &lt;=&gt; *rhs));</span></code></pre></div>
<ol type="1">
<li><p><em>Constraints</em>: <code>*lhs</code> <em>op</em> <code>*rhs</code> is well-formed.</p></li>
<li><p><em>Preconditions</em>: <code>lhs</code> is not valueless, <code>rhs</code> is not valueless.</p></li>
<li><p><em>Effects</em>: Returns <code>*lhs</code> <em>op</em> <code>*rhs</code>.</p></li>
<li><p><em>Remarks</em>: Specializations of this function template for which <code>*lhs</code> <em>op</em> <code>*rhs</code> is a core constant expression are constexpr functions.</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="cb32"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb32-1"><a href="#cb32-1" aria-hidden="true"></a><span class="kw">template</span> &lt;<span class="kw">class</span> U&gt;</span>
<span id="cb32-2"><a href="#cb32-2" aria-hidden="true"></a><span class="kw">constexpr</span> <span class="kw">auto</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="cb32-3"><a href="#cb32-3" aria-hidden="true"></a>  <span class="kw">noexcept</span>(<span class="kw">noexcept</span>(*lhs == rhs));</span></code></pre></div>
<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&gt;</span>
<span id="cb33-2"><a href="#cb33-2" aria-hidden="true"></a><span class="kw">constexpr</span> <span class="kw">auto</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="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>
<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&gt;</span>
<span id="cb34-2"><a href="#cb34-2" aria-hidden="true"></a><span class="kw">constexpr</span> <span class="kw">auto</span> <span class="kw">operator</span>&lt;(<span class="at">const</span> indirect&amp; lhs, <span class="at">const</span> U&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>(*lhs &lt; rhs));</span></code></pre></div>
<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="kw">auto</span> <span class="kw">operator</span>&lt;=(<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 &lt;= rhs));</span></code></pre></div>
<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> <span class="kw">auto</span> <span class="kw">operator</span>&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>(*lhs &gt; rhs));</span></code></pre></div>
<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> U&gt;</span>
<span id="cb37-2"><a href="#cb37-2" aria-hidden="true"></a><span class="kw">constexpr</span> <span class="kw">auto</span> <span class="kw">operator</span>&gt;=(<span class="at">const</span> indirect&amp; lhs, <span class="at">const</span> U&amp; rhs)</span>
<span id="cb37-3"><a href="#cb37-3" aria-hidden="true"></a>  <span class="kw">noexcept</span>(<span class="kw">noexcept</span>(*lhs &gt;= rhs));</span></code></pre></div>
<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> U&gt;</span>
<span id="cb38-2"><a href="#cb38-2" aria-hidden="true"></a><span class="kw">constexpr</span> <span class="kw">auto</span> <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="cb38-3"><a href="#cb38-3" aria-hidden="true"></a>  <span class="kw">noexcept</span>(<span class="kw">noexcept</span>(*lhs &lt;=&gt; rhs));</span></code></pre></div>
<ol type="1">
<li><p><em>Constraints</em>: <code>*lhs</code> <em>op</em> <code>rhs</code> is well-formed.</p></li>
<li><p><em>Preconditions</em>: <code>lhs</code> is not valueless.</p></li>
<li><p><em>Effects</em>: Returns <code>*lhs</code> <em>op</em> <code>rhs</code>.</p></li>
<li><p><em>Remarks</em>: Specializations of this function template for which <code>*lhs</code> <em>op</em> <code>rhs</code> is a core constant expression, are constexpr functions.</p></li>
</ol>
<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">template</span> &lt;<span class="kw">class</span> U&gt;</span>
<span id="cb39-2"><a href="#cb39-2" aria-hidden="true"></a><span class="kw">constexpr</span> <span class="kw">auto</span> <span class="kw">operator</span>==(<span class="at">const</span> U&amp; lhs, <span class="at">const</span> indirect&amp; rhs)</span>
<span id="cb39-3"><a href="#cb39-3" aria-hidden="true"></a>  <span class="kw">noexcept</span>(<span class="kw">noexcept</span>(lhs == *rhs));</span></code></pre></div>
<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">template</span> &lt;<span class="kw">class</span> U&gt;</span>
<span id="cb40-2"><a href="#cb40-2" aria-hidden="true"></a><span class="kw">constexpr</span> <span class="kw">auto</span> <span class="kw">operator</span>!=(<span class="at">const</span> U&amp; lhs, <span class="at">const</span> indirect&amp; rhs)</span>
<span id="cb40-3"><a href="#cb40-3" aria-hidden="true"></a>  <span class="kw">noexcept</span>(<span class="kw">noexcept</span>(lhs != *rhs));</span></code></pre></div>
<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">template</span> &lt;<span class="kw">class</span> U&gt;</span>
<span id="cb41-2"><a href="#cb41-2" aria-hidden="true"></a><span class="kw">constexpr</span> <span class="kw">auto</span> <span class="kw">operator</span>&lt;(<span class="at">const</span> U&amp; lhs, <span class="at">const</span> indirect&amp; rhs)</span>
<span id="cb41-3"><a href="#cb41-3" aria-hidden="true"></a>  <span class="kw">noexcept</span>(<span class="kw">noexcept</span>(lhs &lt; *rhs));</span></code></pre></div>
<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">template</span> &lt;<span class="kw">class</span> U&gt;</span>
<span id="cb42-2"><a href="#cb42-2" aria-hidden="true"></a><span class="kw">constexpr</span> <span class="kw">auto</span> <span class="kw">operator</span>&lt;=(<span class="at">const</span> U&amp; lhs, <span class="at">const</span> indirect&amp; rhs)</span>
<span id="cb42-3"><a href="#cb42-3" aria-hidden="true"></a>  <span class="kw">noexcept</span>(<span class="kw">noexcept</span>(lhs &lt;= *rhs));</span></code></pre></div>
<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">template</span> &lt;<span class="kw">class</span> U&gt;</span>
<span id="cb43-2"><a href="#cb43-2" aria-hidden="true"></a><span class="kw">constexpr</span> <span class="kw">auto</span> <span class="kw">operator</span>&gt;(<span class="at">const</span> U&amp; lhs, <span class="at">const</span> indirect&amp; rhs)</span>
<span id="cb43-3"><a href="#cb43-3" aria-hidden="true"></a>  <span class="kw">noexcept</span>(<span class="kw">noexcept</span>(lhs &gt; *rhs));</span></code></pre></div>
<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">template</span> &lt;<span class="kw">class</span> U&gt;</span>
<span id="cb44-2"><a href="#cb44-2" aria-hidden="true"></a><span class="kw">constexpr</span> <span class="kw">auto</span> <span class="kw">operator</span>&gt;=<span class="at">const</span> U&amp; lhs, <span class="at">const</span> indirect&amp; rhs)</span>
<span id="cb44-3"><a href="#cb44-3" aria-hidden="true"></a>  <span class="kw">noexcept</span>(<span class="kw">noexcept</span>(lhs &gt;= *rhs));</span></code></pre></div>
<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&gt;</span>
<span id="cb45-2"><a href="#cb45-2" aria-hidden="true"></a><span class="kw">constexpr</span> <span class="kw">auto</span> <span class="kw">operator</span>&lt;=&gt;(<span class="at">const</span> U&amp; lhs, <span class="at">const</span> indirect&amp; rhs)</span>
<span id="cb45-3"><a href="#cb45-3" aria-hidden="true"></a>  <span class="kw">noexcept</span>(<span class="kw">noexcept</span>(lhs &lt;=&gt; *rhs));</span></code></pre></div>
<ol start="5" type="1">
<li><p><em>Constraints</em>: <code>lhs</code> <em>op</em> <code>*rhs</code> is well-formed.</p></li>
<li><p><em>Preconditions</em>: <code>rhs</code> is not valueless.</p></li>
<li><p><em>Effects</em>: Returns <code>lhs</code> <em>op</em> <code>*rhs</code>.</p></li>
<li><p><em>Remarks</em>: Specializations of this function template for which <code>lhs</code> <em>op</em> <code>*rhs</code> is a core constant expression, are constexpr functions.</p></li>
</ol>
<h4 id="x.y.10-hash-support-indirect.hash">X.Y.10 Hash support [indirect.hash]</h4>
<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> T, <span class="kw">class</span> Alloc&gt;</span>
<span id="cb46-2"><a href="#cb46-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><p>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 the same value as <code>hash&lt;remove_const_t&lt;T&gt;&gt;()(*i)</code>. The member functions are not guaranteed to be noexcept.</p></li>
<li><p><em>Preconditions</em>: <code>i</code> is not valueless.</p></li>
</ol>
<h4 id="x.y.11-formatter-support-indirect.format">X.Y.11 Formatter support [indirect.format]</h4>
<p>DRAFTING NOTE: following [time.format] precedent for formatting</p>
<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="co">// [indirect.format]</span></span>
<span id="cb47-2"><a href="#cb47-2" aria-hidden="true"></a><span class="kw">template</span> &lt;<span class="kw">class</span> T, <span class="kw">class</span> Alloc, <span class="kw">class</span> charT&gt;</span>
<span id="cb47-3"><a href="#cb47-3" aria-hidden="true"></a><span class="kw">struct</span> formatter&lt;indirect&lt;T, Alloc&gt;, charT&gt; : formatter&lt;T, charT&gt; {</span>
<span id="cb47-4"><a href="#cb47-4" aria-hidden="true"></a>  <span class="kw">template</span>&lt;<span class="kw">class</span> ParseContext&gt;</span>
<span id="cb47-5"><a href="#cb47-5" aria-hidden="true"></a>  <span class="kw">constexpr</span> <span class="kw">typename</span> ParseContext::iterator parse(ParseContext&amp; ctx);</span>
<span id="cb47-6"><a href="#cb47-6" aria-hidden="true"></a></span>
<span id="cb47-7"><a href="#cb47-7" aria-hidden="true"></a>  <span class="kw">template</span>&lt;<span class="kw">class</span> FormatContext&gt;</span>
<span id="cb47-8"><a href="#cb47-8" aria-hidden="true"></a>  <span class="kw">typename</span> FormatContext::iterator format(</span>
<span id="cb47-9"><a href="#cb47-9" aria-hidden="true"></a>    <span class="at">const</span> indirect&lt;T, Alloc&gt;&amp; value, FormatContext&amp; ctx) <span class="at">const</span>;</span>
<span id="cb47-10"><a href="#cb47-10" aria-hidden="true"></a>};</span></code></pre></div>
<ol type="1">
<li>Specializations of <code>formatter&lt;indirect&lt;T, Alloc&gt;, charT&gt;</code> are enabled if and only if <code>formatter&lt;T, charT&gt;</code> is enabled.</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> FormatContext&gt;</span>
<span id="cb48-2"><a href="#cb48-2" aria-hidden="true"></a>  <span class="kw">typename</span> FormatContext::iterator</span>
<span id="cb48-3"><a href="#cb48-3" aria-hidden="true"></a>    format(<span class="at">const</span> indirect&lt;T, Alloc&gt;&amp; value, FormatContext&amp; ctx) <span class="at">const</span>;</span></code></pre></div>
<ol start="2" type="1">
<li>Preconditions: <code>value</code> is not valueless. The specialization <code>formatter&lt;T,   charT&gt;</code> meets the <em>Formatter</em> requirements [formatter.requirements].</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 <em>polymorphic value</em> is an object that manages the lifetime of an owned object. A polymorphic value object may own objects of different types at different points in its lifetime. A polymorphic value object is <em>valueless</em> if it has no owned object. A polymorphic value may only become valueless after it has been moved from.</p></li>
<li><p>In every specialization <code>polymorphic&lt;T, Allocator&gt;</code>, the type <code>allocator_traits&lt;Allocator&gt;::value_type</code> shall be the same type as <code>T</code>. 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. The owned object is constructed using the function <code>allocator_traits&lt;allocator_type&gt;::rebind_traits&lt;U&gt;::construct</code> and destroyed using the function <code>allocator_traits&lt;allocator_type&gt;::rebind_traits&lt;U&gt;::destroy</code>, where <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 value 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 value being copied. Move constructors obtain an allocator by move construction from the allocator belonging to the container being moved. Such move construction of the allocator shall not exit via an exception. All other constructors for these container types take a <code>const allocator_type&amp; argument</code>. [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] 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 (64.1) <code>allocator_traits&lt;allocator_type&gt;::propagate_on_container_copy_assignment::value</code>, (64.2) <code>allocator_traits&lt;allocator_type&gt;::propagate_on_container_move_assignment::value</code>, or (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></li>
<li><p>The template parameter <code>T</code> of <code>polymorphic</code> shall be a non-union class type.</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="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> T, <span class="kw">class</span> Allocator = allocator&lt;T&gt;&gt;</span>
<span id="cb49-2"><a href="#cb49-2" aria-hidden="true"></a><span class="kw">class</span> polymorphic {</span>
<span id="cb49-3"><a href="#cb49-3" aria-hidden="true"></a>  Allocator <span class="va">allocator_</span>; <span class="co">// exposition only</span></span>
<span id="cb49-4"><a href="#cb49-4" aria-hidden="true"></a> <span class="kw">public</span>:</span>
<span id="cb49-5"><a href="#cb49-5" aria-hidden="true"></a>  <span class="kw">using</span> <span class="dt">value_type</span> = T;</span>
<span id="cb49-6"><a href="#cb49-6" aria-hidden="true"></a>  <span class="kw">using</span> <span class="dt">allocator_type</span> = Allocator;</span>
<span id="cb49-7"><a href="#cb49-7" aria-hidden="true"></a>  <span class="kw">using</span> pointer = <span class="kw">typename</span> allocator_traits&lt;Allocator&gt;::pointer;</span>
<span id="cb49-8"><a href="#cb49-8" 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="cb49-9"><a href="#cb49-9" aria-hidden="true"></a></span>
<span id="cb49-10"><a href="#cb49-10" aria-hidden="true"></a>  <span class="kw">explicit</span> <span class="kw">constexpr</span> polymorphic();</span>
<span id="cb49-11"><a href="#cb49-11" aria-hidden="true"></a></span>
<span id="cb49-12"><a href="#cb49-12" 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; alloc);</span>
<span id="cb49-13"><a href="#cb49-13" aria-hidden="true"></a></span>
<span id="cb49-14"><a href="#cb49-14" 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="cb49-15"><a href="#cb49-15" 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="cb49-16"><a href="#cb49-16" aria-hidden="true"></a></span>
<span id="cb49-17"><a href="#cb49-17" 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="cb49-18"><a href="#cb49-18" 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; alloc,</span>
<span id="cb49-19"><a href="#cb49-19" aria-hidden="true"></a>                        <span class="dt">in_place_type_t</span>&lt;U&gt;, Ts&amp;&amp;... ts);</span>
<span id="cb49-20"><a href="#cb49-20" aria-hidden="true"></a></span>
<span id="cb49-21"><a href="#cb49-21" aria-hidden="true"></a>  <span class="kw">constexpr</span> polymorphic(<span class="at">const</span> polymorphic&amp; other);</span>
<span id="cb49-22"><a href="#cb49-22" aria-hidden="true"></a></span>
<span id="cb49-23"><a href="#cb49-23" aria-hidden="true"></a>  <span class="kw">constexpr</span> polymorphic(<span class="dt">allocator_arg_t</span>, <span class="at">const</span> Allocator&amp; alloc,</span>
<span id="cb49-24"><a href="#cb49-24" aria-hidden="true"></a>                        <span class="at">const</span> polymorphic&amp; other);</span>
<span id="cb49-25"><a href="#cb49-25" aria-hidden="true"></a></span>
<span id="cb49-26"><a href="#cb49-26" aria-hidden="true"></a>  <span class="kw">constexpr</span> polymorphic(polymorphic&amp;&amp; other) <span class="kw">noexcept</span>(see below);</span>
<span id="cb49-27"><a href="#cb49-27" aria-hidden="true"></a></span>
<span id="cb49-28"><a href="#cb49-28" aria-hidden="true"></a>  <span class="kw">constexpr</span> polymorphic(<span class="dt">allocator_arg_t</span>, <span class="at">const</span> Allocator&amp; alloc,</span>
<span id="cb49-29"><a href="#cb49-29" aria-hidden="true"></a>                        polymorphic&amp;&amp; other) <span class="kw">noexcept</span>(see below);</span>
<span id="cb49-30"><a href="#cb49-30" aria-hidden="true"></a></span>
<span id="cb49-31"><a href="#cb49-31" aria-hidden="true"></a>  <span class="kw">constexpr</span> ~polymorphic();</span>
<span id="cb49-32"><a href="#cb49-32" aria-hidden="true"></a></span>
<span id="cb49-33"><a href="#cb49-33" 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="cb49-34"><a href="#cb49-34" aria-hidden="true"></a></span>
<span id="cb49-35"><a href="#cb49-35" 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="cb49-36"><a href="#cb49-36" aria-hidden="true"></a></span>
<span id="cb49-37"><a href="#cb49-37" 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="cb49-38"><a href="#cb49-38" aria-hidden="true"></a></span>
<span id="cb49-39"><a href="#cb49-39" aria-hidden="true"></a>  <span class="kw">constexpr</span> T&amp; <span class="kw">operator</span>*() <span class="kw">noexcept</span>;</span>
<span id="cb49-40"><a href="#cb49-40" aria-hidden="true"></a></span>
<span id="cb49-41"><a href="#cb49-41" 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="cb49-42"><a href="#cb49-42" aria-hidden="true"></a></span>
<span id="cb49-43"><a href="#cb49-43" aria-hidden="true"></a>  <span class="kw">constexpr</span> pointer <span class="kw">operator</span>-&gt;() <span class="kw">noexcept</span>;</span>
<span id="cb49-44"><a href="#cb49-44" aria-hidden="true"></a></span>
<span id="cb49-45"><a href="#cb49-45" 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="cb49-46"><a href="#cb49-46" aria-hidden="true"></a></span>
<span id="cb49-47"><a href="#cb49-47" 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="cb49-48"><a href="#cb49-48" aria-hidden="true"></a></span>
<span id="cb49-49"><a href="#cb49-49" 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="cb49-50"><a href="#cb49-50" aria-hidden="true"></a></span>
<span id="cb49-51"><a href="#cb49-51" 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="cb49-52"><a href="#cb49-52" aria-hidden="true"></a>                             polymorphic&amp; rhs) <span class="kw">noexcept</span>(see below);</span>
<span id="cb49-53"><a href="#cb49-53" aria-hidden="true"></a>};</span></code></pre></div>
<h4 id="x.z.3-constructors-polymorphic.ctor">X.Z.3 Constructors [polymorphic.ctor]</h4>
<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">explicit</span> <span class="kw">constexpr</span> polymorphic()</span></code></pre></div>
<ol type="1">
<li><p><em>Mandates</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>Effects</em>: Constructs a polymorphic owning a uses-allocator constructed <code>T</code>. <code>allocator_</code> is default constructed.</p></li>
<li><p><em>Postconditions</em>: <code>*this</code> is not valueless.</p></li>
<li><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></li>
</ol>
<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">explicit</span> <span class="kw">constexpr</span> polymorphic(<span class="dt">allocator_arg_t</span>, <span class="at">const</span> Allocator&amp; alloc);</span></code></pre></div>
<ol start="5" type="1">
<li><p><em>Mandates</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>Effects</em>: Constructs a polymorphic owning a uses-allocator constructed <code>T</code>. <code>allocator_</code> is direct-non-list-initialized with alloc.</p></li>
<li><p><em>Postconditions</em>: <code>*this</code> is not valueless.</p></li>
<li><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></li>
</ol>
<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">template</span> &lt;<span class="kw">class</span> U, <span class="kw">class</span>... Ts&gt;</span>
<span id="cb52-2"><a href="#cb52-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="9" type="1">
<li><em>Effects</em>: Equivalent to <code>polymorphic(allocator_arg_t{}, Allocator(), in_place_type_t&lt;U&gt;{}, std::forward&lt;Ts&gt;(ts)...)</code>.</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">template</span> &lt;<span class="kw">class</span> U, <span class="kw">class</span>... Ts&gt;</span>
<span id="cb53-2"><a href="#cb53-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; alloc,</span>
<span id="cb53-3"><a href="#cb53-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="10" 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>Effects</em>: <code>allocator_</code> is direct-non-list-initialized with alloc.</p></li>
<li><p><em>Postconditions</em>: <code>*this</code> is not valueless. The owned instance targets an object of type <code>U</code> uses-allocator constructed with <code>std::forward&lt;Ts&gt;(ts)...</code>.</p></li>
</ol>
<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> polymorphic(<span class="at">const</span> polymorphic&amp; other);</span></code></pre></div>
<ol start="13" type="1">
<li><em>Effects</em>: Equivalent to <code>polymorphic(allocator_arg_t{}, allocator_traits&lt;allocator_type&gt;::select_on_container_copy_construction(other.alloc_), other)</code>.</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> polymorphic(<span class="dt">allocator_arg_t</span>, <span class="at">const</span> Allocator&amp; alloc,</span>
<span id="cb55-2"><a href="#cb55-2" aria-hidden="true"></a>                      <span class="at">const</span> polymorphic&amp; other);</span></code></pre></div>
<ol start="14" type="1">
<li><p><em>Preconditions</em>: <code>other</code> is not valueless.</p></li>
<li><p><em>Effects</em>: Constructs a polymorphic owning an instance of <code>T</code> created with the copy constructor of the object owned by <code>other</code>. <code>allocator_</code> is direct-non-list-initialized with alloc.</p></li>
<li><p><em>Postconditions</em>: <code>*this</code> is not valueless.</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> polymorphic(polymorphic&amp;&amp; other) <span class="kw">noexcept</span>;</span></code></pre></div>
<ol start="17" type="1">
<li><em>Effects</em>: Equivalent to <code>polymorphic(allocator_arg_t{}, Allocator(std::move(other.alloc_)), other)</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> polymorphic(<span class="dt">allocator_arg_t</span>, <span class="at">const</span> Allocator&amp; alloc,</span>
<span id="cb57-2"><a href="#cb57-2" aria-hidden="true"></a>                      polymorphic&amp;&amp; other) <span class="kw">noexcept</span>;</span></code></pre></div>
<ol start="18" type="1">
<li><p><em>Preconditions</em>: <code>other</code> is not valueless. <em>[Note: This constructor does not require that <code>is_move_constructible_v&lt;T&gt;</code> is <code>true</code>. –end note]</em></p></li>
<li><p><em>Effects</em>: Constructs a polymorphic that takes ownership of the object owned by <code>other</code>. <code>allocator_</code> is direct-non-list-initialized with <code>alloc</code>.</p></li>
<li><p><em>Postconditions</em>: <code>other</code> is valueless.</p></li>
</ol>
<h4 id="x.z.4-destructor-polymorphic.dtor">X.Z.4 Destructor [polymorphic.dtor]</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> ~polymorphic();</span></code></pre></div>
<ol type="1">
<li><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 deallocates the storage using <code>allocator_traits&lt;allocator_type&gt;::deallocate</code>.</li>
</ol>
<h4 id="x.z.5-assignment-polymorphic.assign">X.Z.5 Assignment [polymorphic.assign]</h4>
<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> 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>Preconditions</em>: <code>other</code> is not valueless.</p></li>
<li><p><em>Effects</em>: If <code>&amp;other == this</code>, then has no effects. Otherwise, if <code>*this</code> is not valueless, destroys the owned object. If <code>allocator_traits&lt;allocator_type&gt;::propagate_on_container_copy_assignment::value   == true</code>, <code>allocator_</code> is set to the allocator of <code>other</code>. Copy constructs a new object using the object owned by <code>other</code>.</p></li>
<li><p><em>Postconditions</em>: <code>*this</code> is not valueless.</p></li>
</ol>
<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">constexpr</span> polymorphic&amp; <span class="kw">operator</span>=(polymorphic&amp;&amp; other) <span class="kw">noexcept</span>(</span>
<span id="cb60-2"><a href="#cb60-2" aria-hidden="true"></a>    allocator_traits&lt;Allocator&gt;::propagate_on_container_move_assignment::value ||</span>
<span id="cb60-3"><a href="#cb60-3" aria-hidden="true"></a>    allocator_traits&lt;Allocator&gt;::is_always_equal::value);</span></code></pre></div>
<ol start="4" type="1">
<li><p><em>Preconditions</em>: <code>other</code> is not valueless.</p></li>
<li><p><em>Effects</em>: If <code>&amp;other == this</code>, then has no effects. Otherwise, if <code>allocator_traits&lt;allocator_type&gt;::propagate_on_container_move_assignment::value   == true</code>, <code>allocator_</code> is set to the allocator of <code>other</code>. If allocator is propagated or is equal to the allocator of <code>other</code>, destroys the owned object if any, then takes ownership of the object owned by <code>other</code>. Otherwise, destroys the owned object if any, then move constructs an object from the object owned by <code>other</code>.</p></li>
<li><p><em>Postconditions</em>: <code>*this</code> is not valueless. <code>other</code> is valueless.</p></li>
</ol>
<h4 id="x.z.6-observers-polymorphic.observers">X.Z.6 Observers [polymorphic.observers]</h4>
<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><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="cb61-2"><a href="#cb61-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>Effects</em>: Returns a reference to the owned object.</p></li>
</ol>
<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><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="cb62-2"><a href="#cb62-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>Effects</em>: Returns a pointer to the owned object.</p></li>
</ol>
<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><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="cb64"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb64-1"><a href="#cb64-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>: A copy of the <code>Allocator</code> object used to construct the owned object.</li>
</ol>
<h4 id="x.z.7-swap-polymorphic.swap">X.Z.7 Swap [polymorphic.swap]</h4>
<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><span class="kw">constexpr</span> <span class="dt">void</span> swap(polymorphic&amp; other) <span class="kw">noexcept</span>(</span>
<span id="cb65-2"><a href="#cb65-2" aria-hidden="true"></a>  allocator_traits::propagate_on_container_swap::value</span>
<span id="cb65-3"><a href="#cb65-3" aria-hidden="true"></a>  || allocator_traits::is_always_equal::value);</span></code></pre></div>
<ol type="1">
<li><p><em>Preconditions</em>: <code>*this</code> is not valueless, <code>other</code> is not valueless.</p></li>
<li><p><em>Effects</em>: Swaps the objects owned by <code>*this</code> and <code>other</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 swapped, and the behavior is undefined unless <code>(*this).get_allocator() == other.get_allocator()</code>. <em>[Note: Does not call <code>swap</code> on the owned objects directly. –end note]</em></p></li>
</ol>
<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">constexpr</span> <span class="dt">void</span> swap(polymorphic&amp; lhs, polymorphic&amp; rhs) <span class="kw">noexcept</span>(</span>
<span id="cb66-2"><a href="#cb66-2" aria-hidden="true"></a>  <span class="kw">noexcept</span>(lhs.swap(rhs)));</span></code></pre></div>
<ol start="3" 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 [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 [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 [https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1950r2.html]</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="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 the free store and memory allocation, which is best made explicit by the user.</p>
<div class="sourceCode" id="cb67"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb67-1"><a href="#cb67-1" aria-hidden="true"></a>Rectangle r(w, h);</span>
<span id="cb67-2"><a href="#cb67-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="cb68"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb68-1"><a href="#cb68-1" aria-hidden="true"></a>Rectangle r(w, h);</span>
<span id="cb68-2"><a href="#cb68-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="cb68-3"><a href="#cb68-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="cb69"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb69-1"><a href="#cb69-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="cb69-2"><a href="#cb69-2" aria-hidden="true"></a>polymorphic_value&lt;Shape&gt; s = q;</span>
<span id="cb69-3"><a href="#cb69-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="cb70"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb70-1"><a href="#cb70-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="cb70-2"><a href="#cb70-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-returning-auto">Comparisons returning <code>auto</code></h3>
<p>We opt to return <code>auto</code> from comparison operators on <code>indirect&lt;T&gt;</code> so that the return type perfectly matches that of the underlying comparison for <code>T</code>. While deferring the return type to the underlying type does support unusual user-defined comparison operators, we prefer to do so rather than impose requirements on the user-defined operators for consistency. Adoption of indirect or moving an object onto the heap should not be impeded by unusual choices for the return type of comparison operators on user-defined types.</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="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="cb71"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb71-1"><a href="#cb71-1" aria-hidden="true"></a><span class="kw">template</span> &lt;<span class="kw">typename</span> ...Ts&gt;</span>
<span id="cb71-2"><a href="#cb71-2" aria-hidden="true"></a>indirect::emplace(Ts&amp;&amp; ...ts);</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="kw">template</span> &lt;<span class="kw">typename</span> U, <span class="kw">typename</span> ...Ts&gt;</span>
<span id="cb72-2"><a href="#cb72-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="cb73"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb73-1"><a href="#cb73-1" aria-hidden="true"></a>some_indirect = indirect(<span class="co">/* arguments */</span>);</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>some_polymorphic = polymorphic(<span class="dt">in_place_type</span>&lt;U&gt;, <span class="co">/* arguments */</span>);</span></code></pre></div>
<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 heap 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="cb75"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb75-1"><a href="#cb75-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="cb75-2"><a href="#cb75-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="cb76"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb76-1"><a href="#cb76-1" aria-hidden="true"></a><span class="co">// Class.h</span></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> Class {</span>
<span id="cb76-4"><a href="#cb76-4" aria-hidden="true"></a>  <span class="kw">class</span> Impl;</span>
<span id="cb76-5"><a href="#cb76-5" aria-hidden="true"></a>  <span class="bu">std::</span>unique_ptr&lt;Impl&gt; <span class="va">impl_</span>;</span>
<span id="cb76-6"><a href="#cb76-6" aria-hidden="true"></a> <span class="kw">public</span>:</span>
<span id="cb76-7"><a href="#cb76-7" aria-hidden="true"></a>  Class();</span>
<span id="cb76-8"><a href="#cb76-8" aria-hidden="true"></a>  ~Class();</span>
<span id="cb76-9"><a href="#cb76-9" aria-hidden="true"></a>  Class(<span class="at">const</span> Class&amp;);</span>
<span id="cb76-10"><a href="#cb76-10" aria-hidden="true"></a>  Class&amp; <span class="kw">operator</span>=(<span class="at">const</span> Class&amp;);</span>
<span id="cb76-11"><a href="#cb76-11" aria-hidden="true"></a>  Class(Class&amp;&amp;) <span class="kw">noexcept</span>;</span>
<span id="cb76-12"><a href="#cb76-12" aria-hidden="true"></a>  Class&amp; <span class="kw">operator</span>=(Class&amp;&amp;) <span class="kw">noexcept</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="dt">void</span> do_something();</span>
<span id="cb76-15"><a href="#cb76-15" aria-hidden="true"></a>};</span></code></pre></div>
<div class="sourceCode" id="cb77"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb77-1"><a href="#cb77-1" aria-hidden="true"></a><span class="co">// Class.cpp</span></span>
<span id="cb77-2"><a href="#cb77-2" aria-hidden="true"></a></span>
<span id="cb77-3"><a href="#cb77-3" aria-hidden="true"></a><span class="kw">class</span> Impl {</span>
<span id="cb77-4"><a href="#cb77-4" aria-hidden="true"></a> <span class="kw">public</span>:</span>
<span id="cb77-5"><a href="#cb77-5" aria-hidden="true"></a>  <span class="dt">void</span> do_something();</span>
<span id="cb77-6"><a href="#cb77-6" aria-hidden="true"></a>};</span>
<span id="cb77-7"><a href="#cb77-7" aria-hidden="true"></a></span>
<span id="cb77-8"><a href="#cb77-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="cb77-9"><a href="#cb77-9" aria-hidden="true"></a></span>
<span id="cb77-10"><a href="#cb77-10" aria-hidden="true"></a>Class::~Class() = <span class="cf">default</span>;</span>
<span id="cb77-11"><a href="#cb77-11" aria-hidden="true"></a></span>
<span id="cb77-12"><a href="#cb77-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="cb77-13"><a href="#cb77-13" aria-hidden="true"></a></span>
<span id="cb77-14"><a href="#cb77-14" aria-hidden="true"></a>Class&amp; Class::<span class="kw">operator</span>=(<span class="at">const</span> Class&amp; other) {</span>
<span id="cb77-15"><a href="#cb77-15" aria-hidden="true"></a>  <span class="cf">if</span> (<span class="kw">this</span> != &amp;other) {</span>
<span id="cb77-16"><a href="#cb77-16" aria-hidden="true"></a>    Class tmp(other);</span>
<span id="cb77-17"><a href="#cb77-17" aria-hidden="true"></a>    <span class="kw">using</span> <span class="bu">std::</span>swap;</span>
<span id="cb77-18"><a href="#cb77-18" aria-hidden="true"></a>    swap(*<span class="kw">this</span>, tmp);</span>
<span id="cb77-19"><a href="#cb77-19" aria-hidden="true"></a>  }</span>
<span id="cb77-20"><a href="#cb77-20" aria-hidden="true"></a>  <span class="cf">return</span> *<span class="kw">this</span>;</span>
<span id="cb77-21"><a href="#cb77-21" aria-hidden="true"></a>}</span>
<span id="cb77-22"><a href="#cb77-22" aria-hidden="true"></a></span>
<span id="cb77-23"><a href="#cb77-23" aria-hidden="true"></a>Class(Class&amp;&amp;) <span class="kw">noexcept</span> = <span class="cf">default</span>;</span>
<span id="cb77-24"><a href="#cb77-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="cb77-25"><a href="#cb77-25" aria-hidden="true"></a></span>
<span id="cb77-26"><a href="#cb77-26" aria-hidden="true"></a><span class="dt">void</span> Class::do_something() {</span>
<span id="cb77-27"><a href="#cb77-27" aria-hidden="true"></a>  <span class="va">impl_</span>-&gt;do_something();</span>
<span id="cb77-28"><a href="#cb77-28" aria-hidden="true"></a>}</span></code></pre></div>
<h4 id="after-using-indirect">After, using <code>indirect</code></h4>
<div class="sourceCode" id="cb78"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb78-1"><a href="#cb78-1" aria-hidden="true"></a><span class="co">// Class.h</span></span>
<span id="cb78-2"><a href="#cb78-2" aria-hidden="true"></a></span>
<span id="cb78-3"><a href="#cb78-3" aria-hidden="true"></a><span class="kw">class</span> Class {</span>
<span id="cb78-4"><a href="#cb78-4" aria-hidden="true"></a>  indirect&lt;<span class="kw">class</span> Impl&gt; <span class="va">impl_</span>;</span>
<span id="cb78-5"><a href="#cb78-5" aria-hidden="true"></a> <span class="kw">public</span>:</span>
<span id="cb78-6"><a href="#cb78-6" aria-hidden="true"></a>  Class();</span>
<span id="cb78-7"><a href="#cb78-7" aria-hidden="true"></a>  ~Class();</span>
<span id="cb78-8"><a href="#cb78-8" aria-hidden="true"></a>  Class(<span class="at">const</span> Class&amp;);</span>
<span id="cb78-9"><a href="#cb78-9" aria-hidden="true"></a>  Class&amp; <span class="kw">operator</span>=(<span class="at">const</span> Class&amp;);</span>
<span id="cb78-10"><a href="#cb78-10" aria-hidden="true"></a>  Class(Class&amp;&amp;) <span class="kw">noexcept</span>;</span>
<span id="cb78-11"><a href="#cb78-11" aria-hidden="true"></a>  Class&amp; <span class="kw">operator</span>=(Class&amp;&amp;) <span class="kw">noexcept</span>;</span>
<span id="cb78-12"><a href="#cb78-12" aria-hidden="true"></a></span>
<span id="cb78-13"><a href="#cb78-13" aria-hidden="true"></a>  <span class="dt">void</span> do_something();</span>
<span id="cb78-14"><a href="#cb78-14" aria-hidden="true"></a>};</span></code></pre></div>
<div class="sourceCode" id="cb79"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb79-1"><a href="#cb79-1" aria-hidden="true"></a><span class="co">// Class.cpp</span></span>
<span id="cb79-2"><a href="#cb79-2" aria-hidden="true"></a></span>
<span id="cb79-3"><a href="#cb79-3" aria-hidden="true"></a><span class="kw">class</span> Impl {</span>
<span id="cb79-4"><a href="#cb79-4" aria-hidden="true"></a> <span class="kw">public</span>:</span>
<span id="cb79-5"><a href="#cb79-5" aria-hidden="true"></a>  <span class="dt">void</span> do_something();</span>
<span id="cb79-6"><a href="#cb79-6" aria-hidden="true"></a>};</span>
<span id="cb79-7"><a href="#cb79-7" aria-hidden="true"></a></span>
<span id="cb79-8"><a href="#cb79-8" aria-hidden="true"></a>Class::Class() : <span class="va">impl_</span>(indirect&lt;Impl&gt;()) {}</span>
<span id="cb79-9"><a href="#cb79-9" aria-hidden="true"></a>Class::~Class() = <span class="cf">default</span>;</span>
<span id="cb79-10"><a href="#cb79-10" aria-hidden="true"></a>Class::Class(<span class="at">const</span> Class&amp;) = <span class="cf">default</span>;</span>
<span id="cb79-11"><a href="#cb79-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="cb79-12"><a href="#cb79-12" aria-hidden="true"></a>Class(Class&amp;&amp;) <span class="kw">noexcept</span> = <span class="cf">default</span>;</span>
<span id="cb79-13"><a href="#cb79-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="cb79-14"><a href="#cb79-14" aria-hidden="true"></a></span>
<span id="cb79-15"><a href="#cb79-15" aria-hidden="true"></a><span class="dt">void</span> Class::do_something() {</span>
<span id="cb79-16"><a href="#cb79-16" aria-hidden="true"></a>  <span class="va">impl_</span>-&gt;do_something();</span>
<span id="cb79-17"><a href="#cb79-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="cb80"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb80-1"><a href="#cb80-1" aria-hidden="true"></a><span class="kw">class</span> Canvas;</span>
<span id="cb80-2"><a href="#cb80-2" aria-hidden="true"></a></span>
<span id="cb80-3"><a href="#cb80-3" aria-hidden="true"></a><span class="kw">class</span> Shape {</span>
<span id="cb80-4"><a href="#cb80-4" aria-hidden="true"></a> <span class="kw">public</span>:</span>
<span id="cb80-5"><a href="#cb80-5" aria-hidden="true"></a>  <span class="kw">virtual</span> ~Shape() = <span class="cf">default</span>;</span>
<span id="cb80-6"><a href="#cb80-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="cb80-7"><a href="#cb80-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="cb80-8"><a href="#cb80-8" aria-hidden="true"></a>};</span>
<span id="cb80-9"><a href="#cb80-9" aria-hidden="true"></a></span>
<span id="cb80-10"><a href="#cb80-10" aria-hidden="true"></a><span class="kw">class</span> Picture {</span>
<span id="cb80-11"><a href="#cb80-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="cb80-12"><a href="#cb80-12" aria-hidden="true"></a></span>
<span id="cb80-13"><a href="#cb80-13" aria-hidden="true"></a> <span class="kw">public</span>:</span>
<span id="cb80-14"><a href="#cb80-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="cb80-15"><a href="#cb80-15" aria-hidden="true"></a>    <span class="va">shapes_</span>.reserve(shapes.size());</span>
<span id="cb80-16"><a href="#cb80-16" aria-hidden="true"></a>    <span class="cf">for</span> (<span class="kw">auto</span>&amp; shape : shapes) {</span>
<span id="cb80-17"><a href="#cb80-17" aria-hidden="true"></a>      <span class="va">shapes_</span>.push_back(shape-&gt;clone());</span>
<span id="cb80-18"><a href="#cb80-18" aria-hidden="true"></a>    }</span>
<span id="cb80-19"><a href="#cb80-19" aria-hidden="true"></a>  }</span>
<span id="cb80-20"><a href="#cb80-20" aria-hidden="true"></a></span>
<span id="cb80-21"><a href="#cb80-21" aria-hidden="true"></a>  Picture(<span class="at">const</span> Picture&amp; other) {</span>
<span id="cb80-22"><a href="#cb80-22" aria-hidden="true"></a>    <span class="va">shapes_</span>.reserve(other.<span class="va">shapes_</span>.size());</span>
<span id="cb80-23"><a href="#cb80-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="cb80-24"><a href="#cb80-24" aria-hidden="true"></a>      <span class="va">shapes_</span>.push_back(shape-&gt;clone());</span>
<span id="cb80-25"><a href="#cb80-25" aria-hidden="true"></a>    }</span>
<span id="cb80-26"><a href="#cb80-26" aria-hidden="true"></a>  }</span>
<span id="cb80-27"><a href="#cb80-27" aria-hidden="true"></a></span>
<span id="cb80-28"><a href="#cb80-28" aria-hidden="true"></a>  Picture&amp; <span class="kw">operator</span>=(<span class="at">const</span> Picture&amp; other) {</span>
<span id="cb80-29"><a href="#cb80-29" aria-hidden="true"></a>    <span class="cf">if</span> (<span class="kw">this</span> != &amp;other) {</span>
<span id="cb80-30"><a href="#cb80-30" aria-hidden="true"></a>      Picture tmp(other);</span>
<span id="cb80-31"><a href="#cb80-31" aria-hidden="true"></a>      <span class="kw">using</span> <span class="bu">std::</span>swap;</span>
<span id="cb80-32"><a href="#cb80-32" aria-hidden="true"></a>      swap(*<span class="kw">this</span>, tmp);</span>
<span id="cb80-33"><a href="#cb80-33" aria-hidden="true"></a>    }</span>
<span id="cb80-34"><a href="#cb80-34" aria-hidden="true"></a>    <span class="cf">return</span> *<span class="kw">this</span>;</span>
<span id="cb80-35"><a href="#cb80-35" aria-hidden="true"></a>  }</span>
<span id="cb80-36"><a href="#cb80-36" aria-hidden="true"></a></span>
<span id="cb80-37"><a href="#cb80-37" aria-hidden="true"></a>  <span class="dt">void</span> draw(Canvas&amp; canvas) <span class="at">const</span>;</span>
<span id="cb80-38"><a href="#cb80-38" aria-hidden="true"></a>};</span></code></pre></div>
<h4 id="after-using-polymorphic">After, using <code>polymorphic</code></h4>
<div class="sourceCode" id="cb81"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb81-1"><a href="#cb81-1" aria-hidden="true"></a><span class="kw">class</span> Canvas;</span>
<span id="cb81-2"><a href="#cb81-2" aria-hidden="true"></a></span>
<span id="cb81-3"><a href="#cb81-3" aria-hidden="true"></a><span class="kw">class</span> Shape {</span>
<span id="cb81-4"><a href="#cb81-4" aria-hidden="true"></a> <span class="kw">protected</span>:</span>
<span id="cb81-5"><a href="#cb81-5" aria-hidden="true"></a>  ~Shape() = <span class="cf">default</span>;</span>
<span id="cb81-6"><a href="#cb81-6" aria-hidden="true"></a></span>
<span id="cb81-7"><a href="#cb81-7" aria-hidden="true"></a> <span class="kw">public</span>:</span>
<span id="cb81-8"><a href="#cb81-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="cb81-9"><a href="#cb81-9" aria-hidden="true"></a>};</span>
<span id="cb81-10"><a href="#cb81-10" aria-hidden="true"></a></span>
<span id="cb81-11"><a href="#cb81-11" aria-hidden="true"></a><span class="kw">class</span> Picture {</span>
<span id="cb81-12"><a href="#cb81-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="cb81-13"><a href="#cb81-13" aria-hidden="true"></a></span>
<span id="cb81-14"><a href="#cb81-14" aria-hidden="true"></a> <span class="kw">public</span>:</span>
<span id="cb81-15"><a href="#cb81-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="cb81-16"><a href="#cb81-16" aria-hidden="true"></a>      : <span class="va">shapes_</span>(shapes) {}</span>
<span id="cb81-17"><a href="#cb81-17" aria-hidden="true"></a></span>
<span id="cb81-18"><a href="#cb81-18" aria-hidden="true"></a>  <span class="co">// Picture(const Picture&amp; other) = default;</span></span>
<span id="cb81-19"><a href="#cb81-19" aria-hidden="true"></a></span>
<span id="cb81-20"><a href="#cb81-20" aria-hidden="true"></a>  <span class="co">// Picture&amp; operator=(const Picture&amp; other) = default;</span></span>
<span id="cb81-21"><a href="#cb81-21" aria-hidden="true"></a></span>
<span id="cb81-22"><a href="#cb81-22" aria-hidden="true"></a>  <span class="dt">void</span> draw(Canvas&amp; canvas) <span class="at">const</span>;</span>
<span id="cb81-23"><a href="#cb81-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 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: 20%" />
<col style="width: 20%" />
<col style="width: 20%" />
<col style="width: 20%" />
<col style="width: 20%" />
</colgroup>
<thead>
<tr class="header">
<th>Component</th>
<th>Decision</th>
<th>Alternative</th>
<th>Change impact</th>
<th>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>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>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>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>No</td>
</tr>
<tr class="odd">
<td><code>indirect</code> format preconditions</td>
<td><code>indirect</code> must not be valueless</td>
<td>Allows formatting of valueless objects</td>
<td>Runtime cost</td>
<td>No</td>
</tr>
<tr class="even">
<td>Copy and copy assign preconditions</td>
<td>Object must not be valueless</td>
<td>Allows copying of valueless objects</td>
<td>Runtime cost</td>
<td>No</td>
</tr>
<tr class="odd">
<td>Move and move assign preconditions</td>
<td>Object must not be valueless</td>
<td>Allows moving of valueless objects</td>
<td>Runtime cost</td>
<td>No</td>
</tr>
<tr class="even">
<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>Yes</td>
</tr>
<tr class="odd">
<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>Yes</td>
</tr>
<tr class="even">
<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>Yes</td>
</tr>
<tr class="odd">
<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>Yes</td>
</tr>
<tr class="even">
<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>Yes</td>
</tr>
<tr class="odd">
<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>No</td>
</tr>
</tbody>
</table>
