<?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.12: http://docutils.sourceforge.net/" />
<title>P0468R0 : An Intrusive Smart Pointer</title>
<meta name="author" content="Isabella Muerte &lt;isabella.muerte&#64;mnmlstc.com&gt;" />
<meta name="date" content="2016-10-15" />
<meta content="An Intrusive Smart Pointer Proposal For C++" name="description" />
<meta content="c++, sg14, lewg, wg21, smart pointer, intrusive pointer" name="keywords" />
<style type="text/css">

/*
:Author: Chad Skeeters
:Contact: goobsoft@gmail.com

Stylesheet for use with Docutils/rst2html.
*/

html {
  font-size: 100%;
  -webkit-text-size-adjust: 100%;
      -ms-text-size-adjust: 100%;
}

a:focus {
  outline: thin dotted #333;
  outline: 5px auto -webkit-focus-ring-color;
  outline-offset: -2px;
}

a:hover,
a:active {
  outline: 0;
}

sub,
sup {
  position: relative;
  font-size: 75%;
  line-height: 0;
  vertical-align: baseline;
}

sup {
  top: -0.5em;
}

sub {
  bottom: -0.25em;
}

img {
  width: auto\9;
  height: auto;
  max-width: 100%;
  vertical-align: middle;
  border: 0;
  -ms-interpolation-mode: bicubic;
}

@media print {
  * {
    color: #000 !important;
    text-shadow: none !important;
    background: transparent !important;
    box-shadow: none !important;
  }
  a,
  a:visited {
    text-decoration: underline;
  }
  a[href]:after {
    content: " (" attr(href) ")";
  }
  abbr[title]:after {
    content: " (" attr(title) ")";
  }
  .ir a:after,
  a[href^="javascript:"]:after,
  a[href^="#"]:after {
    content: "";
  }
  pre,
  blockquote {
    border: 1px solid #999;
    page-break-inside: avoid;
  }
  thead {
    display: table-header-group;
  }
  tr,
  img {
    page-break-inside: avoid;
  }
  img {
    max-width: 100% !important;
  }
  @page  {
    margin: 0.5cm;
  }
  h1 {
    page-break-before:always;
  }
  h1.title {
    page-break-before:avoid;
  }
  p,
  h2,
  h3 {
    orphans: 3;
    widows: 3;
  }
  h2,
  h3 {
    page-break-after: avoid;
  }
}

body {
  margin: 40px;
  margin-right: auto;
  margin-left: auto;
  width: 960px;
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 14px;
  line-height: 20px;
  color: #333333;
  background-color: #ffffff;
}

a {
  color: #0088cc;
  text-decoration: none;
}

a:hover,
a:focus {
  color: #005580;
  text-decoration: underline;
}

.img-rounded {
  -webkit-border-radius: 6px;
     -moz-border-radius: 6px;
          border-radius: 6px;
}

.img-polaroid {
  padding: 4px;
  background-color: #fff;
  border: 1px solid #ccc;
  border: 1px solid rgba(0, 0, 0, 0.2);
  -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
     -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
          box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}

p {
  margin: 0 0 10px;
}

small {
  font-size: 85%;
}

strong {
  font-weight: bold;
}

em {
  font-style: italic;
}

cite {
  font-style: normal;
}

h1,
h2,
h3,
h4,
h5,
h6 {
  font-family: inherit;
  font-weight: bold;
  line-height: 30px;
  color: inherit;
  text-rendering: optimizelegibility;
}
h1 {
  font-size: 2em;
  padding-bottom:.2em;
  border-bottom:1px solid grey;
}
h1.title {
  padding-bottom:1em;
  border-bottom:0px;
}
h2 {
  font-size: 1.5em;
}

h3 {
  font-size: 1.3em;
  font-family:Georgia, serif;
  font-style:italic;
  /*font-weight:normal;*/
}

h4 {
  font-size: 1.3em;
}

h5 {
  font-size: 1.2em;
}

h6 {
  font-size: 1.1em;
}

ul,
ol {
  padding: 0;
  margin: 0 0 10px 25px;
}

ul ul,
ul ol,
ol ol,
ol ul {
  margin-bottom: 0;
}

li {
  line-height: 20px;
}

dl {
  margin-bottom: 20px;
}

dt,
dd {
  line-height: 20px;
}

dt {
  font-weight: bold;
}

dd {
  margin-left: 10px;
}

hr {
  margin: 20px 0;
  border: 0;
  border-top: 1px solid #eeeeee;
  border-bottom: 1px solid #ffffff;
}

abbr[title],
abbr[data-original-title] {
  cursor: help;
  border-bottom: 1px dotted #999999;
}

abbr.initialism {
  font-size: 90%;
  text-transform: uppercase;
}

blockquote {
  padding: 0 0 0 15px;
  margin: 0 0 20px;
  border-left: 5px solid #eeeeee;
}

blockquote p {
  margin-bottom: 0;
  font-size: 17.5px;
  font-weight: 300;
  line-height: 1.25;
}

q:before,
q:after,
blockquote:before,
blockquote:after {
  content: "";
}

address {
  display: block;
  margin-bottom: 20px;
  font-style: normal;
  line-height: 20px;
}

code,
pre {
  padding: 0 3px 2px;
  font-family: Consolas, "Courier New", monospace;
  font-size: 12px;
  color: #333333;
  -webkit-border-radius: 3px;
     -moz-border-radius: 3px;
          border-radius: 3px;
}

code {
  padding: 2px 4px;
  color: #d14;
  white-space: nowrap;
  background-color: #f7f7f9;
  border: 1px solid #e1e1e8;
}

pre {
  display: block;
  padding: 9.5px;
  margin: 0 0 10px;
  font-size: 13px;
  line-height: 20px;
  word-break: break-all;
  word-wrap: break-word;
  white-space: pre;
  white-space: pre-wrap;
  background-color: #f5f5f5;
  border: 1px solid #ccc;
  border: 1px solid rgba(0, 0, 0, 0.15);
  -webkit-border-radius: 4px;
     -moz-border-radius: 4px;
          border-radius: 4px;
}

pre.prettyprint {
  margin-bottom: 20px;
}

pre code {
  padding: 0;
  color: inherit;
  white-space: pre;
  white-space: pre-wrap;
  background-color: transparent;
  border: 0;
}

.pre-scrollable {
  max-height: 340px;
  overflow-y: scroll;
}

table {
  max-width: 100%;
  background-color: transparent;
  border-collapse: collapse;
  border-spacing: 0;
}

.table {
  width: 100%;
  margin-bottom: 20px;
}

.table th,
.table td {
  padding: 8px;
  line-height: 20px;
  text-align: left;
  vertical-align: top;
  border-top: 1px solid #dddddd;
}

.table th {
  font-weight: bold;
}

.table thead th {
  vertical-align: bottom;
}

.table caption + thead tr:first-child th,
.table caption + thead tr:first-child td,
.table colgroup + thead tr:first-child th,
.table colgroup + thead tr:first-child td,
.table thead:first-child tr:first-child th,
.table thead:first-child tr:first-child td {
  border-top: 0;
}

.table tbody + tbody {
  border-top: 2px solid #dddddd;
}

.table .table {
  background-color: #ffffff;
}

.table-condensed th,
.table-condensed td {
  padding: 4px 5px;
}

.table-bordered {
  border: 1px solid #dddddd;
  border-collapse: separate;
  *border-collapse: collapse;
  border-left: 0;
  -webkit-border-radius: 4px;
     -moz-border-radius: 4px;
          border-radius: 4px;
}

.table-bordered th,
.table-bordered td {
  border-left: 1px solid #dddddd;
}

.table-bordered caption + thead tr:first-child th,
.table-bordered caption + tbody tr:first-child th,
.table-bordered caption + tbody tr:first-child td,
.table-bordered colgroup + thead tr:first-child th,
.table-bordered colgroup + tbody tr:first-child th,
.table-bordered colgroup + tbody tr:first-child td,
.table-bordered thead:first-child tr:first-child th,
.table-bordered tbody:first-child tr:first-child th,
.table-bordered tbody:first-child tr:first-child td {
  border-top: 0;
}

.table-bordered thead:first-child tr:first-child > th:first-child,
.table-bordered tbody:first-child tr:first-child > td:first-child,
.table-bordered tbody:first-child tr:first-child > th:first-child {
  -webkit-border-top-left-radius: 4px;
          border-top-left-radius: 4px;
  -moz-border-radius-topleft: 4px;
}

.table-bordered thead:first-child tr:first-child > th:last-child,
.table-bordered tbody:first-child tr:first-child > td:last-child,
.table-bordered tbody:first-child tr:first-child > th:last-child {
  -webkit-border-top-right-radius: 4px;
          border-top-right-radius: 4px;
  -moz-border-radius-topright: 4px;
}

.table-bordered thead:last-child tr:last-child > th:first-child,
.table-bordered tbody:last-child tr:last-child > td:first-child,
.table-bordered tbody:last-child tr:last-child > th:first-child,
.table-bordered tfoot:last-child tr:last-child > td:first-child,
.table-bordered tfoot:last-child tr:last-child > th:first-child {
  -webkit-border-bottom-left-radius: 4px;
          border-bottom-left-radius: 4px;
  -moz-border-radius-bottomleft: 4px;
}

.table-bordered thead:last-child tr:last-child > th:last-child,
.table-bordered tbody:last-child tr:last-child > td:last-child,
.table-bordered tbody:last-child tr:last-child > th:last-child,
.table-bordered tfoot:last-child tr:last-child > td:last-child,
.table-bordered tfoot:last-child tr:last-child > th:last-child {
  -webkit-border-bottom-right-radius: 4px;
          border-bottom-right-radius: 4px;
  -moz-border-radius-bottomright: 4px;
}

.table-bordered tfoot + tbody:last-child tr:last-child td:first-child {
  -webkit-border-bottom-left-radius: 0;
          border-bottom-left-radius: 0;
  -moz-border-radius-bottomleft: 0;
}

.table-bordered tfoot + tbody:last-child tr:last-child td:last-child {
  -webkit-border-bottom-right-radius: 0;
          border-bottom-right-radius: 0;
  -moz-border-radius-bottomright: 0;
}

.table-bordered caption + thead tr:first-child th:first-child,
.table-bordered caption + tbody tr:first-child td:first-child,
.table-bordered colgroup + thead tr:first-child th:first-child,
.table-bordered colgroup + tbody tr:first-child td:first-child {
  -webkit-border-top-left-radius: 4px;
          border-top-left-radius: 4px;
  -moz-border-radius-topleft: 4px;
}

.table-bordered caption + thead tr:first-child th:last-child,
.table-bordered caption + tbody tr:first-child td:last-child,
.table-bordered colgroup + thead tr:first-child th:last-child,
.table-bordered colgroup + tbody tr:first-child td:last-child {
  -webkit-border-top-right-radius: 4px;
          border-top-right-radius: 4px;
  -moz-border-radius-topright: 4px;
}

.table-striped tbody > tr:nth-child(odd) > td,
.table-striped tbody > tr:nth-child(odd) > th {
  background-color: #f9f9f9;
}

.table-hover tbody tr:hover > td,
.table-hover tbody tr:hover > th {
  background-color: #f5f5f5;
}

table td[class*="span"],
table th[class*="span"],
.row-fluid table td[class*="span"],
.row-fluid table th[class*="span"] {
  display: table-cell;
  float: none;
  margin-left: 0;
}

.hero-unit {
  padding: 60px;
  margin-bottom: 30px;
  font-size: 18px;
  font-weight: 200;
  line-height: 30px;
  color: inherit;
  background-color: #eeeeee;
  -webkit-border-radius: 6px;
     -moz-border-radius: 6px;
          border-radius: 6px;
}

.hero-unit h1 {
  margin-bottom: 0;
  font-size: 60px;
  line-height: 1;
  letter-spacing: -1px;
  color: inherit;
}

.hero-unit li {
  line-height: 30px;
}


/* rst2html default 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 }

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.note, div.warning {
  margin:1.5em 0px;
  border: none;
}

div.note p.admonition-title,
div.warning p.admonition-title
{
  display:none;
}

/* Clearfix
 * http://css-tricks.com/snippets/css/clear-fix/
 */

div.note:after,
div.warning:after {
  content:"";
  display:table;
  clear:both;
}

div.note p:before,
div.warning p:before {
  display:block;
  float:left;
  font-size:4em;
  line-height:1em;
  margin-right:20px;
  margin-left: 0em;
  margin-top:-10px;
  content:'\0270D'; /*handwriting*/
}

div.warning p:before {
  content:'\026A0'; /*warning*/
}

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 {
  clear: left ;
  float: left ;
  margin-right: 1em }

img.align-right, .figure.align-right, object.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;
}

.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 } */

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: white }
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}

tt.docutils.literal { font-weight: bold }

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 }

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 }

