<html>
<head>
    <!-- TITLE -->
    <title>TriviallyCopyable reference_wrapper</title>
</head>
<body>


<p>Document number: N4151 <br />
Date: 2014-08-08 <br />
Project: Programming Language C++, Library Evolution Working Group <br />
Reply-to: Agustn Berg <a href="&#x6D;&#x61;&#105;&#x6C;&#x74;&#111;:&#97;&#x67;&#117;&#115;&#x74;&#x69;&#110;&#x62;&#101;rg&#x65;&#64;&#x67;&#109;&#x61;&#105;&#x6C;.&#x63;&#x6F;&#x6D;">&#97;&#x67;&#117;&#115;&#x74;&#x69;&#110;&#x62;&#101;rg&#x65;&#64;&#x67;&#109;&#x61;&#105;&#x6C;.&#x63;&#x6F;&#x6D;</a>  </p>

<h1>TriviallyCopyable reference_wrapper</h1>

<h2>1. Introduction</h2>

<p>This paper proposes making <code>reference_wrapper&lt;T&gt;</code> be <code>TriviallyCopyable</code>.</p>

<h2>2. Motivation</h2>

<p>Trivially copyable types make ideal candidates for the small buffer optimization. So does <code>reference_wrapper&lt;T&gt;</code>. <code>reference_wrapper&lt;T&gt;</code> should be trivially copyable.</p>

<p>The simplest way to implement the small buffer optimization is by restricting it to trivially copyable types. Once objects of trivially copyable types are placed into suitable storage, the job is done as the compiler will fill in the details. With this rationale, the following trait can be used to decide when the optimization can be applied:</p>

<pre><code>template &lt;class T, class Buffer&gt;
struct use_small_buffer_optimization
  : std::integral_constant&lt;bool,
        sizeof(T) &lt;= sizeof(Buffer)
     &amp;&amp; alignof(Buffer) % alignof(T) == 0
     &amp;&amp; std::is_trivially_copyable&lt;T&gt;::value
     &amp;&amp; std::is_copy_constructible&lt;T&gt;::value
&gt; {};
</code></pre>

<p>This may or may not include <code>reference_wrapper&lt;T&gt;</code>, given that whether such template class is trivially copyable is unspecified. Yet <code>reference_wrapper&lt;T&gt;</code> would be an ideal candidate for the optimization, to the point that it is guaranteed to be used in <code>std::function</code>. Users may expect <code>reference_wrapper&lt;T&gt;</code> to be trivially copyable given that it is just a pointer in disguise. Depending on their standard library implementation, it will be trivially copyable, leading to unexpected allocations and possibly exceptions when switching to a different implementation.</p>

<h2>3. Implementability</h2>

<p>The following is a trivial implementation of <code>reference_wrapper</code>, modulo the call wrapper related functionality:</p>

<pre><code>template &lt;class T&gt;
class reference_wrapper {
public:
  // types
  typedef T type;

  // construct/copy/destroy
  reference_wrapper(T&amp; ref) noexcept : _ptr(std::addressof(ref)) {}
  reference_wrapper(T&amp;&amp;) = delete;
  reference_wrapper(const reference_wrapper&amp;) noexcept = default;

  // assignment
  reference_wrapper&amp; operator=(const reference_wrapper&amp; x) noexcept = default;

  // access
  operator T&amp; () const noexcept { return *_ptr; }
  T&amp; get() const noexcept { return *_ptr; }

private:
  T* _ptr;
};
</code></pre>

<p>Particular attention should be given to the fact that the copy constructor and copy assignment operator are not user-provided. They are explicitly defaulted on the first declaration, another alternative is to have them be implicitly declared. Given that <code>reference_wrapper</code> has no virtual functions and no subobjects of class type, the implicit definitions provided by the implementation will be trivial. With no non-trivial special member functions and a trivial destructor, this implementation of <code>reference_wrapper</code> is trivially copyable.</p>

<h2>4. Impact on the Standard</h2>

<p>The proposed change incurs no breaking changes, given that whether <code>reference_wrapper&lt;T&gt;</code> is trivially copyable is currently unspecified.</p>

<h2>5. Impact on ABI Stability</h2>

<p>Some ABIs, like the Itanium ABI [ITA], treat types with non-trivial copy constructors differently. They require the caller to allocate space for a temporary copy in which to store the parameter or return value, and pass a pointer to the temporary to the function. This is thus a potential ABI breaking change for those implementations in which <code>reference_wrapper&lt;T&gt;</code> is not already <code>TriviallyCopyable</code>. The situation, at the point of this writing, is the following:</p>

<ul>
<li><p>libc++ implementation is <code>TriviallyCopyable</code>.</p></li>
<li><p>libstdc++ implementation is not <code>TriviallyCopyable</code>, but the C++11 ABI is still in flux.</p></li>
<li><p>msvc implementation is not <code>TriviallyCopyable</code>, but does not guarantee ABI compatibility between major releases.</p></li>
<li><p>(annecdotical) Boost implementation is <code>TriviallyCopyable</code>.</p></li>
</ul>

<h2>6. Proposed Wording</h2>

<p>Change paragraph 1 of subclause 20.9.3 [refwrap] as shown (relative to [N3936]):</p>

<ol>
<li><code>reference_wrapper&lt;T&gt;</code> is a <ins style="background-color: #A0FFA0;"><code>TriviallyCopyable</code>, </ins><code>CopyConstructible</code> and <code>CopyAssignable</code> wrapper around a reference to an object or function of type <code>T</code>.</li>
</ol>

<h2>7. References</h2>

<ul>
<li><p>[ITA] Itanium C++ ABI
http://mentorembedded.github.io/cxx-abi/abi.html</p></li>
<li><p>[N3936] ISO/IEC JTC1 SC22 WG21, Programming Languages - C++, working draft, March 2014
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3936.pdf</p></li>
</ul>

</body>
</html>
