<h1 id="a-polymorphic-value-type-for-c">A polymorphic value-type for <code>C++</code></h1>
<p>ISO/IEC JTC1 SC22 WG21 Programming Language <code>C++</code></p>
<p>P0201R5</p>
<p>Working Group: Library Evolution, Library</p>
<p>Date: 2019-03-11</p>
<p><em>Jonathan Coe &lt;jonathanbcoe@gmail.com&gt;</em></p>
<p><em>Sean Parent &lt;sparent@adobe.com&gt;</em></p>
<h2 id="change-history">Change history</h2>
<p>Changes in P0201R5</p>
<ul>
<li><p>Make constructor of <code>default_copy</code> <code>noexcept</code> and <code>constexpr</code>.</p></li>
<li><p>Clarifications to formal wording.</p></li>
</ul>
<p>Changes in P0201R4</p>
<ul>
<li><p>Clarify authors’ agreement with LEWG design changes.</p></li>
<li><p>Add wording to clarify meaning of custom copier and deleter.</p></li>
<li><p>Make constructors explicit and remove converting assignment.</p></li>
<li><p>Add a second template parameter to <code>make_polymorphic_value</code> to facilitate construction of objects of derived classes.</p></li>
</ul>
<p>Changes in P0201R3</p>
<ul>
<li>Add rationale for absence of allocator support.</li>
</ul>
<p>Changes in P0201R2</p>
<ul>
<li><p>Change name to <code>polymorphic_value</code>.</p></li>
<li><p>Remove <code>operator &lt;&lt;</code>.</p></li>
<li><p>Add construction and assignment from values.</p></li>
<li><p>Use <code>std::default_delete</code>.</p></li>
<li><p>Rename <code>std::default_copier</code> to <code>std::default_copy</code>.</p></li>
<li><p>Add notes on empty state and pointer constructor.</p></li>
<li><p>Add <code>bad_polymorphic_value_construction</code> exception when static and dynamic type of pointee mismatch and no custom copier or deleter are supplied.</p></li>
<li><p>Add clarifying note to say that a small object optimisation is allowed.</p></li>
</ul>
<p>Changes in P0201R1</p>
<ul>
<li><p>Change name to <code>indirect</code>.</p></li>
<li><p>Remove <code>static_cast</code>, <code>dynamic_cast</code> and <code>const_cast</code> as <code>polymorphic_value</code> is modelled on a value not a pointer.</p></li>
<li><p>Add <code>const</code> accessors which return <code>const</code> references/pointers.</p></li>
<li><p>Remove pointer-accessor <code>get</code>.</p></li>
<li><p>Remove specialization of <code>propagate_const</code>.</p></li>
<li><p>Amended authorship and acknowledgements.</p></li>
<li><p>Added support for custom copiers and custom deleters.</p></li>
<li><p>Removed hash and comparison operators.</p></li>
</ul>
<h2 id="tldr">TL;DR</h2>
<p>Add a class template, <code>polymorphic_value&lt;T&gt;</code>, to the standard library to support polymorphic objects with value-like semantics.</p>
<h2 id="introduction">Introduction</h2>
<p>The class template, <code>polymorphic_value</code>, confers value-like semantics on a free-store allocated object. A <code>polymorphic_value&lt;T&gt;</code> may hold an object of a class publicly derived from T, and copying the <code>polymorphic_value&lt;T&gt;</code> will copy the object of the derived type.</p>
<h2 id="motivation-composite-objects">Motivation: Composite objects</h2>
<p>Use of components in the design of object-oriented class hierarchies can aid modular design as components can be potentially re-used as building-blocks for other composite classes.</p>
<p>We can write a simple composite object formed from two components as follows:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode cpp"><code class="sourceCode cpp"><a class="sourceLine" id="cb1-1" title="1"></a>
<a class="sourceLine" id="cb1-2" title="2"><span class="co">// Simple composite</span></a>
<a class="sourceLine" id="cb1-3" title="3"><span class="kw">class</span> CompositeObject_1 {</a>
<a class="sourceLine" id="cb1-4" title="4">  Component1 <span class="va">c1_</span>;</a>
<a class="sourceLine" id="cb1-5" title="5">  Component2 <span class="va">c2_</span>;</a>
<a class="sourceLine" id="cb1-6" title="6"></a>
<a class="sourceLine" id="cb1-7" title="7">  <span class="kw">public</span>:</a>
<a class="sourceLine" id="cb1-8" title="8">  CompositeObject_1(<span class="at">const</span> Component1&amp; c1,</a>
<a class="sourceLine" id="cb1-9" title="9">                    <span class="at">const</span> Component2&amp; c2) :</a>
<a class="sourceLine" id="cb1-10" title="10">                    <span class="va">c1_</span>(c1), <span class="va">c2_</span>(c2) {}</a>
<a class="sourceLine" id="cb1-11" title="11"></a>
<a class="sourceLine" id="cb1-12" title="12">  <span class="dt">void</span> foo() { <span class="va">c1_</span>.foo(); }</a>
<a class="sourceLine" id="cb1-13" title="13">  <span class="dt">void</span> bar() { <span class="va">c2_</span>.bar(); }</a>
<a class="sourceLine" id="cb1-14" title="14">};</a></code></pre></div>
<p>The composite object can be made more flexible by storing pointers to objects allowing it to take derived components in its constructor. (We store pointers to the components rather than references so that we can take ownership of them).</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode cpp"><code class="sourceCode cpp"><a class="sourceLine" id="cb2-1" title="1"></a>
<a class="sourceLine" id="cb2-2" title="2"><span class="co">// Non-copyable composite with polymorphic components (BAD)</span></a>
<a class="sourceLine" id="cb2-3" title="3"><span class="kw">class</span> CompositeObject_2 {</a>
<a class="sourceLine" id="cb2-4" title="4">  IComponent1* <span class="va">c1_</span>;</a>
<a class="sourceLine" id="cb2-5" title="5">  IComponent2* <span class="va">c2_</span>;</a>
<a class="sourceLine" id="cb2-6" title="6"></a>
<a class="sourceLine" id="cb2-7" title="7">  <span class="kw">public</span>:</a>
<a class="sourceLine" id="cb2-8" title="8">  CompositeObject_2(IComponent1* c1,</a>
<a class="sourceLine" id="cb2-9" title="9">                    IComponent2* c2) :</a>
<a class="sourceLine" id="cb2-10" title="10">                    <span class="va">c1_</span>(c1), <span class="va">c2_</span>(c2) {}</a>
<a class="sourceLine" id="cb2-11" title="11"></a>
<a class="sourceLine" id="cb2-12" title="12">  <span class="dt">void</span> foo() { <span class="va">c1_</span>-&gt;foo(); }</a>
<a class="sourceLine" id="cb2-13" title="13">  <span class="dt">void</span> bar() { <span class="va">c2_</span>-&gt;bar(); }</a>
<a class="sourceLine" id="cb2-14" title="14"></a>
<a class="sourceLine" id="cb2-15" title="15">  CompositeObject_2(<span class="at">const</span> CompositeObject_2&amp;) = <span class="kw">delete</span>;</a>
<a class="sourceLine" id="cb2-16" title="16">  CompositeObject_2&amp; <span class="kw">operator</span>=(<span class="at">const</span> CompositeObject_2&amp;) = <span class="kw">delete</span>;</a>
<a class="sourceLine" id="cb2-17" title="17"></a>
<a class="sourceLine" id="cb2-18" title="18">  CompositeObject_2(CompositeObject_2&amp;&amp; o) : <span class="va">c1_</span>(o.<span class="va">c1_</span>), <span class="va">c2_</span>(o.<span class="va">c2_</span>) {</a>
<a class="sourceLine" id="cb2-19" title="19">    o.<span class="va">c1_</span> = <span class="kw">nullptr</span>;</a>
<a class="sourceLine" id="cb2-20" title="20">    o.<span class="va">c2_</span> = <span class="kw">nullptr</span>;</a>
<a class="sourceLine" id="cb2-21" title="21">  }</a>
<a class="sourceLine" id="cb2-22" title="22"></a>
<a class="sourceLine" id="cb2-23" title="23">  CompositeObject_2&amp; <span class="kw">operator</span>=(CompositeObject_2&amp;&amp; o) {</a>
<a class="sourceLine" id="cb2-24" title="24">    <span class="kw">delete</span> <span class="va">c1_</span>;</a>
<a class="sourceLine" id="cb2-25" title="25">    <span class="kw">delete</span> <span class="va">c2_</span>;</a>
<a class="sourceLine" id="cb2-26" title="26">    <span class="va">c1_</span> = o.<span class="va">c1_</span>;</a>
<a class="sourceLine" id="cb2-27" title="27">    <span class="va">c2_</span> = o.<span class="va">c2_</span>;</a>
<a class="sourceLine" id="cb2-28" title="28">    o.<span class="va">c1_</span> = <span class="kw">nullptr</span>;</a>
<a class="sourceLine" id="cb2-29" title="29">    o.<span class="va">c2_</span> = <span class="kw">nullptr</span>;</a>
<a class="sourceLine" id="cb2-30" title="30">  }</a>
<a class="sourceLine" id="cb2-31" title="31"></a>
<a class="sourceLine" id="cb2-32" title="32">  ~CompositeObject_2()</a>
<a class="sourceLine" id="cb2-33" title="33">  {</a>
<a class="sourceLine" id="cb2-34" title="34">    <span class="kw">delete</span> <span class="va">c1_</span>;</a>
<a class="sourceLine" id="cb2-35" title="35">    <span class="kw">delete</span> <span class="va">c2_</span>;</a>
<a class="sourceLine" id="cb2-36" title="36">  }</a>
<a class="sourceLine" id="cb2-37" title="37">};</a></code></pre></div>
<p><code>CompositeObject_2</code>’s constructor API is unclear without knowing that the class takes ownership of the objects. We are forced to explicitly suppress the compiler-generated copy constructor and copy assignment operator to avoid double-deletion of the components <code>c1_</code> and <code>c2_</code>. We also need to write a move constructor and move assignment operator.</p>
<p>Using <code>unique_ptr</code> makes ownership clear and saves us writing or deleting compiler generated methods:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode cpp"><code class="sourceCode cpp"><a class="sourceLine" id="cb3-1" title="1"></a>
<a class="sourceLine" id="cb3-2" title="2"><span class="co">// Non-copyable composite with polymorphic components</span></a>
<a class="sourceLine" id="cb3-3" title="3"><span class="kw">class</span> CompositeObject_3 {</a>
<a class="sourceLine" id="cb3-4" title="4">  <span class="bu">std::</span>unique_ptr&lt;IComponent1&gt; <span class="va">c1_</span>;</a>
<a class="sourceLine" id="cb3-5" title="5">  <span class="bu">std::</span>unique_ptr&lt;IComponent2&gt; <span class="va">c2_</span>;</a>
<a class="sourceLine" id="cb3-6" title="6"></a>
<a class="sourceLine" id="cb3-7" title="7">  <span class="kw">public</span>:</a>
<a class="sourceLine" id="cb3-8" title="8">  CompositeObject_3(<span class="bu">std::</span>unique_ptr&lt;IComponent1&gt; c1,</a>
<a class="sourceLine" id="cb3-9" title="9">                    <span class="bu">std::</span>unique_ptr&lt;IComponent2&gt; c2) :</a>
<a class="sourceLine" id="cb3-10" title="10">                    <span class="va">c1_</span>(<span class="bu">std::</span>move(c1)), <span class="va">c2_</span>(<span class="bu">std::</span>move(c2)) {}</a>
<a class="sourceLine" id="cb3-11" title="11"></a>
<a class="sourceLine" id="cb3-12" title="12">  <span class="dt">void</span> foo() { <span class="va">c1_</span>-&gt;foo(); }</a>
<a class="sourceLine" id="cb3-13" title="13">  <span class="dt">void</span> bar() { <span class="va">c2_</span>-&gt;bar(); }</a>
<a class="sourceLine" id="cb3-14" title="14">};</a></code></pre></div>
<p>The design of <code>CompositeObject_3</code> is good unless we want to copy the object.</p>
<p>We can avoid having to define our own copy constructor by using shared pointers. As <code>shared-ptr</code>’s copy constructor is shallow, we need to modify the component pointers to be pointers-to <code>const</code> to avoid introducing shared mutable state [S.Parent].</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode cpp"><code class="sourceCode cpp"><a class="sourceLine" id="cb4-1" title="1"></a>
<a class="sourceLine" id="cb4-2" title="2"><span class="co">// Copyable composite with immutable polymorphic components class</span></a>
<a class="sourceLine" id="cb4-3" title="3"><span class="kw">class</span> CompositeObject_4 {</a>
<a class="sourceLine" id="cb4-4" title="4">  <span class="bu">std::</span>shared_ptr&lt;<span class="at">const</span> IComponent1&gt; <span class="va">c1_</span>;</a>
<a class="sourceLine" id="cb4-5" title="5">  <span class="bu">std::</span>shared_ptr&lt;<span class="at">const</span> IComponent2&gt; <span class="va">c2_</span>;</a>
<a class="sourceLine" id="cb4-6" title="6"></a>
<a class="sourceLine" id="cb4-7" title="7">  <span class="kw">public</span>:</a>
<a class="sourceLine" id="cb4-8" title="8">  CompositeObject_4(<span class="bu">std::</span>shared_ptr&lt;<span class="at">const</span> IComponent1&gt; c1,</a>
<a class="sourceLine" id="cb4-9" title="9">                    <span class="bu">std::</span>shared_ptr&lt;<span class="at">const</span> IComponent2&gt; c2) :</a>
<a class="sourceLine" id="cb4-10" title="10">                    <span class="va">c1_</span>(<span class="bu">std::</span>move(c1)), <span class="va">c2_</span>(<span class="bu">std::</span>move(c2)) {}</a>
<a class="sourceLine" id="cb4-11" title="11"></a>
<a class="sourceLine" id="cb4-12" title="12">  <span class="dt">void</span> foo() { <span class="va">c1_</span>-&gt;foo(); }</a>
<a class="sourceLine" id="cb4-13" title="13">  <span class="dt">void</span> bar() { <span class="va">c2_</span>-&gt;bar(); }</a>
<a class="sourceLine" id="cb4-14" title="14">};</a></code></pre></div>
<p><code>CompositeObject_4</code> has polymorphism and compiler-generated destructor, copy, move and assignment operators. As long as the components are not mutated, this design is good. If non-const methods of components are used then this won’t compile.</p>
<p>Using <code>polymorphic_value</code> a copyable composite object with polymorphic components can be written as:</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode cpp"><code class="sourceCode cpp"><a class="sourceLine" id="cb5-1" title="1"></a>
<a class="sourceLine" id="cb5-2" title="2"><span class="co">// Copyable composite with mutable polymorphic components</span></a>
<a class="sourceLine" id="cb5-3" title="3"><span class="kw">class</span> CompositeObject_5 {</a>
<a class="sourceLine" id="cb5-4" title="4">  <span class="bu">std::</span>polymorphic_value&lt;IComponent1&gt; <span class="va">c1_</span>;</a>
<a class="sourceLine" id="cb5-5" title="5">  <span class="bu">std::</span>polymorphic_value&lt;IComponent2&gt; <span class="va">c2_</span>;</a>
<a class="sourceLine" id="cb5-6" title="6"></a>
<a class="sourceLine" id="cb5-7" title="7">  <span class="kw">public</span>:</a>
<a class="sourceLine" id="cb5-8" title="8">  CompositeObject_5(<span class="bu">std::</span>polymorphic_value&lt;IComponent1&gt; c1,</a>
<a class="sourceLine" id="cb5-9" title="9">                    <span class="bu">std::</span>polymorphic_value&lt;IComponent2&gt; c2) :</a>
<a class="sourceLine" id="cb5-10" title="10">                    <span class="va">c1_</span>(<span class="bu">std::</span>move(c1)), <span class="va">c2_</span>(<span class="bu">std::</span>move(c2)) {}</a>
<a class="sourceLine" id="cb5-11" title="11"></a>
<a class="sourceLine" id="cb5-12" title="12">  <span class="dt">void</span> foo() { <span class="va">c1_</span>-&gt;foo(); }</a>
<a class="sourceLine" id="cb5-13" title="13">  <span class="dt">void</span> bar() { <span class="va">c2_</span>-&gt;bar(); }</a>
<a class="sourceLine" id="cb5-14" title="14">};</a></code></pre></div>
<p>The component <code>c1_</code> can be constructed from an instance of any class that inherits from <code>IComponent1</code>. Similarly, <code>c2_</code> can be constructed from an instance of any class that inherits from <code>IComponent2</code>.</p>
<p><code>CompositeObject_5</code> has a compiler-generated destructor, copy constructor, move constructor, assignment operator and move assignment operator. All of these compiler-generated functions will behave correctly.</p>
<h2 id="deep-copies">Deep copies</h2>
<p>To allow correct copying of polymorphic objects, <code>polymorphic_value</code> uses the copy constructor of the owned derived-type object when copying a base type <code>polymorphic_value</code>. Similarly, to allow correct destruction of polymorphic component objects, <code>polymorphic_value</code> uses the destructor of the owned derived-type object in the destructor of a base type <code>polymorphic_value</code>.</p>
<p>The requirements of deep-copying can be illustrated by some simple test code:</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode cpp"><code class="sourceCode cpp"><a class="sourceLine" id="cb6-1" title="1"></a>
<a class="sourceLine" id="cb6-2" title="2"><span class="co">// GIVEN base and derived classes.</span></a>
<a class="sourceLine" id="cb6-3" title="3"><span class="kw">class</span> Base { <span class="kw">virtual</span> <span class="dt">void</span> foo() <span class="at">const</span> = <span class="dv">0</span>; };</a>
<a class="sourceLine" id="cb6-4" title="4"><span class="kw">class</span> Derived : <span class="kw">public</span> Base { <span class="dt">void</span> foo() <span class="at">const</span> <span class="kw">override</span> {} };</a>
<a class="sourceLine" id="cb6-5" title="5"></a>
<a class="sourceLine" id="cb6-6" title="6"><span class="co">// WHEN a polymorphic_value to base is formed from a derived object</span></a>
<a class="sourceLine" id="cb6-7" title="7">polymorphic_value&lt;Base&gt; poly(Derived());</a>
<a class="sourceLine" id="cb6-8" title="8"><span class="co">// AND the polymorphic_value to base is copied.</span></a>
<a class="sourceLine" id="cb6-9" title="9"><span class="kw">auto</span> poly_copy = poly;</a>
<a class="sourceLine" id="cb6-10" title="10"></a>
<a class="sourceLine" id="cb6-11" title="11"><span class="co">// THEN the copy owns a distinct object</span></a>
<a class="sourceLine" id="cb6-12" title="12"><span class="ot">assert</span>(&amp;*poly != &amp;*poly_copy);</a>
<a class="sourceLine" id="cb6-13" title="13"><span class="co">// AND the copy owns a derived type.</span></a>
<a class="sourceLine" id="cb6-14" title="14"><span class="ot">assert</span>(<span class="kw">dynamic_cast</span>&lt;Derived*&gt;(*&amp;poly_copy));</a></code></pre></div>
<p>Note that while deep-destruction of a derived class object from a base class pointer can be performed with a virtual destructor, the same is not true for deep-copying. <code>C++</code> has no concept of a virtual copy constructor and we are not proposing its addition. The class template <code>shared_ptr</code> already implements deep-destruction without needing virtual destructors; deep-destruction and deep-copying can be implemented using type-erasure [Impl].</p>
<h2 id="pointer-constructor">Pointer constructor</h2>
<p><code>polymorphic_value</code> can be constructed from a pointer and optionally a copier and/or deleter. The <code>polymorphic_value</code> constructed in this manner takes ownership of the pointer. This constructor is potentially dangerous as a mismatch in the dynamic and static type of the pointer will result in incorrectly synthesized copiers and deleters, potentially resulting in slicing when copying and incomplete deletion during destruction.</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode cpp"><code class="sourceCode cpp"><a class="sourceLine" id="cb7-1" title="1"><span class="kw">class</span> Base { <span class="co">/* methods and members */</span> };</a>
<a class="sourceLine" id="cb7-2" title="2"><span class="kw">class</span> Derived : <span class="kw">public</span> Base { <span class="co">/* methods and members */</span> };</a>
<a class="sourceLine" id="cb7-3" title="3"></a>
<a class="sourceLine" id="cb7-4" title="4">Derived* d = <span class="kw">new</span> Derived();</a>
<a class="sourceLine" id="cb7-5" title="5">Base* p = d; <span class="co">// static type and dynamic type differ</span></a>
<a class="sourceLine" id="cb7-6" title="6">polymorphic_value&lt;Base&gt; poly(p);</a>
<a class="sourceLine" id="cb7-7" title="7"></a>
<a class="sourceLine" id="cb7-8" title="8"><span class="co">// This copy will have been made using Base&#39;s copy constructor.</span></a>
<a class="sourceLine" id="cb7-9" title="9">polymorphic_value&lt;Base&gt; poly_copy = poly;</a>
<a class="sourceLine" id="cb7-10" title="10"></a>
<a class="sourceLine" id="cb7-11" title="11"><span class="co">// Destruction of poly and poly_copy uses Base&#39;s destructor.</span></a></code></pre></div>
<p>While this is potentially error prone, we have elected to trust users with the tools they are given. <code>shared_ptr</code> and <code>unique_ptr</code> have similar constructors and issues. There are more constructors for <code>polymorphic_value</code> of a less expert-friendly nature that do not present such dangers including a factory method <code>make_polymorphic_value</code>.</p>
<p>Static analysis tools can be written to find cases where static and dynamic types for pointers passed in to <code>polymorphic_value</code> constructors are not provably identical.</p>
<p>If the user has not supplied a custom copier or deleter, an exception <code>bad_polymorphic_value_construction</code> is thrown from the pointer-constructor if the dynamic and static types of the pointer argument do not agree. In cases where the user has supplied a custom copier and deleter it is assumed that they will do so to avoid slicing and incomplete destruction: a class heirarchy with a custom <code>Clone</code> method and virtual destructor would make use of <code>Clone</code> in a user-supplied copier.</p>
<h2 id="empty-state">Empty state</h2>
<p><code>polymorphic_value</code> presents an empty state as it is desirable for it to be cheaply constructed and then later assigned. In addition, it may not be possible to construct the <code>T</code> of a <code>polymorphic_value&lt;T&gt;</code> if it is an abstract class (a common intended use pattern). While permitting an empty state will necessitate occasional checks for <code>null</code>, <code>polymorphic_value</code> is intended to replace uses of pointers or smart pointers where such checks are also necessary. The benefits of default constructability (use in vectors and maps) outweigh the costs of a possible empty state.</p>
<h2 id="lack-of-hashing-and-comparisons">Lack of hashing and comparisons</h2>
<p>For a given user-defined type, <code>T</code>, there are multiple strategies to make <code>polymorphic_value&lt;T&gt;</code> hashable and comparable. Without requiring additional named member functions on the type, <code>T</code>, or mandating that <code>T</code> has virtual functions and RTTI, the authors do not see how <code>polymorphic_value</code> can generically support hashing or comparisons. Incurring a cost for functionality that is not required goes against the ‘pay for what you use’ philosophy of <code>C++</code>.</p>
<p>For a given user-defined type <code>T</code> the user is free to specialize <code>std::hash</code> and implement comparison operators for <code>polymorphic_value&lt;T&gt;</code>.</p>
<h2 id="custom-copiers-and-deleters">Custom copiers and deleters</h2>
<p>The resource management performed by <code>polymorphic_value</code> - copying and destruction of the managed object - can be customized by supplying a <em>copier</em> and <em>deleter</em>. If no copier or deleter is supplied then a default copier or deleter may be used.</p>
<p>A custom copier and deleter are <em>not</em> required, if no custom copier and deleter are provided then the copy constructor and destructor of the managed object will be used.</p>
<p>The default deleter is already defined by the standard library and used by <code>unique_ptr</code>.</p>
<p>We define the default copier in technical specifications below.</p>
<h2 id="allocator-support">Allocator Support</h2>
<p>The design of <code>polymorphic_value</code> is similar to that of <code>std::any</code>, which does not have support for allocators.</p>
<p><code>polymorphic_value</code>, like <code>std::any</code> and <code>std::function</code>, is implemented in terms of type-erasure. There are technical issues with storing an allocator in a type-erased context and recovering it later for allocations needed during copy assignment [P0302r1].</p>
<p>Until such technical obstacles can be overcome, <code>polymorphic_value</code> will follow the design of <code>std::any</code> and <code>std::function</code> (post C++17) and will not support allocators.</p>
<h2 id="design-changes-from-cloned_ptr">Design changes from <code>cloned_ptr</code></h2>
<p>The design of <code>polymorphic_value</code> is based upon <code>cloned_ptr</code> (from an early revision of this paper) and modified following advice from LEWG. The authors (who unreservedly agree with the design direction suggested by LEWG) would like to make explicit the cost of these design changes.</p>
<p><code>polymorphic_value&lt;T&gt;</code> has value-like semantics: copies are deep and <code>const</code> is propagated to the owned object. The first revision of this paper presented <code>cloned_ptr&lt;T&gt;</code> which had mixed pointer/value semantics: copies are deep but <code>const</code> is not propagated to the owned object. <code>polymorphic_value</code> can be built from <code>cloned_ptr</code> and <code>propagate_const</code> but there is no way to remove <code>const</code> propagation from <code>polymorphic_value</code>.</p>
<p>As <code>polymorphic_value</code> is a value, <code>dynamic_pointer_cast</code>, <code>static_pointer_cast</code> and <code>const_pointer_cast</code> are not provided. If a <code>polymorphic_value</code> is constructed with a custom copier or deleter, then there is no way for a user to implement cast operations like those that are provided by the standard for <code>std::shared_ptr</code>.</p>
<h2 id="no-implicit-conversions">No implicit conversions</h2>
<p>Following design feedback, <code>polymorphic_value</code>’s constructors have been made explicit so that surprising implicit conversions cannot take place. Any conversion to a <code>polymorphic_value</code> must be explicitly requested by user-code.</p>
<p>The converting assignment operators that were present in earlier drafts have also been removed.</p>
<p>For a base class, <code>BaseClass</code>, and derived class, <code>DerivedClass</code>, the converting assignment</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode cpp"><code class="sourceCode cpp"><a class="sourceLine" id="cb8-1" title="1">polymorphic_value&lt;DerivedClass&gt; derived;</a>
<a class="sourceLine" id="cb8-2" title="2">polymorphic_value&lt;Base&gt; base = derived;</a></code></pre></div>
<p>is no longer valid, the conversion must be made explicit:</p>
<div class="sourceCode" id="cb9"><pre class="sourceCode cpp"><code class="sourceCode cpp"><a class="sourceLine" id="cb9-1" title="1">polymorphic_value&lt;DerivedClass&gt; derived;</a>
<a class="sourceLine" id="cb9-2" title="2"><span class="kw">auto</span> base = polymorphic_value&lt;Base&gt;(derived);</a></code></pre></div>
<p>The removal of converting assigments makes <code>make_polymorphic_value</code> slightly more verbose to use:</p>
<div class="sourceCode" id="cb10"><pre class="sourceCode cpp"><code class="sourceCode cpp"><a class="sourceLine" id="cb10-1" title="1">polymorphic_value&lt;Base&gt; base = make_polymorphic_value&lt;DerivedClass&gt;(args);</a></code></pre></div>
<p>is not longer valid and must be written as</p>
<div class="sourceCode" id="cb11"><pre class="sourceCode cpp"><code class="sourceCode cpp"><a class="sourceLine" id="cb11-1" title="1"><span class="kw">auto</span> base = polymorphic_value&lt;Base&gt;(make_polymorphic_value&lt;DerivedClass&gt;(args));</a></code></pre></div>
<p>This is somewhat cumbersome so <code>make_polymorphic_value</code> has been modified to take an optional extra template argument allowing users to write</p>
<div class="sourceCode" id="cb12"><pre class="sourceCode cpp"><code class="sourceCode cpp"><a class="sourceLine" id="cb12-1" title="1">polymorphic_value&lt;Base&gt; base = make_polymorphic_value&lt;Base, DerivedClass&gt;(args);</a></code></pre></div>
<p>The change from implicit to explicit construction is deliberately conservative. One can change explicit constructors into implicit constructors without breaking code (other than SFINAE checks), the reverse is not true. Similarly, converting assignments could be added non-disruptively but not so readily removed.</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>
<h2 id="x.x-class-template-default_copy-default.copy">X.X Class template <code>default_copy</code> [default.copy]</h2>
<div class="sourceCode" id="cb13"><pre class="sourceCode cpp"><code class="sourceCode cpp"><a class="sourceLine" id="cb13-1" title="1"><span class="kw">namespace</span> std {</a>
<a class="sourceLine" id="cb13-2" title="2"><span class="kw">template</span> &lt;<span class="kw">class</span> T&gt; <span class="kw">struct</span> default_copy {</a>
<a class="sourceLine" id="cb13-3" title="3">  <span class="kw">constexpr</span> default_copy() <span class="kw">noexcept</span>;</a>
<a class="sourceLine" id="cb13-4" title="4">  T* <span class="kw">operator</span>()(<span class="at">const</span> T&amp; t) <span class="at">const</span>;</a>
<a class="sourceLine" id="cb13-5" title="5">};</a>
<a class="sourceLine" id="cb13-6" title="6"></a>
<a class="sourceLine" id="cb13-7" title="7">} <span class="co">// namespace std</span></a></code></pre></div>
<p>The class template <code>default_copy</code> serves as the default copier for the class template <code>polymorphic_value</code>.</p>
<div class="sourceCode" id="cb14"><pre class="sourceCode cpp"><code class="sourceCode cpp"><a class="sourceLine" id="cb14-1" title="1">T* <span class="kw">operator</span>()(<span class="at">const</span> T&amp; t) <span class="at">const</span>;</a></code></pre></div>
<ul>
<li><em>Effects</em>: Equivalent to: <code>return new T(t);</code></li>
</ul>
<h2 id="x.y-class-bad_polymorphic_value_construction-bad_polymorphic_value_construction">X.Y Class <code>bad_polymorphic_value_construction</code> [bad_polymorphic_value_construction]</h2>
<div class="sourceCode" id="cb15"><pre class="sourceCode cpp"><code class="sourceCode cpp"><a class="sourceLine" id="cb15-1" title="1"><span class="kw">namespace</span> std {</a>
<a class="sourceLine" id="cb15-2" title="2"><span class="kw">class</span> bad_polymorphic_value_construction : <span class="kw">public</span> exception</a>
<a class="sourceLine" id="cb15-3" title="3">{</a>
<a class="sourceLine" id="cb15-4" title="4">  <span class="kw">public</span>:</a>
<a class="sourceLine" id="cb15-5" title="5">    bad_polymorphic_value_construction() <span class="kw">noexcept</span>;</a>
<a class="sourceLine" id="cb15-6" title="6"></a>
<a class="sourceLine" id="cb15-7" title="7">    <span class="at">const</span> <span class="dt">char</span>* what() <span class="at">const</span> <span class="kw">noexcept</span> <span class="kw">override</span>;</a>
<a class="sourceLine" id="cb15-8" title="8">};</a>
<a class="sourceLine" id="cb15-9" title="9">}</a></code></pre></div>
<p>Objects of type <code>bad_polymorphic_value_construction</code> are thrown to report invalid construction of a <code>polymorphic_value</code>.</p>
<div class="sourceCode" id="cb16"><pre class="sourceCode cpp"><code class="sourceCode cpp"><a class="sourceLine" id="cb16-1" title="1"><span class="at">const</span> <span class="dt">char</span>* what() <span class="at">const</span> <span class="kw">noexcept</span> <span class="kw">override</span>;</a></code></pre></div>
<ul>
<li><em>Returns</em>: An implementation-defined NTBS.</li>
</ul>
<h2 id="x.z-class-template-polymorphic_value-polymorphic_value">X.Z Class template <code>polymorphic_value</code> [polymorphic_value]</h2>
<h3 id="x.z.1-class-template-polymorphic_value-general-polymorphic_value.general">X.Z.1 Class template <code>polymorphic_value</code> general [polymorphic_value.general]</h3>
<p>A <code>polymorphic_value</code> is an object that manages the lifetime of an owned object. A <code>polymorphic_value</code> object may own objects of different types at different points in its lifetime. A <code>polymorphic_value</code> object is empty if it has no owned object. <code>polymorphic_value</code> implements value semantics: the owned object (if any) is copied or destroyed when the <code>polymorphic_value</code> is copied or destroyed. Copying and destruction of the owned object can be customized by supplying a copier and deleter.</p>
<p>The template parameter <code>T</code> of <code>polymorphic_value&lt;T&gt;</code> shall be a non-union class type; otherwise the program is ill-formed. The template parameter <code>T</code> of <code>polymorphic_value&lt;T&gt;</code> may be an incomplete type.</p>
<p>A copier and deleter are said to be <em>present</em> if a <code>polymorphic_value</code> object is constructed from a non-null pointer, or from a <code>polymorphic_value</code> object where a copier and deleter are present.</p>
<p>[Note: Implementations are encouraged to avoid the use of dynamic memory for ownership of small objects.]</p>
<h3 id="x.z.2-class-template-polymorphic_value-synopsis-polymorphic_value.synopsis">X.Z.2 Class template <code>polymorphic_value</code> synopsis [polymorphic_value.synopsis]</h3>
<div class="sourceCode" id="cb17"><pre class="sourceCode cpp"><code class="sourceCode cpp"><a class="sourceLine" id="cb17-1" title="1"><span class="kw">namespace</span> std {</a>
<a class="sourceLine" id="cb17-2" title="2"><span class="kw">template</span> &lt;<span class="kw">class</span> T&gt; <span class="kw">class</span> polymorphic_value {</a>
<a class="sourceLine" id="cb17-3" title="3"> <span class="kw">public</span>:</a>
<a class="sourceLine" id="cb17-4" title="4">  <span class="kw">using</span> <span class="dt">element_type</span> = T;</a>
<a class="sourceLine" id="cb17-5" title="5"></a>
<a class="sourceLine" id="cb17-6" title="6">  <span class="co">// Constructors</span></a>
<a class="sourceLine" id="cb17-7" title="7">  <span class="kw">constexpr</span> polymorphic_value() <span class="kw">noexcept</span>;</a>
<a class="sourceLine" id="cb17-8" title="8">  </a>
<a class="sourceLine" id="cb17-9" title="9">  <span class="kw">constexpr</span> polymorphic_value(<span class="dt">nullptr_t</span>) <span class="kw">noexcept</span>;</a>
<a class="sourceLine" id="cb17-10" title="10"></a>
<a class="sourceLine" id="cb17-11" title="11">  <span class="kw">template</span> &lt;<span class="kw">class</span> U&gt; <span class="kw">explicit</span> polymorphic_value(U&amp;&amp; u);</a>
<a class="sourceLine" id="cb17-12" title="12"></a>
<a class="sourceLine" id="cb17-13" title="13">  <span class="kw">template</span> &lt;<span class="kw">class</span> U, <span class="kw">class</span> C=default_copy&lt;U&gt;, <span class="kw">class</span> D=default_delete&lt;U&gt;&gt;</a>
<a class="sourceLine" id="cb17-14" title="14">    <span class="kw">explicit</span> polymorphic_value(U* p, C c=C{}, D d=D{});</a>
<a class="sourceLine" id="cb17-15" title="15"></a>
<a class="sourceLine" id="cb17-16" title="16">  polymorphic_value(<span class="at">const</span> polymorphic_value&amp; p);</a>
<a class="sourceLine" id="cb17-17" title="17">  <span class="kw">template</span> &lt;<span class="kw">class</span> U&gt;</a>
<a class="sourceLine" id="cb17-18" title="18">    <span class="kw">explicit</span> polymorphic_value(<span class="at">const</span> polymorphic_value&lt;U&gt;&amp; p);</a>
<a class="sourceLine" id="cb17-19" title="19">  </a>
<a class="sourceLine" id="cb17-20" title="20">  polymorphic_value(polymorphic_value&amp;&amp; p) <span class="kw">noexcept</span>;</a>
<a class="sourceLine" id="cb17-21" title="21">  <span class="kw">template</span> &lt;<span class="kw">class</span> U&gt;</a>
<a class="sourceLine" id="cb17-22" title="22">    <span class="kw">explicit</span> polymorphic_value(polymorphic_value&lt;U&gt;&amp;&amp; p);</a>
<a class="sourceLine" id="cb17-23" title="23"></a>
<a class="sourceLine" id="cb17-24" title="24">  <span class="co">// Destructor</span></a>
<a class="sourceLine" id="cb17-25" title="25">  ~polymorphic_value();</a>
<a class="sourceLine" id="cb17-26" title="26"></a>
<a class="sourceLine" id="cb17-27" title="27">  <span class="co">// Assignment</span></a>
<a class="sourceLine" id="cb17-28" title="28">  polymorphic_value&amp; <span class="kw">operator</span>=(<span class="at">const</span> polymorphic_value&amp; p);</a>
<a class="sourceLine" id="cb17-29" title="29">  polymorphic_value&amp; <span class="kw">operator</span>=(polymorphic_value&amp;&amp; p) <span class="kw">noexcept</span>;</a>
<a class="sourceLine" id="cb17-30" title="30"></a>
<a class="sourceLine" id="cb17-31" title="31">  <span class="co">// Modifiers</span></a>
<a class="sourceLine" id="cb17-32" title="32">  <span class="dt">void</span> swap(polymorphic_value&amp; p) <span class="kw">noexcept</span>;</a>
<a class="sourceLine" id="cb17-33" title="33"></a>
<a class="sourceLine" id="cb17-34" title="34">  <span class="co">// Observers</span></a>
<a class="sourceLine" id="cb17-35" title="35">  <span class="at">const</span> T&amp; <span class="kw">operator</span>*() <span class="at">const</span>;</a>
<a class="sourceLine" id="cb17-36" title="36">  T&amp; <span class="kw">operator</span>*();</a>
<a class="sourceLine" id="cb17-37" title="37">  <span class="at">const</span> T* <span class="kw">operator</span>-&gt;() <span class="at">const</span>;</a>
<a class="sourceLine" id="cb17-38" title="38">  T* <span class="kw">operator</span>-&gt;();</a>
<a class="sourceLine" id="cb17-39" title="39">  <span class="kw">explicit</span> <span class="kw">operator</span> <span class="dt">bool</span>() <span class="at">const</span> <span class="kw">noexcept</span>;</a>
<a class="sourceLine" id="cb17-40" title="40">};</a>
<a class="sourceLine" id="cb17-41" title="41"></a>
<a class="sourceLine" id="cb17-42" title="42"><span class="co">// polymorphic_value creation</span></a>
<a class="sourceLine" id="cb17-43" title="43"><span class="kw">template</span> &lt;<span class="kw">class</span> T, <span class="kw">class</span> U=T, <span class="kw">class</span>... Ts&gt; polymorphic_value&lt;T&gt;</a>
<a class="sourceLine" id="cb17-44" title="44">  make_polymorphic_value(Ts&amp;&amp;... ts);</a>
<a class="sourceLine" id="cb17-45" title="45"></a>
<a class="sourceLine" id="cb17-46" title="46"><span class="co">// polymorphic_value specialized algorithms</span></a>
<a class="sourceLine" id="cb17-47" title="47"><span class="kw">template</span>&lt;<span class="kw">class</span> T&gt;</a>
<a class="sourceLine" id="cb17-48" title="48">  <span class="dt">void</span> swap(polymorphic_value&lt;T&gt;&amp; p, polymorphic_value&lt;T&gt;&amp; u) <span class="kw">noexcept</span>;</a>
<a class="sourceLine" id="cb17-49" title="49"></a>
<a class="sourceLine" id="cb17-50" title="50">} <span class="co">// end namespace std</span></a></code></pre></div>
<h3 id="x.z.3-class-template-polymorphic_value-constructors-polymorphic_value.ctor">X.Z.3 Class template <code>polymorphic_value</code> constructors [polymorphic_value.ctor]</h3>
<div class="sourceCode" id="cb18"><pre class="sourceCode cpp"><code class="sourceCode cpp"><a class="sourceLine" id="cb18-1" title="1"></a>
<a class="sourceLine" id="cb18-2" title="2"><span class="kw">constexpr</span> polymorphic_value() <span class="kw">noexcept</span>;</a>
<a class="sourceLine" id="cb18-3" title="3"><span class="kw">constexpr</span> polymorphic_value(<span class="dt">nullptr_t</span>) <span class="kw">noexcept</span>;</a></code></pre></div>
<ul>
<li><em>Ensures</em>: <code>*this</code> is empty.</li>
</ul>
<div class="sourceCode" id="cb19"><pre class="sourceCode cpp"><code class="sourceCode cpp"><a class="sourceLine" id="cb19-1" title="1"></a>
<a class="sourceLine" id="cb19-2" title="2"><span class="kw">template</span> &lt;<span class="kw">class</span> U&gt; <span class="kw">explicit</span> polymorphic_value(U&amp;&amp; u);</a></code></pre></div>
<p>Let <code>V</code> be <code>remove_cvref_t&lt;U&gt;</code>.</p>
<ul>
<li><p><em>Constraints</em>: <code>V*</code> is convertible to <code>T*</code>.</p></li>
<li><p><em>Effects</em>: Constructs a <code>polymorphic_value</code> which owns an object of type <code>V</code>, direct-non-list-initialized with <code>std::forward&lt;U&gt;(u)</code>.</p></li>
<li><p><em>Throws</em>: Any exception thrown by the selected constructor of <code>V</code> or <code>bad_alloc</code> if required storage cannot be obtained.</p></li>
</ul>
<div class="sourceCode" id="cb20"><pre class="sourceCode cpp"><code class="sourceCode cpp"><a class="sourceLine" id="cb20-1" title="1"><span class="kw">template</span> &lt;<span class="kw">class</span> U, <span class="kw">class</span> C=default_copy&lt;U&gt;, <span class="kw">class</span> D=default_delete&lt;U&gt;&gt;</a>
<a class="sourceLine" id="cb20-2" title="2">  <span class="kw">explicit</span> polymorphic_value(U* p, C c=C{}, D d=D{});</a></code></pre></div>
<ul>
<li><p><em>Constraints</em>: <code>U*</code> is convertible to <code>T*</code>.</p></li>
<li><p><em>Expects</em>: <code>C</code> and <code>D</code> meet the <code>Cpp17CopyConstructible</code> and <code>Cpp17Destructible</code> requirements.</p>
<p>Move-initialization of objects of type <code>C</code> and <code>D</code> does not exit via an exception.</p>
<p>If <code>p</code> is non-null then the expression <code>c(*p)</code> has type <code>U*</code>. The expression <code>d(p)</code> is well formed, has well-defined behavior, and does not throw exceptions.</p></li>
<li><p><em>Effects</em>: If <code>p</code> is null, creates an empty object.</p>
<p>If <code>p</code> is non-null creates an object that owns the object <code>*p</code>, with a copier and deleter initialized from <code>std::move(c)</code> and <code>std::move(d)</code>.</p></li>
<li><p><em>Throws</em>: <code>bad_alloc</code> if required storage cannot be obtained; <code>bad_polymorphic_value_construction</code> if <code>is_same_v&lt;C, default_copy&lt;U&gt;&gt;</code>, <code>is_same_v&lt;D, default_delete&lt;U&gt;&gt;</code> and <code>typeid(*p)!=typeid(U)</code> are all <code>true</code>.</p></li>
<li><p><em>Note</em>: A copier and deleter are said to be <em>present</em> in a non-empty object initialized with this constructor.</p></li>
</ul>
<div class="sourceCode" id="cb21"><pre class="sourceCode cpp"><code class="sourceCode cpp"><a class="sourceLine" id="cb21-1" title="1">polymorphic_value(<span class="at">const</span> polymorphic_value&amp; pv);</a>
<a class="sourceLine" id="cb21-2" title="2"><span class="kw">template</span> &lt;<span class="kw">class</span> U&gt; <span class="kw">explicit</span> polymorphic_value(<span class="at">const</span> polymorphic_value&lt;U&gt;&amp; pv);</a></code></pre></div>
<ul>
<li><p><em>Constraints</em>: For the second constructor, <code>U*</code> is convertible to <code>T*</code>.</p></li>
<li><p><em>Effects</em>: If <code>pv</code> is empty, constructs an empty object. Otherwise creates an object that owns a copy of the object managed by <code>pv</code>. If a copier and deleter are present in <code>pv</code> then the copy is created by the copier in <code>pv</code>. Otherwise the copy is created by copy construction of the owned object. If a copier and deleter are present in <code>pv</code> then the copier and deleter of the object constructed are copied from those in <code>pv</code>.</p></li>
<li><p><em>Ensures</em>: <code>bool(*this) == bool(pv)</code>.</p></li>
<li><p><em>Throws</em>: Any exception thrown by invocation of the copier, copying the copier and deleter, or <code>bad_alloc</code> if required storage cannot be obtained.</p></li>
</ul>
<div class="sourceCode" id="cb22"><pre class="sourceCode cpp"><code class="sourceCode cpp"><a class="sourceLine" id="cb22-1" title="1">polymorphic_value(polymorphic_value&amp;&amp; pv) <span class="kw">noexcept</span>;</a>
<a class="sourceLine" id="cb22-2" title="2"><span class="kw">template</span> &lt;<span class="kw">class</span> U&gt; <span class="kw">explicit</span> polymorphic_value(polymorphic_value&lt;U&gt;&amp;&amp; pv);</a></code></pre></div>
<ul>
<li><p><em>Constraints</em>: For the second constructor, <code>U*</code> is convertible to <code>T*</code>.</p></li>
<li><p><em>Effects</em>: If <code>pv</code> is empty, constructs an empty object. Otherwise the object owned by <code>pv</code> is transferred to the constructed object. If a copier and deleter are present in <code>pv</code> then the copier and deleter are transferred to the constructed object.</p></li>
<li><p><em>Ensures</em>: <code>*this</code> owns the object previously owned by <code>pv</code> (if any). <code>pv</code> is empty.</p></li>
</ul>
<p>[Note: This constructor can allow an implementation to avoid the need for dynamic memory allocation.]</p>
<h3 id="x.z.4-class-template-polymorphic_value-destructor-polymorphic_value.dtor">X.Z.4 Class template <code>polymorphic_value</code> destructor [polymorphic_value.dtor]</h3>
<div class="sourceCode" id="cb23"><pre class="sourceCode cpp"><code class="sourceCode cpp"><a class="sourceLine" id="cb23-1" title="1">~polymorphic_value();</a></code></pre></div>
<ul>
<li><em>Effects</em>: If a copier <code>c</code> and a deleter <code>d</code> are present, evaluates <code>d(operator-&gt;())</code> and destroys <code>c</code> and <code>d</code>. Otherwise destroys the owned object (if any).</li>
</ul>
<h3 id="x.z.5-class-template-polymorphic_value-assignment-polymorphic_value.assignment">X.Z.5 Class template <code>polymorphic_value</code> assignment [polymorphic_value.assignment]</h3>
<div class="sourceCode" id="cb24"><pre class="sourceCode cpp"><code class="sourceCode cpp"><a class="sourceLine" id="cb24-1" title="1">polymorphic_value&amp; <span class="kw">operator</span>=(<span class="at">const</span> polymorphic_value&amp; pv);</a></code></pre></div>
<ul>
<li><p><em>Effects</em>: Equivalent to <code>polymorphic_value(pv).swap(*this)</code>. No effects if an exception is thrown.</p></li>
<li><p><em>Throws</em>: Any exception thrown by the copier or <code>bad_alloc</code> if required storage cannot be obtained.</p></li>
<li><p><em>Returns</em>: <code>*this</code>.</p></li>
<li><p><em>Ensures</em>: The state of <code>*this</code> is as if copy constructed from <code>pv</code>.</p></li>
</ul>
<div class="sourceCode" id="cb25"><pre class="sourceCode cpp"><code class="sourceCode cpp"><a class="sourceLine" id="cb25-1" title="1">polymorphic_value&amp; <span class="kw">operator</span>=(polymorphic_value&amp;&amp; pv) <span class="kw">noexcept</span>;</a></code></pre></div>
<ul>
<li><p><em>Effects</em>: Equivalent to <code>polymorphic_value(pv).swap(*this)</code>.</p></li>
<li><p><em>Returns</em>: <code>*this</code>.</p></li>
<li><p><em>Ensures</em>: The state <code>*this</code> is equivalent to the original state of <code>pv</code>. <code>pv</code> is empty.</p></li>
</ul>
<p>[Note: move construction of an owned object may be used by an implementation to avoid the need for use of dynamic memory.]</p>
<h3 id="x.z.6-class-template-polymorphic_value-modifiers-polymorphic_value.modifiers">X.Z.6 Class template <code>polymorphic_value</code> modifiers [polymorphic_value.modifiers]</h3>
<div class="sourceCode" id="cb26"><pre class="sourceCode cpp"><code class="sourceCode cpp"><a class="sourceLine" id="cb26-1" title="1"><span class="dt">void</span> swap(polymorphic_value&amp; p) <span class="kw">noexcept</span>;</a></code></pre></div>
<ul>
<li><em>Effects</em>: Exchanges the state of <code>p</code> and <code>*this</code>.</li>
</ul>
<h3 id="x.z.7-class-template-polymorphic_value-observers-polymorphic_value.observers">X.Z.7 Class template <code>polymorphic_value</code> observers [polymorphic_value.observers]</h3>
<div class="sourceCode" id="cb27"><pre class="sourceCode cpp"><code class="sourceCode cpp"><a class="sourceLine" id="cb27-1" title="1"><span class="at">const</span> T&amp; <span class="kw">operator</span>*() <span class="at">const</span>;</a>
<a class="sourceLine" id="cb27-2" title="2">T&amp; <span class="kw">operator</span>*();</a></code></pre></div>
<ul>
<li><p><em>Expects</em>: <code>bool(*this)</code> is <code>true</code>.</p></li>
<li><p><em>Returns</em>: A reference to the owned object.</p></li>
</ul>
<div class="sourceCode" id="cb28"><pre class="sourceCode cpp"><code class="sourceCode cpp"><a class="sourceLine" id="cb28-1" title="1"><span class="at">const</span> T* <span class="kw">operator</span>-&gt;() <span class="at">const</span>;</a>
<a class="sourceLine" id="cb28-2" title="2">T* <span class="kw">operator</span>-&gt;();</a></code></pre></div>
<ul>
<li><p><em>Expects</em>: <code>bool(*this)</code> is <code>true</code>.</p></li>
<li><p><em>Returns</em>: A pointer to the owned object.</p></li>
</ul>
<div class="sourceCode" id="cb29"><pre class="sourceCode cpp"><code class="sourceCode cpp"><a class="sourceLine" id="cb29-1" title="1"><span class="kw">explicit</span> <span class="kw">operator</span> <span class="dt">bool</span>() <span class="at">const</span> <span class="kw">noexcept</span>;</a></code></pre></div>
<ul>
<li><em>Returns</em>: <code>true</code> if the <code>polymorphic_value</code> owns an object, otherwise <code>false</code>.</li>
</ul>
<h3 id="x.z.8-class-template-polymorphic_value-creation-polymorphic_value.creation">X.Z.8 Class template <code>polymorphic_value</code> creation [polymorphic_value.creation]</h3>
<div class="sourceCode" id="cb30"><pre class="sourceCode cpp"><code class="sourceCode cpp"><a class="sourceLine" id="cb30-1" title="1"><span class="kw">template</span> &lt;<span class="kw">class</span> T, <span class="kw">class</span> U=T, <span class="kw">class</span> ...Ts&gt; polymorphic_value&lt;T&gt;</a>
<a class="sourceLine" id="cb30-2" title="2">  make_polymorphic_value(Ts&amp;&amp; ...ts);</a></code></pre></div>
<ul>
<li><em>Returns</em>: A <code>polymorphic_value&lt;T&gt;</code> owning an object of type <code>U</code> direct-non-list-initialized with <code>std::forward&lt;Ts&gt;(ts)...</code>.</li>
</ul>
<p>[Note: Implementations are encouraged to avoid multiple allocations.]</p>
<h3 id="x.z.9-class-template-polymorphic_value-specialized-algorithms-polymorphic_value.spec">X.Z.9 Class template <code>polymorphic_value</code> specialized algorithms [polymorphic_value.spec]</h3>
<div class="sourceCode" id="cb31"><pre class="sourceCode cpp"><code class="sourceCode cpp"><a class="sourceLine" id="cb31-1" title="1"><span class="kw">template</span> &lt;<span class="kw">typename</span> T&gt;</a>
<a class="sourceLine" id="cb31-2" title="2"><span class="dt">void</span> swap(polymorphic_value&lt;T&gt;&amp; p, polymorphic_value&lt;T&gt;&amp; u) <span class="kw">noexcept</span>;</a></code></pre></div>
<ul>
<li><em>Effects</em>: Equivalent to <code>p.swap(u)</code>.</li>
</ul>
<h2 id="acknowledgements">Acknowledgements</h2>
<p>The authors would like to thank Maciej Bogus, Matthew Calabrese, Casey Carter, Germán Diago, Louis Dionne, Bengt Gustafsson, Tom Hudson, Stephan T Lavavej, Tomasz Kamiński, David Krauss, Thomas Koeppe, LanguageLawyer, Nevin Liber, Nathan Myers, Roger Orr, Geoff Romer, Patrice Roy, Tony van Eerd and Ville Voutilainen for suggestions and useful discussion.</p>
<h2 id="references">References</h2>
<p>[N3339] “A Preliminary Proposal for a Deep-Copying Smart Pointer”, W.E.Brown, 2012</p>
<p><code>&lt;http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3339.pdf&gt;</code></p>
<p>[S.Parent] “C++ Seasoning”, Sean Parent, 2013</p>
<p><code>&lt;https://github.com/sean-parent/sean-parent.github.io/wiki/Papers-and-Presentations&gt;</code></p>
<p>[Impl] Reference implementation: <code>polymorphic_value</code>, J.B.Coe</p>
<p><code>&lt;https://github.com/jbcoe/polymorphic_value&gt;</code></p>
<p>[P0302r1] “Removing Allocator support in std::function”, Jonathan Wakely</p>
<p><code>&lt;http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0302r1.html&gt;</code></p>
