<!DOCTYPE html>
<html lang="en">
<head>
<title>pointer_traits utility to convert to raw pointer</title>
<meta charset="utf-8"/>
<meta name="author" content="Glen Joseph Fernandes">
<style>
ins { background-color: #A0FFA0; }
del { background-color: #FFA0A0; }
</style>
</head>
<body>
<p><strong>Document Number:</strong> P0653r0<br>
<strong>Date:</strong> 2017-05-28<br>
<strong>Project:</strong> Programming Language C++<br>
<strong>Audience:</strong> Library Evolution Working Group<br>
<strong>Author:</strong> Glen Joseph Fernandes
(<a href="mailto:glenjofe@gmail.com">glenjofe@gmail.com</a>)</p>
<h1>pointer_traits utility to convert to raw pointer</h1>
This paper proposes adding a new static member function to class template
<code>pointer_traits</code> (called <code>to_address</code>) to obtain a raw
pointer from an object of any pointer-like type.
<h2>Motivation</h2>
<p>It is often necessary to obtain a raw pointer from an object of any
pointer-like type. One common use is writing allocator-aware code where an
allocator's <code>pointer</code> member type is not a raw pointer type.</p>
<p>Typically the expression <code>addressof(*p)</code> is used but this is not
well-defined when <code>p</code> does not reference storage that has an object
constructed in it. This means that using this expression to obtain a raw
pointer for the purpose of constructing an object (e.g. via a placement
<em>new-expression</em> or via an allocator) is incorrect.</p>
<p>A typical example of such code:</p>
<blockquote>
<pre>P p = a.allocate(n);
new (addressof(*p)) T();</pre>
</blockquote>
<p>The correct code now looks like:</p>
<blockquote>
<pre>P p = a.allocate(n);
new (pointer_traits&lt;P&gt;::to_address(p)) T();</pre>
</blockquote>
<h3>Why pointer_traits?</h3>
<p>Typically implementors work around this problem by defining a utility like
the following:</p>
<blockquote>
<pre>template &lt;class Ptr&gt;
typename pointer_traits&lt;Ptr&gt;::element_type* to_address(Ptr p) noexcept
{
  return to_address(p.operator->());
}

template &lt;class T&gt;
T* to_address(T* p) noexcept
{
  return p;
}</pre>
</blockquote>
<p>The C++ standard library already provides <code>pointer_traits</code>
for supporting any pointer-like types and this <code>to_address</code> is
the natural inverse of its <code>pointer_to</code> member function.</p>
<h2>Implementation</h2>
<p>The <a href="http://www.boost.org/">Boost</a> C++ library collection now
contains an implementation of this proposal in the Core library. That
<code>boost::pointer_traits</code> implementation is used by several Boost
libraries, starting with the 1.65 release.</p>
<h2>Proposed Wording</h2>
<p>All changes are relative to <a href="#N4640">N4640</a>.</p>
<p>1. Insert into 20.10.3 [pointer.traits] as follows:</p>
<blockquote>
<pre>namespace std {
  template &lt;class Ptr&gt; struct pointer_traits {
    using pointer = Ptr;
    using element_type = <em>see below</em>;
    using difference_type = <em>see below</em>;

    template &lt;class U&gt; using rebind = <em>see below</em>;

    static pointer pointer_to(<em>see below</em> r);
    <ins>static element_type* to_address(pointer p) noexcept;</ins>
  };

  template &lt;class T&gt; struct pointer_traits&lt;T*&gt; {
    using pointer = T*;
    using element_type = T;
    using difference_type = std::ptrdiff_t;

    template &lt;class U&gt; using rebind = U*;

    static pointer pointer_to(<em>see below</em> r) noexcept;
    <ins>static element_type* to_address(pointer p) noexcept;</ins>
  };
}</pre>
</blockquote>
<p>2. Add to 20.10.3.1 [pointer.traits.functions] as follows:</p>
<blockquote>
<dl>
<dt><code><ins>static element_type* pointer_traits::to_address(pointer p)
noexcept;</ins></code><br>
<code><ins>static element_type*
pointer_traits&lt;T*&gt;::to_address(pointer p) noexcept;</ins></code></dt>
<dd><p><ins><em>Returns:</em> A pointer of type <code>element_type*</code>
that references the same location as the argument <code>p</code>.</ins></p>
<p><ins><em>Remarks:</em> The first member function returns
<code>pointer_traits&lt;<em>E</em>&gt;::to_address(<em>expr</em>)</code> where
<em>expr</em> is <code>p.operator-&gt;()</code> and <em>E</em> is its type.
The second member function returns <code>p</code>.</ins></p></dd>
</dl>
</blockquote>
<h2>Acknowledgments</h2>
<p>Peter Dimov suggested a better design as well as reviewed the
implementation and tests of the Boost version. Jonathan Wakely pointed out the
issue that motivated this proposal. Michael Spencer reviewed this paper.</p>
<h2>References</h2>
<ul>
<li id="#N4640">N4640, Working Draft, Standard for Programming Language C++,
<br>
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4640.pdf">
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4640.pdf</a>
</li>
</ul>
</body>
</html>
