<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
<title>allocate_unique and allocator_delete</title>
<meta name="date" content="2017-02-01" />
<meta name="author" content="Miro Knejp (miro.knejp&#64;gmail.com)" />
<style type="text/css">

/*
:Author: David Goodger (goodger@python.org)
:Id: $Id: html4css1.css 7952 2016-07-26 18:15:59Z milde $
:Copyright: This stylesheet has been placed in the public domain.

Default cascading style sheet for the HTML output of Docutils.

See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to
customize this style sheet.
*/

/* used to remove borders from tables and images */
.borderless, table.borderless td, table.borderless th {
  border: 0 }

table.borderless td, table.borderless th {
  /* Override padding for "table.docutils td" with "! important".
     The right padding separates the table cells. */
  padding: 0 0.5em 0 0 ! important }

.first {
  /* Override more specific margin styles with "! important". */
  margin-top: 0 ! important }

.last, .with-subtitle {
  margin-bottom: 0 ! important }

.hidden {
  display: none }

.subscript {
  vertical-align: sub;
  font-size: smaller }

.superscript {
  vertical-align: super;
  font-size: smaller }

a.toc-backref {
  text-decoration: none ;
  color: black }

blockquote.epigraph {
  margin: 2em 5em ; }

dl.docutils dd {
  margin-bottom: 0.5em }

object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] {
  overflow: hidden;
}

/* Uncomment (and remove this text!) to get bold-faced definition list terms
dl.docutils dt {
  font-weight: bold }
*/

div.abstract {
  margin: 2em 5em }

div.abstract p.topic-title {
  font-weight: bold ;
  text-align: center }

div.admonition, div.attention, div.caution, div.danger, div.error,
div.hint, div.important, div.note, div.tip, div.warning {
  margin: 2em ;
  border: medium outset ;
  padding: 1em }

div.admonition p.admonition-title, div.hint p.admonition-title,
div.important p.admonition-title, div.note p.admonition-title,
div.tip p.admonition-title {
  font-weight: bold ;
  font-family: sans-serif }

div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title, .code .error {
  color: red ;
  font-weight: bold ;
  font-family: sans-serif }

/* Uncomment (and remove this text!) to get reduced vertical space in
   compound paragraphs.
div.compound .compound-first, div.compound .compound-middle {
  margin-bottom: 0.5em }

div.compound .compound-last, div.compound .compound-middle {
  margin-top: 0.5em }
*/

div.dedication {
  margin: 2em 5em ;
  text-align: center ;
  font-style: italic }

div.dedication p.topic-title {
  font-weight: bold ;
  font-style: normal }

div.figure {
  margin-left: 2em ;
  margin-right: 2em }

div.footer, div.header {
  clear: both;
  font-size: smaller }

div.line-block {
  display: block ;
  margin-top: 1em ;
  margin-bottom: 1em }

div.line-block div.line-block {
  margin-top: 0 ;
  margin-bottom: 0 ;
  margin-left: 1.5em }

div.sidebar {
  margin: 0 0 0.5em 1em ;
  border: medium outset ;
  padding: 1em ;
  background-color: #ffffee ;
  width: 40% ;
  float: right ;
  clear: right }

div.sidebar p.rubric {
  font-family: sans-serif ;
  font-size: medium }

div.system-messages {
  margin: 5em }

div.system-messages h1 {
  color: red }

div.system-message {
  border: medium outset ;
  padding: 1em }

div.system-message p.system-message-title {
  color: red ;
  font-weight: bold }

div.topic {
  margin: 2em }

h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
  margin-top: 0.4em }

h1.title {
  text-align: center }

h2.subtitle {
  text-align: center }

hr.docutils {
  width: 75% }

img.align-left, .figure.align-left, object.align-left, table.align-left {
  clear: left ;
  float: left ;
  margin-right: 1em }

img.align-right, .figure.align-right, object.align-right, table.align-right {
  clear: right ;
  float: right ;
  margin-left: 1em }

img.align-center, .figure.align-center, object.align-center {
  display: block;
  margin-left: auto;
  margin-right: auto;
}

table.align-center {
  margin-left: auto;
  margin-right: auto;
}

.align-left {
  text-align: left }

.align-center {
  clear: both ;
  text-align: center }

.align-right {
  text-align: right }

/* reset inner alignment in figures */
div.align-right {
  text-align: inherit }

/* div.align-center * { */
/*   text-align: left } */

.align-top    {
  vertical-align: top }

.align-middle {
  vertical-align: middle }

.align-bottom {
  vertical-align: bottom }

ol.simple, ul.simple {
  margin-bottom: 1em }

ol.arabic {
  list-style: decimal }

ol.loweralpha {
  list-style: lower-alpha }

ol.upperalpha {
  list-style: upper-alpha }

ol.lowerroman {
  list-style: lower-roman }

ol.upperroman {
  list-style: upper-roman }

p.attribution {
  text-align: right ;
  margin-left: 50% }

p.caption {
  font-style: italic }

p.credits {
  font-style: italic ;
  font-size: smaller }

p.label {
  white-space: nowrap }

p.rubric {
  font-weight: bold ;
  font-size: larger ;
  color: maroon ;
  text-align: center }

p.sidebar-title {
  font-family: sans-serif ;
  font-weight: bold ;
  font-size: larger }

p.sidebar-subtitle {
  font-family: sans-serif ;
  font-weight: bold }

p.topic-title {
  font-weight: bold }

pre.address {
  margin-bottom: 0 ;
  margin-top: 0 ;
  font: inherit }

pre.literal-block, pre.doctest-block, pre.math, pre.code {
  margin-left: 2em ;
  margin-right: 2em }