.code .pygments-hll { background-color: #ffffcc }
.code .pygments-c { color: #60a0b0; font-style: italic } /* Comment */
.code .pygments-err { border: 1px solid #FF0000 } /* Error */
.code .pygments-k { color: #007020; font-weight: bold } /* Keyword */
.code .pygments-o { color: #666666 } /* Operator */
.code .pygments-cm { color: #60a0b0; font-style: italic } /* Comment.Multiline */
.code .pygments-cp { color: #007020 } /* Comment.Preproc */
.code .pygments-c1 { color: #60a0b0; font-style: italic } /* Comment.Single */
.code .pygments-cs { color: #60a0b0; background-color: #fff0f0 } /* Comment.Special */
.code .pygments-gd { color: #A00000 } /* Generic.Deleted */
.code .pygments-ge { font-style: italic } /* Generic.Emph */
.code .pygments-gr { color: #FF0000 } /* Generic.Error */
.code .pygments-gh { color: #000080; font-weight: bold } /* Generic.Heading */
.code .pygments-gi { color: #00A000 } /* Generic.Inserted */
.code .pygments-go { color: #888888 } /* Generic.Output */
.code .pygments-gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */
.code .pygments-gs { font-weight: bold } /* Generic.Strong */
.code .pygments-gu { color: #800080; font-weight: bold } /* Generic.Subheading */
.code .pygments-gt { color: #0044DD } /* Generic.Traceback */
.code .pygments-kc { color: #007020; font-weight: bold } /* Keyword.Constant */
.code .pygments-kd { color: #007020; font-weight: bold } /* Keyword.Declaration */
.code .pygments-kn { color: #007020; font-weight: bold } /* Keyword.Namespace */
.code .pygments-kp { color: #007020 } /* Keyword.Pseudo */
.code .pygments-kr { color: #007020; font-weight: bold } /* Keyword.Reserved */
.code .pygments-kt { color: #902000 } /* Keyword.Type */
.code .pygments-m { color: #40a070 } /* Literal.Number */
.code .pygments-s { color: #4070a0 } /* Literal.String */
.code .pygments-na { color: #4070a0 } /* Name.Attribute */
.code .pygments-nb { color: #007020 } /* Name.Builtin */
.code .pygments-nc { color: #0e84b5; font-weight: bold } /* Name.Class */
.code .pygments-no { color: #60add5 } /* Name.Constant */
.code .pygments-nd { color: #555555; font-weight: bold } /* Name.Decorator */
.code .pygments-ni { color: #d55537; font-weight: bold } /* Name.Entity */
.code .pygments-ne { color: #007020 } /* Name.Exception */
.code .pygments-nf { color: #06287e } /* Name.Function */
.code .pygments-nl { color: #002070; font-weight: bold } /* Name.Label */
.code .pygments-nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */
.code .pygments-nt { color: #062873; font-weight: bold } /* Name.Tag */
.code .pygments-nv { color: #bb60d5 } /* Name.Variable */
.code .pygments-ow { color: #007020; font-weight: bold } /* Operator.Word */
.code .pygments-w { color: #bbbbbb } /* Text.Whitespace */
.code .pygments-mf { color: #40a070 } /* Literal.Number.Float */
.code .pygments-mh { color: #40a070 } /* Literal.Number.Hex */
.code .pygments-mi { color: #40a070 } /* Literal.Number.Integer */
.code .pygments-mo { color: #40a070 } /* Literal.Number.Oct */
.code .pygments-sb { color: #4070a0 } /* Literal.String.Backtick */
.code .pygments-sc { color: #4070a0 } /* Literal.String.Char */
.code .pygments-sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */
.code .pygments-s2 { color: #4070a0 } /* Literal.String.Double */
.code .pygments-se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */
.code .pygments-sh { color: #4070a0 } /* Literal.String.Heredoc */
.code .pygments-si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */
.code .pygments-sx { color: #c65d09 } /* Literal.String.Other */
.code .pygments-sr { color: #235388 } /* Literal.String.Regex */
.code .pygments-s1 { color: #4070a0 } /* Literal.String.Single */
.code .pygments-ss { color: #517918 } /* Literal.String.Symbol */
.code .pygments-bp { color: #007020 } /* Name.Builtin.Pseudo */
.code .pygments-vc { color: #bb60d5 } /* Name.Variable.Class */
.code .pygments-vg { color: #bb60d5 } /* Name.Variable.Global */
.code .pygments-vi { color: #bb60d5 } /* Name.Variable.Instance */
.code .pygments-il { color: #40a070 } /* Literal.Number.Integer.Long */

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

.hll { background-color: #ffffcc }
.c { color: #8f5902; font-style: italic } /* Comment */
.err { color: #a40000; border: 1px solid #ef2929 } /* Error */
.g { color: #000000 } /* Generic */
.k { color: #204a87; font-weight: bold } /* Keyword */
.l { color: #000000 } /* Literal */
.n { color: #000000 } /* Name */
.o { color: #ce5c00; font-weight: bold } /* Operator */
.x { color: #000000 } /* Other */
.p { color: #000000; font-weight: bold } /* Punctuation */
.ch { color: #8f5902; font-style: italic } /* Comment.Hashbang */
.cm { color: #8f5902; font-style: italic } /* Comment.Multiline */
.cp { color: #8f5902; font-style: italic } /* Comment.Preproc */
.cpf { color: #8f5902; font-style: italic } /* Comment.PreprocFile */
.c1 { color: #8f5902; font-style: italic } /* Comment.Single */
.cs { color: #8f5902; font-style: italic } /* Comment.Special */
.gd { color: #a40000 } /* Generic.Deleted */
.ge { color: #000000; font-style: italic } /* Generic.Emph */
.gr { color: #ef2929 } /* Generic.Error */
.gh { color: #000080; font-weight: bold } /* Generic.Heading */
.gi { color: #00A000 } /* Generic.Inserted */
.go { color: #000000; font-style: italic } /* Generic.Output */
.gp { color: #8f5902 } /* Generic.Prompt */
.gs { color: #000000; font-weight: bold } /* Generic.Strong */
.gu { color: #800080; font-weight: bold } /* Generic.Subheading */
.gt { color: #a40000; font-weight: bold } /* Generic.Traceback */
.kc { color: #204a87; font-weight: bold } /* Keyword.Constant */
.kd { color: #204a87; font-weight: bold } /* Keyword.Declaration */
.kn { color: #204a87; font-weight: bold } /* Keyword.Namespace */
.kp { color: #204a87; font-weight: bold } /* Keyword.Pseudo */
.kr { color: #204a87; font-weight: bold } /* Keyword.Reserved */
.kt { color: #204a87; font-weight: bold } /* Keyword.Type */
.ld { color: #000000 } /* Literal.Date */
.m { color: #0000cf; font-weight: bold } /* Literal.Number */
.s { color: #4e9a06 } /* Literal.String */
.na { color: #c4a000 } /* Name.Attribute */
.nb { color: #204a87 } /* Name.Builtin */
.nc { color: #000000 } /* Name.Class */
.no { color: #000000 } /* Name.Constant */
.nd { color: #5c35cc; font-weight: bold } /* Name.Decorator */
.ni { color: #ce5c00 } /* Name.Entity */
.ne { color: #cc0000; font-weight: bold } /* Name.Exception */
.nf { color: #000000 } /* Name.Function */
.nl { color: #f57900 } /* Name.Label */
.nn { color: #000000 } /* Name.Namespace */
.nx { color: #000000 } /* Name.Other */
.py { color: #000000 } /* Name.Property */
.nt { color: #204a87; font-weight: bold } /* Name.Tag */
.nv { color: #000000 } /* Name.Variable */
.ow { color: #204a87; font-weight: bold } /* Operator.Word */
.w { color: #f8f8f8; text-decoration: underline } /* Text.Whitespace */
.mb { color: #0000cf; font-weight: bold } /* Literal.Number.Bin */
.mf { color: #0000cf; font-weight: bold } /* Literal.Number.Float */
.mh { color: #0000cf; font-weight: bold } /* Literal.Number.Hex */
.mi { color: #0000cf; font-weight: bold } /* Literal.Number.Integer */
.mo { color: #0000cf; font-weight: bold } /* Literal.Number.Oct */
.sb { color: #4e9a06 } /* Literal.String.Backtick */
.sc { color: #4e9a06 } /* Literal.String.Char */
.sd { color: #8f5902; font-style: italic } /* Literal.String.Doc */
.s2 { color: #4e9a06 } /* Literal.String.Double */
.se { color: #4e9a06 } /* Literal.String.Escape */
.sh { color: #4e9a06 } /* Literal.String.Heredoc */
.si { color: #4e9a06 } /* Literal.String.Interpol */
.sx { color: #4e9a06 } /* Literal.String.Other */
.sr { color: #4e9a06 } /* Literal.String.Regex */
.s1 { color: #4e9a06 } /* Literal.String.Single */
.ss { color: #4e9a06 } /* Literal.String.Symbol */
.bp { color: #3465a4 } /* Name.Builtin.Pseudo */
.vc { color: #000000 } /* Name.Variable.Class */
.vg { color: #000000 } /* Name.Variable.Global */
.vi { color: #000000 } /* Name.Variable.Instance */
.il { color: #0000cf; font-weight: bold } /* Literal.Number.Integer.Long */

</style>
</head>
<body>
<div class="document" id="a-proposal-to-add-an-intrusive-smart-pointer-to-the-c-standard-library">
<h1 class="title">A Proposal to Add an Intrusive Smart Pointer to the C++ Standard Library</h1>
<table class="docinfo" frame="void" rules="none">
<col class="docinfo-name" />
<col class="docinfo-content" />
<tbody valign="top">
<tr class="field"><th class="docinfo-name">Audience:</th><td class="field-body">SG14, LEWG</td>
</tr>
<tr class="field"><th class="docinfo-name">Reply-To:</th><td class="field-body">Isabella Muerte &lt;<a class="reference external" href="mailto:isabella.muerte&#64;mnmlstc.com">isabella.muerte&#64;mnmlstc.com</a>&gt;
Bryce Adelstein Lelbach &lt;<a class="reference external" href="mailto:balelbach&#64;lbl.gov">balelbach&#64;lbl.gov</a>&gt;</td>
</tr>
<tr><th class="docinfo-name">Author:</th>
<td>Isabella Muerte &lt;<a class="reference external" href="mailto:isabella.muerte&#64;mnmlstc.com">isabella.muerte&#64;mnmlstc.com</a>&gt;</td></tr>
<tr><th class="docinfo-name">Date:</th>
<td>2016-10-15</td></tr>
<tr class="field"><th class="docinfo-name">ID:</th><td class="field-body">P0468R0</td>
</tr>
</tbody>
</table>
<div class="contents local topic" id="table-of-contents">
<p class="topic-title first">Table of Contents</p>
<ul class="auto-toc simple">
<li><a class="reference internal" href="#abstract" id="id7">1&nbsp;&nbsp;&nbsp;Abstract</a></li>
<li><a class="reference internal" href="#motivation-and-scope" id="id8">2&nbsp;&nbsp;&nbsp;Motivation and Scope</a></li>
<li><a class="reference internal" href="#impact-on-the-standard" id="id9">3&nbsp;&nbsp;&nbsp;Impact On the Standard</a></li>
<li><a class="reference internal" href="#frequently-asked-questions" id="id10">4&nbsp;&nbsp;&nbsp;Frequently Asked Questions</a><ul class="auto-toc">
<li><a class="reference internal" href="#how-does-boost-intrusive-ptr-not-meet-the-needs-of-modern-c" id="id11">4.1&nbsp;&nbsp;&nbsp;How does boost::intrusive_ptr not meet the needs of modern C++?</a></li>
<li><a class="reference internal" href="#is-retain-ptr-atomic" id="id12">4.2&nbsp;&nbsp;&nbsp;Is retain_ptr atomic?</a></li>
<li><a class="reference internal" href="#why-is-it-called-retain-ptr-and-not-intrusive-ptr" id="id13">4.3&nbsp;&nbsp;&nbsp;Why is it called retain_ptr and not intrusive_ptr?</a></li>
<li><a class="reference internal" href="#does-retain-ptr-support-allocators" id="id14">4.4&nbsp;&nbsp;&nbsp;Does retain_ptr support allocators?</a></li>
<li><a class="reference internal" href="#can-retain-ptr-be-constexpr" id="id15">4.5&nbsp;&nbsp;&nbsp;Can retain_ptr be constexpr?</a></li>
<li><a class="reference internal" href="#why-does-retain-ptr-use-detach-instead-of-release-like-unique-ptr" id="id16">4.6&nbsp;&nbsp;&nbsp;Why does retain_ptr use detach instead of release like unique_ptr?</a></li>
<li><a class="reference internal" href="#why-provide-retain-t" id="id17">4.7&nbsp;&nbsp;&nbsp;Why provide retain_t?</a></li>
<li><a class="reference internal" href="#can-retain-traits-store-state" id="id18">4.8&nbsp;&nbsp;&nbsp;Can retain_traits store state?</a></li>
<li><a class="reference internal" href="#why-not-just-wrap-a-unique-ptr-with-a-custom-deleter" id="id19">4.9&nbsp;&nbsp;&nbsp;Why not just wrap a unique_ptr with a custom deleter?</a></li>
</ul>
</li>
<li><a class="reference internal" href="#technical-specification" id="id20">5&nbsp;&nbsp;&nbsp;Technical Specification</a><ul class="auto-toc">
<li><a class="reference internal" href="#atomic-reference-count-t-and-reference-count-t" id="id21">5.1&nbsp;&nbsp;&nbsp;atomic_reference_count&lt;T&gt; and reference_count&lt;T&gt;</a></li>
<li><a class="reference internal" href="#retain-t" id="id22">5.2&nbsp;&nbsp;&nbsp;retain_t</a></li>
<li><a class="reference internal" href="#retain-traits-t" id="id23">5.3&nbsp;&nbsp;&nbsp;retain_traits&lt;T&gt;</a></li>
<li><a class="reference internal" href="#retain-ptr-t-r" id="id24">5.4&nbsp;&nbsp;&nbsp;retain_ptr&lt;T, R&gt;</a><ul class="auto-toc">
<li><a class="reference internal" href="#retain-ptr-constructors" id="id25">5.4.1&nbsp;&nbsp;&nbsp;retain_ptr constructors</a></li>
<li><a class="reference internal" href="#retain-ptr-destructor" id="id26">5.4.2&nbsp;&nbsp;&nbsp;retain_ptr destructor</a></li>
<li><a class="reference internal" href="#retain-ptr-assignment" id="id27">5.4.3&nbsp;&nbsp;&nbsp;retain_ptr assignment</a></li>
<li><a class="reference internal" href="#retain-ptr-observers" id="id28">5.4.4&nbsp;&nbsp;&nbsp;retain_ptr observers</a></li>
<li><a class="reference internal" href="#retain-ptr-modifiers" id="id29">5.4.5&nbsp;&nbsp;&nbsp;retain_ptr modifiers</a></li>
<li><a class="reference internal" href="#retain-ptr-specialized-algorithms" id="id30">5.4.6&nbsp;&nbsp;&nbsp;retain_ptr specialized algorithms</a></li>
</ul>
</li>
</ul>
</li>
<li><a class="reference internal" href="#examples" id="id31">6&nbsp;&nbsp;&nbsp;Examples</a><ul class="auto-toc">
<li><a class="reference internal" href="#futures" id="id32">6.1&nbsp;&nbsp;&nbsp;Futures</a></li>
</ul>
</li>
<li><a class="reference internal" href="#acknowledgements" id="id33">7&nbsp;&nbsp;&nbsp;Acknowledgements</a></li>
<li><a class="reference internal" href="#references" id="id34">8&nbsp;&nbsp;&nbsp;References</a></li>
</ul>
</div>
<div class="section" id="abstract">
<h1><a class="toc-backref" href="#id7">1&nbsp;&nbsp;&nbsp;Abstract</a></h1>
<p>I propose a new smart pointer (<tt class="docutils literal">retain_ptr&lt;T, R&gt;</tt>) whose reference count is
stored inside of a managed object (i.e., intrusively). I believe that this will
reduce the complexity of implementing objects to easily manage C and C++ APIs
whose object lifetimes rely on a reference count stored directly within a
given object.</p>
</div>
<div class="section" id="motivation-and-scope">
<h1><a class="toc-backref" href="#id8">2&nbsp;&nbsp;&nbsp;Motivation and Scope</a></h1>
<p>There are a wide variety of C and C++ APIs that rely on reference counting, but
either because of the language (C) or the age of the library (C++), they are
unable to be safely used with either <tt class="docutils literal"><span class="pre">std::unique_ptr&lt;T&gt;</span></tt> or
<tt class="docutils literal"><span class="pre">std::shared_ptr&lt;T&gt;</span></tt>. In addition, existing intrusive smart pointers such as
<tt class="docutils literal"><span class="pre">boost::intrusive_ptr&lt;T&gt;</span></tt> <a class="footnote-reference" href="#id4" id="id1">[1]</a>, Microsoft's <tt class="docutils literal">ComPtr&lt;T&gt;</tt> <a class="footnote-reference" href="#id5" id="id2">[2]</a>, or WebKit's
<tt class="docutils literal"><span class="pre">WTF::RefPtr&lt;T&gt;</span></tt> <a class="footnote-reference" href="#id6" id="id3">[3]</a> do not meet the needs of modern C++ smart pointers
or APIs, and this paper attempts to solve these shortcomings in an extensible
and future proof manner.</p>
<p>The users that would get the best use out of this type are those that work on
systems that rely on reference counting (usually interacting with C APIs).</p>
<p>Additionally, with an intrusive smart pointer, one can implement a non-atomic
<tt class="docutils literal">shared_ptr</tt> and <tt class="docutils literal">weak_ptr</tt>. Furthermore, implementing ones own
promise and future is possible, which will be useful with the coming Coroutines
TS.</p>
<p>A reference implementation of <tt class="docutils literal">retain_ptr&lt;T&gt;</tt>, along with an example of its
use, can be found on <a class="reference external" href="https://github.com/slurps-mad-rips/retain-ptr">github</a>.</p>
</div>
<div class="section" id="impact-on-the-standard">
<h1><a class="toc-backref" href="#id9">3&nbsp;&nbsp;&nbsp;Impact On the Standard</a></h1>
<p><tt class="docutils literal">retain_ptr&lt;T, R&gt;</tt> would ideally be available in the <tt class="docutils literal">&lt;memory&gt;</tt> standard
header. It is a pure extension to the C++ standard library and can be
implemented using any conforming C++14 or C++11 compiler with very little
effort. See the <a class="reference internal" href="#technical-specification">Technical Specification</a> for interface and behavior details.</p>
</div>
<div class="section" id="frequently-asked-questions">
<h1><a class="toc-backref" href="#id10">4&nbsp;&nbsp;&nbsp;Frequently Asked Questions</a></h1>
<p>Several common questions regarding the design of <tt class="docutils literal">retain_ptr&lt;T, R&gt;</tt> can be
found below.</p>
<div class="section" id="how-does-boost-intrusive-ptr-not-meet-the-needs-of-modern-c">
<h2><a class="toc-backref" href="#id11">4.1&nbsp;&nbsp;&nbsp;How does boost::intrusive_ptr not meet the needs of modern C++?</a></h2>
<p><tt class="docutils literal"><span class="pre">boost::intrusive_ptr&lt;T&gt;</span></tt> has had nearly the same interface since its
introduction in 2001 by Peter Dimov. Furthermore, <tt class="docutils literal"><span class="pre">boost::intrusive_ptr</span></tt> has
several failings in its API that cannot be changed from without breaking
compatability. When constructing a <tt class="docutils literal"><span class="pre">boost::intrusive_ptr&lt;T&gt;</span></tt>, by default it
increments the reference count. This is because of its <tt class="docutils literal">intrusive_ref_count</tt>
mixin, which starts with a reference count of 0 when it is default constructed.
Out of all the libraries I tried to look at, this was the one instance where an
object required it be incremented after construction. This should be the
exception, and this proposal rectifies this with its equivalent mixins, which
start with a reference count of 1.</p>
<p>Additionally, <tt class="docutils literal"><span class="pre">boost::intrusive_ptr</span></tt> does not have the ability to &quot;overload&quot;
its <tt class="docutils literal">pointer</tt> type member, requiring some additional work when interfacing
with C APIs (e.g., <tt class="docutils literal"><span class="pre">boost::intrusive_ptr&lt;decltype(*declval&lt;cl_mem&gt;())&gt;</span></tt>).</p>
<p>Furthermore, <tt class="docutils literal"><span class="pre">boost::intrusive_ptr</span></tt> relies on ADL calls of two functions:
<tt class="docutils literal">intrusive_add_ref</tt> and <tt class="docutils literal">intrusive_release</tt>. While this approach is fine in
most cases, it does remove the ability to easily &quot;swap out&quot; the approach used
when incrementing or decrementing the reference count (e.g., logging when
reference count reaches 0, but not when in a production environment). This
approach also uses terms found in Microsoft's COM. While this isn't an issue
per se, it would be odd to have functions with those names found in the
standard.</p>
</div>
<div class="section" id="is-retain-ptr-atomic">
<h2><a class="toc-backref" href="#id12">4.2&nbsp;&nbsp;&nbsp;Is retain_ptr atomic?</a></h2>
<p><tt class="docutils literal">retain_ptr&lt;T&gt;</tt> is only atomic in its reference count increment and decrement
if the object it manages is itself atomic in its reference count operations.</p>
</div>
<div class="section" id="why-is-it-called-retain-ptr-and-not-intrusive-ptr">
<h2><a class="toc-backref" href="#id13">4.3&nbsp;&nbsp;&nbsp;Why is it called retain_ptr and not intrusive_ptr?</a></h2>
<p><tt class="docutils literal">retain_ptr&lt;T, R&gt;</tt> diverges from the design of <tt class="docutils literal"><span class="pre">boost::intrusive_ptr&lt;T&gt;</span></tt>.
It was decided to change the name so as to not cause assumptions of
<tt class="docutils literal">retain_ptr&lt;T, R&gt;</tt> interface and behavior.</p>
<p>Some additional names that might be considered (for bikeshedding) are:</p>
<blockquote>
<ul class="simple">
<li>extend_ptr</li>
<li>counted_ptr</li>
<li>borrow_ptr</li>
<li>mutual_ptr</li>
<li>joint_ptr</li>
</ul>
</blockquote>
<p>Comedy Option:</p>
<blockquote>
<ul class="simple">
<li>auto_ptr</li>
</ul>
</blockquote>
</div>
<div class="section" id="does-retain-ptr-support-allocators">
<h2><a class="toc-backref" href="#id14">4.4&nbsp;&nbsp;&nbsp;Does retain_ptr support allocators?</a></h2>
<p><tt class="docutils literal">retain_ptr</tt> itself does not support allocators, however the object whose
lifetime it extends can.</p>
</div>
<div class="section" id="can-retain-ptr-be-constexpr">
<h2><a class="toc-backref" href="#id15">4.5&nbsp;&nbsp;&nbsp;Can retain_ptr be constexpr?</a></h2>
<p>Possibly, however the author questions the usefulness for a constexpr capable
intrusive smart pointer, as most use cases are intended for migrating existing
non-constexpr interfaces, and for types that simply cannot be constexpr, such
as incomplete types and polymorphic classes.</p>
</div>
<div class="section" id="why-does-retain-ptr-use-detach-instead-of-release-like-unique-ptr">
<h2><a class="toc-backref" href="#id16">4.6&nbsp;&nbsp;&nbsp;Why does retain_ptr use detach instead of release like unique_ptr?</a></h2>
<p><tt class="docutils literal">retain_ptr&lt;T&gt;</tt> diverges from common smart pointer functions that release
ownership of their managed object via a function <tt class="docutils literal">release()</tt>, which returns
the object in its current state, and places the <tt class="docutils literal">retain_ptr</tt> into an empty
state. <tt class="docutils literal">retain_ptr&lt;T&gt;</tt> opts to use the name <tt class="docutils literal">detach()</tt> for semantic
reasons. Many objects that might be managed by <tt class="docutils literal">retain_ptr&lt;T&gt;</tt> tend to use a
function or operation named <tt class="docutils literal">release</tt> to decrement the internal reference
count. To reduce confusion for implementers and those curious enough to look
under the hood, a different name was chosen (i.e., <tt class="docutils literal">detach()</tt>). This name
was also used by <tt class="docutils literal"><span class="pre">boost::intrusive_ptr</span></tt>.</p>
<p>A <tt class="docutils literal">retain_ptr&lt;T&gt;</tt> does not <em>own</em> the object is manages. Rather it is
<em>extending</em> ownership. When we use <tt class="docutils literal">detach</tt>, we aren't telling the
<tt class="docutils literal">retain_ptr&lt;T&gt;</tt> to release ownership to the caller. Instead we are expressing
our desire for the <tt class="docutils literal">retain_ptr&lt;T&gt;</tt> to <em>detach</em> its management of the object
it stores. Other possible names for <tt class="docutils literal">detach()</tt> that could be considered are
<tt class="docutils literal">disengage</tt>, <tt class="docutils literal">discard</tt>, and <tt class="docutils literal">withdraw</tt>.</p>
</div>
<div class="section" id="why-provide-retain-t">
<h2><a class="toc-backref" href="#id17">4.7&nbsp;&nbsp;&nbsp;Why provide retain_t?</a></h2>
<p><tt class="docutils literal">retain_t</tt> (and its instance <tt class="docutils literal">retain</tt>) are currently used to represent the
case where a <tt class="docutils literal">retain_ptr</tt> needs to <em>extend</em> (i.e., retain) a pointer to an
object. This mostly comes into play when interacting with APIs that return a
borrowed reference to an object without incrementing its reference count to
begin with. Additionally, an <tt class="docutils literal">enum class retain : bool { no, yes }</tt> would
technically be possible, but this would be the first time such an API is placed
into the standard library.</p>
<p>The name of this type is available for bikeshedding however. Some other less
elegant names include:</p>
<blockquote>
<ul class="simple">
<li>retain_element_t</li>
<li>extend_element_t</li>
<li>retainobj_t</li>
<li>extendobj_t</li>
<li>extend_t</li>
</ul>
</blockquote>
</div>
<div class="section" id="can-retain-traits-store-state">
<h2><a class="toc-backref" href="#id18">4.8&nbsp;&nbsp;&nbsp;Can retain_traits store state?</a></h2>
<p>No. Any important state regarding the object or how it is retained, can be
stored in the object itself. For example, if the reference count needs to be
external from the object, <tt class="docutils literal"><span class="pre">std::shared_ptr</span></tt> would be a better choice.</p>
</div>
<div class="section" id="why-not-just-wrap-a-unique-ptr-with-a-custom-deleter">
<h2><a class="toc-backref" href="#id19">4.9&nbsp;&nbsp;&nbsp;Why not just wrap a unique_ptr with a custom deleter?</a></h2>
<p>This is an extraordinary amount of code that would not be guaranteed to have
a homogenous interface across different libraries and implementations. For
example, using <tt class="docutils literal">retain_ptr</tt> with an OpenCL context object (without checking
for errors in both implementations) is as simple as:</p>
<pre class="code c++ literal-block">
<span class="ln"> 1 </span><span class="k">struct</span> <span class="n">context_traits</span> <span class="p">{</span>
<span class="ln"> 2 </span>  <span class="k">using</span> <span class="n">pointer</span> <span class="o">=</span> <span class="n">cl_context</span><span class="p">;</span>
<span class="ln"> 3 </span>  <span class="k">static</span> <span class="kt">void</span> <span class="nf">increment</span> <span class="p">(</span><span class="n">pointer</span> <span class="n">p</span><span class="p">)</span> <span class="p">{</span> <span class="n">clRetainContext</span><span class="p">(</span><span class="n">p</span><span class="p">);</span> <span class="p">}</span>
<span class="ln"> 4 </span>  <span class="k">static</span> <span class="kt">void</span> <span class="nf">decrement</span> <span class="p">(</span><span class="n">pointer</span> <span class="n">p</span><span class="p">)</span> <span class="p">{</span> <span class="n">clReleaseContext</span><span class="p">(</span><span class="n">p</span><span class="p">);</span> <span class="p">}</span>
<span class="ln"> 5 </span><span class="p">};</span>
<span class="ln"> 6 </span>
<span class="ln"> 7 </span><span class="k">struct</span> <span class="n">context</span> <span class="p">{</span>
<span class="ln"> 8 </span>  <span class="k">using</span> <span class="n">handle_type</span> <span class="o">=</span> <span class="n">retain_ptr</span><span class="o">&lt;</span><span class="n">cl_context</span><span class="p">,</span> <span class="n">context_traits</span><span class="o">&gt;</span><span class="p">;</span>
<span class="ln"> 9 </span>  <span class="k">using</span> <span class="n">pointer</span> <span class="o">=</span> <span class="n">handle_type</span><span class="o">::</span><span class="n">pointer</span><span class="p">;</span>
<span class="ln">10 </span>  <span class="n">context</span> <span class="p">(</span><span class="n">pointer</span> <span class="n">p</span><span class="p">,</span> <span class="n">retain_t</span><span class="p">)</span> <span class="o">:</span> <span class="n">handle</span><span class="p">(</span><span class="n">p</span><span class="p">,</span> <span class="n">retain</span><span class="p">)</span> <span class="p">{</span> <span class="p">}</span>
<span class="ln">11 </span>  <span class="n">context</span> <span class="p">(</span><span class="n">pointer</span> <span class="n">p</span><span class="p">)</span> <span class="o">:</span> <span class="n">handle</span><span class="p">(</span><span class="n">p</span><span class="p">)</span> <span class="p">{</span> <span class="p">}</span>
<span class="ln">12 </span><span class="k">private</span><span class="o">:</span>
<span class="ln">13 </span>  <span class="n">handle_type</span> <span class="n">handle</span><span class="p">;</span>
<span class="ln">14 </span><span class="p">};</span>
</pre>
<p>Using the <tt class="docutils literal">unique_ptr</tt> approach requires more effort. In this case, it is
twice as long to get the same functionality:</p>
<pre class="code c++ literal-block">
<span class="ln"> 1 </span><span class="k">struct</span> <span class="n">context_deleter</span> <span class="p">{</span>
<span class="ln"> 2 </span>  <span class="k">using</span> <span class="n">pointer</span> <span class="o">=</span> <span class="n">cl_context</span><span class="p">;</span>
<span class="ln"> 3 </span>  <span class="kt">void</span> <span class="nf">increment</span> <span class="p">(</span><span class="n">pointer</span> <span class="n">p</span><span class="p">)</span> <span class="k">const</span> <span class="p">{</span>
<span class="ln"> 4 </span>    <span class="k">if</span> <span class="p">(</span><span class="n">p</span><span class="p">)</span> <span class="p">{</span> <span class="n">clRetainContext</span><span class="p">(</span><span class="n">p</span><span class="p">);</span> <span class="p">}</span> <span class="c1">// retain_ptr checks for null for us
</span><span class="ln"> 5 </span><span class="c1"></span>  <span class="p">}</span>
<span class="ln"> 6 </span>  <span class="kt">void</span> <span class="nf">operator</span> <span class="p">()</span> <span class="p">(</span><span class="n">pointer</span> <span class="n">p</span><span class="p">)</span> <span class="k">const</span> <span class="p">{</span> <span class="n">clReleaseContext</span><span class="p">(</span><span class="n">p</span><span class="p">);</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">struct</span> <span class="n">retain_t</span> <span class="p">{</span> <span class="p">};</span>
<span class="ln">10 </span><span class="k">constexpr</span> <span class="n">retain_t</span> <span class="n">retain</span> <span class="p">{</span> <span class="p">};</span>
<span class="ln">11 </span>
<span class="ln">12 </span><span class="k">struct</span> <span class="n">context</span> <span class="p">{</span>
<span class="ln">13 </span>  <span class="k">using</span> <span class="n">handle_type</span> <span class="o">=</span> <span class="n">unique_ptr</span><span class="o">&lt;</span><span class="n">cl_context</span><span class="p">,</span> <span class="n">context_deleter</span><span class="o">&gt;</span><span class="p">;</span>
<span class="ln">14 </span>  <span class="k">using</span> <span class="n">pointer</span> <span class="o">=</span> <span class="n">handle_type</span><span class="o">::</span><span class="n">pointer</span><span class="p">;</span>
<span class="ln">15 </span>
<span class="ln">16 </span>  <span class="n">context</span> <span class="p">(</span><span class="n">pointer</span> <span class="n">p</span><span class="p">,</span> <span class="n">retain_t</span><span class="p">)</span> <span class="o">:</span>
<span class="ln">17 </span>    <span class="n">context</span><span class="p">(</span><span class="n">p</span><span class="p">)</span>
<span class="ln">18 </span>  <span class="p">{</span> <span class="n">handle</span><span class="p">.</span><span class="n">get_deleter</span><span class="p">().</span><span class="n">increment</span><span class="p">(</span><span class="n">handle</span><span class="p">.</span><span class="n">get</span><span class="p">());</span> <span class="p">}</span>
<span class="ln">19 </span>
<span class="ln">20 </span>  <span class="n">context</span> <span class="p">(</span><span class="n">pointer</span> <span class="n">p</span><span class="p">)</span> <span class="o">:</span> <span class="n">handle</span><span class="p">(</span><span class="n">p</span><span class="p">)</span> <span class="p">{</span> <span class="p">}</span>
<span class="ln">21 </span>
<span class="ln">22 </span>  <span class="n">context</span> <span class="p">(</span><span class="n">context</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">that</span><span class="p">)</span> <span class="o">:</span>
<span class="ln">23 </span>    <span class="n">handle</span><span class="p">(</span><span class="n">that</span><span class="p">.</span><span class="n">handle</span><span class="p">.</span><span class="n">get</span><span class="p">())</span>
<span class="ln">24 </span>  <span class="p">{</span> <span class="n">handle</span><span class="p">.</span><span class="n">get_deleter</span><span class="p">().</span><span class="n">increment</span><span class="p">(</span><span class="n">handle</span><span class="p">.</span><span class="n">get</span><span class="p">())</span> <span class="p">}</span>
<span class="ln">25 </span>
<span class="ln">26 </span>  <span class="n">context</span><span class="o">&amp;</span> <span class="k">operator</span> <span class="o">=</span> <span class="p">(</span><span class="n">context</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">that</span><span class="p">)</span> <span class="p">{</span>
<span class="ln">27 </span>    <span class="n">context</span><span class="p">(</span><span class="n">that</span><span class="p">.</span><span class="n">handle</span><span class="p">.</span><span class="n">get</span><span class="p">(),</span> <span class="n">retain</span><span class="p">).</span><span class="n">swap</span><span class="p">(</span><span class="o">*</span><span class="k">this</span><span class="p">);</span>
<span class="ln">28 </span>    <span class="k">return</span> <span class="o">*</span><span class="k">this</span><span class="p">;</span>
<span class="ln">29 </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">handle_type</span> <span class="n">handle</span><span class="p">;</span>
<span class="ln">33 </span><span class="p">};</span>
</pre>
<p>As we can see, using <tt class="docutils literal">retain_ptr&lt;T&gt;</tt> saves effort, allowing us in most cases
to simply rely on the &quot;rule of zero&quot; for constructor management. It will also
not confuse/terrify potential maintainers of code bases where objects construct
a <tt class="docutils literal">unique_ptr</tt> with the raw pointer of another (and ownership is not
transferred).</p>
</div>
</div>
<div class="section" id="technical-specification">
<h1><a class="toc-backref" href="#id20">5&nbsp;&nbsp;&nbsp;Technical Specification</a></h1>
<p>A <em>retain pointer</em> is an object that extends the lifetime of another object
(which in turn manages its own dispostion) and manages that other object
through a pointer. Specifically, a retain pointer is an object <em>r</em> that stores
a pointer to a second object <em>p</em> and will cease to extend the lifetime of <em>p</em>
when <em>r</em> is itself destroyed (e.g., when leaving a block scope). In this
context, <em>r</em> is said to <em>retain</em> <tt class="docutils literal">p</tt>, and <em>p</em> is said to be a <em>self disposing
object</em>.</p>
<p>When <em>p</em>'s lifetime has reached its end, <em>p</em> will dispose of itself as it sees
fit. The conditions regarding <em>p</em>'s lifetime is handled by some count <em>c</em> that
<em>p</em> comprehends, but is otherwise not directly accessible to <em>r</em>.</p>
<p>The mechanism by which <em>r</em> retains and manages the lifetime of <em>p</em> is known as
<em>p</em>'s associated <em>retainer</em>, a stateless object that provides mechanisms for
<em>r</em> to increment, decrement, and (optionally) provide access to <em>c</em>. In this
context, <em>r</em> is able to <em>increment</em> <tt class="docutils literal">c</tt>, <em>decrement</em> <tt class="docutils literal">c</tt>, or access the <em>c</em>
of <em>p</em>.</p>
<p>Let the notation <em>r.p</em> denote the pointer stored by <em>r</em>. Upon request, <em>r</em> can
Furthermore, <em>r</em> can explicitly choose to increment <em>c</em> when <em>r.p</em> is replaced.</p>
<p>Additionally, <em>r</em> can, upon request, <em>transfer ownership</em> to another retain
pointer <em>r2</em>. Upon completion of such a transfer, the following postconditions
hold:</p>
<blockquote>
<ul class="simple">
<li><em>r2.p</em> is equal to the pre-transfer <em>r.p</em>, and</li>
<li><em>r.p</em> is equal to <tt class="docutils literal">nullptr</tt></li>
</ul>
</blockquote>
<p>Furthermore, <em>r</em> can, upon request, <em>extend ownership</em> to another retain
pointer <em>r2</em>. Upon completion of such an extension, the following
postconditions hold:</p>
<blockquote>
<ul class="simple">
<li><em>r2.p</em> is equal to <em>r.p</em></li>
<li><em>c</em> has been incremented by 1</li>
</ul>
</blockquote>
<p>Each object of a type <tt class="docutils literal">U</tt> instantiated from the <tt class="docutils literal">retain_ptr</tt> template
specified in this proposal has the lifetime extension semantics specified
above of a retain pointer. In partical satisfaction of these semantics, each
such <tt class="docutils literal">U</tt> is <tt class="docutils literal">MoveConstructible</tt>, <tt class="docutils literal">MoveAssignable</tt>, <tt class="docutils literal">CopyConstructible</tt>
and <tt class="docutils literal">CopyAssignable</tt>. The template parameter <tt class="docutils literal">T</tt> of <tt class="docutils literal">retain_ptr</tt> may be
an incomplete type. (<em>Note: The uses of</em> <tt class="docutils literal">retain_ptr</tt> <em>include providing
exception safety for self disposing objects, extending management of self
disposing objects to a function, and returning self disposing objects from a
function.</em>)</p>
<pre class="code c++ literal-block">
<span class="k">class</span> <span class="nc">atomic_reference_count</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">;</span>
<span class="k">class</span> <span class="nc">reference_count</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">;</span>

<span class="k">class</span> <span class="nc">retain_t</span><span class="p">;</span>

<span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">T</span><span class="o">&gt;</span> <span class="k">struct</span> <span class="n">retain_traits</span><span class="p">;</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">R</span> <span class="o">=</span> <span class="n">retain_traits</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;&gt;</span> <span class="k">class</span> <span class="nc">retain_ptr</span><span class="p">;</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">R</span><span class="o">&gt;</span>
<span class="kt">void</span> <span class="n">swap</span> <span class="p">(</span><span class="n">retain_ptr</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">R</span><span class="o">&gt;&amp;</span> <span class="n">x</span><span class="p">,</span> <span class="n">retain_ptr</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">R</span><span class="o">&gt;&amp;</span> <span class="n">y</span><span class="p">)</span> <span class="k">noexcept</span><span class="p">;</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">R</span><span class="o">&gt;</span>
<span class="kt">bool</span> <span class="k">operator</span> <span class="o">==</span> <span class="p">(</span><span class="n">retain_ptr</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">R</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">x</span><span class="p">,</span> <span class="n">retain_ptr</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">R</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">y</span><span class="p">)</span> <span class="k">noexcept</span><span class="p">;</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">R</span><span class="o">&gt;</span>
<span class="kt">bool</span> <span class="k">operator</span> <span class="o">!=</span> <span class="p">(</span><span class="n">retain_ptr</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">R</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">x</span><span class="p">,</span> <span class="n">retain_ptr</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">R</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">y</span><span class="p">)</span> <span class="k">noexcept</span><span class="p">;</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">R</span><span class="o">&gt;</span>
<span class="kt">bool</span> <span class="k">operator</span> <span class="o">&gt;=</span> <span class="p">(</span><span class="n">retain_ptr</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">R</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">x</span><span class="p">,</span> <span class="n">retain_ptr</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">R</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">y</span><span class="p">)</span> <span class="k">noexcept</span><span class="p">;</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">R</span><span class="o">&gt;</span>
<span class="kt">bool</span> <span class="k">operator</span> <span class="o">&lt;=</span> <span class="p">(</span><span class="n">retain_ptr</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">R</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">x</span><span class="p">,</span> <span class="n">retain_ptr</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">R</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">y</span><span class="p">)</span> <span class="k">noexcept</span><span class="p">;</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">R</span><span class="o">&gt;</span>
<span class="kt">bool</span> <span class="k">operator</span> <span class="o">&gt;</span> <span class="p">(</span><span class="n">retain_ptr</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">R</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">x</span><span class="p">,</span> <span class="n">retain_ptr</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">R</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">y</span><span class="p">)</span> <span class="k">noexcept</span><span class="p">;</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">R</span><span class="o">&gt;</span>
<span class="kt">bool</span> <span class="k">operator</span> <span class="o">&lt;</span> <span class="p">(</span><span class="n">retain_ptr</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">R</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">x</span><span class="p">,</span> <span class="n">retain_ptr</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">R</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">y</span><span class="p">)</span> <span class="k">noexcept</span><span class="p">;</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">R</span><span class="o">&gt;</span>
<span class="kt">bool</span> <span class="k">operator</span> <span class="o">==</span> <span class="p">(</span><span class="n">retain_ptr</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">R</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">x</span><span class="p">,</span> <span class="n">nullptr_t</span><span class="p">)</span> <span class="k">noexcept</span><span class="p">;</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">R</span><span class="o">&gt;</span>
<span class="kt">bool</span> <span class="k">operator</span> <span class="o">!=</span> <span class="p">(</span><span class="n">retain_ptr</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">R</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">x</span><span class="p">,</span> <span class="n">nullptr_t</span><span class="p">)</span> <span class="k">noexcept</span><span class="p">;</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">R</span><span class="o">&gt;</span>
<span class="kt">bool</span> <span class="k">operator</span> <span class="o">&gt;=</span> <span class="p">(</span><span class="n">retain_ptr</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">R</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">x</span><span class="p">,</span> <span class="n">nullptr_t</span><span class="p">)</span> <span class="k">noexcept</span><span class="p">;</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">R</span><span class="o">&gt;</span>
<span class="kt">bool</span> <span class="k">operator</span> <span class="o">&lt;=</span> <span class="p">(</span><span class="n">retain_ptr</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">R</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">x</span><span class="p">,</span> <span class="n">nullptr_t</span><span class="p">)</span> <span class="k">noexcept</span><span class="p">;</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">R</span><span class="o">&gt;</span>
<span class="kt">bool</span> <span class="k">operator</span> <span class="o">&gt;</span> <span class="p">(</span><span class="n">retain_ptr</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">R</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">x</span><span class="p">,</span> <span class="n">nullptr_t</span><span class="p">)</span> <span class="k">noexcept</span><span class="p">;</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">R</span><span class="o">&gt;</span>
<span class="kt">bool</span> <span class="k">operator</span> <span class="o">&lt;</span> <span class="p">(</span><span class="n">retain_ptr</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">R</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">x</span><span class="p">,</span> <span class="n">nullptr_t</span><span class="p">)</span> <span class="k">noexcept</span><span class="p">;</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">R</span><span class="o">&gt;</span>
<span class="kt">bool</span> <span class="k">operator</span> <span class="o">==</span> <span class="p">(</span><span class="n">nullptr_t</span><span class="p">,</span> <span class="n">retain_ptr</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">R</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">y</span><span class="p">)</span> <span class="k">noexcept</span><span class="p">;</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">R</span><span class="o">&gt;</span>
<span class="kt">bool</span> <span class="k">operator</span> <span class="o">!=</span> <span class="p">(</span><span class="n">nullptr_t</span><span class="p">,</span> <span class="n">retain_ptr</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">R</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">y</span><span class="p">)</span> <span class="k">noexcept</span><span class="p">;</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">R</span><span class="o">&gt;</span>
<span class="kt">bool</span> <span class="k">operator</span> <span class="o">&gt;=</span> <span class="p">(</span><span class="n">nullptr_t</span><span class="p">,</span> <span class="n">retain_ptr</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">R</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">y</span><span class="p">)</span> <span class="k">noexcept</span><span class="p">;</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">R</span><span class="o">&gt;</span>
<span class="kt">bool</span> <span class="k">operator</span> <span class="o">&lt;=</span> <span class="p">(</span><span class="n">nullptr_t</span><span class="p">,</span> <span class="n">retain_ptr</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">R</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">y</span><span class="p">)</span> <span class="k">noexcept</span><span class="p">;</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">R</span><span class="o">&gt;</span>
<span class="kt">bool</span> <span class="k">operator</span> <span class="o">&gt;</span> <span class="p">(</span><span class="n">nullptr_t</span><span class="p">,</span> <span class="n">retain_ptr</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">R</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">y</span><span class="p">)</span> <span class="k">noexcept</span><span class="p">;</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">R</span><span class="o">&gt;</span>
<span class="kt">bool</span> <span class="k">operator</span> <span class="o">&lt;</span> <span class="p">(</span><span class="n">nullptr_t</span><span class="p">,</span> <span class="n">retain_ptr</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">R</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">y</span><span class="p">)</span> <span class="k">noexcept</span><span class="p">;</span>
</pre>
<div class="section" id="atomic-reference-count-t-and-reference-count-t">
<h2><a class="toc-backref" href="#id21">5.1&nbsp;&nbsp;&nbsp;atomic_reference_count&lt;T&gt; and reference_count&lt;T&gt;</a></h2>
<p><tt class="docutils literal">atomic_reference_count&lt;T&gt;</tt> and <tt class="docutils literal">reference_count&lt;T&gt;</tt> are mixin types,
provided for user defined types that simply rely on <tt class="docutils literal">new</tt> and <tt class="docutils literal">delete</tt> to
have their lifetime extended by <tt class="docutils literal">retain_ptr</tt>. The template parameter <tt class="docutils literal">T</tt> is
intended to be the type deriving from <tt class="docutils literal">atomic_reference_count</tt> or
<tt class="docutils literal">reference_count</tt> (a.k.a. the curiously repeating template pattern, CRTP).</p>
<pre class="code c++ literal-block">
<span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">T</span><span class="o">&gt;</span>
 <span class="k">struct</span> <span class="n">atomic_reference_count</span> <span class="p">{</span>
   <span class="k">friend</span> <span class="n">retain_traits</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">;</span>
 <span class="k">protected</span><span class="o">:</span>
   <span class="n">atomic_reference_count</span> <span class="p">()</span> <span class="o">=</span> <span class="k">default</span><span class="p">;</span>
 <span class="k">private</span><span class="o">:</span>
   <span class="n">atomic</span><span class="o">&lt;</span><span class="kt">uint_least64_t</span><span class="o">&gt;</span> <span class="n">count</span> <span class="p">{</span> <span class="mi">1</span> <span class="p">};</span> <span class="c1">// provided for exposition
</span> <span class="p">};</span>

 <span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">T</span><span class="o">&gt;</span>
 <span class="k">struct</span> <span class="n">reference_count</span> <span class="p">{</span>
   <span class="k">friend</span> <span class="n">retain_traits</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">;</span>
 <span class="k">protected</span><span class="o">:</span>
   <span class="n">reference_count</span> <span class="p">()</span> <span class="o">=</span> <span class="k">default</span><span class="p">;</span>
 <span class="k">private</span><span class="o">:</span>
   <span class="kt">uint_least64_t</span> <span class="n">count</span> <span class="p">{</span> <span class="mi">1</span> <span class="p">};</span> <span class="c1">// provided for exposition
</span> <span class="p">};</span>
</pre>
</div>
<div class="section" id="retain-t">
<h2><a class="toc-backref" href="#id22">5.2&nbsp;&nbsp;&nbsp;retain_t</a></h2>
<p><tt class="docutils literal">retain_t</tt> is a sentinel type, with a constexpr instance <tt class="docutils literal">retain</tt>.</p>
<pre class="code c++ literal-block">
<span class="k">namespace</span> <span class="n">std</span> <span class="p">{</span>
  <span class="k">struct</span> <span class="n">retain_element_t</span> <span class="p">{</span> <span class="k">constexpr</span> <span class="n">retain_element_t</span> <span class="p">()</span> <span class="o">=</span> <span class="k">default</span><span class="p">;</span> <span class="p">}</span>
  <span class="k">constexpr</span> <span class="n">retain_t</span> <span class="n">retain</span> <span class="p">{</span> <span class="p">};</span>
<span class="p">}</span>
</pre>
</div>
<div class="section" id="retain-traits-t">
<h2><a class="toc-backref" href="#id23">5.3&nbsp;&nbsp;&nbsp;retain_traits&lt;T&gt;</a></h2>
<p>The class template <tt class="docutils literal">retain_traits</tt> serves as the default traits object for
the class template <tt class="docutils literal">retain_ptr</tt>. Unless <tt class="docutils literal">retain_traits</tt> is specialized for
a specific type, the template parameter <tt class="docutils literal">T</tt> must inherit from either
<tt class="docutils literal">atomic_reference_count&lt;T&gt;</tt> or <tt class="docutils literal">reference_count&lt;T&gt;</tt>. In the event that
<tt class="docutils literal">retain_traits</tt> is specialized for a type, the template parameter <tt class="docutils literal">T</tt> may
be an incomplete type.</p>
<pre class="code c++ literal-block">
<span class="k">namespace</span> <span class="n">std</span> <span class="p">{</span>
  <span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">T</span><span class="o">&gt;</span> <span class="k">struct</span> <span class="n">retain_traits</span> <span class="p">{</span>
    <span class="k">static</span> <span class="kt">void</span> <span class="n">increment</span> <span class="p">(</span><span class="n">atomic_reference_count</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;*</span><span class="p">)</span> <span class="k">noexcept</span><span class="p">;</span>
    <span class="k">static</span> <span class="kt">void</span> <span class="nf">decrement</span> <span class="p">(</span><span class="n">atomic_reference_count</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;*</span><span class="p">)</span> <span class="k">noexcept</span><span class="p">;</span>
    <span class="k">static</span> <span class="kt">long</span> <span class="nf">use_count</span> <span class="p">(</span><span class="n">atomic_reference_count</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;*</span><span class="p">)</span> <span class="k">noexcept</span><span class="p">;</span>

    <span class="k">static</span> <span class="kt">void</span> <span class="nf">increment</span> <span class="p">(</span><span class="n">reference_count</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;*</span><span class="p">)</span> <span class="k">noexcept</span><span class="p">;</span>
    <span class="k">static</span> <span class="kt">void</span> <span class="nf">decrement</span> <span class="p">(</span><span class="n">reference_count</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;*</span><span class="p">)</span> <span class="k">noexcept</span><span class="p">;</span>
    <span class="k">static</span> <span class="kt">long</span> <span class="nf">use_count</span> <span class="p">(</span><span class="n">reference_count</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;*</span><span class="p">)</span> <span class="k">noexcept</span><span class="p">;</span>
  <span class="p">};</span>
<span class="p">}</span>
</pre>
<p><tt class="docutils literal">static void increment (atomic_reference_count&lt;T&gt;* ptr) noexcept;</tt></p>
<blockquote>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">effects:</th><td class="field-body">Increments the internal reference count for <em>ptr</em> with
<tt class="docutils literal">memory_order_acq_rel</tt></td>
</tr>
<tr class="field"><th class="field-name">postcondition:</th><td class="field-body"><tt class="docutils literal"><span class="pre">ptr-&gt;count</span></tt> has been incremented by 1.</td>
</tr>
</tbody>
</table>
</blockquote>
<p><tt class="docutils literal">static void decrement (atomic_reference_count&lt;T&gt;* ptr) noexcept;</tt></p>
<blockquote>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">effects:</th><td class="field-body">Decrements the internal reference count for <em>ptr</em> with
<tt class="docutils literal">memory_order_acq_rel</tt>. If the internal reference count of <em>ptr</em>
reaches 0, it is disposed of via <tt class="docutils literal">delete</tt>.</td>
</tr>
</tbody>
</table>
</blockquote>
<p><tt class="docutils literal">static long use_count (atomic_reference_count&lt;T&gt;* ptr) noexcept;</tt></p>
<blockquote>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">returns:</th><td class="field-body">The internal reference count for <em>ptr</em> with
<tt class="docutils literal">memory_order_acquire</tt>.</td>
</tr>
</tbody>
</table>
</blockquote>
<p><tt class="docutils literal">static void increment (reference_count&lt;T&gt;* ptr) noexcept;</tt></p>
<blockquote>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">effects:</th><td class="field-body">Increments the internal reference count for <em>ptr</em> by 1.</td>
</tr>
</tbody>
</table>
</blockquote>
<p><tt class="docutils literal">static void decrement (reference_count&lt;T&gt;* ptr) noexcept;</tt></p>
<blockquote>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">effects:</th><td class="field-body">Decrements the internal reference for <em>ptr</em> by 1. If the count
reaches 0, <em>ptr</em> is disposed of via <tt class="docutils literal">delete</tt>.</td>
</tr>
</tbody>
</table>
</blockquote>
<p><tt class="docutils literal">static long use_count (reference_count&lt;T&gt;* ptr) noexcept;</tt></p>
<blockquote>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">returns:</th><td class="field-body">The reference count for <em>ptr</em>.</td>
</tr>
</tbody>
</table>
</blockquote>
</div>
<div class="section" id="retain-ptr-t-r">
<h2><a class="toc-backref" href="#id24">5.4&nbsp;&nbsp;&nbsp;retain_ptr&lt;T, R&gt;</a></h2>
<p>The default type for the template parameter <tt class="docutils literal">R</tt> is <tt class="docutils literal">retain_traits</tt>. A
client supplied template argument <tt class="docutils literal">R</tt> shall be an object with non-member
functions  for which, given a <tt class="docutils literal">ptr</tt> of type <tt class="docutils literal">unique_ptr&lt;T, <span class="pre">R&gt;::pointer</span></tt>,
the expressions <tt class="docutils literal"><span class="pre">R::increment(ptr)</span></tt> and <tt class="docutils literal"><span class="pre">R::decrement(ptr)</span></tt> are valid and
has the effect of retaining or disposing of the pointer as appropriate for that
retainer.</p>
<p>If the <em>qualified-id</em> <tt class="docutils literal"><span class="pre">R::pointer</span></tt> is valid and denotes a type, then
<tt class="docutils literal">retain_ptr&lt;T, <span class="pre">R&gt;::pointer</span></tt> shall be synonymous with <tt class="docutils literal"><span class="pre">R::pointer</span></tt>.
Otherwise <tt class="docutils literal">retain_ptr&lt;T, <span class="pre">R&gt;::pointer</span></tt> shall be a synonym for
<tt class="docutils literal">element_type*</tt>. The type <tt class="docutils literal">retain_ptr&lt;T, <span class="pre">R&gt;::pointer</span></tt> shall satisfy the
requirements of <tt class="docutils literal">NullablePointer</tt>.</p>
<pre class="code c++ literal-block">
<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">R</span><span class="o">=</span><span class="n">retain_traits</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;&gt;</span>
<span class="k">struct</span> <span class="n">retain_ptr</span> <span class="p">{</span>
  <span class="k">using</span> <span class="n">element_type</span> <span class="o">=</span> <span class="n">T</span><span class="p">;</span>
  <span class="k">using</span> <span class="n">traits_type</span> <span class="o">=</span> <span class="n">R</span><span class="p">;</span>
  <span class="k">using</span> <span class="n">pointer</span> <span class="o">=</span> <span class="cm">/* see below */</span>

  <span class="n">retain_ptr</span> <span class="p">(</span><span class="n">pointer</span><span class="p">,</span> <span class="n">retain_t</span><span class="p">)</span> <span class="k">noexcept</span><span class="p">(</span><span class="cm">/* see below */</span><span class="p">);</span>
  <span class="k">explicit</span> <span class="nf">retain_ptr</span> <span class="p">(</span><span class="n">pointer</span><span class="p">)</span> <span class="k">noexcept</span><span class="p">;</span>
  <span class="n">retain_ptr</span> <span class="p">(</span><span class="n">nullptr_t</span><span class="p">)</span> <span class="k">noexcept</span> <span class="o">:</span> <span class="n">retain_ptr</span><span class="p">()</span> <span class="p">{</span> <span class="p">}</span>

  <span class="n">retain_ptr</span> <span class="p">(</span><span class="n">retain_ptr</span> <span class="k">const</span><span class="o">&amp;</span><span class="p">)</span> <span class="k">noexcept</span><span class="p">(</span><span class="cm">/* see below */</span><span class="p">);</span>
  <span class="n">retain_ptr</span> <span class="p">(</span><span class="n">retain_ptr</span><span class="o">&amp;&amp;</span><span class="p">)</span> <span class="k">noexcept</span><span class="p">;</span>
  <span class="n">retain_ptr</span> <span class="p">()</span> <span class="k">noexcept</span><span class="p">;</span>
  <span class="o">~</span><span class="n">retain_ptr</span> <span class="p">()</span> <span class="k">noexcept</span><span class="p">(</span><span class="cm">/* see below */</span><span class="p">);</span>

  <span class="n">retain_ptr</span><span class="o">&amp;</span> <span class="k">operator</span> <span class="o">=</span> <span class="p">(</span><span class="n">retain_ptr</span> <span class="k">const</span><span class="o">&amp;</span><span class="p">)</span> <span class="k">noexcept</span><span class="p">(</span><span class="cm">/* see below */</span><span class="p">);</span>
  <span class="n">retain_ptr</span><span class="o">&amp;</span> <span class="k">operator</span> <span class="o">=</span> <span class="p">(</span><span class="n">retain</span><span class="o">&amp;&amp;</span><span class="p">)</span> <span class="k">noexcept</span><span class="p">;</span>

  <span class="n">retain_ptr</span><span class="o">&amp;</span> <span class="k">operator</span> <span class="o">=</span> <span class="p">(</span><span class="n">nullptr_t</span><span class="p">)</span> <span class="k">noexcept</span><span class="p">;</span>

  <span class="kt">void</span> <span class="nf">swap</span> <span class="p">(</span><span class="n">retain_ptr</span><span class="o">&amp;</span><span class="p">)</span> <span class="k">noexcept</span><span class="p">;</span>

  <span class="k">explicit</span> <span class="k">operator</span> <span class="nf">pointer</span> <span class="p">()</span> <span class="k">const</span> <span class="k">noexcept</span><span class="p">;</span>
  <span class="k">explicit</span> <span class="k">operator</span> <span class="nf">bool</span> <span class="p">()</span> <span class="k">const</span> <span class="k">noexcept</span><span class="p">;</span>

  <span class="n">element_type</span><span class="o">&amp;</span> <span class="k">operator</span> <span class="o">*</span> <span class="p">()</span> <span class="k">const</span> <span class="k">noexcept</span><span class="p">;</span>
  <span class="n">pointer</span> <span class="k">operator</span> <span class="o">-&gt;</span> <span class="p">()</span> <span class="k">const</span> <span class="k">noexcept</span><span class="p">;</span>
  <span class="n">pointer</span> <span class="nf">get</span> <span class="p">()</span> <span class="k">const</span> <span class="k">noexcept</span><span class="p">;</span>

  <span class="kt">long</span> <span class="nf">use_count</span> <span class="p">()</span> <span class="k">const</span> <span class="k">noexcept</span><span class="p">(</span><span class="cm">/* see below */</span><span class="p">);</span>
  <span class="kt">bool</span> <span class="nf">unique</span> <span class="p">()</span> <span class="k">const</span> <span class="k">noexcept</span><span class="p">(</span><span class="cm">/* see below */</span><span class="p">);</span>

  <span class="p">[[</span><span class="n">nodiscard</span><span class="p">]]</span> <span class="n">pointer</span> <span class="n">detach</span> <span class="p">()</span> <span class="k">noexcept</span><span class="p">;</span>

  <span class="kt">void</span> <span class="nf">reset</span> <span class="p">(</span><span class="n">pointer</span><span class="p">,</span> <span class="n">retain_t</span><span class="p">)</span> <span class="k">noexcept</span><span class="p">(</span><span class="cm">/* see below */</span><span class="p">);</span>
  <span class="kt">void</span> <span class="nf">reset</span> <span class="p">(</span><span class="n">pointer</span> <span class="n">p</span> <span class="o">=</span> <span class="n">pointer</span> <span class="p">{</span> <span class="p">})</span> <span class="k">noexcept</span><span class="p">(</span><span class="cm">/* see below */</span><span class="p">);</span>
<span class="p">};</span>
</pre>
<div class="section" id="retain-ptr-constructors">
<h3><a class="toc-backref" href="#id25">5.4.1&nbsp;&nbsp;&nbsp;retain_ptr constructors</a></h3>
<p><tt class="docutils literal">retain_ptr (pointer p, retain_t) noexcept(maybe);</tt></p>
<blockquote>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">effects:</th><td class="field-body">Constructs a <tt class="docutils literal">retain_ptr</tt> that retains <tt class="docutils literal">p</tt>, initializing the
stored pointer with <tt class="docutils literal">p</tt>, and increments the reference count of
<tt class="docutils literal">p</tt> if <tt class="docutils literal">p != nullptr</tt>.</td>
</tr>
<tr class="field"><th class="field-name">postconditions:</th><td class="field-body"><tt class="docutils literal">get() == p</tt>.</td>
</tr>
<tr class="field"><th class="field-name">remarks:</th><td class="field-body">This constructor is only specified <tt class="docutils literal">noexcept</tt> if
<tt class="docutils literal"><span class="pre">traits_type::increment</span></tt> function is also specified <tt class="docutils literal">noexcept</tt>.
If an exception is thrown during this operation, this constructor
will have no effect.</td>
</tr>
</tbody>
</table>
</blockquote>
<p><tt class="docutils literal">explicit retain_ptr (pointer p) noexcept;</tt></p>
<blockquote>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">effects:</th><td class="field-body">Constructs a <tt class="docutils literal">retain_ptr</tt> that retains <tt class="docutils literal">p</tt>, initializing the
stored pointer with <tt class="docutils literal">p</tt>.</td>
</tr>
<tr class="field"><th class="field-name">postconditions:</th><td class="field-body"><tt class="docutils literal">get() == p</tt></td>
</tr>
<tr class="field"><th class="field-name">remarks:</th><td class="field-body"><tt class="docutils literal">p</tt>'s reference count remains untouched.</td>
</tr>
</tbody>
</table>
</blockquote>
<p><tt class="docutils literal">retain_ptr () noexcept;</tt></p>
<blockquote>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">effects:</th><td class="field-body">Constructs a <tt class="docutils literal">retain_ptr</tt> object that retains nothing,
value-initializing the stored pointer.</td>
</tr>
<tr class="field"><th class="field-name">postconditions:</th><td class="field-body"><tt class="docutils literal">get() == nullptr</tt></td>
</tr>
</tbody>
</table>
</blockquote>
<p><tt class="docutils literal">retain_ptr(retain_ptr const&amp; r) noexcept(maybe);</tt></p>
<blockquote>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">effects:</th><td class="field-body">Constructs a <tt class="docutils literal">retain_ptr</tt> by extending management from <tt class="docutils literal">r</tt> to
<tt class="docutils literal">*this</tt>.</td>
</tr>
<tr class="field"><th class="field-name">postconditions:</th><td class="field-body"><tt class="docutils literal">get() == r.get()</tt></td>
</tr>
<tr class="field"><th class="field-name">remarks:</th><td class="field-body">This constructor is only specified <tt class="docutils literal">noexcept</tt> if
<tt class="docutils literal"><span class="pre">traits_type::increment</span></tt> function is specified <tt class="docutils literal">noexcept</tt>.
If an exception is thrown during this operation, this constructor
will have no effect.</td>
</tr>
</tbody>
</table>
</blockquote>
<p><tt class="docutils literal">retain_ptr(retain_ptr&amp;&amp; r) noexcept;</tt></p>
<blockquote>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">effects:</th><td class="field-body">Constructs a <tt class="docutils literal">retain_ptr</tt> by transferring management from <tt class="docutils literal">r</tt>
to <tt class="docutils literal">*this</tt>.</td>
</tr>
<tr class="field"><th class="field-name">postconditions:</th><td class="field-body"><tt class="docutils literal">get()</tt> yields the value <tt class="docutils literal">r.get()</tt> yielded before the
construction.</td>
</tr>
</tbody>
</table>
</blockquote>
</div>
<div class="section" id="retain-ptr-destructor">
<h3><a class="toc-backref" href="#id26">5.4.2&nbsp;&nbsp;&nbsp;retain_ptr destructor</a></h3>
<p><tt class="docutils literal">~retain_ptr() noexcept(maybe);</tt></p>
<blockquote>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">effects:</th><td class="field-body">If <tt class="docutils literal">get() == nullptr</tt>, there are no effects. Otherwise,
<tt class="docutils literal"><span class="pre">traits_type::decrement(get())</span></tt>.</td>
</tr>
<tr class="field"><th class="field-name">remarks:</th><td class="field-body">This destructor is only specified <tt class="docutils literal">noexcept</tt> if the
<tt class="docutils literal"><span class="pre">traits_type::decrement</span></tt> function is specified <tt class="docutils literal">noexcept</tt></td>
</tr>
</tbody>
</table>
</blockquote>
</div>
<div class="section" id="retain-ptr-assignment">
<h3><a class="toc-backref" href="#id27">5.4.3&nbsp;&nbsp;&nbsp;retain_ptr assignment</a></h3>
<p><tt class="docutils literal">retain_ptr&amp; operator = (retain_ptr const&amp; r) noexcept(maybe);</tt></p>
<blockquote>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">effects:</th><td class="field-body">Extends ownership from <tt class="docutils literal">r</tt> to <tt class="docutils literal">*this</tt> as if by calling
<tt class="docutils literal"><span class="pre">reset(r.get(),</span> retain)</tt>.</td>
</tr>
<tr class="field"><th class="field-name">returns:</th><td class="field-body"><tt class="docutils literal">*this</tt></td>
</tr>
<tr class="field"><th class="field-name">remarks:</th><td class="field-body">This operator is only specified <tt class="docutils literal">noexcept</tt> if both
<tt class="docutils literal"><span class="pre">traits_type::increment</span></tt> and <tt class="docutils literal"><span class="pre">traits_type::decrement</span></tt> functions
are specified <tt class="docutils literal">noexcept</tt>.</td>
</tr>
</tbody>
</table>
</blockquote>
<p><tt class="docutils literal">retain_ptr&amp; operator = (retain_ptr&amp;&amp; r) noexcept;</tt></p>
<blockquote>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">effects:</th><td class="field-body">Transfers ownership from <tt class="docutils literal">r</tt> to <tt class="docutils literal">*this</tt> as if by calling
<tt class="docutils literal"><span class="pre">reset(r.detach())</span></tt></td>
</tr>
<tr class="field"><th class="field-name">returns:</th><td class="field-body"><tt class="docutils literal">*this</tt></td>
</tr>
</tbody>
</table>
</blockquote>
<p><tt class="docutils literal">retain_ptr&amp; operator = (nullptr_t) noexcept;</tt></p>
<blockquote>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">effects:</th><td class="field-body"><tt class="docutils literal">reset()</tt></td>
</tr>
<tr class="field"><th class="field-name">postconditions:</th><td class="field-body"><tt class="docutils literal">get() == nullptr</tt></td>
</tr>
<tr class="field"><th class="field-name">returns:</th><td class="field-body"><tt class="docutils literal">*this</tt></td>
</tr>
</tbody>
</table>
</blockquote>
</div>
<div class="section" id="retain-ptr-observers">
<h3><a class="toc-backref" href="#id28">5.4.4&nbsp;&nbsp;&nbsp;retain_ptr observers</a></h3>
<p><tt class="docutils literal">element_type&amp; operator * () const noexcept;</tt></p>
<blockquote>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">requires:</th><td class="field-body"><tt class="docutils literal">get() != nullptr</tt></td>
</tr>
<tr class="field"><th class="field-name">returns:</th><td class="field-body"><tt class="docutils literal">*get()</tt></td>
</tr>
</tbody>
</table>
</blockquote>
<p><tt class="docutils literal">pointer operator <span class="pre">-&gt;</span> () const noexcept;</tt></p>
<blockquote>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">requires:</th><td class="field-body"><tt class="docutils literal">get() != nullptr</tt></td>
</tr>
<tr class="field"><th class="field-name">returns:</th><td class="field-body"><tt class="docutils literal">get()</tt></td>
</tr>
<tr class="field"><th class="field-name">note:</th><td class="field-body">use typically requires that <tt class="docutils literal">element_type</tt> be a complete type.</td>
</tr>
</tbody>
</table>
</blockquote>
<p><tt class="docutils literal">pointer get () const noexcept;</tt></p>
<blockquote>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">returns:</th><td class="field-body">The stored pointer</td>
</tr>
</tbody>
</table>
</blockquote>
<p><tt class="docutils literal">explicit operator pointer () const noexcept;</tt></p>
<blockquote>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">returns:</th><td class="field-body"><tt class="docutils literal">get()</tt></td>
</tr>
</tbody>
</table>
</blockquote>
<p><tt class="docutils literal">explicit operator bool () const noexcept;</tt></p>
<blockquote>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">returns:</th><td class="field-body"><tt class="docutils literal">get() != nullptr</tt></td>
</tr>
</tbody>
</table>
</blockquote>
<p><tt class="docutils literal">long use_count () const noexcept(maybe);</tt></p>
<blockquote>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">returns:</th><td class="field-body">Value representing the current reference count of the stored
pointer. If <tt class="docutils literal"><span class="pre">traits_type::use_count(get())</span></tt> is not a valid
expression, <tt class="docutils literal"><span class="pre">-1</span></tt> is returned. If <tt class="docutils literal">get() == nullptr</tt> <tt class="docutils literal">0</tt> is
returned</td>
</tr>
<tr class="field"><th class="field-name">remarks:</th><td class="field-body">This observer is only specified <tt class="docutils literal">noexcept</tt> if
<tt class="docutils literal"><span class="pre">traits_type::use_count</span></tt> is specified <tt class="docutils literal">noexcept</tt>. Unless otherwise
specified, the value returned should be considered stale.</td>
</tr>
</tbody>
</table>
</blockquote>
<p><tt class="docutils literal">bool unique () const noexcept(maybe);</tt></p>
<blockquote>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">returns:</th><td class="field-body"><tt class="docutils literal">use_count() == 1</tt></td>
</tr>
<tr class="field"><th class="field-name">remarks:</th><td class="field-body">This observer is only specified <tt class="docutils literal">noexcept</tt> if
<tt class="docutils literal"><span class="pre">traits_type::use_count</span></tt> is specified <tt class="docutils literal">noexcept</tt>. Unless otherwise
specified, the value returned should be considered stale.</td>
</tr>
</tbody>
</table>
</blockquote>
</div>
<div class="section" id="retain-ptr-modifiers">
<h3><a class="toc-backref" href="#id29">5.4.5&nbsp;&nbsp;&nbsp;retain_ptr modifiers</a></h3>
<p><tt class="docutils literal">[[nodiscard]] pointer detach () noexcept;</tt></p>
<blockquote>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">postcondition:</th><td class="field-body"><tt class="docutils literal">get() == nullptr</tt></td>
</tr>
<tr class="field"><th class="field-name">returns:</th><td class="field-body">The value <tt class="docutils literal">get()</tt> had at the start of the call to <tt class="docutils literal">detach</tt></td>
</tr>
</tbody>
</table>
</blockquote>
<p><tt class="docutils literal">void reset (pointer p, retain_t) noexcept(maybe);</tt></p>
<blockquote>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">effects:</th><td class="field-body">Assigns <tt class="docutils literal">p</tt> to the stored pointer, and then if the old value of
the stored pointer <tt class="docutils literal">old_p</tt>, was not equal to <tt class="docutils literal">nullptr</tt>, calls
<tt class="docutils literal"><span class="pre">traits_type::decrement</span></tt>. Then if <tt class="docutils literal">p</tt> is not equal to
<tt class="docutils literal">nullptr</tt>, <tt class="docutils literal"><span class="pre">traits_type::increment</span></tt> is called.</td>
</tr>
<tr class="field"><th class="field-name">postconditions:</th><td class="field-body"><tt class="docutils literal">get() == p</tt></td>
</tr>
<tr class="field"><th class="field-name">remarks:</th><td class="field-body">This modifier is only specified <tt class="docutils literal">noexcept</tt> if both
<tt class="docutils literal"><span class="pre">traits_type::decrement</span></tt> and <tt class="docutils literal"><span class="pre">traits_type::increment</span></tt> are
specified <tt class="docutils literal">noexcept</tt>.</td>
</tr>
</tbody>
</table>
</blockquote>
<p><tt class="docutils literal">void reset (pointer p = pointer { }) noexcept(maybe);</tt></p>
<blockquote>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">effects:</th><td class="field-body">Assigns <tt class="docutils literal">p</tt> to the stored pointer, and then if the old value of
the stored pointer, <tt class="docutils literal">old_p</tt>, was not equal to <tt class="docutils literal">nullptr</tt>, calls
<tt class="docutils literal"><span class="pre">traits_type::decrement</span></tt>.</td>
</tr>
<tr class="field"><th class="field-name">postconditions:</th><td class="field-body"><tt class="docutils literal">get() == p</tt></td>
</tr>
<tr class="field"><th class="field-name">remarks:</th><td class="field-body">This modifier is only specified <tt class="docutils literal">noexcept</tt> if
<tt class="docutils literal"><span class="pre">traits_type::decrement</span></tt> is specified <tt class="docutils literal">noexcept</tt>.</td>
</tr>
</tbody>
</table>
</blockquote>
<p><tt class="docutils literal">void swap (retain_ptr&amp; r) noexcept;</tt></p>
<blockquote>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">effects:</th><td class="field-body">Invokes <tt class="docutils literal">swap</tt> on the stored pointers of <tt class="docutils literal">*this</tt> and <tt class="docutils literal">r</tt>.</td>
</tr>
</tbody>
</table>
</blockquote>
</div>
<div class="section" id="retain-ptr-specialized-algorithms">
<h3><a class="toc-backref" href="#id30">5.4.6&nbsp;&nbsp;&nbsp;retain_ptr specialized algorithms</a></h3>
<pre class="code c++ literal-block">
<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">R</span><span class="o">&gt;</span>
<span class="kt">void</span> <span class="n">swap</span> <span class="p">(</span><span class="n">retain_ptr</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">R</span><span class="o">&gt;&amp;</span><span class="p">,</span> <span class="n">retain_ptr</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">R</span><span class="o">&gt;&amp;</span><span class="p">)</span> <span class="k">noexcept</span><span class="p">;</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">R</span><span class="o">&gt;</span>
<span class="kt">bool</span> <span class="k">operator</span> <span class="o">==</span> <span class="p">(</span><span class="n">retain_ptr</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">R</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span><span class="p">,</span> <span class="n">retain_ptr</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">R</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span><span class="p">)</span> <span class="k">noexcept</span><span class="p">;</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">R</span><span class="o">&gt;</span>
<span class="kt">bool</span> <span class="k">operator</span> <span class="o">!=</span> <span class="p">(</span><span class="n">retain_ptr</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">R</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span><span class="p">,</span> <span class="n">retain_ptr</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">R</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span><span class="p">)</span> <span class="k">noexcept</span><span class="p">;</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">R</span><span class="o">&gt;</span>
<span class="kt">bool</span> <span class="k">operator</span> <span class="o">&gt;=</span> <span class="p">(</span><span class="n">retain_ptr</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">R</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span><span class="p">,</span> <span class="n">retain_ptr</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">R</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span><span class="p">)</span> <span class="k">noexcept</span><span class="p">;</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">R</span><span class="o">&gt;</span>
<span class="kt">bool</span> <span class="k">operator</span> <span class="o">&lt;=</span> <span class="p">(</span><span class="n">retain_ptr</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">R</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span><span class="p">,</span> <span class="n">retain_ptr</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">R</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span><span class="p">)</span> <span class="k">noexcept</span><span class="p">;</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">R</span><span class="o">&gt;</span>
<span class="kt">bool</span> <span class="k">operator</span> <span class="o">&gt;</span> <span class="p">(</span><span class="n">retain_ptr</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">R</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span><span class="p">,</span> <span class="n">retain_ptr</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">R</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span><span class="p">)</span> <span class="k">noexcept</span><span class="p">;</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">R</span><span class="o">&gt;</span>
<span class="kt">bool</span> <span class="k">operator</span> <span class="o">&lt;</span> <span class="p">(</span><span class="n">retain_ptr</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">R</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span><span class="p">,</span> <span class="n">retain_ptr</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">R</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span><span class="p">)</span> <span class="k">noexcept</span><span class="p">;</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">R</span><span class="o">&gt;</span>
<span class="kt">bool</span> <span class="k">operator</span> <span class="o">==</span> <span class="p">(</span><span class="n">retain_ptr</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">R</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span><span class="p">,</span> <span class="n">nullptr_t</span><span class="p">)</span> <span class="k">noexcept</span><span class="p">;</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">R</span><span class="o">&gt;</span>
<span class="kt">bool</span> <span class="k">operator</span> <span class="o">!=</span> <span class="p">(</span><span class="n">retain_ptr</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">R</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span><span class="p">,</span> <span class="n">nullptr_t</span><span class="p">)</span> <span class="k">noexcept</span><span class="p">;</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">R</span><span class="o">&gt;</span>
<span class="kt">bool</span> <span class="k">operator</span> <span class="o">&gt;=</span> <span class="p">(</span><span class="n">retain_ptr</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">R</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span><span class="p">,</span> <span class="n">nullptr_t</span><span class="p">)</span> <span class="k">noexcept</span><span class="p">;</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">R</span><span class="o">&gt;</span>
<span class="kt">bool</span> <span class="k">operator</span> <span class="o">&lt;=</span> <span class="p">(</span><span class="n">retain_ptr</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">R</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span><span class="p">,</span> <span class="n">nullptr_t</span><span class="p">)</span> <span class="k">noexcept</span><span class="p">;</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">R</span><span class="o">&gt;</span>
<span class="kt">bool</span> <span class="k">operator</span> <span class="o">&gt;</span> <span class="p">(</span><span class="n">retain_ptr</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">R</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span><span class="p">,</span> <span class="n">nullptr_t</span><span class="p">)</span> <span class="k">noexcept</span><span class="p">;</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">R</span><span class="o">&gt;</span>
<span class="kt">bool</span> <span class="k">operator</span> <span class="o">&lt;</span> <span class="p">(</span><span class="n">retain_ptr</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">R</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span><span class="p">,</span> <span class="n">nullptr_t</span><span class="p">)</span> <span class="k">noexcept</span><span class="p">;</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">R</span><span class="o">&gt;</span>
<span class="kt">bool</span> <span class="k">operator</span> <span class="o">==</span> <span class="p">(</span><span class="n">nullptr_t</span><span class="p">,</span> <span class="n">retain_ptr</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">R</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span><span class="p">)</span> <span class="k">noexcept</span><span class="p">;</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">R</span><span class="o">&gt;</span>
<span class="kt">bool</span> <span class="k">operator</span> <span class="o">!=</span> <span class="p">(</span><span class="n">nullptr_t</span><span class="p">,</span> <span class="n">retain_ptr</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">R</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span><span class="p">)</span> <span class="k">noexcept</span><span class="p">;</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">R</span><span class="o">&gt;</span>
<span class="kt">bool</span> <span class="k">operator</span> <span class="o">&gt;=</span> <span class="p">(</span><span class="n">nullptr_t</span><span class="p">,</span> <span class="n">retain_ptr</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">R</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span><span class="p">)</span> <span class="k">noexcept</span><span class="p">;</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">R</span><span class="o">&gt;</span>
<span class="kt">bool</span> <span class="k">operator</span> <span class="o">&lt;=</span> <span class="p">(</span><span class="n">nullptr_t</span><span class="p">,</span> <span class="n">retain_ptr</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">R</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span><span class="p">)</span> <span class="k">noexcept</span><span class="p">;</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">R</span><span class="o">&gt;</span>
<span class="kt">bool</span> <span class="k">operator</span> <span class="o">&gt;</span> <span class="p">(</span><span class="n">nullptr_t</span><span class="p">,</span> <span class="n">retain_ptr</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">R</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span><span class="p">)</span> <span class="k">noexcept</span><span class="p">;</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">R</span><span class="o">&gt;</span>
<span class="kt">bool</span> <span class="k">operator</span> <span class="o">&lt;</span> <span class="p">(</span><span class="n">nullptr_t</span><span class="p">,</span> <span class="n">retain_ptr</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">R</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span><span class="p">)</span> <span class="k">noexcept</span><span class="p">;</span>
</pre>
<p><tt class="docutils literal">template &lt;class T, class R&gt; void swap (retain_ptr&lt;T, R&gt;&amp; x, retain_ptr&lt;T, R&gt;&amp; y) noexcept</tt></p>
<blockquote>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">effects:</th><td class="field-body">Calls <tt class="docutils literal">x.swap(y)</tt></td>
</tr>
</tbody>
</table>
</blockquote>
<p><tt class="docutils literal">template &lt;class T, class R&gt; bool operator == (retain_ptr&lt;T, R&gt; const&amp; x, retain_ptr&lt;T, R&gt; const&amp; y) noexcept;</tt></p>
<blockquote>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">returns:</th><td class="field-body"><tt class="docutils literal">x.get() == y.get()</tt></td>
</tr>
</tbody>
</table>
</blockquote>
<p><tt class="docutils literal">template &lt;class T, class R&gt; bool operator != (retain_ptr&lt;T, R&gt; const&amp; x, retain_ptr&lt;T, R&gt; const&amp; y) noexcept;</tt></p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">returns:</th><td class="field-body"><tt class="docutils literal">x.get() != y.get()</tt></td>
</tr>
</tbody>
</table>
<p><tt class="docutils literal">template &lt;class T, class R&gt; bool operator &gt;= (retain_ptr&lt;T, R&gt; const&amp; x, retain_ptr&lt;T, R&gt; const&amp; y) noexcept;</tt></p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">returns:</th><td class="field-body"><tt class="docutils literal">not (x &lt; y)</tt></td>
</tr>
</tbody>
</table>
<p><tt class="docutils literal">template &lt;class T, class R&gt; bool operator &lt;= (retain_ptr&lt;T, R&gt; const&amp; x, retain_ptr&lt;T, R&gt; const&amp; y) noexcept;</tt></p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">returns:</th><td class="field-body"><tt class="docutils literal">not (y &lt; x)</tt></td>
</tr>
</tbody>
</table>
<p><tt class="docutils literal">template &lt;class T, class R&gt; bool operator &gt; (retain_ptr&lt;T, R&gt; const&amp; x, retain_ptr&lt;T, R&gt; const&amp; y) noexcept;</tt></p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">returns:</th><td class="field-body"><tt class="docutils literal">y &lt; x</tt></td>
</tr>
</tbody>
</table>
<p><tt class="docutils literal">template &lt;class T, class R&gt; bool operator &lt; (retain_ptr&lt;T, R&gt; const&amp; x, retain_ptr&lt;T, R&gt; const&amp; y) noexcept;</tt></p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">returns:</th><td class="field-body"><tt class="docutils literal">x.get() &lt; y.get()</tt></td>
</tr>
</tbody>
</table>
<p><tt class="docutils literal">template &lt;class T, class R&gt; bool operator == (retain_ptr&lt;T, R&gt; const&amp; x, nullptr_t) noexcept</tt></p>
<p><tt class="docutils literal">template &lt;class T, class R&gt; bool operator == (nullptr_t, retain_ptr&lt;T, R&gt; const&amp; x) noexcept</tt></p>
<blockquote>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">returns:</th><td class="field-body"><tt class="docutils literal">not x</tt></td>
</tr>
</tbody>
</table>
</blockquote>
<p><tt class="docutils literal">template &lt;class T, class R&gt; bool operator != (retain_ptr&lt;T, R&gt; const&amp; x, nullptr_t) noexcept</tt>
<tt class="docutils literal">template &lt;class T, class R&gt; bool operator != (nullptr_t, retain_ptr&lt;T, R&gt; const&amp; x) noexcept</tt></p>
<blockquote>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">returns:</th><td class="field-body"><tt class="docutils literal">bool(x)</tt></td>
</tr>
</tbody>
</table>
</blockquote>
<p><tt class="docutils literal">template &lt;class T, class R&gt; bool operator &gt;= (retain_ptr&lt;T, R&gt; const&amp; x, nullptr_t) noexcept</tt></p>
<p><tt class="docutils literal">template &lt;class T, class R&gt; bool operator &gt;= (nullptr_t, retain_ptr&lt;T, R&gt; const&amp; x) noexcept</tt></p>
<blockquote>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">returns:</th><td class="field-body">The first function template returns <tt class="docutils literal">not (x &lt; nullptr)</tt>. The
second function template returns <tt class="docutils literal">not (nullptr &lt; x)</tt></td>
</tr>
</tbody>
</table>
</blockquote>
<p><tt class="docutils literal">template &lt;class T, class R&gt; bool operator &lt;= (retain_ptr&lt;T, R&gt; const&amp; x, nullptr_t) noexcept</tt></p>
<p><tt class="docutils literal">template &lt;class T, class R&gt; bool operator &lt;= (nullptr_t, retain_ptr&lt;T, R&gt; const&amp; x) noexcept</tt></p>
<blockquote>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">returns:</th><td class="field-body">The first function template returns <tt class="docutils literal">not (nullptr &lt; x)</tt>. The
second function template returns <tt class="docutils literal">not (x &lt; nullptr)</tt>.</td>
</tr>
</tbody>
</table>
</blockquote>
<p><tt class="docutils literal">template &lt;class T, class R&gt; bool operator &gt; (retain_ptr&lt;T, R&gt; const&amp; x, nullptr_t) noexcept</tt></p>
<p><tt class="docutils literal">template &lt;class T, class R&gt; bool operator &gt; (nullptr_t, retain_ptr&lt;T, R&gt; const&amp; x) noexcept</tt></p>
<blockquote>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">returns:</th><td class="field-body">The first function template returns <tt class="docutils literal">nullptr &lt; x</tt>. The second
function template returns <tt class="docutils literal">x &lt; nullptr</tt>.</td>
</tr>
</tbody>
</table>
</blockquote>
<p><tt class="docutils literal">template &lt;class T, class R&gt; bool operator &lt; (retain_ptr&lt;T, R&gt; const&amp; x, nullptr_t) noexcept</tt></p>
<p><tt class="docutils literal">template &lt;class T, class R&gt; bool operator &lt; (nullptr_t, retain_ptr&lt;T, R&gt; const&amp; x) noexcept</tt></p>
<blockquote>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">returns:</th><td class="field-body">The first function template returns <tt class="docutils literal">x.get() &lt; nullptr</tt>. The
second function template returns <tt class="docutils literal">nullptr &lt; x.get()</tt>.</td>
</tr>
</tbody>
</table>
</blockquote>
</div>
</div>
</div>
<div class="section" id="examples">
<h1><a class="toc-backref" href="#id31">6&nbsp;&nbsp;&nbsp;Examples</a></h1>
<p>Some C APIs that would benefit from <tt class="docutils literal">retain_ptr&lt;T&gt;</tt> are:</p>
<blockquote>
<ul class="simple">
<li>OpenCL</li>
<li>Mono</li>
<li>Python</li>
<li>ObjC Runtime</li>
<li>Grand Central Dispatch</li>
</ul>
</blockquote>
<p>Inside the <a class="reference external" href="https://github.com/slurps-mad-rips/retain-ptr">github</a> repository is an example of using <tt class="docutils literal">retain_ptr</tt> with
Python. Below is a basic example of how a future/promise would be implemented
without a void specialization (as this is not done for completeness).</p>
<div class="section" id="futures">
<h2><a class="toc-backref" href="#id32">6.1&nbsp;&nbsp;&nbsp;Futures</a></h2>
<pre class="code c++ literal-block">
<span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">T</span><span class="o">&gt;</span>
<span class="k">struct</span> <span class="nl">shared_state</span> <span class="p">:</span> <span class="n">atomic_reference_counter</span> <span class="p">{</span>
  <span class="kt">bool</span> <span class="n">empty</span> <span class="p">()</span> <span class="k">const</span> <span class="k">noexcept</span> <span class="p">{</span> <span class="k">return</span> <span class="n">get_if</span><span class="o">&lt;</span><span class="mi">0</span><span class="o">&gt;</span><span class="p">(</span><span class="k">this</span><span class="o">-&gt;</span><span class="n">obj</span><span class="p">);</span> <span class="p">}</span>
  <span class="n">T</span> <span class="n">get</span> <span class="p">()</span> <span class="k">const</span> <span class="k">noexcept</span><span class="p">(</span><span class="nb">false</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">if</span> <span class="p">(</span><span class="k">auto</span> <span class="n">ptr</span> <span class="o">=</span> <span class="n">get_if</span><span class="o">&lt;</span><span class="mi">1</span><span class="o">&gt;</span><span class="p">(</span><span class="k">this</span><span class="o">-&gt;</span><span class="n">obj</span><span class="p">))</span> <span class="p">{</span> <span class="k">return</span> <span class="n">move</span><span class="p">(</span><span class="o">*</span><span class="n">ptr</span><span class="p">);</span> <span class="p">}</span>
    <span class="n">rethrow_exception</span><span class="p">(</span><span class="n">get</span><span class="o">&lt;</span><span class="mi">2</span><span class="o">&gt;</span><span class="p">(</span><span class="k">this</span><span class="o">-&gt;</span><span class="n">obj</span><span class="p">));</span>
  <span class="p">}</span>
  <span class="n">variant</span><span class="o">&lt;</span><span class="n">monostate</span><span class="p">,</span> <span class="n">T</span><span class="p">,</span> <span class="n">exception_ptr</span><span class="o">&gt;</span> <span class="n">obj</span><span class="p">;</span>
<span class="p">};</span>

<span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">T</span><span class="o">&gt;</span>
<span class="k">struct</span> <span class="n">promise</span> <span class="p">{</span>
  <span class="k">using</span> <span class="n">value_type</span> <span class="o">=</span> <span class="n">T</span><span class="p">;</span>

  <span class="n">future</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="n">get_future</span> <span class="p">()</span> <span class="k">const</span> <span class="k">noexcept</span> <span class="p">{</span> <span class="k">return</span> <span class="k">this</span><span class="o">-&gt;</span><span class="n">state</span><span class="p">;</span> <span class="p">}</span>

  <span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">U</span><span class="o">&gt;</span>
  <span class="kt">void</span> <span class="n">set_value</span> <span class="p">(</span><span class="n">U</span><span class="o">&amp;&amp;</span> <span class="n">value</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">this</span><span class="o">-&gt;</span><span class="n">state</span><span class="p">.</span><span class="k">template</span> <span class="n">emplace</span><span class="o">&lt;</span><span class="mi">1</span><span class="o">&gt;</span><span class="p">(</span><span class="n">forward</span><span class="o">&lt;</span><span class="n">U</span><span class="o">&gt;</span><span class="p">(</span><span class="n">value</span><span class="p">));</span>
  <span class="p">}</span>

  <span class="kt">void</span> <span class="n">set_exception</span> <span class="p">(</span><span class="n">exception_ptr</span> <span class="n">ptr</span><span class="p">)</span> <span class="k">noexcept</span> <span class="p">{</span>
    <span class="k">this</span><span class="o">-&gt;</span><span class="n">state</span><span class="p">.</span><span class="k">template</span> <span class="n">emplace</span><span class="o">&lt;</span><span class="mi">2</span><span class="o">&gt;</span><span class="p">(</span><span class="n">ptr</span><span class="p">);</span>
  <span class="p">}</span>

<span class="k">private</span><span class="o">:</span>
  <span class="n">retain_ptr</span><span class="o">&lt;</span><span class="n">shared_state</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;&gt;</span> <span class="n">state</span> <span class="p">{</span> <span class="k">new</span> <span class="n">shared_state</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">()</span> <span class="p">};</span>
<span class="p">};</span>

<span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">T</span><span class="o">&gt;</span>
<span class="k">struct</span> <span class="n">future</span> <span class="p">{</span>
  <span class="k">friend</span> <span class="n">promise</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">;</span>

  <span class="kt">bool</span> <span class="nf">valid</span> <span class="p">()</span> <span class="k">const</span> <span class="k">noexcept</span> <span class="p">{</span> <span class="k">return</span> <span class="k">this</span><span class="o">-&gt;</span><span class="n">state</span><span class="o">-&gt;</span><span class="n">empty</span><span class="p">();</span> <span class="p">}</span>
  <span class="n">T</span> <span class="nf">get</span> <span class="p">()</span> <span class="k">noexcept</span><span class="p">(</span><span class="nb">false</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">if</span> <span class="p">(</span><span class="n">not</span> <span class="k">this</span><span class="o">-&gt;</span><span class="n">valid</span><span class="p">())</span> <span class="p">{</span> <span class="k">throw</span> <span class="n">future_error</span><span class="p">(</span><span class="n">future_errc</span><span class="o">::</span><span class="n">no_state</span><span class="p">);</span> <span class="p">}</span>
    <span class="k">return</span> <span class="k">this</span><span class="o">-&gt;</span><span class="n">state</span><span class="o">-&gt;</span><span class="n">get</span><span class="p">();</span>
  <span class="p">}</span>

<span class="k">private</span><span class="o">:</span>
  <span class="n">future</span> <span class="p">(</span><span class="n">retain_ptr</span><span class="o">&lt;</span><span class="n">shared_state</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;&gt;</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">state</span><span class="p">)</span> <span class="o">:</span> <span class="n">state</span><span class="p">(</span><span class="n">state</span><span class="p">)</span> <span class="p">{</span> <span class="p">}</span>
  <span class="n">retain_ptr</span><span class="o">&lt;</span><span class="n">shared_state</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;&gt;</span> <span class="n">state</span><span class="p">;</span>
<span class="p">};</span>
</pre>
</div>
</div>
<div class="section" id="acknowledgements">
<h1><a class="toc-backref" href="#id33">7&nbsp;&nbsp;&nbsp;Acknowledgements</a></h1>
<p>A special thanks to Jackie Kay and Brittany Friedman for offering advice and
pushing me to finally sit down and write this proposal.</p>
</div>
<div class="section" id="references">
<h1><a class="toc-backref" href="#id34">8&nbsp;&nbsp;&nbsp;References</a></h1>
<table class="docutils footnote" frame="void" id="id4" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id1">[1]</a></td><td><a class="reference external" href="http://www.boost.org/doc/libs/1_62_0/libs/smart_ptr/intrusive_ptr.html">http://www.boost.org/doc/libs/1_62_0/libs/smart_ptr/intrusive_ptr.html</a></td></tr>
</tbody>
</table>
<table class="docutils footnote" frame="void" id="id5" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id2">[2]</a></td><td><a class="reference external" href="https://msdn.microsoft.com/en-us/library/br244983.aspx">https://msdn.microsoft.com/en-us/library/br244983.aspx</a></td></tr>
</tbody>
</table>
<table class="docutils footnote" frame="void" id="id6" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id3">[3]</a></td><td><a class="reference external" href="https://github.com/WebKit/webkit/blob/master/Source/WTF/wtf/RefPtr.h">https://github.com/WebKit/webkit/blob/master/Source/WTF/wtf/RefPtr.h</a></td></tr>
</tbody>
</table>
</div>
</div>
</body>
</html>