pre.code .ln { color: grey; } /* line numbers */
pre.code, code { background-color: #eeeeee }
pre.code .comment, code .comment { color: #5C6576 }
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
pre.code .literal.string, code .literal.string { color: #0C5404 }
pre.code .name.builtin, code .name.builtin { color: #352B84 }
pre.code .deleted, code .deleted { background-color: #DEB0A1}
pre.code .inserted, code .inserted { background-color: #A3D289}

span.classifier {
  font-family: sans-serif ;
  font-style: oblique }

span.classifier-delimiter {
  font-family: sans-serif ;
  font-weight: bold }

span.interpreted {
  font-family: sans-serif }

span.option {
  white-space: nowrap }

span.pre {
  white-space: pre }

span.problematic {
  color: red }

span.section-subtitle {
  /* font-size relative to parent (h1..h6 element) */
  font-size: 80% }

table.citation {
  border-left: solid 1px gray;
  margin-left: 1px }

table.docinfo {
  margin: 2em 4em }

table.docutils {
  margin-top: 0.5em ;
  margin-bottom: 0.5em }

table.footnote {
  border-left: solid 1px black;
  margin-left: 1px }

table.docutils td, table.docutils th,
table.docinfo td, table.docinfo th {
  padding-left: 0.5em ;
  padding-right: 0.5em ;
  vertical-align: top }

table.docutils th.field-name, table.docinfo th.docinfo-name {
  font-weight: bold ;
  text-align: left ;
  white-space: nowrap ;
  padding-left: 0 }

/* "booktabs" style (no vertical lines) */
table.docutils.booktabs {
  border: 0px;
  border-top: 2px solid;
  border-bottom: 2px solid;
  border-collapse: collapse;
}
table.docutils.booktabs * {
  border: 0px;
}
table.docutils.booktabs th {
  border-bottom: thin solid;
  text-align: left;
}

h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
  font-size: 100% }

ul.auto-toc {
  list-style-type: none }

</style>
<style type="text/css">

.hll { background-color: #ffffcc }
.c { color: #008000 } /* Comment */
.err { border: 1px solid #FF0000 } /* Error */
.k { color: #0000ff } /* Keyword */
.ch { color: #008000 } /* Comment.Hashbang */
.cm { color: #008000 } /* Comment.Multiline */
.cp { color: #0000ff } /* Comment.Preproc */
.cpf { color: #008000 } /* Comment.PreprocFile */
.c1 { color: #008000 } /* Comment.Single */
.cs { color: #008000 } /* Comment.Special */
.ge { font-style: italic } /* Generic.Emph */
.gh { font-weight: bold } /* Generic.Heading */
.gp { font-weight: bold } /* Generic.Prompt */
.gs { font-weight: bold } /* Generic.Strong */
.gu { font-weight: bold } /* Generic.Subheading */
.kc { color: #0000ff } /* Keyword.Constant */
.kd { color: #0000ff } /* Keyword.Declaration */
.kn { color: #0000ff } /* Keyword.Namespace */
.kp { color: #0000ff } /* Keyword.Pseudo */
.kr { color: #0000ff } /* Keyword.Reserved */
.kt { color: #2b91af } /* Keyword.Type */
.s { color: #a31515 } /* Literal.String */
.nc { color: #2b91af } /* Name.Class */
.ow { color: #0000ff } /* Operator.Word */
.sb { color: #a31515 } /* Literal.String.Backtick */
.sc { color: #a31515 } /* Literal.String.Char */
.sd { color: #a31515 } /* Literal.String.Doc */
.s2 { color: #a31515 } /* Literal.String.Double */
.se { color: #a31515 } /* Literal.String.Escape */
.sh { color: #a31515 } /* Literal.String.Heredoc */
.si { color: #a31515 } /* Literal.String.Interpol */
.sx { color: #a31515 } /* Literal.String.Other */
.sr { color: #a31515 } /* Literal.String.Regex */
.s1 { color: #a31515 } /* Literal.String.Single */
.ss { color: #a31515 } /* Literal.String.Symbol */

</style>
<style type="text/css">

/* code-formatted insertions to the standard */
pre.insert { background: lightgreen }

.std-section { font-weight: bold }

.std-note { font-style: italic }

</style>
</head>
<body>
<div class="document" id="allocate-unique-and-allocator-delete">
<h1 class="title"><tt class="docutils literal">allocate_unique</tt> and <tt class="docutils literal">allocator_delete</tt></h1>
<table class="docinfo" frame="void" rules="none">
<col class="docinfo-name" />
<col class="docinfo-content" />
<tbody valign="top">
<tr class="document field"><th class="docinfo-name">Document:</th><td class="field-body">P0316R0</td>
</tr>
<tr><th class="docinfo-name">Date:</th>
<td>2017-02-01</td></tr>
<tr class="project field"><th class="docinfo-name">Project:</th><td class="field-body">Programming Language C++</td>
</tr>
<tr class="audience field"><th class="docinfo-name">Audience:</th><td class="field-body">Library Evolution Working Group</td>
</tr>
<tr><th class="docinfo-name">Author:</th>
<td>Miro Knejp (<a class="reference external" href="mailto:miro.knejp&#64;gmail.com">miro.knejp&#64;gmail.com</a>)</td></tr>
</tbody>
</table>
<div class="section" id="abstract">
<h1><a class="toc-backref" href="#id2">Abstract</a></h1>
<p>This paper proposes the addition of the function <tt class="docutils literal">allocate_unique()</tt> to complement the functionality of <tt class="docutils literal">allocate_shared()</tt> for <tt class="docutils literal">unique_ptr</tt>, as well as the addition of the utility <tt class="docutils literal">allocator_delete</tt> to hide frequently needed boilerplate when implementing allocator-aware data structures.</p>
<div class="contents topic" id="contents">
<p class="topic-title first">Contents</p>
<ul class="simple">
<li><a class="reference internal" href="#abstract" id="id2">Abstract</a></li>
<li><a class="reference internal" href="#motivation" id="id3">Motivation</a></li>
<li><a class="reference internal" href="#proposal" id="id4">Proposal</a><ul>
<li><a class="reference internal" href="#overview" id="id5">Overview</a></li>
<li><a class="reference internal" href="#allocator-delete" id="id6">allocator_delete</a></li>
<li><a class="reference internal" href="#allocate-unique" id="id7">allocate_unique</a></li>
</ul>
</li>
<li><a class="reference internal" href="#applications-outside-of-allocate-unique" id="id8">Applications Outside of allocate_unique</a><ul>
<li><a class="reference internal" href="#node-based-containers" id="id9">Node-Based Containers</a></li>
<li><a class="reference internal" href="#type-erasure" id="id10">Type Erasure</a></li>
</ul>
</li>
<li><a class="reference internal" href="#open-issues" id="id11">Open Issues</a><ul>
<li><a class="reference internal" href="#allocate-unique-t" id="id12">allocate_unique&lt;T[]&gt;</a></li>
</ul>
</li>
<li><a class="reference internal" href="#summary" id="id13">Summary</a></li>
<li><a class="reference internal" href="#proposed-wording" id="id14">Proposed Wording</a></li>
<li><a class="reference internal" href="#references" id="id15">References</a></li>
</ul>
</div>
</div>
<div class="section" id="motivation">
<h1><a class="toc-backref" href="#id3">Motivation</a></h1>
<p>There is currently an asymmetry in functionality regarding the creation of <tt class="docutils literal">shared_ptr</tt> and <tt class="docutils literal">unique_ptr</tt>. Both of them can be conviently created with <tt class="docutils literal">make_shared()</tt> and <tt class="docutils literal">make_unique()</tt>, respectively, using the default allocator. However if one wishes to use a custom allocator only the former provides a convenient factory in the form of <tt class="docutils literal">allocate_shared()</tt> whereas there is no such facility for <tt class="docutils literal">unique_ptr</tt> and one has to write quite an amount of non-trivial code to create one's own.</p>
<p>The additions proposed in this paper can be found re-intenved in virtually every library that offers custom allocator support and are already present in standard library implementations for internal use making it obvious this is a frequently sought after functionality that should be readily available in the standard (and <em>de-facto</em> already is, albeit not under a well-known name).</p>
<p>The inclusion of <tt class="docutils literal">allocator_delete</tt> removes an additional burden for implementing allocator-aware data structures outside the scope of <tt class="docutils literal">unique_ptr</tt>. Together with <tt class="docutils literal">allocate_unique</tt> it provides the means to conveniently create and destroy objects with custom allocators which are not directly tied to <tt class="docutils literal">unique_ptr</tt> lifetimes (such as node-based or type-erasing containers, to name a few).</p>
</div>
<div class="section" id="proposal">
<h1><a class="toc-backref" href="#id4">Proposal</a></h1>
<div class="section" id="overview">
<h2><a class="toc-backref" href="#id5">Overview</a></h2>
<pre class="code c++ literal-block">
<span class="ln"> 1 </span><span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">T</span><span class="p">,</span> <span class="k">class</span> <span class="nc">Alloc</span><span class="o">&gt;</span>
<span class="ln"> 2 </span><span class="k">class</span> <span class="nc">allocator_delete</span> <span class="p">{</span>
<span class="ln"> 3 </span><span class="k">public</span><span class="o">:</span>
<span class="ln"> 4 </span>  <span class="k">using</span> <span class="n">allocator_type</span> <span class="o">=</span> <span class="n">remove_cv_t</span><span class="o">&lt;</span><span class="n">Alloc</span><span class="o">&gt;</span><span class="p">;</span>
<span class="ln"> 5 </span>  <span class="k">using</span> <span class="n">pointer</span> <span class="o">=</span> <span class="k">typename</span> <span class="n">allocator_traits</span><span class="o">&lt;</span><span class="n">allocator_type</span><span class="o">&gt;::</span><span class="n">pointer</span><span class="p">;</span>
<span class="ln"> 6 </span>
<span class="ln"> 7 </span>  <span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">OtherAlloc</span><span class="o">&gt;</span>
<span class="ln"> 8 </span>  <span class="n">allocator_delete</span><span class="p">(</span><span class="n">OtherAlloc</span><span class="o">&amp;&amp;</span> <span class="n">other</span><span class="p">);</span>
<span class="ln"> 9 </span>
<span class="ln">10 </span>  <span class="kt">void</span> <span class="nf">operator</span><span class="p">()(</span><span class="n">pointer</span> <span class="n">p</span><span class="p">);</span>
<span class="ln">11 </span>
<span class="ln">12 </span>  <span class="n">allocator_type</span><span class="o">&amp;</span> <span class="n">get_allocator</span><span class="p">();</span>
<span class="ln">13 </span>  <span class="k">const</span> <span class="n">allocator_type</span><span class="o">&amp;</span> <span class="n">get_allocator</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
<span class="ln">14 </span>
<span class="ln">15 </span><span class="k">private</span><span class="o">:</span>
<span class="ln">16 </span>  <span class="n">allocator_type</span> <span class="n">alloc</span><span class="p">;</span> <span class="c1">// for exposition only
</span><span class="ln">17 </span><span class="c1"></span><span class="p">};</span>
<span class="ln">18 </span>
<span class="ln">19 </span><span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">T</span><span class="p">,</span> <span class="k">class</span> <span class="nc">Alloc</span><span class="o">&gt;</span>
<span class="ln">20 </span><span class="k">class</span> <span class="nc">allocator_delete</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">Alloc</span><span class="o">&amp;&gt;</span> <span class="p">{</span>
<span class="ln">21 </span><span class="k">public</span><span class="o">:</span>
<span class="ln">22 </span>  <span class="k">using</span> <span class="n">allocator_type</span> <span class="o">=</span> <span class="n">remove_cv_t</span><span class="o">&lt;</span><span class="n">Alloc</span><span class="o">&gt;</span><span class="p">;</span>
<span class="ln">23 </span>  <span class="k">using</span> <span class="n">pointer</span> <span class="o">=</span> <span class="k">typename</span> <span class="n">allocator_traits</span><span class="o">&lt;</span><span class="n">allocator_type</span><span class="o">&gt;::</span><span class="n">pointer</span><span class="p">;</span>
<span class="ln">24 </span>
<span class="ln">25 </span>  <span class="n">allocator_delete</span><span class="p">(</span><span class="n">reference_wrapper</span><span class="o">&lt;</span><span class="n">Alloc</span><span class="o">&gt;</span> <span class="n">alloc</span><span class="p">);</span>
<span class="ln">26 </span>
<span class="ln">27 </span>  <span class="kt">void</span> <span class="nf">operator</span><span class="p">()(</span><span class="n">pointer</span> <span class="n">p</span><span class="p">);</span>
<span class="ln">28 </span>
<span class="ln">29 </span>  <span class="n">Alloc</span><span class="o">&amp;</span> <span class="n">get_allocator</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
<span class="ln">30 </span>
<span class="ln">31 </span><span class="k">private</span><span class="o">:</span>
<span class="ln">32 </span>  <span class="n">reference_wrapper</span><span class="o">&lt;</span><span class="n">Alloc</span><span class="o">&gt;</span> <span class="n">alloc</span><span class="p">;</span> <span class="c1">// for exposition only
</span><span class="ln">33 </span><span class="c1"></span><span class="p">};</span>
<span class="ln">34 </span>
<span class="ln">35 </span><span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">T</span><span class="p">,</span> <span class="k">class</span> <span class="nc">OtherAlloc</span><span class="o">&gt;</span>
<span class="ln">36 </span><span class="n">allocator_delete</span><span class="p">(</span><span class="n">OtherAlloc</span><span class="o">&amp;&amp;</span> <span class="n">alloc</span><span class="p">)</span>
<span class="ln">37 </span>  <span class="o">-&gt;</span> <span class="n">allocator_delete</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="k">typename</span> <span class="n">allocator_traits</span><span class="o">&lt;</span><span class="n">OtherAlloc</span><span class="o">&gt;::</span><span class="k">template</span> <span class="n">rebind_alloc</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;&gt;</span><span class="p">;</span>
<span class="ln">38 </span>
<span class="ln">39 </span><span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">T</span><span class="p">,</span> <span class="k">class</span> <span class="nc">Alloc</span><span class="o">&gt;</span>
<span class="ln">40 </span><span class="n">allocator_delete</span><span class="p">(</span><span class="n">reference_wrapper</span><span class="o">&lt;</span><span class="n">Alloc</span><span class="o">&gt;</span> <span class="n">alloc</span><span class="p">)</span>
<span class="ln">41 </span>  <span class="o">-&gt;</span> <span class="n">allocator_delete</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">Alloc</span><span class="o">&amp;&gt;</span><span class="p">;</span>
<span class="ln">42 </span>
<span class="ln">43 </span><span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">T</span><span class="p">,</span> <span class="k">class</span> <span class="nc">Alloc</span><span class="p">,</span> <span class="n">class</span><span class="p">...</span> <span class="n">Args</span><span class="o">&gt;</span>
<span class="ln">44 </span>  <span class="n">unique_ptr</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">allocator_delete</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="k">typename</span> <span class="n">allocator_traits</span><span class="o">&lt;</span><span class="n">Alloc</span><span class="o">&gt;::</span><span class="k">template</span> <span class="n">rebind_alloc</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;&gt;&gt;</span>
<span class="ln">45 </span>    <span class="n">allocate_unique</span><span class="p">(</span><span class="n">Alloc</span><span class="o">&amp;&amp;</span> <span class="n">alloc</span><span class="p">,</span> <span class="n">Args</span><span class="o">&amp;&amp;</span><span class="p">...</span> <span class="n">args</span><span class="p">);</span>
<span class="ln">46 </span>
<span class="ln">47 </span><span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">T</span><span class="p">,</span> <span class="k">class</span> <span class="nc">Alloc</span><span class="p">,</span> <span class="n">class</span><span class="p">...</span> <span class="n">Args</span><span class="o">&gt;</span>
<span class="ln">48 </span>  <span class="n">unique_ptr</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">allocator_delete</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">Alloc</span><span class="o">&amp;&gt;&gt;</span>
<span class="ln">49 </span>    <span class="n">allocate_unique</span><span class="p">(</span><span class="n">reference_wrapper</span><span class="o">&lt;</span><span class="n">Alloc</span><span class="o">&gt;</span> <span class="n">alloc</span><span class="p">,</span> <span class="n">Args</span><span class="o">&amp;&amp;</span><span class="p">...</span> <span class="n">args</span><span class="p">);</span>
</pre>
</div>
<div class="section" id="allocator-delete">
<h2><a class="toc-backref" href="#id6">allocator_delete</a></h2>
<p>The standard library already provides one type intended to be used as the <tt class="docutils literal">Deleter</tt> for <tt class="docutils literal">unique_ptr</tt>, namely <tt class="docutils literal">default_delete</tt>. The proposed <tt class="docutils literal">allocator_delete</tt> is a second standard-provided deleter which does not use the <tt class="docutils literal">delete</tt> operator but instead delegates destruction and deletion to a user-provided allocator. By default it stores a copy of the allocator and delegates the necessary operations to the stored copy. A partial specialization for allocator references is provided which only stores a reference to the actual allocator instead of a copy for cases where allocators are stateful and either too big to be carried around in every <tt class="docutils literal">unique_ptr</tt> instance or expensive to copy.</p>
<p><tt class="docutils literal">allocator_delete</tt> does not perform rebinding in its call operator. It is an error to instantiate <tt class="docutils literal">allocator_delete</tt> with a type <tt class="docutils literal">Alloc</tt> not capable of deallocating objects of type <tt class="docutils literal">T</tt>. This decision was deliberately made to avoid unnecessary rebinding and copy-constructing of potentially stateful allocators for every single deletion in the call operator.</p>
<p>Because <tt class="docutils literal">allocator_delete</tt> must be instantiated only with an allocator type capable of deallocating the intended target type it cannot be naively created from an existing allocator without doing additional work. Class template deduction guides help picking the correct template argument for <tt class="docutils literal">Alloc</tt> and hide the required allocator rebinding.</p>
<p>Constructing it with a <tt class="docutils literal">reference_wrapper&lt;Alloc&gt;</tt> argument deduces the second template argument to a reference type resulting in <tt class="docutils literal">allocator_delete</tt> storing only a reference to an allocator instead of a copy. In this case no rebinding takes place as that would necessitate copying and the user <em>deliberately</em> requested reference semantics.</p>
</div>
<div class="section" id="allocate-unique">
<h2><a class="toc-backref" href="#id7">allocate_unique</a></h2>
<p>This is the main motivation of this proposal. The above is required to implement <tt class="docutils literal">allocate_unique()</tt> but is useful enough on its own outside the scope of <tt class="docutils literal">allocate_unique()</tt> and is therefore proposed as well.</p>
<p>The <tt class="docutils literal">allocate_unique()</tt> function is not overly big but tricky enough to implement that a naive approach might be incorrect. Below is an implementation that, to the author's knowledge, is correct and exception safe. Achieving exception safety with the two-phase creation required with the allocator interface is a common oversight.</p>
<pre class="code c++ literal-block">
<span class="ln"> 1 </span><span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">T</span><span class="p">,</span> <span class="k">class</span> <span class="nc">Alloc</span><span class="p">,</span> <span class="n">class</span><span class="p">...</span> <span class="n">Args</span><span class="o">&gt;</span>
<span class="ln"> 2 </span><span class="k">auto</span> <span class="n">allocate_unique</span><span class="p">(</span><span class="k">const</span> <span class="n">Alloc</span><span class="o">&amp;</span> <span class="n">alloc</span><span class="p">,</span> <span class="n">Args</span><span class="o">&amp;&amp;</span><span class="p">...</span> <span class="n">args</span><span class="p">)</span> <span class="p">{</span>
<span class="ln"> 3 </span>  <span class="k">using</span> <span class="n">traits</span> <span class="o">=</span> <span class="k">typename</span> <span class="n">allocator_traits</span><span class="o">&lt;</span><span class="n">Alloc</span><span class="o">&gt;::</span><span class="k">template</span> <span class="n">rebind_traits</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">;</span>
<span class="ln"> 4 </span>  <span class="k">auto</span> <span class="n">my_alloc</span> <span class="o">=</span> <span class="k">typename</span> <span class="n">traits</span><span class="o">::</span><span class="n">allocator_type</span><span class="p">(</span><span class="n">alloc</span><span class="p">);</span>
<span class="ln"> 5 </span>  <span class="k">auto</span> <span class="n">hold_deleter</span> <span class="o">=</span> <span class="p">[</span><span class="o">&amp;</span><span class="n">my_alloc</span><span class="p">]</span> <span class="p">(</span><span class="k">auto</span> <span class="n">p</span><span class="p">)</span> <span class="p">{</span>
<span class="ln"> 6 </span>    <span class="n">traits</span><span class="o">::</span><span class="n">deallocate</span><span class="p">(</span><span class="n">my_alloc</span><span class="p">,</span> <span class="n">p</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
<span class="ln"> 7 </span>  <span class="p">};</span>
<span class="ln"> 8 </span>  <span class="k">using</span> <span class="n">hold_t</span> <span class="o">=</span> <span class="n">unique_ptr</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="k">decltype</span><span class="p">(</span><span class="n">hold_deleter</span><span class="p">)</span><span class="o">&gt;</span><span class="p">;</span>
<span class="ln"> 9 </span>  <span class="k">auto</span> <span class="n">hold</span> <span class="o">=</span> <span class="n">hold_t</span><span class="p">(</span><span class="n">traits</span><span class="o">::</span><span class="n">allocate</span><span class="p">(</span><span class="n">my_alloc</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="n">hold_deleter</span><span class="p">);</span>
<span class="ln">10 </span>  <span class="n">traits</span><span class="o">::</span><span class="n">construct</span><span class="p">(</span><span class="n">my_alloc</span><span class="p">,</span> <span class="n">hold</span><span class="p">.</span><span class="n">get</span><span class="p">(),</span> <span class="n">forward</span><span class="o">&lt;</span><span class="n">Args</span><span class="o">&gt;</span><span class="p">(</span><span class="n">args</span><span class="p">)...);</span>
<span class="ln">11 </span>  <span class="k">auto</span> <span class="n">deleter</span> <span class="o">=</span> <span class="n">allocator_delete</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">(</span><span class="n">my_alloc</span><span class="p">);</span>
<span class="ln">12 </span>  <span class="k">return</span> <span class="n">unique_ptr</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="k">decltype</span><span class="p">(</span><span class="n">deleter</span><span class="p">)</span><span class="o">&gt;</span><span class="p">{</span><span class="n">hold</span><span class="p">.</span><span class="n">release</span><span class="p">(),</span> <span class="n">move</span><span class="p">(</span><span class="n">deleter</span><span class="p">)};</span>
<span class="ln">13 </span><span class="p">}</span>
</pre>
<p>Implementations very similar to the above can be found in numerous libraries and standard implementations. It is a pattern of boilerplate that is repeated frequently enough that it should be included in the standard. Often the intermediary use of a RAII wrapper around the <tt class="docutils literal">allocate</tt>-<tt class="docutils literal">deallocate</tt> pair is forgotten thus resulting in memory leaks if the constructor of <tt class="docutils literal">T</tt> throws. This is a trap people should not have to worry about in the first place.</p>
</div>
</div>
<div class="section" id="applications-outside-of-allocate-unique">
<h1><a class="toc-backref" href="#id8">Applications Outside of allocate_unique</a></h1>
<p><tt class="docutils literal">allocator_delete</tt> is technically not required to be made available in the standard library's public interface as it can be easily marked as <em>implementation-defined</em> in the return type of <tt class="docutils literal">allocate_unique()</tt> as is currently done for the return type of <tt class="docutils literal">bind()</tt>. However its utility shows itself even in other applications for which some examples are given here to convince the reader of their usefulness.</p>
<div class="section" id="node-based-containers">
<h2><a class="toc-backref" href="#id9">Node-Based Containers</a></h2>
<p>Node-based containers like <tt class="docutils literal">map</tt> or <tt class="docutils literal">list</tt> do typically not store a <tt class="docutils literal">unique_ptr</tt> referencing each and every node. That would store <tt class="docutils literal">n</tt> copies of the deleter which would each have to either copy the allocator for every node or store a reference to the allocator to utilize automatic cleanup. Both are unnecessarily wasteful. The latter establishes a <em>back reference</em> from the node to the container, meaning the container becomes expensive to move as all the back references have to be updated. Instead these containers typically manually allocate/deallocate each node, store them as raw pointers, and because the type of a node is virtually never the same type as the payload, rebinding the allocator for the node type is necessary as well. Then for actually allocating each node a procedure similar to the above is performed, followed later by the manual deletion.</p>
<p>This means in practice something like this:</p>
<pre class="code c++ literal-block">
<span class="ln"> 1 </span><span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">T</span><span class="p">,</span> <span class="k">class</span> <span class="nc">Alloc</span><span class="o">&gt;</span>
<span class="ln"> 2 </span><span class="k">class</span> <span class="nc">list</span> <span class="p">{</span>
<span class="ln"> 3 </span>  <span class="k">struct</span> <span class="n">node</span> <span class="p">{</span>
<span class="ln"> 4 </span>    <span class="n">node</span><span class="o">*</span> <span class="n">next</span><span class="p">;</span>
<span class="ln"> 5 </span>    <span class="n">T</span> <span class="n">payload</span><span class="p">;</span>
<span class="ln"> 6 </span>    <span class="p">...</span>
<span class="ln"> 7 </span>  <span class="p">}</span>
<span class="ln"> 8 </span>  <span class="k">using</span> <span class="n">node_allocator</span> <span class="o">=</span> <span class="k">typename</span> <span class="n">allocator_traits</span><span class="o">&lt;</span><span class="n">Alloc</span><span class="o">&gt;::</span><span class="k">template</span> <span class="n">rebind_alloc</span><span class="o">&lt;</span><span class="n">node</span><span class="o">&gt;</span><span class="p">;</span>
<span class="ln"> 9 </span>  <span class="k">using</span> <span class="n">traits</span> <span class="o">=</span> <span class="n">allocator_traits</span><span class="o">&lt;</span><span class="n">node_allocator</span><span class="o">&gt;</span><span class="p">;</span>
<span class="ln">10 </span>  <span class="n">node_allocator</span> <span class="n">alloc</span><span class="p">;</span>
<span class="ln">11 </span>
<span class="ln">12 </span>  <span class="p">...</span>
<span class="ln">13 </span>
<span class="ln">14 </span><span class="k">public</span><span class="o">:</span>
<span class="ln">15 </span>  <span class="kt">void</span> <span class="n">push_back</span><span class="p">(</span><span class="n">T</span> <span class="n">x</span><span class="p">)</span> <span class="p">{</span>
<span class="ln">16 </span>    <span class="k">auto</span> <span class="n">hold_deleter</span> <span class="o">=</span> <span class="p">[</span><span class="o">&amp;</span><span class="n">alloc</span><span class="p">]</span> <span class="p">(</span><span class="k">auto</span> <span class="n">p</span><span class="p">)</span> <span class="p">{</span>
<span class="ln">17 </span>      <span class="n">traits</span><span class="o">::</span><span class="n">deallocate</span><span class="p">(</span><span class="n">alloc</span><span class="p">,</span> <span class="n">p</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
<span class="ln">18 </span>    <span class="p">};</span>
<span class="ln">19 </span>    <span class="k">using</span> <span class="n">hold_t</span> <span class="o">=</span> <span class="n">unique_ptr</span><span class="o">&lt;</span><span class="n">node</span><span class="p">,</span> <span class="k">decltype</span><span class="p">(</span><span class="n">hold_deleter</span><span class="p">)</span><span class="o">&gt;</span><span class="p">;</span>
<span class="ln">20 </span>    <span class="k">auto</span> <span class="n">hold</span> <span class="o">=</span> <span class="n">hold_t</span><span class="p">(</span><span class="n">traits</span><span class="o">::</span><span class="n">allocate</span><span class="p">(</span><span class="n">alloc</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="n">hold_deleter</span><span class="p">);</span>
<span class="ln">21 </span>    <span class="n">traits</span><span class="o">::</span><span class="n">construct</span><span class="p">(</span><span class="n">alloc</span><span class="p">,</span> <span class="n">hold</span><span class="p">.</span><span class="n">get</span><span class="p">(),</span> <span class="p">...);</span>
<span class="ln">22 </span>    <span class="n">append_node_to_list</span><span class="p">(</span><span class="n">hold</span><span class="p">.</span><span class="n">release</span><span class="p">());</span> <span class="c1">// noexcept
</span><span class="ln">23 </span><span class="c1"></span>  <span class="p">}</span>
<span class="ln">24 </span>
<span class="ln">25 </span>  <span class="o">~</span><span class="n">list</span><span class="p">()</span> <span class="p">{</span>
<span class="ln">26 </span>    <span class="k">for</span><span class="p">(</span><span class="k">auto</span><span class="o">*</span> <span class="nl">node</span> <span class="p">:</span> <span class="n">nodes</span><span class="p">())</span> <span class="p">{</span>
<span class="ln">27 </span>      <span class="n">traits</span><span class="o">::</span><span class="n">destroy</span><span class="p">(</span><span class="n">alloc</span><span class="p">,</span> <span class="n">node</span><span class="p">);</span>
<span class="ln">28 </span>      <span class="n">traits</span><span class="o">::</span><span class="n">deallocate</span><span class="p">(</span><span class="n">alloc</span><span class="p">,</span> <span class="n">node</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
<span class="ln">29 </span>    <span class="p">}</span>
<span class="ln">30 </span>  <span class="p">}</span>
<span class="ln">31 </span><span class="p">};</span>
</pre>
<p>Compare this to using the utilities proposed in this paper:</p>
<pre class="code c++ literal-block">
<span class="ln"> 1 </span><span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">T</span><span class="p">,</span> <span class="k">class</span> <span class="nc">Alloc</span><span class="o">&gt;</span>
<span class="ln"> 2 </span><span class="k">class</span> <span class="nc">list</span> <span class="p">{</span>
<span class="ln"> 3 </span>  <span class="k">struct</span> <span class="n">node</span> <span class="p">{</span>
<span class="ln"> 4 </span>    <span class="n">node</span><span class="o">*</span> <span class="n">next</span><span class="p">;</span>
<span class="ln"> 5 </span>    <span class="n">T</span> <span class="n">payload</span><span class="p">;</span>
<span class="ln"> 6 </span>    <span class="p">...</span>
<span class="ln"> 7 </span>  <span class="p">}</span>
<span class="ln"> 8 </span>  <span class="k">using</span> <span class="n">node_allocator</span> <span class="o">=</span> <span class="k">typename</span> <span class="n">allocator_traits</span><span class="o">&lt;</span><span class="n">Alloc</span><span class="o">&gt;::</span><span class="k">template</span> <span class="n">rebind_alloc</span><span class="o">&lt;</span><span class="n">node</span><span class="o">&gt;</span><span class="p">;</span>
<span class="ln"> 9 </span>  <span class="n">node_allocator</span> <span class="n">alloc</span><span class="p">;</span>
<span class="ln">10 </span>
<span class="ln">11 </span>  <span class="p">...</span>
<span class="ln">12 </span>
<span class="ln">13 </span><span class="k">public</span><span class="o">:</span>
<span class="ln">14 </span>  <span class="kt">void</span> <span class="n">push_back</span><span class="p">(</span><span class="n">T</span> <span class="n">x</span><span class="p">)</span> <span class="p">{</span>
<span class="ln">15 </span>    <span class="k">auto</span> <span class="n">p</span> <span class="o">=</span> <span class="n">allocate_unique</span><span class="o">&lt;</span><span class="n">node</span><span class="o">&gt;</span><span class="p">(</span><span class="n">ref</span><span class="p">(</span><span class="n">alloc</span><span class="p">),</span> <span class="p">...);</span>
<span class="ln">16 </span>    <span class="n">append_node_to_list</span><span class="p">(</span><span class="n">p</span><span class="p">.</span><span class="n">release</span><span class="p">());</span> <span class="c1">// noexcept
</span><span class="ln">17 </span><span class="c1"></span>  <span class="p">}</span>
<span class="ln">18 </span>
<span class="ln">19 </span>  <span class="o">~</span><span class="n">list</span><span class="p">()</span> <span class="p">{</span>
<span class="ln">20 </span>    <span class="k">auto</span> <span class="n">del</span> <span class="o">=</span> <span class="n">allocator_delete</span><span class="o">&lt;</span><span class="n">node</span><span class="o">&gt;</span><span class="p">(</span><span class="n">ref</span><span class="p">(</span><span class="n">alloc</span><span class="p">));</span>
<span class="ln">21 </span>    <span class="k">for</span><span class="p">(</span><span class="k">auto</span><span class="o">*</span> <span class="nl">node</span> <span class="p">:</span> <span class="n">nodes</span><span class="p">())</span> <span class="p">{</span>
<span class="ln">22 </span>      <span class="n">del</span><span class="p">(</span><span class="n">node</span><span class="p">);</span>
<span class="ln">23 </span>    <span class="p">}</span>
<span class="ln">24 </span>  <span class="p">}</span>
<span class="ln">25 </span><span class="p">};</span>
</pre>
<p>It may not seem like much but the parts that were replaced in the second snippet were the most error-prone. It has much less fiddling around with <tt class="docutils literal">allocator_traits</tt> and one did not have to bother themselves with the nature of two-phase initialization and teardown of objects imposed by the allocator interface.</p>
</div>
<div class="section" id="type-erasure">
<h2><a class="toc-backref" href="#id10">Type Erasure</a></h2>
<p>Containers like <tt class="docutils literal">function</tt> or <tt class="docutils literal">shared_ptr</tt> employ a technique called <em>type erasure</em> where the exact type of the stored object is not visible in the container's type signature. Implementations often rely on using an internal abstract base class from which concrete class templates are derived. If the container has support for user-provided allocators then the allocator has to be stored somewhere as well. But because the type of the allocator is not part of the container's type signature it, too, must be erased. This means both the payload <em>and</em> the actual allocator are part of the internal object, often simply combined into a <tt class="docutils literal">tuple&lt;Alloc, T&gt;</tt>.</p>
<p>Below is an excerpt showing how such type erasure is frequently implemented:</p>
<pre class="code c++ literal-block">
<span class="ln"> 1 </span><span class="k">class</span> <span class="nc">any</span> <span class="p">{</span>
<span class="ln"> 2 </span>  <span class="k">struct</span> <span class="n">base</span> <span class="p">{</span>
<span class="ln"> 3 </span>    <span class="k">virtual</span> <span class="kt">void</span> <span class="n">destroy</span><span class="p">()</span> <span class="k">noexcept</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="ln"> 4 </span>    <span class="k">virtual</span> <span class="kt">void</span> <span class="nf">do_something</span><span class="p">()</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="ln"> 5 </span>  <span class="k">protected</span><span class="o">:</span>
<span class="ln"> 6 </span>    <span class="o">~</span><span class="n">base</span><span class="p">()</span> <span class="o">=</span> <span class="k">default</span><span class="p">;</span>
<span class="ln"> 7 </span>  <span class="p">}</span>
<span class="ln"> 8 </span>
<span class="ln"> 9 </span>  <span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">Alloc</span><span class="p">,</span> <span class="k">class</span> <span class="nc">T</span><span class="o">&gt;</span>
<span class="ln">10 </span>  <span class="k">struct</span> <span class="nl">derived</span> <span class="p">:</span> <span class="n">base</span> <span class="p">{</span>
<span class="ln">11 </span>    <span class="n">derived</span><span class="p">(</span><span class="k">const</span> <span class="n">Alloc</span><span class="o">&amp;</span> <span class="n">alloc</span><span class="p">,</span> <span class="n">T</span> <span class="n">x</span><span class="p">);</span>
<span class="ln">12 </span>    <span class="kt">void</span> <span class="nf">destroy</span><span class="p">()</span> <span class="k">noexcept</span> <span class="k">override</span> <span class="p">{</span>
<span class="ln">13 </span>      <span class="k">using</span> <span class="n">rebind</span> <span class="o">=</span> <span class="k">typename</span> <span class="n">allocator_traits</span><span class="o">&lt;</span><span class="n">Alloc</span><span class="o">&gt;::</span><span class="k">template</span> <span class="n">rebind_alloc</span><span class="o">&lt;</span><span class="n">derived</span><span class="o">&gt;</span><span class="p">;</span> <span class="c1">// X
</span><span class="ln">14 </span><span class="c1"></span>      <span class="k">auto</span> <span class="n">alloc</span> <span class="o">=</span> <span class="n">rebind</span><span class="p">{</span><span class="n">move</span><span class="p">(</span><span class="n">get</span><span class="o">&lt;</span><span class="mi">0</span><span class="o">&gt;</span><span class="p">(</span><span class="n">data</span><span class="p">))};</span>                                         <span class="c1">// X
</span><span class="ln">15 </span><span class="c1"></span>      <span class="k">auto</span><span class="o">*</span> <span class="n">p</span> <span class="o">=</span> <span class="k">this</span><span class="p">;</span>                                                                  <span class="c1">// X
</span><span class="ln">16 </span><span class="c1"></span>      <span class="n">allocator_traits</span><span class="o">&lt;</span><span class="n">rebind</span><span class="o">&gt;::</span><span class="n">destroy</span><span class="p">(</span><span class="n">alloc</span><span class="p">,</span> <span class="n">p</span><span class="p">);</span>                                     <span class="c1">// X
</span><span class="ln">17 </span><span class="c1"></span>      <span class="n">allocator_traits</span><span class="o">&lt;</span><span class="n">rebind</span><span class="o">&gt;::</span><span class="n">deallocate</span><span class="p">(</span><span class="n">alloc</span><span class="p">,</span> <span class="n">p</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>                               <span class="c1">// X
</span><span class="ln">18 </span><span class="c1"></span>    <span class="p">}</span>
<span class="ln">19 </span>    <span class="kt">void</span> <span class="nf">do_something</span><span class="p">()</span> <span class="k">override</span> <span class="p">{</span> <span class="p">...</span> <span class="p">}</span>
<span class="ln">20 </span>    <span class="n">tuple</span><span class="o">&lt;</span><span class="n">Alloc</span><span class="p">,</span> <span class="n">T</span><span class="o">&gt;</span> <span class="n">data</span><span class="p">;</span>
<span class="ln">21 </span>  <span class="p">};</span>
<span class="ln">22 </span>
<span class="ln">23 </span>  <span class="n">base</span><span class="o">*</span> <span class="n">value</span><span class="p">;</span>
<span class="ln">24 </span>
<span class="ln">25 </span><span class="k">public</span><span class="o">:</span>
<span class="ln">26 </span>  <span class="p">...</span>
<span class="ln">27 </span>
<span class="ln">28 </span>  <span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">Alloc</span><span class="p">,</span> <span class="k">class</span> <span class="nc">T</span><span class="o">&gt;</span>
<span class="ln">29 </span>  <span class="kt">void</span> <span class="n">assign</span><span class="p">(</span><span class="k">const</span> <span class="n">Alloc</span><span class="o">&amp;</span> <span class="n">alloc</span><span class="p">,</span> <span class="n">T</span> <span class="n">x</span><span class="p">)</span> <span class="p">{</span>
<span class="ln">30 </span>    <span class="k">using</span> <span class="n">node</span> <span class="o">=</span> <span class="n">derived</span><span class="o">&lt;</span><span class="n">Alloc</span><span class="p">,</span> <span class="n">T</span><span class="o">&gt;</span><span class="p">;</span>
<span class="ln">31 </span>    <span class="k">using</span> <span class="n">rebind</span> <span class="o">=</span> <span class="k">typename</span> <span class="n">allocator_traits</span><span class="o">&lt;</span><span class="n">Alloc</span><span class="o">&gt;::</span><span class="k">template</span> <span class="n">rebind_alloc</span><span class="o">&lt;</span><span class="n">node</span><span class="o">&gt;</span><span class="p">;</span> <span class="c1">// X
</span><span class="ln">32 </span><span class="c1"></span>    <span class="k">using</span> <span class="n">traits</span> <span class="o">=</span> <span class="n">allocator_traits</span><span class="o">&lt;</span><span class="n">rebind</span><span class="o">&gt;</span><span class="p">;</span>                                      <span class="c1">// X
</span><span class="ln">33 </span><span class="c1"></span>    <span class="k">auto</span> <span class="n">node_alloc</span> <span class="o">=</span> <span class="n">rebind</span><span class="p">{</span><span class="n">alloc</span><span class="p">};</span>                                              <span class="c1">// X
</span><span class="ln">34 </span><span class="c1"></span>    <span class="k">auto</span> <span class="n">hold_deleter</span> <span class="o">=</span> <span class="p">[</span><span class="o">&amp;</span><span class="n">node_alloc</span><span class="p">]</span> <span class="p">(</span><span class="k">auto</span> <span class="n">p</span><span class="p">)</span> <span class="p">{</span>                                  <span class="c1">// X
</span><span class="ln">35 </span><span class="c1"></span>      <span class="n">traits</span><span class="o">::</span><span class="n">deallocate</span><span class="p">(</span><span class="n">node_alloc</span><span class="p">,</span> <span class="n">p</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>                                       <span class="c1">// X
</span><span class="ln">36 </span><span class="c1"></span>    <span class="p">};</span>                                                                            <span class="c1">// X
</span><span class="ln">37 </span><span class="c1"></span>    <span class="k">using</span> <span class="n">hold_t</span> <span class="o">=</span> <span class="n">unique_ptr</span><span class="o">&lt;</span><span class="n">node</span><span class="p">,</span> <span class="k">decltype</span><span class="p">(</span><span class="n">hold_deleter</span><span class="p">)</span><span class="o">&gt;</span><span class="p">;</span>                      <span class="c1">// X
</span><span class="ln">38 </span><span class="c1"></span>    <span class="k">auto</span> <span class="n">hold</span> <span class="o">=</span> <span class="n">hold_t</span><span class="p">(</span><span class="n">traits</span><span class="o">::</span><span class="n">allocate</span><span class="p">(</span><span class="n">node_alloc</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="n">hold_deleter</span><span class="p">);</span>            <span class="c1">// X
</span><span class="ln">39 </span><span class="c1"></span>    <span class="n">traits</span><span class="o">::</span><span class="n">construct</span><span class="p">(</span><span class="n">node_alloc</span><span class="p">,</span> <span class="n">hold</span><span class="p">.</span><span class="n">get</span><span class="p">(),</span> <span class="n">alloc</span><span class="p">,</span> <span class="n">move</span><span class="p">(</span><span class="n">x</span><span class="p">));</span>                    <span class="c1">// X
</span><span class="ln">40 </span><span class="c1"></span>    <span class="k">if</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> <span class="p">{</span>
<span class="ln">41 </span>      <span class="n">value</span><span class="o">-&gt;</span><span class="n">destroy</span><span class="p">();</span>
<span class="ln">42 </span>    <span class="p">}</span>
<span class="ln">43 </span>    <span class="n">value</span> <span class="o">=</span> <span class="n">hold</span><span class="p">.</span><span class="n">release</span><span class="p">();</span>
<span class="ln">44 </span>  <span class="p">}</span>
<span class="ln">45 </span>  <span class="o">~</span><span class="n">any</span> <span class="p">{</span>
<span class="ln">46 </span>    <span class="k">if</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> <span class="p">{</span>
<span class="ln">47 </span>      <span class="n">value</span><span class="o">-&gt;</span><span class="n">destroy</span><span class="p">();</span>
<span class="ln">48 </span>    <span class="p">}</span>
<span class="ln">49 </span>  <span class="p">}</span>
<span class="ln">50 </span><span class="p">};</span>
</pre>
<p>About half the functional code in this example (marked with <tt class="docutils literal">X</tt>) does the allocator dance. The above can be significantly simplified with the proper tools:</p>
<pre class="code c++ literal-block">
<span class="ln"> 1 </span><span class="k">class</span> <span class="nc">any</span> <span class="p">{</span>
<span class="ln"> 2 </span>  <span class="k">struct</span> <span class="n">base</span> <span class="p">{</span>
<span class="ln"> 3 </span>    <span class="k">virtual</span> <span class="kt">void</span> <span class="n">destroy</span><span class="p">()</span> <span class="k">noexcept</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="ln"> 4 </span>    <span class="k">virtual</span> <span class="kt">void</span> <span class="nf">do_something</span><span class="p">()</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="ln"> 5 </span>  <span class="k">protected</span><span class="o">:</span>
<span class="ln"> 6 </span>    <span class="o">~</span><span class="n">base</span><span class="p">()</span> <span class="o">=</span> <span class="k">default</span><span class="p">;</span>
<span class="ln"> 7 </span>  <span class="p">}</span>
<span class="ln"> 8 </span>
<span class="ln"> 9 </span>  <span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">Alloc</span><span class="p">,</span> <span class="k">class</span> <span class="nc">T</span><span class="o">&gt;</span>
<span class="ln">10 </span>  <span class="k">struct</span> <span class="nl">derived</span> <span class="p">:</span> <span class="n">base</span> <span class="p">{</span>
<span class="ln">11 </span>    <span class="n">derived</span><span class="p">(</span><span class="k">const</span> <span class="n">Alloc</span><span class="o">&amp;</span> <span class="n">alloc</span><span class="p">,</span> <span class="n">T</span> <span class="n">x</span><span class="p">);</span>
<span class="ln">12 </span>    <span class="kt">void</span> <span class="nf">destroy</span><span class="p">()</span> <span class="k">noexcept</span> <span class="k">override</span> <span class="p">{</span>
<span class="ln">13 </span>      <span class="k">auto</span> <span class="n">deleter</span> <span class="o">=</span> <span class="n">allocator_delete</span><span class="o">&lt;</span><span class="n">derived</span><span class="o">&gt;</span><span class="p">(</span><span class="n">move</span><span class="p">(</span><span class="n">get</span><span class="o">&lt;</span><span class="mi">0</span><span class="o">&gt;</span><span class="p">(</span><span class="n">data</span><span class="p">)));</span> <span class="c1">// X
</span><span class="ln">14 </span><span class="c1"></span>      <span class="n">deleter</span><span class="p">(</span><span class="k">this</span><span class="p">);</span>                                                <span class="c1">// X
</span><span class="ln">15 </span><span class="c1"></span>    <span class="p">}</span>
<span class="ln">16 </span>    <span class="kt">void</span> <span class="nf">do_something</span><span class="p">()</span> <span class="k">override</span> <span class="p">{</span> <span class="p">...</span> <span class="p">}</span>
<span class="ln">17 </span>    <span class="n">tuple</span><span class="o">&lt;</span><span class="n">Alloc</span><span class="p">,</span> <span class="n">T</span><span class="o">&gt;</span> <span class="n">data</span><span class="p">;</span>
<span class="ln">18 </span>  <span class="p">};</span>
<span class="ln">19 </span>
<span class="ln">20 </span>  <span class="n">base</span><span class="o">*</span> <span class="n">value</span><span class="p">;</span>
<span class="ln">21 </span>
<span class="ln">22 </span><span class="k">public</span><span class="o">:</span>
<span class="ln">23 </span>  <span class="p">...</span>
<span class="ln">24 </span>
<span class="ln">25 </span>  <span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">Alloc</span><span class="p">,</span> <span class="k">class</span> <span class="nc">T</span><span class="o">&gt;</span>
<span class="ln">26 </span>  <span class="kt">void</span> <span class="n">assign</span><span class="p">(</span><span class="k">const</span> <span class="n">Alloc</span><span class="o">&amp;</span> <span class="n">alloc</span><span class="p">,</span> <span class="n">T</span> <span class="n">x</span><span class="p">)</span> <span class="p">{</span>
<span class="ln">27 </span>    <span class="k">using</span> <span class="n">node</span> <span class="o">=</span> <span class="n">derived</span><span class="o">&lt;</span><span class="n">Alloc</span><span class="p">,</span> <span class="n">T</span><span class="o">&gt;</span><span class="p">;</span>
<span class="ln">28 </span>    <span class="k">auto</span> <span class="n">p</span> <span class="o">=</span> <span class="n">allocate_unique</span><span class="o">&lt;</span><span class="n">node</span><span class="o">&gt;</span><span class="p">(</span><span class="n">alloc</span><span class="p">,</span> <span class="n">alloc</span><span class="p">,</span> <span class="n">x</span><span class="p">);</span> <span class="c1">// X
</span><span class="ln">29 </span><span class="c1"></span>    <span class="k">if</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> <span class="p">{</span>
<span class="ln">30 </span>      <span class="n">value</span><span class="o">-&gt;</span><span class="n">destroy</span><span class="p">();</span>
<span class="ln">31 </span>    <span class="p">}</span>
<span class="ln">32 </span>    <span class="n">value</span> <span class="o">=</span> <span class="n">p</span><span class="p">.</span><span class="n">release</span><span class="p">();</span>
<span class="ln">33 </span>  <span class="p">}</span>
<span class="ln">34 </span>  <span class="o">~</span><span class="n">any</span> <span class="p">{</span>
<span class="ln">35 </span>    <span class="k">if</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> <span class="p">{</span>
<span class="ln">36 </span>      <span class="n">value</span><span class="o">-&gt;</span><span class="n">destroy</span><span class="p">();</span>
<span class="ln">37 </span>    <span class="p">}</span>
<span class="ln">38 </span>  <span class="p">}</span>
<span class="ln">39 </span><span class="p">};</span>
</pre>
<p>In the altered example only <em>three lines of code</em> (marked with <tt class="docutils literal">X</tt>) deal with creation and destuction of the type erased objects with a custom allocator. Note that we pass the allocator twice to <tt class="docutils literal">allocate_unique()</tt> as the first argument is the allocator used to allocate the node (automatically rebound for us to the compatible type) and the second argument is forwarded to the allocated node to make a copy available for the <tt class="docutils literal">destroy()</tt> method.</p>
</div>
</div>
<div class="section" id="open-issues">
<h1><a class="toc-backref" href="#id11">Open Issues</a></h1>
<div class="section" id="allocate-unique-t">
<h2><a class="toc-backref" href="#id12">allocate_unique&lt;T[]&gt;</a></h2>
<p>The current design of <tt class="docutils literal">unique_ptr</tt> and the associated deleter means we cannot make <tt class="docutils literal">allocator_delete</tt> compatible with the array-based <tt class="docutils literal"><span class="pre">unique_ptr&lt;T[]&gt;</span></tt> specialization because there is no way to tell the deleter how many objects to delete. <tt class="docutils literal">default_delete</tt> circumvents this problem because the <tt class="docutils literal">delete[]</tt> operator knows how many elements were allocated with <tt class="docutils literal">new T[]</tt> and it combines both destruction and deallocation in one operation. In contrast the allocator interface imposes a two-phase cleanup process. Making <tt class="docutils literal">allocator_delete</tt> universally compatible with array-based <tt class="docutils literal"><span class="pre">unique_ptr&lt;T[]&gt;</span></tt> requires either the addition of a second overload to the deleter's call operator with the signature <tt class="docutils literal">void(pointer p, size_t n)</tt> which <tt class="docutils literal"><span class="pre">unique_ptr&lt;T[]&gt;</span></tt> would prefer if present, or make it store the number of allocated elements in advance.</p>
<p>Therefore <tt class="docutils literal">allocate_unique()</tt> with its first template parameter being of the form <tt class="docutils literal">T[]</tt> is currently considered ill-formed until this issue finds a resolution.</p>
</div>
</div>
<div class="section" id="summary">
<h1><a class="toc-backref" href="#id13">Summary</a></h1>
<p>Experience shows that the mechanism abstracted behind <tt class="docutils literal">allocate_unique()</tt> is widely re-invented in many projects. Standard library implementations already have it for internal use but people still have to implement their own. As shown in this proposal doing so correctly is tricky and requires more knowledge about the interface of allocators than is usually necessary to actually do the required job. As such the barrier of entry to providing allocator support in a library is often very high as doing it properly involves careful studying of the allocator interface which many consider to be expert-level territory and prefer not to touch with a ten foot pole.</p>
<p>The provided examples show how making internal utilities used to implement <tt class="docutils literal">allocate_unique()</tt> available as part of the public interface can greatly help in adding allocator support to other data structures by significantly cutting down on the required boilerplate.</p>
</div>
<div class="section" id="proposed-wording">
<h1><a class="toc-backref" href="#id14">Proposed Wording</a></h1>
<p>These changes are based on <a class="citation-reference" href="#n4618" id="id1">[N4618]</a>.</p>
<ol class="arabic">
<li><p class="first">Change 20.11.1 [unique.ptr] paragraph 6 as follows:</p>
<blockquote>
<pre class="literal-block">
template&lt;class T&gt; struct default_delete;
template&lt;class T&gt; struct default_delete&lt;T[]&gt;;
</pre>
<pre class="insert literal-block">
template&lt;class T, class Alloc&gt; class allocator_delete;
template&lt;class T, class Alloc&gt; class allocator_delete&lt;T, Alloc&amp;&gt;;

template&lt;class T, class Alloc&gt;
allocator_delete(Alloc&amp;&amp; alloc)
  -&gt; allocator_delete&lt;T, typename allocator_traits&lt;Alloc&gt;::template rebind_alloc&lt;T&gt;&gt;;

template&lt;class T, class Alloc&gt;
allocator_delete(reference_wrapper&lt;Alloc&gt; alloc)
  -&gt; allocator_delete&lt;T, Alloc&amp;&gt;;
</pre>
<pre class="literal-block">
template&lt;class T, class D = default_delete&lt;T&gt;&gt; class unique_ptr;
template&lt;class T, class D&gt; class unique_ptr&lt;T[], D&gt;;

template&lt;class T, class... Args&gt; unique_ptr&lt;T&gt; make_unique(Args&amp;&amp;... args);
template&lt;class T&gt; unique_ptr&lt;T&gt; make_unique(size_t n);
template&lt;class T, class... Args&gt; unspecified make_unique(Args&amp;&amp;...) = delete;
</pre>
<pre class="insert literal-block">
template&lt;class T, class Alloc, class... Args&gt;
  unique_ptr&lt;T, see below&gt; allocate_unique(Alloc&amp;&amp; alloc, Args&amp;&amp;... args);
template&lt;class T, class Alloc, class... Args&gt;
  unique_ptr&lt;T, see below&gt; allocate_unique(reference_wrapper&lt;Alloc&gt; alloc, Args&amp;&amp;... args);
template&lt;class T, class Alloc, class... Args&gt;
  unspecified allocate_unique(Alloc&amp;&amp; alloc, Args&amp;&amp;... args) = delete;
</pre>
<pre class="literal-block">
template&lt;class T, class D&gt; void swap(unique_ptr&lt;T, D&gt;&amp; x, unique_ptr&lt;T, D&gt;&amp; y) noexcept;
</pre>
</blockquote>
</li>
<li><p class="first">Add a new section to 20.11.1 [unique.ptr] as follows:</p>
<blockquote>
<p class="std-section">20.11.1.x Allocator deleter [unique.ptr.allocdltr]</p>
<p class="std-section">20.11.1.x.1 In general [unique.ptr.allocdltr.general]</p>
<p>The class template <tt class="docutils literal">allocator_delete</tt> delegates deletion to client-supplied allocators when used as deleter (destruction policy) for the class template <tt class="docutils literal">unique_ptr</tt>.</p>
<p>The template parameter <tt class="docutils literal">Alloc</tt> of <tt class="docutils literal">allocator_delete</tt> shall satisfy the requirements of <tt class="docutils literal">Allocator</tt> (Table 31) unless it is a reference type in which case the requirement applies to the referred-to type.</p>
<p>The template parameter <tt class="docutils literal">Alloc</tt> of <tt class="docutils literal">allocator_delete</tt> shall not be a rvalue reference type.</p>
<p>The template parameter <tt class="docutils literal">T</tt> of <tt class="docutils literal">allocator_delete</tt> may be an incomplete type if the used allocator satisfies the allocator completeness requirements 17.5.3.5.1.</p>
<p class="std-note">[Note: The intended way of creating <tt class="docutils literal">allocator_delete</tt> objects is utilizing the class template deduction guides via <tt class="docutils literal"><span class="pre">allocator_delete&lt;T&gt;(alloc)</span></tt> and <tt class="docutils literal"><span class="pre">allocator_delete&lt;T&gt;(ref(alloc))</span></tt> (where <tt class="docutils literal">alloc</tt> is an allocator) which take care of allocator rebinding. -end note]</p>
<p class="std-section">20.11.1.x.2 <tt class="docutils literal">allocator_delete</tt> [unique.ptr.allocdltr.copy]</p>
<pre class="literal-block">
namespace std {
  template&lt;class T, class Alloc&gt;
  class allocator_delete {
  public:
    using allocator_type = remove_cv_t&lt;Alloc&gt;;
    using pointer = typename allocator_traits&lt;allocator_type&gt;::pointer;

    template&lt;class OtherAlloc&gt;
      allocator_delete(OtherAlloc&amp;&amp; other) noexcept;
    template&lt;class U, class OtherAlloc&gt;
      allocator_delete(const allocator_delete&lt;U, OtherAlloc&gt;&amp; other) noexcept;
    template&lt;class U, class OtherAlloc&gt;
      allocator_delete(allocator_delete&lt;U, OtherAlloc&gt;&amp;&amp; other) noexcept;

    template&lt;class U, class OtherAlloc&gt;
      allocator_delete&amp; operator=(const allocator_delete&lt;U, OtherAlloc&gt;&amp; other) noexcept;
    template&lt;class U, class OtherAlloc&gt;
      allocator_delete&amp; operator=(allocator_delete&lt;U, OtherAlloc&gt;&amp;&amp; other) noexcept;

    void operator()(pointer p);

    Alloc&amp; get_allocator() noexcept;
    const Alloc&amp; get_allocator() const noexcept;

    void swap(allocator_delete&amp; other) noexcept;

  private:
    Alloc alloc; // for exposition only
  };
}
</pre>
<p>The primary class template <tt class="docutils literal">allocator_delete</tt> delegates the deletion operation to an instance of <tt class="docutils literal">Alloc</tt> stored as part of the deleter.</p>
<p class="std-section"><tt class="docutils literal">template&lt;class OtherAlloc&gt; allocator_delete(OtherAlloc&amp;&amp; other) noexcept;</tt></p>
<blockquote>
<p><em>Requires:</em> <tt class="docutils literal">OtherAlloc</tt> shall satisfy the requirements of <tt class="docutils literal">Allocator</tt> (Table 31).</p>
<p><em>Effects:</em> Constructs an <tt class="docutils literal">allocator_delete</tt> object initializing the stored allocator with <tt class="docutils literal"><span class="pre">forward&lt;OtherAlloc&gt;(other)</span></tt>.</p>
<p><em>Remarks:</em> This constructor shall not participate in overload resolution unless <tt class="docutils literal">is_constructible_v&lt;Alloc, <span class="pre">OtherAlloc&amp;&amp;&gt;</span></tt> is <tt class="docutils literal">true</tt>.</p>
</blockquote>
<p class="std-section"><tt class="docutils literal">template&lt;class U, class OtherAlloc&gt; allocator_delete(const allocator_delete&lt;U, OtherAlloc&gt;&amp; other) noexcept;</tt></p>
<blockquote>
<p><em>Effects:</em> Constructs an <tt class="docutils literal">allocator_delete</tt> object initializing the stored allocator with <tt class="docutils literal">other.get_allocator()</tt>.</p>
<dl class="docutils">
<dt><em>Remarks:</em> This constructor shall not participate in overload resolution unless:</dt>
<dd><ul class="first last simple">
<li><tt class="docutils literal">U*</tt> is implicitly convertible to <tt class="docutils literal">T*</tt>, and</li>
<li><tt class="docutils literal">is_constructible_v&lt;Alloc, const <span class="pre">remove_reference_t&lt;OtherAlloc&gt;&amp;&gt;</span></tt> is <tt class="docutils literal">true</tt>.</li>
</ul>
</dd>
</dl>
</blockquote>
<p class="std-section"><tt class="docutils literal">template&lt;class U, class OtherAlloc&gt; allocator_delete(allocator_delete&lt;U, <span class="pre">OtherAlloc&gt;&amp;&amp;</span> other) noexcept;</tt></p>
<blockquote>
<p><em>Effects:</em> Constructs an <tt class="docutils literal">allocator_delete</tt> object initializing the stored allocator with <tt class="docutils literal"><span class="pre">move(other.get_allocator())</span></tt>.</p>
<dl class="docutils">
<dt><em>Remarks:</em> This constructor shall not participate in overload resolution unless:</dt>
<dd><ul class="first last simple">
<li><tt class="docutils literal">U*</tt> is implicitly convertible to <tt class="docutils literal">T*</tt>, and</li>
<li><tt class="docutils literal">is_constructible_v&lt;Alloc, <span class="pre">remove_reference_t&lt;OtherAlloc&gt;&amp;&amp;)</span></tt> is <tt class="docutils literal">true</tt>.</li>
</ul>
</dd>
</dl>
</blockquote>
<p class="std-section"><tt class="docutils literal">template&lt;class U, class OtherAlloc&gt; allocator_delete&amp; <span class="pre">operator=(const</span> allocator_delete&lt;U, OtherAlloc&gt;&amp; other) noexcept;</tt></p>
<blockquote>
<p><em>Effects:</em> <tt class="docutils literal">get_allocator() = other.get_allocator()</tt>.</p>
<dl class="docutils">
<dt><em>Remarks:</em> This operator shall not participate in overload resolution unless:</dt>
<dd><ul class="first last simple">
<li><tt class="docutils literal">U*</tt> is implicitly convertible to <tt class="docutils literal">T*</tt>, and</li>
<li><tt class="docutils literal">is_assignable_v&lt;Alloc, const <span class="pre">remove_reference_t&lt;OtherAlloc&gt;&amp;&gt;</span></tt> is <tt class="docutils literal">true</tt>.</li>
</ul>
</dd>
</dl>
<p><em>Returns:</em> <tt class="docutils literal">*this</tt>.</p>
</blockquote>
<p class="std-section"><tt class="docutils literal">template&lt;class U, class OtherAlloc&gt; allocator_delete&amp; <span class="pre">operator=(allocator_delete&lt;U,</span> <span class="pre">OtherAlloc&gt;&amp;&amp;</span> other) noexcept;</tt></p>
<blockquote>
<p><em>Effects:</em> <tt class="docutils literal">get_allocator() = <span class="pre">move(other.get_allocator())</span></tt>.</p>
<dl class="docutils">
<dt><em>Remarks:</em> This constructor shall not participate in overload resolution unless:</dt>
<dd><ul class="first last simple">
<li><tt class="docutils literal">U*</tt> is implicitly convertible to <tt class="docutils literal">T*</tt>, and</li>
<li><tt class="docutils literal">is_assignable_v&lt;Alloc, <span class="pre">remove_reference_t&lt;OtherAlloc&gt;&amp;&amp;)</span></tt> is <tt class="docutils literal">true</tt>.</li>
</ul>
</dd>
</dl>
<p><em>Returns:</em> <tt class="docutils literal">*this</tt>.</p>
</blockquote>
<p class="std-section"><tt class="docutils literal">void <span class="pre">operator()(pointer</span> p);</tt></p>
<blockquote>
<p><em>Effects:</em> Calls <tt class="docutils literal"><span class="pre">p-&gt;~T()</span></tt> followed by <tt class="docutils literal"><span class="pre">allocator_traits&lt;Alloc&gt;::deallocate(get_allocator(),</span> p, 1)</tt>.</p>
</blockquote>
<div class="std-section line-block">
<div class="line"><tt class="docutils literal">Alloc&amp; get_allocator() noexcept;</tt></div>
<div class="line"><tt class="docutils literal">const Alloc&amp; get_allocator() const noexcept;</tt></div>
</div>
<blockquote>
<p><em>Returns:</em> A reference to the stored allocator.</p>
</blockquote>
<p class="std-section"><tt class="docutils literal">void swap(allocator_delete&amp; other) noexcept;</tt></p>
<blockquote>
<p><em>Requires:</em> <tt class="docutils literal">get_allocator()</tt> shall be swappable (17.5.3.2) and shall not throw an exception under <tt class="docutils literal">swap</tt>.</p>
<p><em>Effects:</em> Invokes <tt class="docutils literal">swap</tt> on the stored allocators of <tt class="docutils literal">*this</tt> and <tt class="docutils literal">other</tt>.</p>
</blockquote>
<p class="std-section">20.11.1.x.3 <tt class="docutils literal">allocator_delete&lt;T, Alloc&amp;&gt;</tt> [unique.ptr.allocdltr.ref]</p>
<pre class="literal-block">
namespace std {
  template&lt;class T, class Alloc&gt;
  class allocator_delete&lt;T, Alloc&amp;&gt; {
  public:
    using allocator_type = remove_cv_t&lt;Alloc&gt;;
    using pointer = typename allocator_traits&lt;allocator_type&gt;::pointer;

    template&lt;class OtherAlloc&gt;
      allocator_delete(reference_wrapper&lt;OtherAlloc&gt; other) noexcept;
    template&lt;class U, class OtherAlloc&gt;
      allocator_delete(allocator_delete&lt;U, OtherAlloc&amp;&gt; other) noexcept;
    template&lt;class U, class OtherAlloc&gt;
      allocator_delete&amp; operator=(allocator_delete&lt;U, OtherAlloc&amp;&gt; other) noexcept;

    void operator()(pointer p);

    Alloc&amp; get_allocator() const noexcept;

    void swap(allocator_delete&amp; other) noexcept;

  private:
    reference_wrapper&lt;Alloc&gt; alloc; // for exposition only
  };
}
</pre>
<p>A specialization for allocator lvalue references is provided to delegate deletion to a referred-to allocator instead of to a stored copy.</p>
<p class="std-section"><tt class="docutils literal">template&lt;class OtherAlloc&gt; allocator_delete(reference_wrapper&lt;OtherAlloc&gt; other) noexcept;</tt></p>
<blockquote>
<p><em>Requires:</em> <tt class="docutils literal">OtherAlloc</tt> shall satisfy the requirements of <tt class="docutils literal">Allocator</tt> (Table 31).</p>
<p><em>Effects:</em> Constructs an <tt class="docutils literal">allocator_delete</tt> object storing a reference to <tt class="docutils literal">other.get()</tt>.</p>
<p><em>Remarks:</em> This constructor shall not participate in overload resolution unless <tt class="docutils literal">OtherAlloc&amp;</tt> is implicitly convertible to <tt class="docutils literal">Alloc&amp;</tt>.</p>
</blockquote>
<p class="std-section"><tt class="docutils literal">template&lt;class U, class OtherAlloc&gt; allocator_delete(allocator_delete&lt;U, OtherAlloc&amp;&gt; other) noexcept;</tt></p>
<blockquote>
<p><em>Effects:</em> Constructs an <tt class="docutils literal">allocator_delete</tt> object storing a reference to <tt class="docutils literal">other.get_allocator()</tt>.</p>
<dl class="docutils">
<dt><em>Remarks:</em> This constructor shall not participate in overload resolution unless:</dt>
<dd><ul class="first last simple">
<li><tt class="docutils literal">U*</tt> is implicitly convertible to <tt class="docutils literal">T*</tt>, and</li>
<li><tt class="docutils literal">OtherAlloc&amp;</tt> is implicitly convertible to <tt class="docutils literal">Alloc&amp;</tt>.</li>
</ul>
</dd>
</dl>
</blockquote>
<p class="std-section"><tt class="docutils literal">template&lt;class U, class OtherAlloc&gt; allocator_delete&amp; <span class="pre">operator=(allocator_delete&lt;U,</span> OtherAlloc&amp;&gt; other) noexcept;</tt></p>
<blockquote>
<p><em>Effects:</em> Rebinds the stored allocator reference to <tt class="docutils literal">other.get_allocator()</tt>.</p>
<dl class="docutils">
<dt><em>Remarks:</em> This operator shall not participate in overload resolution unless:</dt>
<dd><ul class="first last simple">
<li><tt class="docutils literal">U*</tt> is implicitly convertible to <tt class="docutils literal">T*</tt>, and</li>
<li><tt class="docutils literal">OtherAlloc&amp;</tt> is implicitly convertible to <tt class="docutils literal">Alloc&amp;</tt>.</li>
</ul>
</dd>
</dl>
<p><em>Returns:</em> <tt class="docutils literal">*this</tt>.</p>
</blockquote>
<p class="std-section"><tt class="docutils literal">void <span class="pre">operator()(pointer</span> p);</tt></p>
<blockquote>
<p><em>Effects:</em> Calls <tt class="docutils literal"><span class="pre">p-&gt;~T()</span></tt> followed by <tt class="docutils literal"><span class="pre">allocator_traits&lt;Alloc&gt;::deallocate(get_allocator(),</span> p, 1)</tt>.</p>
</blockquote>
<p class="std-section"><tt class="docutils literal">Alloc&amp; get_allocator() const noexcept;</tt></p>
<blockquote>
<p><em>Returns:</em> <tt class="docutils literal">alloc.get()</tt>.</p>
</blockquote>
<p class="std-section"><tt class="docutils literal">void swap(allocator_delete&amp; other) noexcept;</tt></p>
<blockquote>
<p><em>Effects:</em> Swaps the allocator references of <tt class="docutils literal">*this</tt> and <tt class="docutils literal">other</tt>.</p>
</blockquote>
</blockquote>
</li>
<li><p class="first">Append new paragraphs to section 20.11.1.4 [unique.ptr.create] as follows:</p>
<blockquote>
<p class="std-section"><tt class="docutils literal">template&lt;class T, class Alloc, <span class="pre">class...</span> Args&gt; unique_ptr&lt;T,</tt> <em>see below</em> <tt class="docutils literal">&gt; allocate_unique(Alloc&amp;&amp; alloc, <span class="pre">Args&amp;&amp;...</span> args);</tt></p>
<blockquote>
<p><em>Requires:</em> The expression <tt class="docutils literal">::new (pv) <span class="pre">T(forward&lt;Args&gt;(args)...)</span></tt> where <tt class="docutils literal">pv</tt> has type <tt class="docutils literal">void*</tt> and points to storage suitable for holding an object of type <tt class="docutils literal">T</tt>, shall be well formed. <tt class="docutils literal">Alloc</tt> shall satisfy the requirements of <tt class="docutils literal">Allocator</tt> (17.5.3.5).</p>
<p><em>Effects:</em> Allocates memory suitable for holding an object of type <tt class="docutils literal">T</tt> using a copy of <tt class="docutils literal">alloc</tt> and constructs an object in that memory via the placement <em>new-expression</em> <tt class="docutils literal">::new (pv) <span class="pre">T(forward&lt;Args&gt;(args)...)</span></tt>.</p>
<p><em>Returns:</em> An instance of <tt class="docutils literal">unique_ptr&lt;T, allocator_delete&lt;T, A&gt;&gt;</tt> with ownership of the allocated object and the deleter holding the allocator used for allocation, where <tt class="docutils literal">A</tt> has type <tt class="docutils literal"><span class="pre">allocator_traits&lt;Alloc&gt;::rebind_alloc&lt;T&gt;</span></tt>.</p>
<p><em>Postcondition:</em> <tt class="docutils literal">get() != nullptr</tt>.</p>
<p><em>Throws:</em> Any exception thrown from <tt class="docutils literal"><span class="pre">Alloc::allocate</span></tt> or the constructor of <tt class="docutils literal">T</tt>.</p>
<p><em>Remarks:</em> This function shall not participate in overload resolution unless <tt class="docutils literal">T</tt> is not an array.</p>
</blockquote>
<p class="std-section"><tt class="docutils literal">template&lt;class T, class Alloc, <span class="pre">class...</span> Args&gt; unique_ptr&lt;T,</tt> <em>see below</em> <tt class="docutils literal">&gt; allocate_unique(reference_wrapper&lt;Alloc&gt; alloc, <span class="pre">Args&amp;&amp;...</span> args);</tt></p>
<blockquote>
<p><em>Requires:</em> The expression <tt class="docutils literal">::new (pv) <span class="pre">T(forward&lt;Args&gt;(args)...)</span></tt>, where <tt class="docutils literal">pv</tt> has type <tt class="docutils literal">void*</tt> and points to storage suitable for holding an object of type <tt class="docutils literal">T</tt>, shall be well formed. <tt class="docutils literal">Alloc</tt> shall satisfy the requirements of <tt class="docutils literal">Allocator</tt> (17.5.3.5). <tt class="docutils literal">Alloc</tt> shall be capable of allocating memory suitable for holding an object of type <tt class="docutils literal">T</tt>.</p>
<p><em>Effects:</em> Allocates memory suitable for holding an object of type <tt class="docutils literal">T</tt> using <tt class="docutils literal">alloc.get()</tt> directly and constructs an object in that memory via the placement <em>new-expression</em> <tt class="docutils literal">::new (pv) <span class="pre">T(forward&lt;Args&gt;(args)...)</span></tt>.</p>
<p><em>Returns:</em> An instance of <tt class="docutils literal">unique_ptr&lt;T, allocator_delete&lt;T, <span class="pre">Alloc&amp;&gt;&gt;</span></tt> with ownership of the allocated object and the deleter initialized with <tt class="docutils literal">ref(alloc)</tt>.</p>
<p><em>Postcondition:</em> <tt class="docutils literal">get() != nullptr</tt>.</p>
<p><em>Throws:</em> Any exception thrown from <tt class="docutils literal"><span class="pre">Alloc::allocate</span></tt> or the constructor of <tt class="docutils literal">T</tt>.</p>
<p><em>Remarks:</em> This function shall not participate in overload resolution unless <tt class="docutils literal">T</tt> is not an array.</p>
</blockquote>
<p class="std-section"><tt class="docutils literal">template&lt;class T, class Alloc, <span class="pre">class...</span> Args&gt;</tt> <em>unspecified</em> <tt class="docutils literal">allocate_unique(Alloc&amp;&amp; alloc, <span class="pre">Args&amp;&amp;...</span> args) = delete;</tt></p>
<blockquote>
<p><em>Remarks:</em> This function shall not participate in overload resolution unless <tt class="docutils literal">T</tt> is an array.</p>
</blockquote>
</blockquote>
</li>
</ol>
</div>
<div class="section" id="references">
<h1><a class="toc-backref" href="#id15">References</a></h1>
<table class="docutils citation" frame="void" id="n4618" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id1">[N4618]</a></td><td><a class="reference external" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/n4618.pdf">Working Draft, Standard for Programming Language C++</a></td></tr>
</tbody>
</table>
</div>
</div>
</body>
</html>
