<!doctype html><html lang="en">
 <head>
  <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
  <meta content="width=device-width, initial-scale=1, shrink-to-fit=no" name="viewport">
  <title>P0468R1: An Intrusive Smart Pointer</title>
<style data-fill-with="stylesheet">/******************************************************************************
 *                   Style sheet for the W3C specifications                   *
 *
 * Special classes handled by this style sheet include:
 *
 * Indices
 *   - .toc for the Table of Contents (<ol class="toc">)
 *     + <span class="secno"> for the section numbers
 *   - #toc for the Table of Contents (<nav id="toc">)
 *   - ul.index for Indices (<a href="#ref">term</a><span>, in §N.M</span>)
 *   - table.index for Index Tables (e.g. for properties or elements)
 *
 * Structural Markup
 *   - table.data for general data tables
 *     -> use 'scope' attribute, <colgroup>, <thead>, and <tbody> for best results !
 *     -> use <table class='complex data'> for extra-complex tables
 *     -> use <td class='long'> for paragraph-length cell content
 *     -> use <td class='pre'> when manual line breaks/indentation would help readability
 *   - dl.switch for switch statements
 *   - ol.algorithm for algorithms (helps to visualize nesting)
 *   - .figure and .caption (HTML4) and figure and figcaption (HTML5)
 *     -> .sidefigure for right-floated figures
 *   - ins/del
 *
 * Code
 *   - pre and code
 *
 * Special Sections
 *   - .note       for informative notes             (div, p, span, aside, details)
 *   - .example    for informative examples          (div, p, pre, span)
 *   - .issue      for issues                        (div, p, span)
 *   - .assertion  for assertions                    (div, p, span)
 *   - .advisement for loud normative statements     (div, p, strong)
 *   - .annoying-warning for spec obsoletion notices (div, aside, details)
 *
 * Definition Boxes
 *   - pre.def   for WebIDL definitions
 *   - table.def for tables that define other entities (e.g. CSS properties)
 *   - dl.def    for definition lists that define other entitles (e.g. HTML elements)
 *
 * Numbering
 *   - .secno for section numbers in .toc and headings (<span class='secno'>3.2</span>)
 *   - .marker for source-inserted example/figure/issue numbers (<span class='marker'>Issue 4</span>)
 *   - ::before styled for CSS-generated issue/example/figure numbers:
 *     -> Documents wishing to use this only need to add
 *        figcaption::before,
 *        .caption::before { content: "Figure "  counter(figure) " ";  }
 *        .example::before { content: "Example " counter(example) " "; }
 *        .issue::before   { content: "Issue "   counter(issue) " ";   }
 *
 * Header Stuff (ignore, just don't conflict with these classes)
 *   - .head for the header
 *   - .copyright for the copyright
 *
 * Miscellaneous
 *   - .overlarge for things that should be as wide as possible, even if
 *     that overflows the body text area. This can be used on an item or
 *     on its container, depending on the effect desired.
 *     Note that this styling basically doesn't help at all when printing,
 *     since A4 paper isn't much wider than the max-width here.
 *     It's better to design things to fit into a narrower measure if possible.
 *   - js-added ToC jump links (see fixup.js)
 *
 ******************************************************************************/

/******************************************************************************/
/*                                   Body                                     */
/******************************************************************************/

	body {
		counter-reset: example figure issue;

		/* Layout */
		max-width: 50em;               /* limit line length to 50em for readability   */
		margin: 0 auto;                /* center text within page                     */
		padding: 1.6em 1.5em 2em 50px; /* assume 16px font size for downlevel clients */
		padding: 1.6em 1.5em 2em calc(26px + 1.5em); /* leave space for status flag     */

		/* Typography */
		line-height: 1.5;
		font-family: sans-serif;
		widows: 2;
		orphans: 2;
		word-wrap: break-word;
		overflow-wrap: break-word;
		hyphens: auto;

		/* Colors */
		color: black;
		background: white top left fixed no-repeat;
		background-size: 25px auto;
	}


/******************************************************************************/
/*                         Front Matter & Navigation                          */
/******************************************************************************/

/** Header ********************************************************************/

	div.head { margin-bottom: 1em }
	div.head hr { border-style: solid; }

	div.head h1 {
		font-weight: bold;
		margin: 0 0 .1em;
		font-size: 220%;
	}

	div.head h2 { margin-bottom: 1.5em;}

/** W3C Logo ******************************************************************/

	.head .logo {
		float: right;
		margin: 0.4rem 0 0.2rem .4rem;
	}

	.head img[src*="logos/W3C"] {
		display: block;
		border: solid #1a5e9a;
		border-width: .65rem .7rem .6rem;
		border-radius: .4rem;
		background: #1a5e9a;
		color: white;
		font-weight: bold;
	}

	.head a:hover > img[src*="logos/W3C"],
	.head a:focus > img[src*="logos/W3C"] {
		opacity: .8;
	}

	.head a:active > img[src*="logos/W3C"] {
		background: #c00;
		border-color: #c00;
	}

	/* see also additional rules in Link Styling section */

/** Copyright *****************************************************************/

	p.copyright,
	p.copyright small { font-size: small }

/** Back to Top / ToC Toggle **************************************************/

	@media print {
		#toc-nav {
			display: none;
		}
	}
	@media not print {
		#toc-nav {
			position: fixed;
			z-index: 2;
			bottom: 0; left: 0;
			margin: 0;
			min-width: 1.33em;
			border-top-right-radius: 2rem;
			box-shadow: 0 0 2px;
			font-size: 1.5em;
			color: black;
		}
		#toc-nav > a {
			display: block;
			white-space: nowrap;

			height: 1.33em;
			padding: .1em 0.3em;
			margin: 0;

			background: white;
			box-shadow: 0 0 2px;
			border: none;
			border-top-right-radius: 1.33em;
			background: white;
		}
		#toc-nav > #toc-jump {
			padding-bottom: 2em;
			margin-bottom: -1.9em;
		}

		#toc-nav > a:hover,
		#toc-nav > a:focus {
			background: #f8f8f8;
		}
		#toc-nav > a:not(:hover):not(:focus) {
			color: #707070;
		}

		/* statusbar gets in the way on keyboard focus; remove once browsers fix */
		#toc-nav > a[href="#toc"]:not(:hover):focus:last-child {
			padding-bottom: 1.5rem;
		}

		#toc-nav:not(:hover) > a:not(:focus) > span + span {
			/* Ideally this uses :focus-within on #toc-nav */
			display: none;
		}
		#toc-nav > a > span + span {
			padding-right: 0.2em;
		}

		#toc-toggle-inline {
			vertical-align: 0.05em;
			font-size: 80%;
			color: gray;
			color: hsla(203,20%,40%,.7);
			border-style: none;
			background: transparent;
			position: relative;
		}
		#toc-toggle-inline:hover:not(:active),
		#toc-toggle-inline:focus:not(:active) {
			text-shadow: 1px 1px silver;
			top: -1px;
			left: -1px;
		}

		#toc-nav :active {
			color: #C00;
		}
	}

/** ToC Sidebar ***************************************************************/

	/* Floating sidebar */
	@media screen {
		body.toc-sidebar #toc {
			position: fixed;
			top: 0; bottom: 0;
			left: 0;
			width: 23.5em;
			max-width: 80%;
			max-width: calc(100% - 2em - 26px);
			overflow: auto;
			padding: 0 1em;
			padding-left: 42px;
			padding-left: calc(1em + 26px);
			background: inherit;
			background-color: #f7f8f9;
			z-index: 1;
			box-shadow: -.1em 0 .25em rgba(0,0,0,.1) inset;
		}
		body.toc-sidebar #toc h2 {
			margin-top: .8rem;
			font-variant: small-caps;
			font-variant: all-small-caps;
			text-transform: lowercase;
			font-weight: bold;
			color: gray;
			color: hsla(203,20%,40%,.7);
		}
		body.toc-sidebar #toc-jump:not(:focus) {
			width: 0;
			height: 0;
			padding: 0;
			position: absolute;
			overflow: hidden;
		}
	}
	/* Hide main scroller when only the ToC is visible anyway */
	@media screen and (max-width: 28em) {
		body.toc-sidebar {
			overflow: hidden;
		}
	}

	/* Sidebar with its own space */
	@media screen and (min-width: 78em) {
		body:not(.toc-inline) #toc {
			position: fixed;
			top: 0; bottom: 0;
			left: 0;
			width: 23.5em;
			overflow: auto;
			padding: 0 1em;
			padding-left: 42px;
			padding-left: calc(1em + 26px);
			background: inherit;
			background-color: #f7f8f9;
			z-index: 1;
			box-shadow: -.1em 0 .25em rgba(0,0,0,.1) inset;
		}
		body:not(.toc-inline) #toc h2 {
			margin-top: .8rem;
			font-variant: small-caps;
			font-variant: all-small-caps;
			text-transform: lowercase;
			font-weight: bold;
			color: gray;
			color: hsla(203,20%,40%,.7);
		}

		body:not(.toc-inline) {
			padding-left: 29em;
		}
		/* See also Overflow section at the bottom */

		body:not(.toc-inline) #toc-jump:not(:focus) {
			width: 0;
			height: 0;
			padding: 0;
			position: absolute;
			overflow: hidden;
		}
	}
	@media screen and (min-width: 90em) {
		body:not(.toc-inline) {
			margin: 0 4em;
		}
	}

/******************************************************************************/
/*                                Sectioning                                  */
/******************************************************************************/

/** Headings ******************************************************************/

	h1, h2, h3, h4, h5, h6, dt {
		page-break-after: avoid;
		page-break-inside: avoid;
		font: 100% sans-serif;   /* Reset all font styling to clear out UA styles */
		font-family: inherit;    /* Inherit the font family. */
		line-height: 1.2;        /* Keep wrapped headings compact */
		hyphens: manual;         /* Hyphenated headings look weird */
	}

	h2, h3, h4, h5, h6 {
		margin-top: 3rem;
	}

	h1, h2, h3 {
		color: #005A9C;
		background: transparent;
	}

	h1 { font-size: 170%; }
	h2 { font-size: 140%; }
	h3 { font-size: 120%; }
	h4 { font-weight: bold; }
	h5 { font-style: italic; }
	h6 { font-variant: small-caps; }
	dt { font-weight: bold; }

/** Subheadings ***************************************************************/

	h1 + h2,
	#subtitle {
		/* #subtitle is a subtitle in an H2 under the H1 */
		margin-top: 0;
	}
	h2 + h3,
	h3 + h4,
	h4 + h5,
	h5 + h6 {
		margin-top: 1.2em; /* = 1 x line-height */
	}

/** Section divider ***********************************************************/

	:not(.head) > hr {
		font-size: 1.5em;
		text-align: center;
		margin: 1em auto;
		height: auto;
		border: transparent solid 0;
		background: transparent;
	}
	:not(.head) > hr::before {
		content: "\2727\2003\2003\2727\2003\2003\2727";
	}

/******************************************************************************/
/*                            Paragraphs and Lists                            */
/******************************************************************************/

	p {
		margin: 1em 0;
	}

	dd > p:first-child,
	li > p:first-child {
		margin-top: 0;
	}

	ul, ol {
		margin-left: 0;
		padding-left: 2em;
	}

	li {
		margin: 0.25em 0 0.5em;
		padding: 0;
	}

	dl dd {
		margin: 0 0 .5em 2em;
	}

	.head dd + dd { /* compact for header */
		margin-top: -.5em;
	}

	/* Style for algorithms */
	ol.algorithm ol:not(.algorithm),
	.algorithm > ol ol:not(.algorithm) {
	 border-left: 0.5em solid #DEF;
	}

	/* Put nice boxes around each algorithm. */
	[data-algorithm]:not(.heading) {
	  padding: .5em;
	  border: thin solid #ddd; border-radius: .5em;
	  margin: .5em calc(-0.5em - 1px);
	}
	[data-algorithm]:not(.heading) > :first-child {
	  margin-top: 0;
	}
	[data-algorithm]:not(.heading) > :last-child {
	  margin-bottom: 0;
	}

	/* Style for switch/case <dl>s */
	dl.switch > dd > ol.only,
	dl.switch > dd > .only > ol {
	 margin-left: 0;
	}
	dl.switch > dd > ol.algorithm,
	dl.switch > dd > .algorithm > ol {
	 margin-left: -2em;
	}
	dl.switch {
	 padding-left: 2em;
	}
	dl.switch > dt {
	 text-indent: -1.5em;
	 margin-top: 1em;
	}
	dl.switch > dt + dt {
	 margin-top: 0;
	}
	dl.switch > dt::before {
	 content: '\21AA';
	 padding: 0 0.5em 0 0;
	 display: inline-block;
	 width: 1em;
	 text-align: right;
	 line-height: 0.5em;
	}

/** Terminology Markup ********************************************************/


/******************************************************************************/
/*                                 Inline Markup                              */
/******************************************************************************/

/** Terminology Markup ********************************************************/
	dfn   { /* Defining instance */
		font-weight: bolder;
	}
	a > i { /* Instance of term */
		font-style: normal;
	}
	dt dfn code, code.idl {
		font-size: medium;
	}
	dfn var {
		font-style: normal;
	}

/** Change Marking ************************************************************/

	del { color: red;  text-decoration: line-through; }
	ins { color: #080; text-decoration: underline;    }

/** Miscellaneous improvements to inline formatting ***************************/

	sup {
		vertical-align: super;
		font-size: 80%
	}

/******************************************************************************/
/*                                    Code                                    */
/******************************************************************************/

/** General monospace/pre rules ***********************************************/

	pre, code, samp {
		font-family: Menlo, Consolas, "DejaVu Sans Mono", Monaco, monospace;
		font-size: .9em;
		page-break-inside: avoid;
		hyphens: none;
		text-transform: none;
	}
	pre code,
	code code {
		font-size: 100%;
	}

	pre {
		margin-top: 1em;
		margin-bottom: 1em;
		overflow: auto;
	}

/** Inline Code fragments *****************************************************/

  /* Do something nice. */

/******************************************************************************/
/*                                    Links                                   */
/******************************************************************************/

/** General Hyperlinks ********************************************************/

	/* We hyperlink a lot, so make it less intrusive */
	a[href] {
		color: #034575;
		text-decoration: none;
		border-bottom: 1px solid #707070;
		/* Need a bit of extending for it to look okay */
		padding: 0 1px 0;
		margin: 0 -1px 0;
	}
	a:visited {
		border-bottom-color: #BBB;
	}

	/* Use distinguishing colors when user is interacting with the link */
	a[href]:focus,
	a[href]:hover {
		background: #f8f8f8;
		background: rgba(75%, 75%, 75%, .25);
		border-bottom-width: 3px;
		margin-bottom: -2px;
	}
	a[href]:active {
		color: #C00;
		border-color: #C00;
	}

	/* Backout above styling for W3C logo */
	.head .logo,
	.head .logo a {
		border: none;
		text-decoration: none;
		background: transparent;
	}

/******************************************************************************/
/*                                    Images                                  */
/******************************************************************************/

	img {
		border-style: none;
	}

	/* For autogen numbers, add
	   .caption::before, figcaption::before { content: "Figure " counter(figure) ". "; }
	*/

	figure, .figure, .sidefigure {
		page-break-inside: avoid;
		text-align: center;
		margin: 2.5em 0;
	}
	.figure img,    .sidefigure img,    figure img,
	.figure object, .sidefigure object, figure object {
		max-width: 100%;
		margin: auto;
	}
	.figure pre, .sidefigure pre, figure pre {
		text-align: left;
		display: table;
		margin: 1em auto;
	}
	.figure table, figure table {
		margin: auto;
	}
	@media screen and (min-width: 20em) {
		.sidefigure {
			float: right;
			width: 50%;
			margin: 0 0 0.5em 0.5em
		}
	}
	.caption, figcaption, caption {
		font-style: italic;
		font-size: 90%;
	}
	.caption::before, figcaption::before, figcaption > .marker {
		font-weight: bold;
	}
	.caption, figcaption {
		counter-increment: figure;
	}

	/* DL list is indented 2em, but figure inside it is not */
	dd > .figure, dd > figure { margin-left: -2em }

/******************************************************************************/
/*                             Colored Boxes                                  */
/******************************************************************************/

	.issue, .note, .example, .assertion, .advisement, blockquote {
		padding: .5em;
		border: .5em;
		border-left-style: solid;
		page-break-inside: avoid;
	}
	span.issue, span.note {
		padding: .1em .5em .15em;
		border-right-style: solid;
	}

	.issue,
	.note,
	.example,
	.advisement,
	.assertion,
	blockquote {
		margin: 1em auto;
	}
	.note  > p:first-child,
	.issue > p:first-child,
	blockquote > :first-child {
		margin-top: 0;
	}
	blockquote > :last-child {
		margin-bottom: 0;
	}

/** Blockquotes ***************************************************************/

	blockquote {
		border-color: silver;
	}

/** Open issue ****************************************************************/

	.issue {
		border-color: #E05252;
		background: #FBE9E9;
		counter-increment: issue;
		overflow: auto;
	}
	.issue::before, .issue > .marker {
		text-transform: uppercase;
		color: #AE1E1E;
		padding-right: 1em;
		text-transform: uppercase;
	}
	/* Add .issue::before { content: "Issue " counter(issue) " "; } for autogen numbers,
	   or use class="marker" to mark up the issue number in source. */

/** Example *******************************************************************/

	.example {
		border-color: #E0CB52;
		background: #FCFAEE;
		counter-increment: example;
		overflow: auto;
		clear: both;
	}
	.example::before, .example > .marker {
		text-transform: uppercase;
		color: #827017;
		min-width: 7.5em;
		display: block;
	}
	/* Add .example::before { content: "Example " counter(example) " "; } for autogen numbers,
	   or use class="marker" to mark up the example number in source. */

/** Non-normative Note ********************************************************/

	.note {
		border-color: #52E052;
		background: #E9FBE9;
		overflow: auto;
	}

	.note::before, .note > .marker,
	details.note > summary::before,
	details.note > summary > .marker {
		text-transform: uppercase;
		display: block;
		color: hsl(120, 70%, 30%);
	}
	/* Add .note::before { content: "Note"; } for autogen label,
	   or use class="marker" to mark up the label in source. */

	details.note > summary {
		display: block;
		color: hsl(120, 70%, 30%);
	}
	details.note[open] > summary {
		border-bottom: 1px silver solid;
	}

/** Assertion Box *************************************************************/
	/*  for assertions in algorithms */

	.assertion {
		border-color: #AAA;
		background: #EEE;
	}

/** Advisement Box ************************************************************/
	/*  for attention-grabbing normative statements */

	.advisement {
		border-color: orange;
		border-style: none solid;
		background: #FFEECC;
	}
	strong.advisement {
		display: block;
		text-align: center;
	}
	.advisement > .marker {
		color: #B35F00;
	}

/** Spec Obsoletion Notice ****************************************************/
	/* obnoxious obsoletion notice for older/abandoned specs. */

	details {
		display: block;
	}
	summary {
		font-weight: bolder;
	}

	.annoying-warning:not(details),
	details.annoying-warning:not([open]) > summary,
	details.annoying-warning[open] {
		background: #fdd;
		color: red;
		font-weight: bold;
		padding: .75em 1em;
		border: thick red;
		border-style: solid;
		border-radius: 1em;
	}
	.annoying-warning :last-child {
		margin-bottom: 0;
	}

@media not print {
	details.annoying-warning[open] {
		position: fixed;
		left: 1em;
		right: 1em;
		bottom: 1em;
		z-index: 1000;
	}
}

	details.annoying-warning:not([open]) > summary {
		text-align: center;
	}

/** Entity Definition Boxes ***************************************************/

	.def {
		padding: .5em 1em;
		background: #DEF;
		margin: 1.2em 0;
		border-left: 0.5em solid #8CCBF2;
	}

/******************************************************************************/
/*                                    Tables                                  */
/******************************************************************************/

	th, td {
		text-align: left;
		text-align: start;
	}

/** Property/Descriptor Definition Tables *************************************/

	table.def {
		/* inherits .def box styling, see above */
		width: 100%;
		border-spacing: 0;
	}

	table.def td,
	table.def th {
		padding: 0.5em;
		vertical-align: baseline;
		border-bottom: 1px solid #bbd7e9;
	}

	table.def > tbody > tr:last-child th,
	table.def > tbody > tr:last-child td {
		border-bottom: 0;
	}

	table.def th {
		font-style: italic;
		font-weight: normal;
		padding-left: 1em;
		width: 3em;
	}

	/* For when values are extra-complex and need formatting for readability */
	table td.pre {
		white-space: pre-wrap;
	}

	/* A footnote at the bottom of a def table */
	table.def           td.footnote {
		padding-top: 0.6em;
	}
	table.def           td.footnote::before {
		content: " ";
		display: block;
		height: 0.6em;
		width: 4em;
		border-top: thin solid;
	}

/** Data tables (and properly marked-up index tables) *************************/
	/*
		 <table class="data"> highlights structural relationships in a table
		 when correct markup is used (e.g. thead/tbody, th vs. td, scope attribute)

		 Use class="complex data" for particularly complicated tables --
		 (This will draw more lines: busier, but clearer.)

		 Use class="long" on table cells with paragraph-like contents
		 (This will adjust text alignment accordingly.)
		 Alternately use class="longlastcol" on tables, to have the last column assume "long".
	*/

	table {
		word-wrap: normal;
		overflow-wrap: normal;
		hyphens: manual;
	}

	table.data,
	table.index {
		margin: 1em auto;
		border-collapse: collapse;
		border: hidden;
		width: 100%;
	}
	table.data caption,
	table.index caption {
		max-width: 50em;
		margin: 0 auto 1em;
	}

	table.data td,  table.data th,
	table.index td, table.index th {
		padding: 0.5em 1em;
		border-width: 1px;
		border-color: silver;
		border-top-style: solid;
	}

	table.data thead td:empty {
		padding: 0;
		border: 0;
	}

	table.data  thead,
	table.index thead,
	table.data  tbody,
	table.index tbody {
		border-bottom: 2px solid;
	}

	table.data colgroup,
	table.index colgroup {
		border-left: 2px solid;
	}

	table.data  tbody th:first-child,
	table.index tbody th:first-child  {
		border-right: 2px solid;
		border-top: 1px solid silver;
		padding-right: 1em;
	}

	table.data th[colspan],
	table.data td[colspan] {
		text-align: center;
	}

	table.complex.data th,
	table.complex.data td {
		border: 1px solid silver;
		text-align: center;
	}

	table.data.longlastcol td:last-child,
	table.data td.long {
	 vertical-align: baseline;
	 text-align: left;
	}

	table.data img {
		vertical-align: middle;
	}


/*
Alternate table alignment rules

	table.data,
	table.index {
		text-align: center;
	}

	table.data  thead th[scope="row"],
	table.index thead th[scope="row"] {
		text-align: right;
	}

	table.data  tbody th:first-child,
	table.index tbody th:first-child  {
		text-align: right;
	}

Possible extra rowspan handling

	table.data  tbody th[rowspan]:not([rowspan='1']),
	table.index tbody th[rowspan]:not([rowspan='1']),
	table.data  tbody td[rowspan]:not([rowspan='1']),
	table.index tbody td[rowspan]:not([rowspan='1']) {
		border-left: 1px solid silver;
	}

	table.data  tbody th[rowspan]:first-child,
	table.index tbody th[rowspan]:first-child,
	table.data  tbody td[rowspan]:first-child,
	table.index tbody td[rowspan]:first-child{
		border-left: 0;
		border-right: 1px solid silver;
	}
*/

/******************************************************************************/
/*                                  Indices                                   */
/******************************************************************************/


/** Table of Contents *********************************************************/

	.toc a {
		/* More spacing; use padding to make it part of the click target. */
		padding-top: 0.1rem;
		/* Larger, more consistently-sized click target */
		display: block;
		/* Reverse color scheme */
		color: black;
		border-color: #3980B5;
		border-bottom-width: 3px !important;
		margin-bottom: 0px !important;
	}
	.toc a:visited {
		border-color: #054572;
	}
	.toc a:not(:focus):not(:hover) {
		/* Allow colors to cascade through from link styling */
		border-bottom-color: transparent;
	}

	.toc, .toc ol, .toc ul, .toc li {
		list-style: none; /* Numbers must be inlined into source */
		/* because generated content isn't search/selectable and markers can't do multilevel yet */
		margin:  0;
		padding: 0;
		line-height: 1.1rem; /* consistent spacing */
	}

	/* ToC not indented until third level, but font style & margins show hierarchy */
	.toc > li             { font-weight: bold;   }
	.toc > li li          { font-weight: normal; }
	.toc > li li li       { font-size:   95%;    }
	.toc > li li li li    { font-size:   90%;    }
	.toc > li li li li .secno { font-size: 85%; }
	.toc > li li li li li { font-size:   85%;    }
	.toc > li li li li li .secno { font-size: 100%; }

	/* @supports not (display:grid) { */
		.toc > li             { margin: 1.5rem 0;    }
		.toc > li li          { margin: 0.3rem 0;    }
		.toc > li li li       { margin-left: 2rem;   }

		/* Section numbers in a column of their own */
		.toc .secno {
			float: left;
			width: 4rem;
			white-space: nowrap;
		}

		.toc li {
			clear: both;
		}

		:not(li) > .toc              { margin-left:  5rem; }
		.toc .secno                  { margin-left: -5rem; }
		.toc > li li li .secno       { margin-left: -7rem; }
		.toc > li li li li .secno    { margin-left: -9rem; }
		.toc > li li li li li .secno { margin-left: -11rem; }

		/* Tighten up indentation in narrow ToCs */
		@media (max-width: 30em) {
			:not(li) > .toc              { margin-left:  4rem; }
			.toc .secno                  { margin-left: -4rem; }
			.toc > li li li              { margin-left:  1rem; }
			.toc > li li li .secno       { margin-left: -5rem; }
			.toc > li li li li .secno    { margin-left: -6rem; }
			.toc > li li li li li .secno { margin-left: -7rem; }
		}
	/* } */

	@supports (display:grid) {
		/* Use #toc over .toc to override non-@supports rules. */
		#toc {
			display: grid;
			align-content: start;
			grid-template-columns: auto 1fr;
			grid-column-gap: 1rem;
			column-gap: 1rem;
			grid-row-gap: .6rem;
			row-gap: .6rem;
		}
		#toc h2 {
			grid-column: 1 / -1;
			margin-bottom: 0;
		}
		#toc ol,
		#toc li,
		#toc a {
			display: contents;
			/* Switch <a> to subgrid when supported */
		}
		#toc span {
			margin: 0;
		}
		#toc > .toc > li > a > span {
			/* The spans of the top-level list,
			   comprising the first items of each top-level section. */
			margin-top: 1.1rem;
		}
		#toc#toc .secno { /* Ugh, need more specificity to override base.css */
			grid-column: 1;
			width: auto;
			margin-left: 0;
		}
		#toc .content {
			grid-column: 2;
			width: auto;
			margin-right: 1rem;
		}
		#toc .content:hover {
			background: rgba(75%, 75%, 75%, .25);
			border-bottom: 3px solid #054572;
			margin-bottom: -3px;
		}
		#toc li li li .content {
			margin-left: 1rem;
		}
		#toc li li li li .content {
			margin-left: 2rem;
		}
	}


/** Index *********************************************************************/

	/* Index Lists: Layout */
	ul.index       { margin-left: 0; columns: 15em; text-indent: 1em hanging; }
	ul.index li    { margin-left: 0; list-style: none; break-inside: avoid; }
	ul.index li li { margin-left: 1em }
	ul.index dl    { margin-top: 0; }
	ul.index dt    { margin: .2em 0 .2em 20px;}
	ul.index dd    { margin: .2em 0 .2em 40px;}
	/* Index Lists: Typography */
	ul.index ul,
	ul.index dl { font-size: smaller; }
	@media not print {
		ul.index li span {
			white-space: nowrap;
			color: transparent; }
		ul.index li a:hover + span,
		ul.index li a:focus + span {
			color: #707070;
		}
	}

/** Index Tables *****************************************************/
	/* See also the data table styling section, which this effectively subclasses */

	table.index {
		font-size: small;
		border-collapse: collapse;
		border-spacing: 0;
		text-align: left;
		margin: 1em 0;
	}

	table.index td,
	table.index th {
		padding: 0.4em;
	}

	table.index tr:hover td:not([rowspan]),
	table.index tr:hover th:not([rowspan]) {
		background: #f7f8f9;
	}

	/* The link in the first column in the property table (formerly a TD) */
	table.index th:first-child a {
		font-weight: bold;
	}

/******************************************************************************/
/*                                    Print                                   */
/******************************************************************************/

	@media print {
		/* Pages have their own margins. */
		html {
			margin: 0;
		}
		/* Serif for print. */
		body {
			font-family: serif;
		}
	}
	@page {
		margin: 1.5cm 1.1cm;
	}

/******************************************************************************/
/*                                    Legacy                                  */
/******************************************************************************/

	/* This rule is inherited from past style sheets. No idea what it's for. */
	.hide { display: none }



/******************************************************************************/
/*                             Overflow Control                               */
/******************************************************************************/

	.figure .caption, .sidefigure .caption, figcaption {
		/* in case figure is overlarge, limit caption to 50em */
		max-width: 50rem;
		margin-left: auto;
		margin-right: auto;
	}
	.overlarge > table {
		/* limit preferred width of table */
		max-width: 50em;
		margin-left: auto;
		margin-right: auto;
	}

	@media (min-width: 55em) {
		.overlarge {
			margin-left: calc(13px + 26.5rem - 50vw);
			margin-right: calc(13px + 26.5rem - 50vw);
			max-width: none;
		}
	}
	@media screen and (min-width: 78em) {
		body:not(.toc-inline) .overlarge {
			/* 30.5em body padding 50em content area */
			margin-left: calc(40em - 50vw) !important;
			margin-right: calc(40em - 50vw) !important;
		}
	}
	@media screen and (min-width: 90em) {
		body:not(.toc-inline) .overlarge {
			/* 4em html margin 30.5em body padding 50em content area */
			margin-left: 0 !important;
			margin-right: calc(84.5em - 100vw) !important;
		}
	}

	@media not print {
		.overlarge {
			overflow-x: auto;
			/* See Lea Verou's explanation background-attachment:
			 * http://lea.verou.me/2012/04/background-attachment-local/
			 *
			background: top left  / 4em 100% linear-gradient(to right,  #ffffff, rgba(255, 255, 255, 0)) local,
			            top right / 4em 100% linear-gradient(to left, #ffffff, rgba(255, 255, 255, 0)) local,
			            top left  / 1em 100% linear-gradient(to right,  #c3c3c5, rgba(195, 195, 197, 0)) scroll,
			            top right / 1em 100% linear-gradient(to left, #c3c3c5, rgba(195, 195, 197, 0)) scroll,
			            white;
			background-repeat: no-repeat;
			*/
		}
	}
</style>
<style type="text/css">
    table, th, td {
      border: 1px solid black;
      border-collapse: collapse;
      vertical-align: top;
    }
    th, td {
      border-left: none;
      border-right: none;
      padding: 0px 10px;
    }
    th {
      text-align: center;
    }
  </style>
  <meta content="Bikeshed version 47cb5324cd11789aef12f220cf86d1780f94ab9c" name="generator">
  <link href="https://wg21.link/p0468r1" rel="canonical">
  <link href="https://isocpp.org/favicon.ico" rel="icon">
<style>
ins  {background-color: #CCFFCC; text-decoration: underline;}
del  {background-color: #FFCACA; text-decoration: line-through;}
</style>
<style>/* style-md-lists */

/* This is a weird hack for me not yet following the commonmark spec
   regarding paragraph and lists. */
[data-md] > :first-child {
    margin-top: 0;
}
[data-md] > :last-child {
    margin-bottom: 0;
}</style>
<style>/* style-counters */

body {
    counter-reset: example figure issue;
}
.issue {
    counter-increment: issue;
}
.issue:not(.no-marker)::before {
    content: "Issue " counter(issue);
}

.example {
    counter-increment: example;
}
.example:not(.no-marker)::before {
    content: "Example " counter(example);
}
.invalid.example:not(.no-marker)::before,
.illegal.example:not(.no-marker)::before {
    content: "Invalid Example" counter(example);
}

figcaption {
    counter-increment: figure;
}
figcaption:not(.no-marker)::before {
    content: "Figure " counter(figure) " ";
}</style>
<style>/* style-syntax-highlighting */

.highlight:not(.idl) { background: hsl(24, 20%, 95%); }
code.highlight { padding: .1em; border-radius: .3em; }
pre.highlight, pre > code.highlight { display: block; padding: 1em; margin: .5em 0; overflow: auto; border-radius: 0; }
c-[a] { color: #990055 } /* Keyword.Declaration */
c-[b] { color: #990055 } /* Keyword.Type */
c-[c] { color: #708090 } /* Comment */
c-[d] { color: #708090 } /* Comment.Multiline */
c-[e] { color: #0077aa } /* Name.Attribute */
c-[f] { color: #669900 } /* Name.Tag */
c-[g] { color: #222222 } /* Name.Variable */
c-[k] { color: #990055 } /* Keyword */
c-[l] { color: #000000 } /* Literal */
c-[m] { color: #000000 } /* Literal.Number */
c-[n] { color: #0077aa } /* Name */
c-[o] { color: #999999 } /* Operator */
c-[p] { color: #999999 } /* Punctuation */
c-[s] { color: #a67f59 } /* Literal.String */
c-[t] { color: #a67f59 } /* Literal.String.Single */
c-[u] { color: #a67f59 } /* Literal.String.Double */
c-[cp] { color: #708090 } /* Comment.Preproc */
c-[c1] { color: #708090 } /* Comment.Single */
c-[cs] { color: #708090 } /* Comment.Special */
c-[kc] { color: #990055 } /* Keyword.Constant */
c-[kn] { color: #990055 } /* Keyword.Namespace */
c-[kp] { color: #990055 } /* Keyword.Pseudo */
c-[kr] { color: #990055 } /* Keyword.Reserved */
c-[ld] { color: #000000 } /* Literal.Date */
c-[nc] { color: #0077aa } /* Name.Class */
c-[no] { color: #0077aa } /* Name.Constant */
c-[nd] { color: #0077aa } /* Name.Decorator */
c-[ni] { color: #0077aa } /* Name.Entity */
c-[ne] { color: #0077aa } /* Name.Exception */
c-[nf] { color: #0077aa } /* Name.Function */
c-[nl] { color: #0077aa } /* Name.Label */
c-[nn] { color: #0077aa } /* Name.Namespace */
c-[py] { color: #0077aa } /* Name.Property */
c-[ow] { color: #999999 } /* Operator.Word */
c-[mb] { color: #000000 } /* Literal.Number.Bin */
c-[mf] { color: #000000 } /* Literal.Number.Float */
c-[mh] { color: #000000 } /* Literal.Number.Hex */
c-[mi] { color: #000000 } /* Literal.Number.Integer */
c-[mo] { color: #000000 } /* Literal.Number.Oct */
c-[sb] { color: #a67f59 } /* Literal.String.Backtick */
c-[sc] { color: #a67f59 } /* Literal.String.Char */
c-[sd] { color: #a67f59 } /* Literal.String.Doc */
c-[se] { color: #a67f59 } /* Literal.String.Escape */
c-[sh] { color: #a67f59 } /* Literal.String.Heredoc */
c-[si] { color: #a67f59 } /* Literal.String.Interpol */
c-[sx] { color: #a67f59 } /* Literal.String.Other */
c-[sr] { color: #a67f59 } /* Literal.String.Regex */
c-[ss] { color: #a67f59 } /* Literal.String.Symbol */
c-[vc] { color: #0077aa } /* Name.Variable.Class */
c-[vg] { color: #0077aa } /* Name.Variable.Global */
c-[vi] { color: #0077aa } /* Name.Variable.Instance */
c-[il] { color: #000000 } /* Literal.Number.Integer.Long */
</style>
<style>/* style-selflinks */

.heading, .issue, .note, .example, li, dt {
    position: relative;
}
a.self-link {
    position: absolute;
    top: 0;
    left: calc(-1 * (3.5rem - 26px));
    width: calc(3.5rem - 26px);
    height: 2em;
    text-align: center;
    border: none;
    transition: opacity .2s;
    opacity: .5;
}
a.self-link:hover {
    opacity: 1;
}
.heading > a.self-link {
    font-size: 83%;
}
li > a.self-link {
    left: calc(-1 * (3.5rem - 26px) - 2em);
}
dfn > a.self-link {
    top: auto;
    left: auto;
    opacity: 0;
    width: 1.5em;
    height: 1.5em;
    background: gray;
    color: white;
    font-style: normal;
    transition: opacity .2s, background-color .2s, color .2s;
}
dfn:hover > a.self-link {
    opacity: 1;
}
dfn > a.self-link:hover {
    color: black;
}

a.self-link::before            { content: "¶"; }
.heading > a.self-link::before { content: "§"; }
dfn > a.self-link::before      { content: "#"; }</style>
<style>/* style-autolinks */

.css.css, .property.property, .descriptor.descriptor {
    color: #005a9c;
    font-size: inherit;
    font-family: inherit;
}
.css::before, .property::before, .descriptor::before {
    content: "‘";
}
.css::after, .property::after, .descriptor::after {
    content: "’";
}
.property, .descriptor {
    /* Don't wrap property and descriptor names */
    white-space: nowrap;
}
.type { /* CSS value <type> */
    font-style: italic;
}
pre .property::before, pre .property::after {
    content: "";
}
[data-link-type="property"]::before,
[data-link-type="propdesc"]::before,
[data-link-type="descriptor"]::before,
[data-link-type="value"]::before,
[data-link-type="function"]::before,
[data-link-type="at-rule"]::before,
[data-link-type="selector"]::before,
[data-link-type="maybe"]::before {
    content: "‘";
}
[data-link-type="property"]::after,
[data-link-type="propdesc"]::after,
[data-link-type="descriptor"]::after,
[data-link-type="value"]::after,
[data-link-type="function"]::after,
[data-link-type="at-rule"]::after,
[data-link-type="selector"]::after,
[data-link-type="maybe"]::after {
    content: "’";
}

[data-link-type].production::before,
[data-link-type].production::after,
.prod [data-link-type]::before,
.prod [data-link-type]::after {
    content: "";
}

[data-link-type=element],
[data-link-type=element-attr] {
    font-family: Menlo, Consolas, "DejaVu Sans Mono", monospace;
    font-size: .9em;
}
[data-link-type=element]::before { content: "<" }
[data-link-type=element]::after  { content: ">" }

[data-link-type=biblio] {
    white-space: pre;
}</style>
 <body class="h-entry">
  <div class="head">
   <p data-fill-with="logo"></p>
   <h1 class="p-name no-ref" id="title">P0468R1<br>An Intrusive Smart Pointer</h1>
   <h2 class="no-num no-toc no-ref heading settled" id="subtitle"><span class="content">Published Proposal, <time class="dt-updated" datetime="2018-06-19">2018-06-19</time></span></h2>
   <div data-fill-with="spec-metadata">
    <dl>
     <dt>This version:
     <dd><a class="u-url" href="https://wg21.link/p0468r1">https://wg21.link/p0468r1</a>
     <dt>Author:
     <dd>
      <dd class="editor p-author h-card vcard"><a class="p-name fn u-url url" href="https://twitter.com/slurpsmadrips">Isabella Muerte</a>
     <dt>Audience:
     <dd>LEWG, LWG, SG1
     <dt>Project:
     <dd>ISO/IEC JTC1/SC22/WG21 14882: Programming Language — C++
     <dt>Current Render:
     <dd><a href="https://api.csswg.org/bikeshed/?force=1&amp;url=https://git.io/fxsVI">P0468</a>
     <dt>Current Source:
     <dd><a href="https://git.io/fxsVq">slurps-mad-rips/papers/proposals/retain-ptr</a>
    </dl>
   </div>
   <div data-fill-with="warning"></div>
   <hr title="Separator for header">
  </div>
  <div class="p-summary" data-fill-with="abstract">
   <h2 class="no-num no-toc no-ref heading settled" id="abstract"><span class="content">Abstract</span></h2>
   <p>A smart pointer is needed to manage objects with internal reference

counts to reduce maintenance overhead of C and C++ APIs.</p>
  </div>
  <nav data-fill-with="table-of-contents" id="toc">
   <h2 class="no-num no-toc no-ref" id="contents">Table of Contents</h2>
   <ol class="toc" role="directory">
    <li><a href="#acknowledgements"><span class="secno">1</span> <span class="content">Acknowledgements</span></a>
    <li>
     <a href="#changelog"><span class="secno">2</span> <span class="content">Revision History</span></a>
     <ol class="toc">
      <li><a href="#r1"><span class="secno">2.1</span> <span class="content">Revision 1</span></a>
      <li><a href="#r0"><span class="secno">2.2</span> <span class="content">Revision 0</span></a>
     </ol>
    <li><a href="#motivation"><span class="secno">3</span> <span class="content">Motivation</span></a>
    <li><a href="#scope"><span class="secno">4</span> <span class="content">Scope and Impact</span></a>
    <li>
     <a href="#faq"><span class="secno">5</span> <span class="content">Frequently Asked Questions</span></a>
     <ol class="toc">
      <li><a href="#faq-1"><span class="secno">5.1</span> <span class="content">How does <code class="highlight"><c- n>intrusive_ptr</c-></code> not meet the needs of modern C++?</span></a>
      <li><a href="#faq-2"><span class="secno">5.2</span> <span class="content">Why is it called <code class="highlight"><c- n>retain_ptr</c-></code> and not <code class="highlight"><c- n>intrusive_ptr</c-></code>?</span></a>
      <li><a href="#faq-3"><span class="secno">5.3</span> <span class="content">Is <code class="highlight"><c- n>retain_ptr</c-></code> atomic?</span></a>
      <li><a href="#faq-4"><span class="secno">5.4</span> <span class="content">Does <code class="highlight"><c- n>retain_ptr</c-></code> support allocators?</span></a>
      <li><a href="#faq-5"><span class="secno">5.5</span> <span class="content">Can <code class="highlight"><c- n>retain_ptr</c-></code> be constexpr?</span></a>
      <li><a href="#faq-7"><span class="secno">5.6</span> <span class="content">Does <code class="highlight"><c- n>retain_ptr</c-></code> adopt or retain an object on construction?</span></a>
      <li><a href="#faq-8"><span class="secno">5.7</span> <span class="content">Why provide <code class="highlight"><c- n>retain_object_t</c-></code> and <code class="highlight"><c- n>adopt_object_t</c-></code>?</span></a>
      <li><a href="#faq-9"><span class="secno">5.8</span> <span class="content">Does <code class="highlight"><c- n>retain_ptr</c-></code> overload the addressof operator?</span></a>
      <li><a href="#faq-10"><span class="secno">5.9</span> <span class="content">Can <code class="highlight"><c- n>retain_traits</c-></code> store state?</span></a>
      <li><a href="#faq-11"><span class="secno">5.10</span> <span class="content">Why not just wrap a <code class="highlight"><c- n>unique_ptr</c-></code> with a custom deleter?</span></a>
     </ol>
    <li>
     <a href="#examples"><span class="secno">6</span> <span class="content">Examples</span></a>
     <ol class="toc">
      <li><a href="#examples-opencl"><span class="secno">6.1</span> <span class="content">OpenCL</span></a>
      <li><a href="#examples-objc"><span class="secno">6.2</span> <span class="content">ObjC Runtime</span></a>
      <li><a href="#examples-directx"><span class="secno">6.3</span> <span class="content">DirectX and COM</span></a>
      <li><a href="#examples-webkit"><span class="secno">6.4</span> <span class="content">WebKit’s RefPtr</span></a>
     </ol>
    <li>
     <a href="#specification"><span class="secno">7</span> <span class="content">Technical Specification</span></a>
     <ol class="toc">
      <li><a href="#wording-mixins"><span class="secno">7.1</span> <span class="content"><code class="highlight"><c- n>atomic_reference_count</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-></code> and <code class="highlight"><c- n>reference_count</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-></code></span></a>
      <li><a href="#wording-sentinels"><span class="secno">7.2</span> <span class="content"><code class="highlight"><c- n>retain_object_t</c-></code> and <code class="highlight"><c- n>adopt_object_t</c-></code></span></a>
      <li><a href="#wording-traits"><span class="secno">7.3</span> <span class="content"><code class="highlight"><c- n>retain_traits</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-></code></span></a>
      <li>
       <a href="#wording-pointer"><span class="secno">7.4</span> <span class="content"><code class="highlight"><c- n>retain_ptr</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-></code></span></a>
       <ol class="toc">
        <li><a href="#wording-pointer-ctor"><span class="secno">7.4.1</span> <span class="content"><code class="highlight"><c- n>retain_ptr</c-></code> constructors</span></a>
        <li><a href="#wording-pointer-dtor"><span class="secno">7.4.2</span> <span class="content"><code class="highlight"><c- n>retain_ptr</c-></code> destructor</span></a>
        <li><a href="#wording-pointer-assignment"><span class="secno">7.4.3</span> <span class="content"><code class="highlight"><c- n>retain_ptr</c-></code> assignment</span></a>
        <li><a href="#wording-pointer-observers"><span class="secno">7.4.4</span> <span class="content"><code class="highlight"><c- n>retain_ptr</c-></code> observers</span></a>
        <li><a href="#wording-pointer-modifiers"><span class="secno">7.4.5</span> <span class="content"><code class="highlight"><c- n>retain_ptr</c-></code> modifiers</span></a>
        <li><a href="#wording-pointer-algorithms"><span class="secno">7.4.6</span> <span class="content"><code class="highlight"><c- n>retain_ptr</c-></code> specialized algorithms</span></a>
       </ol>
     </ol>
    <li>
     <a href="#references"><span class="secno"></span> <span class="content">References</span></a>
     <ol class="toc">
      <li><a href="#informative"><span class="secno"></span> <span class="content">Informative References</span></a>
     </ol>
   </ol>
  </nav>
  <main>
   <h2 class="heading settled" data-level="1" id="acknowledgements"><span class="secno">1. </span><span class="content">Acknowledgements</span><a class="self-link" href="#acknowledgements"></a></h2>
   <p>I’d like to thank the following:</p>
   <ul>
    <li data-md>
     <p>Jackie Kay and Brittany Friedman for encouraging me to submit this proposal.</p>
    <li data-md>
     <p>Gor Nishanov, whose coroutine slides at CppCon 2016 gave me the final push
to sit down and write this.</p>
    <li data-md>
     <p>Bryce "Wash" Lelbach for representing this paper when I was unable to.</p>
    <li data-md>
     <p>Mark Zeren for <em>constantly</em> bugging me to see if I might update this paper.</p>
    <li data-md>
     <p>JF Bastien and Billy O’Neal for assisting me with some atomic operations,
which I am absolute garbage at.</p>
   </ul>
   <h2 class="heading settled" data-level="2" id="changelog"><span class="secno">2. </span><span class="content">Revision History</span><a class="self-link" href="#changelog"></a></h2>
   <h3 class="heading settled" data-level="2.1" id="r1"><span class="secno">2.1. </span><span class="content">Revision 1</span><a class="self-link" href="#r1"></a></h3>
   <ul>
    <li data-md>
     <p>Rewrote proposal in bikeshed, the hot new format that every cool proposal
writer is using now.</p>
    <li data-md>
     <p>Clarified section on addressof operator, now that <code class="highlight"><c- n>out_ptr</c-></code> is being
submitted</p>
    <li data-md>
     <p>Removed <code class="highlight"><c- n>retain_ptr</c-><c- o>::</c-><c- n>unique</c-></code> as it was removed from <code class="highlight"><c- n>shared_ptr</c-></code> for C++20.</p>
    <li data-md>
     <p>Removed code example of implementing a <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>future</c-></code>-like type.</p>
    <li data-md>
     <p>Changed <code class="highlight"><c- n>retain_ptr</c-><c- o>::</c-><c- n>detach</c-></code> to <code class="highlight"><c- n>retain_ptr</c-><c- o>::</c-><c- n>release</c-></code></p>
    <li data-md>
     <p>Changed name of <code class="highlight"><c- n>retain_t</c-></code> to <code class="highlight"><c- n>retain_object_t</c-></code></p>
    <li data-md>
     <p>Changed atomicity of <code class="highlight"><c- n>atomic_reference_count</c-></code> based on suggestions from
Billy O’Neal.</p>
    <li data-md>
     <p>Changed wording to use C++17/C++20 features.</p>
    <li data-md>
     <p>Changed order of document. <a href="#specification">§7 Technical Specification</a> is now at the very end
of the document, and <a href="#examples">§6 Examples</a> are further up.</p>
    <li data-md>
     <p>Added <code class="highlight"><c- n>adopt_object_t</c-></code> and <code class="highlight"><c- n>default_action</c-></code> to let users decide what
action they want on construction and reset.</p>
    <li data-md>
     <p>Added <code class="highlight"><c- n>static_pointer_cast</c-></code>, <code class="highlight"><c- n>dynamic_pointer_cast</c-></code>, <code class="highlight"><c- n>const_pointer_cast</c-></code>,
and <code class="highlight"><c- n>reinterpret_pointer_cast</c-></code>.</p>
    <li data-md>
     <p>Added deduction guides to bring <code class="highlight"><c- n>retain_ptr</c-></code> in line with other smart
pointers</p>
    <li data-md>
     <p>Added more code examples</p>
   </ul>
   <h3 class="heading settled" data-level="2.2" id="r0"><span class="secno">2.2. </span><span class="content">Revision 0</span><a class="self-link" href="#r0"></a></h3>
   <p>Initial Release 🎉</p>
   <h2 class="heading settled" data-level="3" id="motivation"><span class="secno">3. </span><span class="content">Motivation</span><a class="self-link" href="#motivation"></a></h2>
   <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 use with either <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>unique_ptr</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-></code> or <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>shared_ptr</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-></code>. In the former case, there is no guaranteed way to make
sure the <code class="highlight"><c- n>unique_ptr</c-></code> is the last instance (i.e., that it is <em>unique</em>), and in
the latter case, <code class="highlight"><c- n>shared_ptr</c-></code> manages its own API. In addition, existing
intrusive smart pointers such as <a href="https://bit.ly/intrusive-ptr"> <code class="highlight"><c- n>boost</c-><c- o>::</c-><c- n>intrusive_ptr</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-></code></a>, <a href="https://bit.ly/com-ptr">Microsoft’s <code class="highlight"><c- n>ComPtr</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-></code></a>, or <a href="https://git.io/fCl9x">WebKit’s aptly named <code class="highlight"><c- n>WTF</c-><c- o>::</c-><c- n>RefPtr</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-></code></a> do not meet the needs of modern C++ smart pointers or APIs.
This proposal attempts to solve these shortcomings in an extensible and future
proof manner, while permitting a simple upgrade path for existing project
specific intrusive smart pointers and providing the opportunity for value
semantics when interfacing with opaque interfaces.</p>
   <p>Those that work on systems or tools that rely on reference counting stand to
benefit most from <code class="highlight"><c- n>retain_ptr</c-></code>. Additionally, <code class="highlight"><c- n>retain_ptr</c-></code> would be a benefit
to standard library implementers for types that <em>secretly</em> use intrusive
reference counting such as a coroutines capable future and promise.</p>
   <p>If <code class="highlight"><c- n>retain_ptr</c-></code> is added to the standard library, the C++ community would also
be one step closer to a non-atomic <code class="highlight"><c- n>shared_ptr</c-></code> and <code class="highlight"><c- n>weak_ptr</c-></code>, much like
Rust’s <code class="highlight"><c- n>Rc</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-></code>.</p>
   <p>A reference implementation of <code class="highlight"><c- n>retain_ptr</c-></code>, along with examples of its use,
can be found on <a data-link-type="biblio" href="#biblio-implementation">github</a>.</p>
   <h2 class="heading settled" data-level="4" id="scope"><span class="secno">4. </span><span class="content">Scope and Impact</span><a class="self-link" href="#scope"></a></h2>
   <p><code class="highlight"><c- n>retain_ptr</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- n>R</c-><c- o>></c-></code> would ideally be available in the <code class="highlight"><c- o>&lt;</c-><c- n>memory</c-><c- o>></c-></code> standard
header. It is a pure extension to the C++ standard library and can (more or
less) be implemented using any conforming C++14 or C++11 compiler with very
little effort. See the <a href="#specification">§7 Technical Specification</a> for interface and behavior
details.</p>
   <h2 class="heading settled" data-level="5" id="faq"><span class="secno">5. </span><span class="content">Frequently Asked Questions</span><a class="self-link" href="#faq"></a></h2>
   <p>Several common questions regarding the design of <code class="highlight"><c- n>retain_ptr</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- n>R</c-><c- o>></c-></code> can be
found below.</p>
   <h3 class="heading settled" data-level="5.1" id="faq-1"><span class="secno">5.1. </span><span class="content">How does <code class="highlight"><c- n>intrusive_ptr</c-></code> not meet the needs of modern C++?</span><a class="self-link" href="#faq-1"></a></h3>
   <p><code class="highlight"><c- n>boost</c-><c- o>::</c-><c- n>intrusive_ptr</c-></code> has had nearly the same interface since its introduction
in 2001 by Peter Dimov. Furthermore, <code class="highlight"><c- n>boost</c-><c- o>::</c-><c- n>intrusive_ptr</c-></code> has several
failings in its API that cannot be changed from without breaking compatibility.
When constructing a <code class="highlight"><c- n>boost</c-><c- o>::</c-><c- n>intrusive_ptr</c-></code>, by default it increments the
reference count. This is because of its <code class="highlight"><c- n>intrusive_ref_count</c-></code> 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 proposal rectifies this
by permitting each traits instance to choose its default action during
construction.</p>
   <p>Additionally, <code class="highlight"><c- n>boost</c-><c- o>::</c-><c- n>intrusive_ptr</c-></code> does not have the ability to "overload"
its <code class="highlight"><c- n>pointer</c-></code> type member, requiring some additional work when interfacing with
C APIs (e.g., <code class="highlight"><c- n>boost</c-><c- o>::</c-><c- n>intrusive_ptr</c-><c- o>&lt;</c-><c- k>decltype</c-><c- p>(</c-><c- o>*</c-><c- n>declval</c-><c- o>&lt;</c-><c- n>cl_mem</c-><c- o>></c-><c- p>())</c-><c- o>></c-></code>). This
also precludes it from working with types that meet the <em>NullablePointer</em> named requirements (a feature that <code class="highlight"><c- n>unique_ptr</c-></code> supports).</p>
   <p>Furthermore, <code class="highlight"><c- n>boost</c-><c- o>::</c-><c- n>intrusive_ptr</c-></code> relies on ADL calls of two functions:</p>
   <ul>
    <li data-md>
     <p><code class="highlight"><c- n>intrusive_add_ref</c-></code></p>
    <li data-md>
     <p><code class="highlight"><c- n>intrusive_release</c-></code></p>
   </ul>
   <p>While this approach is fine in most cases, it does remove the ability to easily
"swap out" the actions taken when increment or decrementing the reference count
(e.g., setting a debugger breakpoint on a specific traits implementation, but
not on <em>all</em> traits implementations). This naming convention 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>
   <h3 class="heading settled" data-level="5.2" id="faq-2"><span class="secno">5.2. </span><span class="content">Why is it called <code class="highlight"><c- n>retain_ptr</c-></code> and not <code class="highlight"><c- n>intrusive_ptr</c-></code>?</span><a class="self-link" href="#faq-2"></a></h3>
   <p><code class="highlight"><c- n>retain_ptr</c-></code> diverges from the design of <code class="highlight"><c- n>boost</c-><c- o>::</c-><c- n>intrusive_ptr</c-></code>. It was decided
to change the name so as to not cause assumptions of <code class="highlight"><c- n>retain_ptr</c-></code>'s interface
and behavior.</p>
   <p>Some additional names that might be considered (for bikeshedding) are:</p>
   <ul>
    <li data-md>
     <p><code class="highlight"><c- n>extend_ptr</c-></code></p>
    <li data-md>
     <p><code class="highlight"><c- n>counted_ptr</c-></code></p>
    <li data-md>
     <p><code class="highlight"><c- n>borrow_ptr</c-></code></p>
    <li data-md>
     <p><code class="highlight"><c- n>mutual_ptr</c-></code></p>
    <li data-md>
     <p><code class="highlight"><c- n>joint_ptr</c-></code></p>
   </ul>
   <p>Comedy Option:</p>
   <ul>
    <li data-md>
     <p><code class="highlight"><c- n>auto_ptr</c-></code></p>
   </ul>
   <h3 class="heading settled" data-level="5.3" id="faq-3"><span class="secno">5.3. </span><span class="content">Is <code class="highlight"><c- n>retain_ptr</c-></code> atomic?</span><a class="self-link" href="#faq-3"></a></h3>
   <p><code class="highlight"><c- n>retain_ptr</c-></code> is only atomic in its reference count increment and decrements
if the object it manages is itself atomic in its reference count operations.</p>
   <h3 class="heading settled" data-level="5.4" id="faq-4"><span class="secno">5.4. </span><span class="content">Does <code class="highlight"><c- n>retain_ptr</c-></code> support allocators?</span><a class="self-link" href="#faq-4"></a></h3>
   <p><code class="highlight"><c- n>retain_ptr</c-></code> itself does not support allocators, however the object whose
lifetime it extends can.</p>
   <h3 class="heading settled" data-level="5.5" id="faq-5"><span class="secno">5.5. </span><span class="content">Can <code class="highlight"><c- n>retain_ptr</c-></code> be constexpr?</span><a class="self-link" href="#faq-5"></a></h3>
   <p>Possibly. However, I question the usefulness for a constexpr capable intrusive
smart pointer, as most use cases are intended for non-constexpr capable
interfaces such as incomplete types and polymorphic classes. Additionally, <code class="highlight"><c- n>retain_ptr</c-></code> allows one to utilize value semantics on C and C++ APIs. If this
is desired in a constexpr context, one can simply use constexpr values (i.e.,
reference counting is not a necessary aspect of constexpr)</p>
   <h3 class="heading settled" data-level="5.6" id="faq-7"><span class="secno">5.6. </span><span class="content">Does <code class="highlight"><c- n>retain_ptr</c-></code> adopt or retain an object on construction?</span><a class="self-link" href="#faq-7"></a></h3>
   <p>The default action that <code class="highlight"><c- n>retain_ptr</c-></code> takes on construction or reset is
determined by the <code class="highlight"><c- n>traits_type</c-></code> for the <code class="highlight"><c- n>retain_ptr</c-></code>. If the traits type
has a member named <code class="highlight"><c- n>default_action</c-></code>, the <code class="highlight"><c- n>retain_ptr</c-></code> will use that to delegate
to the correct constructor. If there is no type alias member named <code class="highlight"><c- n>default_action</c-></code>, the default operation is to <em>adopt</em> the object (i.e., it
does not increment the reference count during its construction). The <code class="highlight"><c- n>default_action</c-></code> type alias <em>must</em> be either <code class="highlight"><c- n>adopt_object_t</c-></code> or <code class="highlight"><c- n>retain_object_t</c-></code>.</p>
   <h3 class="heading settled" data-level="5.7" id="faq-8"><span class="secno">5.7. </span><span class="content">Why provide <code class="highlight"><c- n>retain_object_t</c-></code> and <code class="highlight"><c- n>adopt_object_t</c-></code>?</span><a class="self-link" href="#faq-8"></a></h3>
   <p><code class="highlight"><c- n>retain_object_t</c-></code> and <code class="highlight"><c- n>adopt_object_t</c-></code> act as sentinel types to provide
explicit requests to either <em>extend</em> or <em>adopt</em> an object when constructing
or resetting a <code class="highlight"><c- n>retain_ptr</c-></code>. This mostly comes into play when interacting
with APIs that return a borrowed (rather than a new) reference to an object
without increment its reference count.</p>
   <p>Technically, an <code class="highlight"><c- k>enum</c-> <c- k>class</c-> <c- nc>retain</c-> <c- o>:</c-> <c- b>bool</c-> <c- p>{</c-> <c- n>no</c-><c- p>,</c-> <c- n>yes</c-> <c- p>}</c-></code> would be possible.
However, this would be the first time such an API is placed into the standard
library. Using a boolean parameter, as found in <code class="highlight"><c- n>boost</c-><c- o>::</c-><c- n>intrusive_ptr</c-></code> is
unsatisfactory and does not help describe the operation the user is requesting.</p>
   <p>The names of these sentinels are available for bikeshedding. Some other
possible names for <code class="highlight"><c- n>retain_object_t</c-></code> include:</p>
   <ul>
    <li data-md>
     <p><code class="highlight"><c- n>retain_element_t</c-></code></p>
    <li data-md>
     <p><code class="highlight"><c- n>extend_element_t</c-></code></p>
    <li data-md>
     <p><code class="highlight"><c- n>retainobj_t</c-></code></p>
    <li data-md>
     <p><code class="highlight"><c- n>extendobj_t</c-></code></p>
   </ul>
   <p>While <code class="highlight"><c- n>adopt_object_t</c-></code> names include:</p>
   <ul>
    <li data-md>
     <p><code class="highlight"><c- n>borrow_object_t</c-></code></p>
    <li data-md>
     <p><code class="highlight"><c- n>borrow_element_t</c-></code></p>
    <li data-md>
     <p><code class="highlight"><c- n>borrowobj_t</c-></code></p>
    <li data-md>
     <p><code class="highlight"><c- n>adopt_element_t</c-></code></p>
    <li data-md>
     <p><code class="highlight"><c- n>adoptobj_t</c-></code></p>
   </ul>
   <h3 class="heading settled" data-level="5.8" id="faq-9"><span class="secno">5.8. </span><span class="content">Does <code class="highlight"><c- n>retain_ptr</c-></code> overload the addressof operator?</span><a class="self-link" href="#faq-9"></a></h3>
   <p>Originally, this proposal suggested <code class="highlight"><c- n>retain_ptr</c-></code> might in some small edge case
require an overload for the addressof <code class="highlight"><c- k>operator</c-> <c- o>&amp;</c-></code>. This was, with absolutely
no surprise, contentious and asked to be removed. However, Microsoft’s <code class="highlight"><c- n>ComPtr</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-></code> overloads the addressof operator for initializing it via C APIs
(i.e., APIs which initialize a pointer to a pointer). Since then, JeanHyde
Meneide’s <em>out_ptr</em> proposal <a data-link-type="biblio" href="#biblio-p1132">[P1132]</a> was written and thus solves this slight
issue.</p>
   <h3 class="heading settled" data-level="5.9" id="faq-10"><span class="secno">5.9. </span><span class="content">Can <code class="highlight"><c- n>retain_traits</c-></code> store state?</span><a class="self-link" href="#faq-10"></a></h3>
   <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, <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>shared_ptr</c-></code> would be a better choice.</p>
   <h3 class="heading settled" data-level="5.10" id="faq-11"><span class="secno">5.10. </span><span class="content">Why not just wrap a <code class="highlight"><c- n>unique_ptr</c-></code> with a custom deleter?</span><a class="self-link" href="#faq-11"></a></h3>
   <p>This is an extraordinary amount of code across many existing libraries that
would not be guaranteed to have a homogenous interface. For example, using <code class="highlight"><c- n>retain_ptr</c-></code> with an OpenCL context object (without checking for errors in both
implementations) is as simple as:</p>
<pre class="language-cpp highlight"><c- k>struct</c-> <c- n>context_traits</c-> <c- p>{</c->
  <c- k>using</c-> <c- n>pointer</c-> <c- o>=</c-> <c- n>cl_context</c-><c- p>;</c->
  <c- k>static</c-> <c- b>void</c-> <c- nf>increment</c-> <c- p>(</c-><c- n>pointer</c-> <c- n>p</c-><c- p>)</c-> <c- p>{</c-> <c- n>clRetainContext</c-><c- p>(</c-><c- n>p</c-><c- p>);</c-> <c- p>}</c->
  <c- k>static</c-> <c- b>void</c-> <c- nf>decrement</c-> <c- p>(</c-><c- n>pointer</c-> <c- n>p</c-><c- p>)</c-> <c- p>{</c-> <c- n>clReleaseContext</c-><c- p>(</c-><c- n>p</c-><c- p>);</c-> <c- p>}</c->
<c- p>};</c->

<c- k>struct</c-> <c- n>context</c-> <c- p>{</c->
  <c- k>using</c-> <c- n>handle_type</c-> <c- o>=</c-> <c- n>retain_ptr</c-><c- o>&lt;</c-><c- n>cl_context</c-><c- p>,</c-> <c- n>context_traits</c-><c- o>></c-><c- p>;</c->
  <c- k>using</c-> <c- n>pointer</c-> <c- o>=</c-> <c- n>handle_type</c-><c- o>::</c-><c- n>pointer</c-><c- p>;</c->
  <c- n>context</c-> <c- p>(</c-><c- n>pointer</c-> <c- n>p</c-><c- p>,</c-> <c- n>retain_object_t</c-><c- p>)</c-> <c- o>:</c-> <c- n>handle</c-><c- p>(</c-><c- n>p</c-><c- p>,</c-> <c- n>retain</c-><c- p>)</c-> <c- p>{</c-> <c- p>}</c->
  <c- n>context</c-> <c- p>(</c-><c- n>pointer</c-> <c- n>p</c-><c- p>)</c-> <c- o>:</c-> <c- n>handle</c-><c- p>(</c-><c- n>p</c-><c- p>)</c-> <c- p>{</c-> <c- p>}</c->
<c- k>private</c-><c- o>:</c->
  <c- n>handle_type</c-> <c- n>handle</c-><c- p>;</c->
<c- p>};</c->
</pre>
   <p>Using the <code class="highlight"><c- n>unique_ptr</c-></code> approach requires more effort. In this case, it is
twice as long to get the same functionality.</p>
<pre class="language-cpp highlight"><c- k>struct</c-> <c- n>context_deleter</c-> <c- p>{</c->
  <c- k>using</c-> <c- n>pointer</c-> <c- o>=</c-> <c- n>cl_context</c-><c- p>;</c->
  <c- b>void</c-> <c- nf>increment</c-> <c- p>(</c-><c- n>pointer</c-> <c- n>p</c-><c- p>)</c-> <c- k>const</c-> <c- p>{</c->
    <c- k>if</c-> <c- p>(</c-><c- n>p</c-><c- p>)</c-> <c- p>{</c-> <c- n>clRetainContext</c-><c- p>(</c-><c- n>p</c-><c- p>);</c-> <c- p>}</c-> <c- c1>// retain_ptr checks for null for us</c->
  <c- p>}</c->
  <c- b>void</c-> <c- nf>operator</c-> <c- p>()</c-> <c- p>(</c-><c- n>pointer</c-> <c- n>p</c-><c- p>)</c-> <c- k>const</c-> <c- p>{</c-> <c- n>clReleaseContext</c-><c- p>(</c-><c- n>p</c-><c- p>);</c-> <c- p>}</c->
<c- p>};</c->

<c- k>struct</c-> <c- n>retain_object_t</c-> <c- p>{</c-> <c- p>};</c->
<c- k>constexpr</c-> <c- n>retain_object_t</c-> <c- n>retain</c-> <c- p>{</c-> <c- p>};</c->

<c- k>struct</c-> <c- n>context</c-> <c- p>{</c->
  <c- k>using</c-> <c- n>handle_type</c-> <c- o>=</c-> <c- n>unique_ptr</c-><c- o>&lt;</c-><c- n>cl_context</c-><c- p>,</c-> <c- n>context_deleter</c-><c- o>></c-><c- p>;</c->
  <c- k>using</c-> <c- n>pointer</c-> <c- o>=</c-> <c- n>handle_type</c-><c- o>::</c-><c- n>pointer</c-><c- p>;</c->

  <c- n>context</c-> <c- p>(</c-><c- n>pointer</c-> <c- n>p</c-><c- p>,</c-> <c- n>retain_object_t</c-><c- p>)</c-> <c- o>:</c->
    <c- n>context</c-><c- p>(</c-><c- n>p</c-><c- p>)</c->
  <c- p>{</c-> <c- n>handle</c-><c- p>.</c-><c- n>get_deleter</c-><c- p>().</c-><c- n>increment</c-><c- p>(</c-><c- n>handle</c-><c- p>.</c-><c- n>get</c-><c- p>());</c-> <c- p>}</c->

  <c- n>context</c-> <c- p>(</c-><c- n>pointer</c-> <c- n>p</c-><c- p>)</c-> <c- o>:</c-> <c- n>handle</c-><c- p>(</c-><c- n>p</c-><c- p>)</c-> <c- p>{</c-> <c- p>}</c->

  <c- n>context</c-> <c- p>(</c-><c- n>context</c-> <c- k>const</c-><c- o>&amp;</c-> <c- n>that</c-><c- p>)</c-> <c- o>:</c->
    <c- n>handle</c-><c- p>(</c-><c- n>that</c-><c- p>.</c-><c- n>handle</c-><c- p>.</c-><c- n>get</c-><c- p>())</c->
  <c- p>{</c-> <c- n>handle</c-><c- p>.</c-><c- n>get_deleter</c-><c- p>().</c-><c- n>increment</c-><c- p>(</c-><c- n>handle</c-><c- p>.</c-><c- n>get</c-><c- p>())</c-> <c- p>}</c->

  <c- n>context</c-><c- o>&amp;</c-> <c- k>operator</c-> <c- o>=</c-> <c- p>(</c-><c- n>context</c-> <c- k>const</c-><c- o>&amp;</c-> <c- n>that</c-><c- p>)</c-> <c- p>{</c->
    <c- n>context</c-><c- p>(</c-><c- n>that</c-><c- p>.</c-><c- n>handle</c-><c- p>.</c-><c- n>get</c-><c- p>(),</c-> <c- n>retain</c-><c- p>).</c-><c- n>swap</c-><c- p>(</c-><c- o>*</c-><c- k>this</c-><c- p>);</c->
    <c- k>return</c-> <c- o>*</c-><c- k>this</c-><c- p>;</c->
  <c- p>}</c->

  <c- b>void</c-> <c- n>swap</c-> <c- p>(</c-><c- n>context</c-><c- o>&amp;</c-> <c- n>that</c-><c- p>)</c-> <c- k>noexcept</c-> <c- p>{</c-> <c- n>handle</c-><c- p>.</c-><c- n>swap</c-><c- p>(</c-><c- n>that</c-><c- p>);</c-> <c- p>}</c->
    
<c- k>private</c-><c- o>:</c->
  <c- n>handle_type</c-> <c- n>handle</c-><c- p>;</c->
<c- p>};</c->
</pre>
   <p>As we can see, using <code class="highlight"><c- n>retain_ptr</c-></code> saves effort, allowing us in most cases to
simply rely on the "rule of zero" for constructor management. It will also not
confuse/terrify maintainers of code bases where objects construct a <code class="highlight"><c- n>unique_ptr</c-></code> with the raw pointer of another (and <em>unique ownership</em> is not
transferred).</p>
   <h2 class="heading settled" data-level="6" id="examples"><span class="secno">6. </span><span class="content">Examples</span><a class="self-link" href="#examples"></a></h2>
   <p>Some C APIs that would benefit from <code class="highlight"><c- n>retain_ptr</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-></code> are</p>
   <ul>
    <li data-md>
     <p>OpenCL</p>
    <li data-md>
     <p>Mono (Assembly and Image types)</p>
    <li data-md>
     <p>CPython</p>
    <li data-md>
     <p>ObjC Runtime</p>
    <li data-md>
     <p>Grand Central Dispatch</p>
   </ul>
   <p>Inside the <a data-link-type="biblio" href="#biblio-implementation">[implementation]</a> repository is an extremely basic example of using <code class="highlight"><c- n>retain_ptr</c-></code> with Python.</p>
   <h3 class="heading settled" data-level="6.1" id="examples-opencl"><span class="secno">6.1. </span><span class="content">OpenCL</span><a class="self-link" href="#examples-opencl"></a></h3>
   <p>As shown above, using <code class="highlight"><c- n>retain_ptr</c-></code> with OpenCL is extremely simple.</p>
<pre class="language-cpp highlight"><c- k>struct</c-> <c- n>context_traits</c-> <c- p>{</c->
  <c- k>using</c-> <c- n>pointer</c-> <c- o>=</c-> <c- n>cl_context</c-><c- p>;</c->
  <c- k>static</c-> <c- b>void</c-> <c- nf>increment</c-> <c- p>(</c-><c- n>pointer</c-> <c- n>p</c-><c- p>)</c-> <c- p>{</c-> <c- n>clRetainContext</c-><c- p>(</c-><c- n>p</c-><c- p>);</c-> <c- p>}</c->
  <c- k>static</c-> <c- b>void</c-> <c- nf>decrement</c-> <c- p>(</c-><c- n>pointer</c-> <c- n>p</c-><c- p>)</c-> <c- p>{</c-> <c- n>clReleaseContext</c-><c- p>(</c-><c- n>p</c-><c- p>);</c-> <c- p>}</c->
<c- p>};</c->

<c- k>struct</c-> <c- n>context</c-> <c- p>{</c->
  <c- k>using</c-> <c- n>handle_type</c-> <c- o>=</c-> <c- n>retain_ptr</c-><c- o>&lt;</c-><c- n>cl_context</c-><c- p>,</c-> <c- n>context_traits</c-><c- o>></c-><c- p>;</c->
  <c- k>using</c-> <c- n>pointer</c-> <c- o>=</c-> <c- n>handle_type</c-><c- o>::</c-><c- n>pointer</c-><c- p>;</c->
  <c- n>context</c-> <c- p>(</c-><c- n>pointer</c-> <c- n>p</c-><c- p>,</c-> <c- n>retain_object_t</c-><c- p>)</c-> <c- o>:</c-> <c- n>handle</c-><c- p>(</c-><c- n>p</c-><c- p>,</c-> <c- n>retain</c-><c- p>)</c-> <c- p>{</c-> <c- p>}</c->
  <c- n>context</c-> <c- p>(</c-><c- n>pointer</c-> <c- n>p</c-><c- p>)</c-> <c- o>:</c-> <c- n>handle</c-><c- p>(</c-><c- n>p</c-><c- p>)</c-> <c- p>{</c-> <c- p>}</c->
<c- k>private</c-><c- o>:</c->
  <c- n>handle_type</c-> <c- n>handle</c-><c- p>;</c->
<c- p>};</c->
</pre>
   <h3 class="heading settled" data-level="6.2" id="examples-objc"><span class="secno">6.2. </span><span class="content">ObjC Runtime</span><a class="self-link" href="#examples-objc"></a></h3>
   <p>Additionally, while some additional work is needed to interact with the rest of
the ObjC runtime, <code class="highlight"><c- n>retain_ptr</c-></code> can be used to simulate ARC and remove its
need entirely when writing ObjC. This means that one could, theoretically,
write ObjC and ObjC++ capable code without having to actually write ObjC or
ObjC++.</p>
<pre class="language-cpp highlight"><c- k>struct</c-> <c- n>objc_traits</c-> <c- p>{</c->
  <c- k>using</c-> <c- n>pointer</c-> <c- o>=</c-> <c- n>CFTypeRef</c-><c- p>;</c->
  <c- k>static</c-> <c- b>void</c-> <c- nf>increment</c-> <c- p>(</c-><c- n>pointer</c-> <c- n>p</c-><c- p>)</c-> <c- p>{</c-> <c- n>CFRetain</c-><c- p>(</c-><c- n>p</c-><c- p>);</c-> <c- p>}</c->
  <c- k>static</c-> <c- b>void</c-> <c- nf>decrement</c-> <c- p>(</c-><c- n>pointer</c-> <c- n>p</c-><c- p>)</c-> <c- p>{</c-> <c- n>CFRelease</c-><c- p>(</c-><c- n>p</c-><c- p>);</c-> <c- p>}</c->
<c- p>};</c->
</pre>
   <h3 class="heading settled" data-level="6.3" id="examples-directx"><span class="secno">6.3. </span><span class="content">DirectX and COM</span><a class="self-link" href="#examples-directx"></a></h3>
   <p>Because DirectX is a COM interface, it can also benefit from the use of <code class="highlight"><c- n>retain_ptr</c-></code> by simply using the same common traits interface used for all COM
objects. The following code is slightly adapted from Microsoft’s GpuResource
class in the DirectX Graphics Samples. The current form of the code uses the
Microsoft provided <code class="highlight"><c- n>WRL</c-><c- o>::</c-><c- n>ComPtr</c-></code>, however the point here is to show how <code class="highlight"><c- n>retain_ptr</c-></code> can work as a drop-in replacement for this type.</p>
<pre class="language-cpp highlight"><c- k>struct</c-> <c- n>com_traits</c-> <c- p>{</c->
  <c- k>static</c-> <c- b>void</c-> <c- n>increment</c-> <c- p>(</c-><c- n>IUnknown</c-><c- o>*</c-> <c- n>ptr</c-><c- p>)</c-> <c- p>{</c-> <c- n>ptr</c-><c- o>-></c-><c- n>AddRef</c-><c- p>();</c-> <c- p>}</c->
  <c- k>static</c-> <c- b>void</c-> <c- n>decrement</c-> <c- p>(</c-><c- n>IUnknown</c-><c- o>*</c-> <c- n>ptr</c-><c- p>)</c-> <c- p>{</c-> <c- n>ptr</c-><c- o>-></c-><c- n>Release</c-><c- p>();</c-> <c- p>}</c->
<c- p>};</c->

<c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- o>></c-> <c- k>using</c-> <c- n>com_ptr</c-> <c- o>=</c-> <c- n>retain_ptr</c-><c- o>&lt;</c-><c- n>T</c-><c- o>*</c-><c- p>,</c-> <c- n>com_traits</c-><c- o>></c-><c- p>;</c->

<c- k>struct</c-> <c- n>GpuResource</c-> <c- p>{</c->

  <c- k>friend</c-> <c- k>class</c-> <c- nc>GraphicsContext</c-><c- p>;</c->
  <c- k>friend</c-> <c- k>class</c-> <c- nc>CommandContext</c-><c- p>;</c->
  <c- k>friend</c-> <c- k>class</c-> <c- nc>ComputeContext</c-><c- p>;</c->

  <c- n>GpuResource</c-> <c- p>(</c-><c- n>ID3D12Resource</c-><c- o>*</c-> <c- n>resource</c-><c- p>,</c-> <c- n>D3D12_RESOURCE_STATES</c-> <c- n>current</c-><c- p>)</c-> <c- o>:</c->
    <c- n>resource</c-><c- p>(</c-><c- n>resource</c-><c- p>),</c->
    <c- n>usage_state</c-><c- p>(</c-><c- n>current</c-><c- p>)</c->
  <c- p>{</c-> <c- p>}</c->

  <c- n>GpuResource</c-> <c- p>()</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c->

  <c- n>ID3D12Resource</c-><c- o>*</c-> <c- k>operator</c-> <c- o>-></c-> <c- p>()</c-> <c- k>noexcept</c-> <c- p>{</c-> <c- k>return</c-> <c- k>this</c-><c- o>-></c-><c- n>resource</c-><c- p>.</c-><c- n>get</c-><c- p>();</c-> <c- p>}</c->
  <c- n>ID3D12Resource</c-> <c- k>const</c-><c- o>*</c-> <c- k>operator</c-> <c- o>-></c-> <c- p>()</c-> <c- k>const</c-> <c- k>noexcept</c-> <c- p>{</c->
    <c- k>return</c-> <c- k>this</c-><c- o>-></c-><c- n>resource</c-><c- p>.</c-><c- n>get</c-><c- p>();</c->
  <c- p>}</c->

<c- k>protected</c-><c- o>:</c->
  <c- n>com_ptr</c-><c- o>&lt;</c-><c- n>ID3D12Resource</c-><c- o>></c-> <c- n>resource</c-> <c- p>{</c-> <c- p>};</c->
  <c- n>D3D12_RESOURCE_STATES</c-> <c- n>usage_state</c-> <c- o>=</c-> <c- n>D3D12_RESOURCE_STATE_COMMON</c-><c- p>;</c->
  <c- n>D3D12_RESOURCE_STATES</c-> <c- n>transitioning_state</c-> <c- o>=</c-> <c- n>D3D_RESOURCE_STATES</c-><c- p>(</c-><c- o>-</c-><c- mi>1</c-><c- p>);</c->
  <c- n>D3D12_GPU_VIRTUAL_ADDRESS</c-> <c- n>virtual_address</c-> <c- o>=</c-> <c- n>D3D12_GPU_VIRTUAL_ADDRESS_NULL</c-><c- p>;</c->
  <c- b>void</c-><c- o>*</c-> <c- n>user_memory</c-> <c- o>=</c-> <c- k>nullptr</c-><c- p>;</c->
<c- p>};</c->
</pre>
   <h3 class="heading settled" data-level="6.4" id="examples-webkit"><span class="secno">6.4. </span><span class="content">WebKit’s RefPtr</span><a class="self-link" href="#examples-webkit"></a></h3>
   <p>As a small demonstration of replacing existing intrusive smart pointers with <code class="highlight"><c- n>retain_ptr</c-></code> the author presents the following code from WebKit that uses the
existing <code class="highlight"><c- n>RefPtr</c-></code> type, followed by the same code expressed with <code class="highlight"><c- n>retain_ptr</c-></code>.
This is not meant to be a fully functionioning code sample, but rather what the
effects of a refactor to using <code class="highlight"><c- n>retain_ptr</c-></code> might result in</p>
<pre class="language-cpp highlight"><c- n>RefPtr</c-><c- o>&lt;</c-><c- n>Node</c-><c- o>></c-> <c- n>node</c-> <c- o>=</c-> <c- n>adoptRef</c-><c- p>(</c-><c- n>rawNodePointer</c-><c- p>);</c->
</pre>
<pre class="language-cpp highlight"><c- k>auto</c-> <c- n>node</c-> <c- o>=</c-> <c- n>retain_ptr</c-><c- o>&lt;</c-><c- n>Node</c-><c- o>></c-><c- p>(</c-><c- n>rawNodePointer</c-><c- p>,</c-> <c- n>adopt_object</c-><c- p>);</c->
</pre>
   <h2 class="heading settled" data-level="7" id="specification"><span class="secno">7. </span><span class="content">Technical Specification</span><a class="self-link" href="#specification"></a></h2>
   <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> <code class="highlight"><c- n>p</c-></code>, 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> <code class="highlight"><c- n>c</c-></code>, <em>decrement</em> <code class="highlight"><c- n>c</c-></code>, 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
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>
   <ul>
    <li data-md>
     <p><em>r2.p</em> is equal to the pre-transfer <em>r.p</em>, and</p>
    <li data-md>
     <p><em>r.p</em> is equal to <code class="highlight"><c- k>nullptr</c-></code></p>
   </ul>
   <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>
   <ul>
    <li data-md>
     <p><em>r2.p</em> is equal to <em>r.p</em></p>
    <li data-md>
     <p><em>c</em> has been incremented by 1</p>
   </ul>
   <p>Each object of a type <code class="highlight"><c- n>U</c-></code> instantiated from the <code class="highlight"><c- n>retain_ptr</c-></code> template
specified in this proposal has the lifetime extension semantics specified
above of a retain pointer. In partical satisfaction of these semantics, each
such <code class="highlight"><c- n>U</c-></code> is <code class="highlight"><c- n>MoveConstructible</c-></code>, <code class="highlight"><c- n>MoveAssignable</c-></code>, <code class="highlight"><c- n>CopyConstructible</c-></code> and <code class="highlight"><c- n>CopyAssignable</c-></code>. The template parameter <code class="highlight"><c- n>T</c-></code> of <code class="highlight"><c- n>retain_ptr</c-></code> may be
an incomplete type. (<em>Note: The uses of</em> <code class="highlight"><c- n>retain_ptr</c-></code> <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="language-cpp highlight"><c- k>class</c-> <c- nc>atomic_reference_count</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-><c- p>;</c->
<c- k>class</c-> <c- nc>reference_count</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-><c- p>;</c->

<c- k>class</c-> <c- nc>retain_object_t</c-><c- p>;</c->
<c- k>class</c-> <c- nc>adopt_object_t</c-><c- p>;</c->

<c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- o>></c-> <c- k>struct</c-> <c- n>retain_traits</c-><c- p>;</c->

<c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- p>,</c-> <c- k>class</c-> <c- nc>R</c-> <c- o>=</c-> <c- n>retain_traits</c-><c- o>&lt;</c-><c- n>T</c-><c- o>>></c-> <c- k>class</c-> <c- nc>retain_ptr</c-><c- p>;</c->

<c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- p>,</c-> <c- k>class</c-> <c- nc>R</c-><c- o>></c->
<c- b>void</c-> <c- n>swap</c-> <c- p>(</c-><c- n>retain_ptr</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- n>R</c-><c- o>>&amp;</c-> <c- n>x</c-><c- p>,</c-> <c- n>retain_ptr</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- n>R</c-><c- o>>&amp;</c-> <c- n>y</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c->

<c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- p>,</c-> <c- k>class</c-> <c- nc>R</c-><c- p>,</c-> <c- k>class</c-> <c- nc>U</c-><c- o>></c->
<c- n>retain_ptr</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- n>R</c-><c- o>></c-> <c- n>dynamic_pointer_cast</c-> <c- p>(</c-><c- n>retain_ptr</c-><c- o>&lt;</c-><c- n>U</c-><c- p>,</c-> <c- n>R</c-><c- o>></c-> <c- k>const</c-><c- o>&amp;</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c->

<c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- p>,</c-> <c- k>class</c-> <c- nc>R</c-><c- p>,</c-> <c- k>class</c-> <c- nc>U</c-><c- o>></c->
<c- n>retain_ptr</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- n>R</c-><c- o>></c-> <c- n>static_pointer_cast</c-> <c- p>(</c-><c- n>retain_ptr</c-><c- o>&lt;</c-><c- n>U</c-><c- p>,</c-> <c- n>R</c-><c- o>></c-> <c- k>const</c-><c- o>&amp;</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c->

<c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- p>,</c-> <c- k>class</c-> <c- nc>R</c-><c- p>,</c-> <c- k>class</c-> <c- nc>U</c-><c- o>></c->
<c- n>retain_ptr</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- n>R</c-><c- o>></c-> <c- n>const_pointer_cast</c-> <c- p>(</c-><c- n>retain_ptr</c-><c- o>&lt;</c-><c- n>U</c-><c- p>,</c-> <c- n>R</c-><c- o>></c-> <c- k>const</c-><c- o>&amp;</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c->

<c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- p>,</c-> <c- k>class</c-> <c- nc>R</c-><c- p>,</c-> <c- k>class</c-> <c- nc>U</c-><c- o>></c->
<c- n>retain_ptr</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- n>R</c-><c- o>></c-> <c- n>reinterpret_pointer_cast</c-> <c- p>(</c-><c- n>retain_ptr</c-><c- o>&lt;</c-><c- n>U</c-><c- p>,</c-> <c- n>R</c-><c- o>></c-> <c- k>const</c-><c- o>&amp;</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c->

<c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- p>,</c-> <c- k>class</c-> <c- nc>R</c-><c- p>,</c-> <c- k>class</c-> <c- nc>S</c-><c- o>=</c-><c- n>R</c-><c- o>></c->
<c- n>strong_ordering</c-> <c- k>operator</c-> <c- o>&lt;=></c-> <c- p>(</c-><c- n>retain_ptr</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- n>R</c-><c- o>></c-> <c- k>const</c-><c- o>&amp;</c-> <c- n>x</c-><c- p>,</c-> <c- n>retain_ptr</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- n>S</c-><c- o>></c-> <c- k>const</c-><c- o>&amp;</c-> <c- n>y</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c->
<c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- p>,</c-> <c- k>class</c-> <c- nc>R</c-><c- o>></c->
<c- n>strong_ordering</c-> <c- k>operator</c-> <c- o>&lt;=></c-> <c- p>(</c-><c- n>retain_ptr</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- n>R</c-><c- o>></c-> <c- k>const</c-><c- o>&amp;</c-> <c- n>x</c-><c- p>,</c-> <c- n>nullptr_t</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c->
<c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- p>,</c-> <c- k>class</c-> <c- nc>R</c-><c- o>></c->
<c- n>strong_ordering</c-> <c- k>operator</c-> <c- o>&lt;=></c-> <c- p>(</c-><c- n>nullptr_t</c-><c- p>,</c-> <c- n>retain_ptr</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- n>R</c-><c- o>></c-> <c- k>const</c-><c- o>&amp;</c-> <c- n>y</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c->
</pre>
   <h3 class="heading settled" data-level="7.1" id="wording-mixins"><span class="secno">7.1. </span><span class="content"><code class="highlight"><c- n>atomic_reference_count</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-></code> and <code class="highlight"><c- n>reference_count</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-></code></span><a class="self-link" href="#wording-mixins"></a></h3>
   <p><code class="highlight"><c- n>atomic_reference_count</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-></code> and <code class="highlight"><c- n>reference_count</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-></code> are mixin types,
provided for user defined types that simply rely on <code class="highlight"><c- k>new</c-></code> and <code class="highlight"><c- k>delete</c-></code> to
have their lifetime extended by <code class="highlight"><c- n>retain_ptr</c-></code>. The template parameter <code class="highlight"><c- n>T</c-></code> is
intended to be the type deriving from <code class="highlight"><c- n>atomic_reference_count</c-></code> or <code class="highlight"><c- n>reference_count</c-></code> (a.k.a. the curiously repeating template pattern, CRTP).</p>
<pre class="language-cpp highlight"><c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- o>></c->
<c- k>struct</c-> <c- n>atomic_reference_count</c-> <c- p>{</c->
  <c- k>friend</c-> <c- n>retain_traits</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-><c- p>;</c->
<c- k>protected</c-><c- o>:</c->
  <c- n>atomic_reference_count</c-> <c- p>()</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c->
<c- k>private</c-><c- o>:</c->
  <c- n>atomic</c-><c- o>&lt;</c-><c- b>uint_least64_t</c-><c- o>></c-> <c- n>count</c-> <c- p>{</c-> <c- mi>1</c-> <c- p>};</c-> <c- c1>// provided for exposition</c->
<c- p>};</c->

<c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- o>></c->
<c- k>struct</c-> <c- n>reference_count</c-> <c- p>{</c->
  <c- k>friend</c-> <c- n>retain_traits</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-><c- p>;</c->
<c- k>protected</c-><c- o>:</c->
  <c- n>reference_count</c-> <c- p>()</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c->
<c- k>private</c-><c- o>:</c->
  <c- b>uint_least64_t</c-> <c- n>count</c-> <c- p>{</c-> <c- mi>1</c-> <c- p>};</c-> <c- c1>// provided for exposition</c->
<c- p>};</c->
</pre>
   <h3 class="heading settled" data-level="7.2" id="wording-sentinels"><span class="secno">7.2. </span><span class="content"><code class="highlight"><c- n>retain_object_t</c-></code> and <code class="highlight"><c- n>adopt_object_t</c-></code></span><a class="self-link" href="#wording-sentinels"></a></h3>
   <p><code class="highlight"><c- n>retain_object_t</c-></code> and <code class="highlight"><c- n>adopt_object_t</c-></code> are sentinel types, with constexpr
instances <code class="highlight"><c- n>retain_object</c-></code> and <code class="highlight"><c- n>adopt_object</c-></code> respectively.</p>
<pre class="language-cpp highlight"><c- k>namespace</c-> <c- n>std</c-> <c- p>{</c->
  <c- k>struct</c-> <c- n>retain_object_t</c-> <c- p>{</c-> <c- k>constexpr</c-> <c- n>retain_object_t</c-> <c- p>()</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c-> <c- p>};</c->
  <c- k>struct</c-> <c- n>adopt_object_t</c-> <c- p>{</c-> <c- k>constexpr</c-> <c- n>adopt_object_t</c-> <c- p>()</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c-> <c- p>};</c->
  <c- k>constexpr</c-> <c- n>retain_object_t</c-> <c- n>retain_object</c-> <c- p>{</c-> <c- p>};</c->
  <c- k>constexpr</c-> <c- n>adopt_object_t</c-> <c- n>adopt_object</c-> <c- p>{</c-> <c- p>};</c->
<c- p>}</c->
</pre>
   <h3 class="heading settled" data-level="7.3" id="wording-traits"><span class="secno">7.3. </span><span class="content"><code class="highlight"><c- n>retain_traits</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-></code></span><a class="self-link" href="#wording-traits"></a></h3>
   <p>The class template <code class="highlight"><c- n>retain_traits</c-></code> serves the default traits object for the
class template <code class="highlight"><c- n>retain_ptr</c-></code>. Unless <code class="highlight"><c- n>retain_traits</c-></code> is specialized for a
specific type, the template parameter <code class="highlight"><c- n>T</c-></code> must inherit from either <code class="highlight"><c- n>atomic_reference_count</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-></code> or <code class="highlight"><c- n>reference_count</c-></code>. In the event that <code class="highlight"><c- n>retain_traits</c-></code> is specialized for a type, the template parameter <code class="highlight"><c- n>T</c-></code> may be
an incomplete type.</p>
<pre class="language-cpp highlight"><c- k>namespace</c-> <c- n>std</c-> <c- p>{</c->
  <c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- o>></c-> <c- k>struct</c-> <c- n>retain_traits</c-> <c- p>{</c->
    <c- k>static</c-> <c- b>void</c-> <c- n>increment</c-> <c- p>(</c-><c- n>atomic_reference_count</c-><c- o>&lt;</c-><c- n>T</c-><c- o>>*</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c->
    <c- k>static</c-> <c- b>void</c-> <c- nf>decrement</c-> <c- p>(</c-><c- n>atomic_reference_count</c-><c- o>&lt;</c-><c- n>T</c-><c- o>>*</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c->
    <c- k>static</c-> <c- b>long</c-> <c- nf>use_count</c-> <c- p>(</c-><c- n>atomic_reference_count</c-><c- o>&lt;</c-><c- n>T</c-><c- o>>*</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c->

    <c- k>static</c-> <c- b>void</c-> <c- nf>increment</c-> <c- p>(</c-><c- n>reference_count</c-><c- o>&lt;</c-><c- n>T</c-><c- o>>*</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c->
    <c- k>static</c-> <c- b>void</c-> <c- nf>decrement</c-> <c- p>(</c-><c- n>reference_count</c-><c- o>&lt;</c-><c- n>T</c-><c- o>>*</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c->
    <c- k>static</c-> <c- b>long</c-> <c- nf>use_count</c-> <c- p>(</c-><c- n>reference_count</c-><c- o>&lt;</c-><c- n>T</c-><c- o>>*</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c->
  <c- p>};</c->
<c- p>}</c->
</pre>
   <blockquote>
    <p><code class="highlight"><c- k>static</c-> <c- b>void</c-> <c- nf>increment</c-> <c- p>(</c-><c- n>atomic_reference_count</c-><c- o>&lt;</c-><c- n>T</c-><c- o>>*</c-> <c- n>ptr</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c-></code> <br><sup>1</sup> Effects: Increments the internal reference count for <em>ptr</em> with <code class="highlight"><c- n>memory_order</c-><c- o>::</c-><c- n>relaxed</c-></code> <br><sup>2</sup> Postcondition: <code class="highlight"><c- n>ptr</c-><c- o>-></c-><c- n>count</c-></code> has been incremented by 1.</p>
   </blockquote>
   <blockquote>
    <p><code class="highlight"><c- k>static</c-> <c- b>void</c-> <c- nf>decrement</c-> <c- p>(</c-><c- n>atomic_reference_count</c-><c- o>&lt;</c-><c- n>T</c-><c- o>>*</c-> <c- n>ptr</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c-></code> <br><sup>1</sup> Effects: Decrements the internal reference count for <em>ptr</em> with <code class="highlight"><c- n>memory_order</c-><c- o>::</c-><c- n>acq_rel</c-></code>. If the internal reference count of <em>ptr</em> reaches 0, it is disposed of via <code class="highlight"><c- k>delete</c-></code>.</p>
   </blockquote>
   <blockquote>
    <p><code class="highlight"><c- k>static</c-> <c- b>long</c-> <c- nf>use_count</c-> <c- p>(</c-><c- n>atomic_reference_count</c-><c- o>&lt;</c-><c- n>T</c-><c- o>>*</c-> <c- n>ptr</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c-></code> <br><sup>1</sup> Returns: The internal reference count for <em>ptr</em> with <code class="highlight"><c- n>memory_order</c-><c- o>::</c-><c- n>acquire</c-></code>.</p>
   </blockquote>
   <blockquote>
    <p><code class="highlight"><c- k>static</c-> <c- b>void</c-> <c- nf>increment</c-> <c- p>(</c-><c- n>reference_count</c-><c- o>&lt;</c-><c- n>T</c-><c- o>>*</c-> <c- n>ptr</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c-></code> <br><sup>1</sup> Effects: Increments the internal reference count for <em>ptr</em> by 1.</p>
   </blockquote>
   <blockquote>
    <p><code class="highlight"><c- k>static</c-> <c- b>void</c-> <c- nf>decrement</c-> <c- p>(</c-><c- n>reference_count</c-><c- o>&lt;</c-><c- n>T</c-><c- o>>*</c-> <c- n>ptr</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c-></code> <br><sup>1</sup> Effects: Decrements the internal reference count for <em>ptr</em> by 1. If the count reaches 0, <em>ptr</em> is disposed of via <code class="highlight"><c- k>delete</c-></code>.</p>
   </blockquote>
   <blockquote>
    <p><code class="highlight"><c- k>static</c-> <c- b>long</c-> <c- nf>use_count</c-> <c- p>(</c-><c- n>reference_count</c-><c- o>&lt;</c-><c- n>T</c-><c- o>>*</c-> <c- n>ptr</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c-></code> <br><sup>1</sup> Returns: The reference count for <em>ptr</em>.</p>
   </blockquote>
   <h3 class="heading settled" data-level="7.4" id="wording-pointer"><span class="secno">7.4. </span><span class="content"><code class="highlight"><c- n>retain_ptr</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-></code></span><a class="self-link" href="#wording-pointer"></a></h3>
   <p>The default type for the template parameter <code class="highlight"><c- n>R</c-></code> is <code class="highlight"><c- n>retain_traits</c-></code>. A
client supplied template argument <code class="highlight"><c- n>R</c-></code> shall be an object with non-member
functions for which, given a <code class="highlight"><c- n>ptr</c-></code> of type <code class="highlight"><c- n>retain_ptr</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- n>R</c-><c- o>>::</c-><c- n>pointer</c-></code>, the
expressions <code class="highlight"><c- n>R</c-><c- o>::</c-><c- n>increment</c-><c- p>(</c-><c- n>ptr</c-><c- p>)</c-></code> and <code class="highlight"><c- n>R</c-><c- o>::</c-><c- n>decrement</c-><c- p>(</c-><c- n>ptr</c-><c- p>)</c-></code> 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> <code class="highlight"><c- n>R</c-><c- o>::</c-><c- n>pointer</c-></code> is valid and denotes a type, then <code class="highlight"><c- n>retain_ptr</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- n>R</c-><c- o>>::</c-><c- n>pointer</c-></code> shall be synonymous with <code class="highlight"><c- n>R</c-><c- o>::</c-><c- n>pointer</c-></code>. Otherwise <code class="highlight"><c- n>retain_ptr</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- n>R</c-><c- o>>::</c-><c- n>pointer</c-></code> shall be a synonym for <code class="highlight"><c- n>element_type</c-><c- o>*</c-></code>. The type <code class="highlight"><c- n>retain_ptr</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- n>R</c-><c- o>>::</c-><c- n>pointer</c-></code> shall satisfy the requirements of <em>NullablePointer</em>.</p>
<pre class="language-cpp highlight"><c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- p>,</c-> <c- k>class</c-> <c- nc>R</c-><c- o>=</c-><c- n>retain_traits</c-><c- o>&lt;</c-><c- n>T</c-><c- o>>></c->
<c- k>struct</c-> <c- n>retain_ptr</c-> <c- p>{</c->
  <c- k>using</c-> <c- n>element_type</c-> <c- o>=</c-> <c- n>T</c-><c- p>;</c->
  <c- k>using</c-> <c- n>traits_type</c-> <c- o>=</c-> <c- n>R</c-><c- p>;</c->
  <c- k>using</c-> <c- n>pointer</c-> <c- o>=</c-> <c- d>/* see below */</c->

  <c- n>retain_ptr</c-> <c- p>(</c-><c- n>pointer</c-><c- p>,</c-> <c- n>retain_object_t</c-><c- p>);</c->
  <c- n>retain_ptr</c-> <c- p>(</c-><c- n>pointer</c-><c- p>,</c-> <c- n>adopt_object_t</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c->
  <c- k>explicit</c-> <c- nf>retain_ptr</c-> <c- p>(</c-><c- n>pointer</c-><c- p>);</c->
  <c- n>retain_ptr</c-> <c- p>(</c-><c- n>nullptr_t</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c->

  <c- n>retain_ptr</c-> <c- p>(</c-><c- n>retain_ptr</c-> <c- k>const</c-><c- o>&amp;</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c->
  <c- n>retain_ptr</c-> <c- p>(</c-><c- n>retain_ptr</c-><c- o>&amp;&amp;</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c->
  <c- n>retain_ptr</c-> <c- p>()</c-> <c- k>noexcept</c-><c- p>;</c->
  <c- o>~</c-><c- n>retain_ptr</c-> <c- p>();</c->

  <c- n>retain_ptr</c-><c- o>&amp;</c-> <c- k>operator</c-> <c- o>=</c-> <c- p>(</c-><c- n>retain_ptr</c-> <c- k>const</c-><c- o>&amp;</c-><c- p>);</c->
  <c- n>retain_ptr</c-><c- o>&amp;</c-> <c- k>operator</c-> <c- o>=</c-> <c- p>(</c-><c- n>retain_ptr</c-><c- o>&amp;&amp;</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c->
  <c- n>retain_ptr</c-><c- o>&amp;</c-> <c- k>operator</c-> <c- o>=</c-> <c- p>(</c-><c- n>nullptr_t</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c->

  <c- b>void</c-> <c- nf>swap</c-> <c- p>(</c-><c- n>retain_ptr</c-><c- o>&amp;</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c->

  <c- k>explicit</c-> <c- k>operator</c-> <c- nf>pointer</c-> <c- p>()</c-> <c- k>const</c-> <c- k>noexcept</c-><c- p>;</c->
  <c- k>explicit</c-> <c- k>operator</c-> <c- nf>bool</c-> <c- p>()</c-> <c- k>const</c-> <c- k>noexcept</c-><c- p>;</c->

  <c- n>element_type</c-><c- o>&amp;</c-> <c- k>operator</c-> <c- o>*</c-> <c- p>()</c-> <c- k>const</c-> <c- k>noexcept</c-><c- p>;</c->
  <c- n>pointer</c-> <c- k>operator</c-> <c- o>-></c-> <c- p>()</c-> <c- k>const</c-> <c- k>noexcept</c-><c- p>;</c->
  <c- n>pointer</c-> <c- nf>get</c-> <c- p>()</c-> <c- k>const</c-> <c- k>noexcept</c-><c- p>;</c->

  <c- b>long</c-> <c- nf>use_count</c-> <c- p>()</c-> <c- k>const</c-><c- p>;</c->

  <c- p>[[</c-><c- n>nodiscard</c-><c- p>]]</c-> <c- n>pointer</c-> <c- n>release</c-> <c- p>()</c-> <c- k>noexcept</c-><c- p>;</c->

  <c- b>void</c-> <c- nf>reset</c-> <c- p>(</c-><c- n>pointer</c-><c- p>,</c-> <c- n>retain_object_t</c-><c- p>);</c->
  <c- b>void</c-> <c- nf>reset</c-> <c- p>(</c-><c- n>pointer</c-><c- p>,</c-> <c- n>adopt_object_t</c-><c- p>);</c->
  <c- b>void</c-> <c- nf>reset</c-> <c- p>(</c-><c- n>pointer</c-> <c- n>p</c-> <c- o>=</c-> <c- n>pointer</c-> <c- p>{</c-> <c- p>});</c->
<c- p>};</c->
</pre>
   <h4 class="heading settled" data-level="7.4.1" id="wording-pointer-ctor"><span class="secno">7.4.1. </span><span class="content"><code class="highlight"><c- n>retain_ptr</c-></code> constructors</span><a class="self-link" href="#wording-pointer-ctor"></a></h4>
   <blockquote>
<pre class="language-cpp highlight"><c- n>retain_ptr</c-> <c- p>(</c-><c- n>pointer</c-> <c- n>p</c-><c- p>,</c-> <c- n>retain_object_t</c-><c- p>);</c->
</pre>
   </blockquote>
   <p><em>Effects</em>: Constructs a <code class="highlight"><c- n>retain_ptr</c-></code> that retains <code class="highlight"><c- n>p</c-></code>, initializing the stored
pointer with <code class="highlight"><c- n>p</c-></code>, and increments the reference count of <code class="highlight"><c- n>p</c-></code> if <code class="highlight"><c- n>p</c-> <c- o>!=</c-> <c- k>nullptr</c-></code> by way of <code class="highlight"><c- n>traits_type</c-><c- o>::</c-><c- n>increment</c-></code>.</p>
   <p><em>Postconditions</em>: <code class="highlight"><c- n>get</c-><c- p>()</c-> <c- o>==</c-> <c- n>p</c-></code></p>
   <p><em>Remarks</em>: If an exception is thrown during increment, this constructor will
have no effect.</p>
   <blockquote>
<pre class="language-cpp highlight"><c- n>retain_ptr</c-> <c- p>(</c-><c- n>pointer</c-> <c- n>p</c-><c- p>,</c-> <c- n>adopt_object_t</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c->
</pre>
   </blockquote>
   <p><em>Effects</em>: Constructs a <code class="highlight"><c- n>retain_ptr</c-></code> that adopts <code class="highlight"><c- n>p</c-></code>, initializing the stored
pointer with <code class="highlight"><c- n>p</c-></code>.</p>
   <p><em>Postconditions</em>: <code class="highlight"><c- n>get</c-><c- p>()</c-> <c- o>==</c-> <c- n>p</c-></code></p>
   <p><em>Remarks</em>: <code class="highlight"><c- n>p</c-></code>'s refrence count remains untouched.</p>
   <blockquote>
<pre class="language-cpp highlight"><c- k>explicit</c-> <c- nf>retain_ptr</c-> <c- p>(</c-><c- n>pointer</c-> <c- n>p</c-><c- p>);</c->
</pre>
   </blockquote>
   <p><em>Effects</em>: Constructs a <code class="highlight"><c- n>retain_ptr</c-></code> by delegating to another <code class="highlight"><c- n>retain_ptr</c-></code> constructor via <code class="highlight"><c- n>traits_type</c-><c- o>::</c-><c- n>default_action</c-></code>. If <code class="highlight"><c- n>traits_type</c-><c- o>::</c-><c- n>default_action</c-></code> does not exist, <code class="highlight"><c- n>retain_ptr</c-></code> is constructed as if by <code class="highlight"><c- n>retain_ptr</c-><c- p>(</c-><c- n>p</c-><c- p>,</c-> <c- n>adopt_object_t</c-><c- p>)</c-></code>.</p>
   <p><em>Postconditions</em>: <code class="highlight"><c- n>get</c-><c- p>()</c-> <c- o>==</c-> <c- n>p</c-></code></p>
   <p><em>Remarks</em>: If an exception is thrown, this constructor will have no effect.</p>
   <blockquote>
<pre class="language-cpp highlight"><c- n>retain_ptr</c-> <c- p>()</c-> <c- k>noexcept</c-><c- p>;</c->
</pre>
   </blockquote>
   <p><em>Effects</em>: Constructs a <code class="highlight"><c- n>retain_ptr</c-></code> object that retains nothing,
value-initializing the stored pointer.</p>
   <p><em>Postconditions</em>: <code class="highlight"><c- n>get</c-><c- p>()</c-> <c- o>==</c-> <c- k>nullptr</c-></code></p>
   <blockquote>
<pre class="language-cpp highlight"><c- n>retain_ptr</c-><c- p>(</c-><c- n>retain_ptr</c-> <c- k>const</c-><c- o>&amp;</c-> <c- n>r</c-><c- p>);</c->
</pre>
   </blockquote>
   <p><em>Effects</em>: Constructs a <code class="highlight"><c- n>retain_ptr</c-></code> by extending management from <code class="highlight"><c- n>r</c-></code> to <code class="highlight"><c- o>*</c-><c- k>this</c-></code>. The stored pointer’s reference count is incremented.</p>
   <p><em>Postconditions</em>: <code class="highlight"><c- n>get</c-><c- p>()</c-> <c- o>==</c-> <c- n>r</c-><c- p>.</c-><c- n>get</c-><c- p>()</c-></code></p>
   <p><em>Remarks</em>: If an exception is thrown, this constructor will have no effect.</p>
   <blockquote>
<pre class="language-cpp highlight"><c- n>retain_ptr</c-><c- p>(</c-><c- n>retain_ptr</c-><c- o>&amp;&amp;</c-> <c- n>r</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c->
</pre>
   </blockquote>
   <p><em>Effects</em>: Constructs a <code class="highlight"><c- n>retain_ptr</c-></code> by transferring management from <code class="highlight"><c- n>r</c-></code> to <code class="highlight"><c- o>*</c-><c- k>this</c-></code>. The stored pointer’s reference count remains untouched.</p>
   <p><em>Postconditions</em>: <code class="highlight"><c- n>get</c-><c- p>()</c-></code> yields the value <code class="highlight"><c- n>r</c-><c- p>.</c-><c- n>get</c-><c- p>()</c-></code> yielded before the
construction.</p>
   <h4 class="heading settled" data-level="7.4.2" id="wording-pointer-dtor"><span class="secno">7.4.2. </span><span class="content"><code class="highlight"><c- n>retain_ptr</c-></code> destructor</span><a class="self-link" href="#wording-pointer-dtor"></a></h4>
   <blockquote>
<pre class="language-cpp highlight"><c- o>~</c-><c- n>retain_ptr</c-><c- p>();</c->
</pre>
   </blockquote>
   <p><em>Effects</em>: If <code class="highlight"><c- n>get</c-><c- p>()</c-> <c- o>==</c-> <c- k>nullptr</c-></code>, there are no effects. Otherwise, <code class="highlight"><c- n>traits_type</c-><c- o>::</c-><c- n>decrement</c-><c- p>(</c-><c- n>get</c-><c- p>())</c-></code>.</p>
   <h4 class="heading settled" data-level="7.4.3" id="wording-pointer-assignment"><span class="secno">7.4.3. </span><span class="content"><code class="highlight"><c- n>retain_ptr</c-></code> assignment</span><a class="self-link" href="#wording-pointer-assignment"></a></h4>
   <blockquote>
<pre class="language-cpp highlight"><c- n>retain_ptr</c-><c- o>&amp;</c-> <c- k>operator</c-> <c- o>=</c-> <c- p>(</c-><c- n>retain_ptr</c-> <c- k>const</c-><c- o>&amp;</c-> <c- n>r</c-><c- p>);</c->
</pre>
   </blockquote>
   <p><em>Effects</em>: Extends ownership from <code class="highlight"><c- n>r</c-></code> to <code class="highlight"><c- o>*</c-><c- k>this</c-></code> as if by calling <code class="highlight"><c- n>reset</c-><c- p>(</c-><c- n>r</c-><c- p>.</c-><c- n>get</c-><c- p>(),</c-> <c- n>retain</c-><c- p>)</c-></code>. <em>Returns</em>: <code class="highlight"><c- o>*</c-><c- k>this</c-></code></p>
   <blockquote>
<pre class="language-cpp highlight"><c- n>retain_ptr</c-><c- o>&amp;</c-> <c- k>operator</c-> <c- o>=</c-> <c- p>(</c-><c- n>retain_ptr</c-><c- o>&amp;&amp;</c-> <c- n>r</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c->
</pre>
   </blockquote>
   <p><em>Effects</em>: Transfers ownership from <code class="highlight"><c- n>r</c-></code> to <code class="highlight"><c- o>*</c-><c- k>this</c-></code> as if by calling <code class="highlight"><c- n>reset</c-><c- p>(</c-><c- n>r</c-><c- p>.</c-><c- n>release</c-><c- p>())</c-></code> <em>Returns</em>: <code class="highlight"><c- o>*</c-><c- k>this</c-></code></p>
   <blockquote>
<pre class="language-cpp highlight"><c- n>retain_ptr</c-><c- o>&amp;</c-> <c- k>operator</c-> <c- o>=</c-> <c- p>(</c-><c- n>nullptr_t</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c->
</pre>
   </blockquote>
   <p><em>Effects</em>: <code class="highlight"><c- n>reset</c-><c- p>()</c-></code> <em>Postconditions</em>: <code class="highlight"><c- n>get</c-><c- p>()</c-> <c- o>==</c-> <c- k>nullptr</c-></code> <em>Returns</em>: <code class="highlight"><c- o>*</c-><c- k>this</c-></code></p>
   <h4 class="heading settled" data-level="7.4.4" id="wording-pointer-observers"><span class="secno">7.4.4. </span><span class="content"><code class="highlight"><c- n>retain_ptr</c-></code> observers</span><a class="self-link" href="#wording-pointer-observers"></a></h4>
   <blockquote>
<pre class="language-cpp highlight"><c- n>element_type</c-><c- o>&amp;</c-> <c- k>operator</c-> <c- o>*</c-> <c- p>()</c-> <c- k>const</c-> <c- k>noexcept</c-><c- p>;</c->
</pre>
   </blockquote>
   <p><em>Requires</em>: <code class="highlight"><c- n>get</c-><c- p>()</c-> <c- o>!=</c-> <c- k>nullptr</c-></code> <em>Returns</em>: <code class="highlight"><c- o>*</c-><c- n>get</c-><c- p>()</c-></code></p>
   <blockquote>
<pre class="language-cpp highlight"><c- n>pointer</c-> <c- k>operator</c-> <c- o>-></c-> <c- p>()</c-> <c- k>const</c-> <c- k>noexcept</c-><c- p>;</c->
</pre>
   </blockquote>
   <p><em>Requires</em>: <code class="highlight"><c- n>get</c-><c- p>()</c-> <c- o>!=</c-> <c- k>nullptr</c-></code> <em>Returns</em>: <code class="highlight"><c- n>get</c-><c- p>()</c-></code> <em>Note</em>: Use typically requires that <code class="highlight"><c- n>element_type</c-></code> be a complete type.</p>
   <blockquote>
<pre class="language-cpp highlight"><c- n>pointer</c-> <c- nf>get</c-> <c- p>()</c-> <c- k>const</c-> <c- k>noexcept</c-><c- p>;</c->
</pre>
   </blockquote>
   <p><em>Returns</em>: The stored pointer</p>
   <blockquote>
<pre class="language-cpp highlight"><c- k>explicit</c-> <c- k>operator</c-> <c- nf>pointer</c-> <c- p>()</c-> <c- k>const</c-> <c- k>noexcept</c-><c- p>;</c->
</pre>
   </blockquote>
   <p><em>Returns</em>: <code class="highlight"><c- n>get</c-><c- p>()</c-></code></p>
   <blockquote>
<pre class="language-cpp highlight"><c- k>explicit</c-> <c- k>operator</c-> <c- nf>bool</c-> <c- p>()</c-> <c- k>const</c-> <c- k>noexcept</c-><c- p>;</c->
</pre>
   </blockquote>
   <p><em>Returns</em>: <code class="highlight"><c- n>get</c-><c- p>()</c-> <c- o>!=</c-> <c- k>nullptr</c-></code></p>
   <blockquote>
<pre class="language-cpp highlight"><c- b>long</c-> <c- nf>use_count</c-> <c- p>()</c-> <c- k>const</c-><c- p>;</c->
</pre>
   </blockquote>
   <p><em>Returns</em>: Value representing the current reference count of the current stored
pointer. If <code class="highlight"><c- n>traits_type</c-><c- o>::</c-><c- n>use_count</c-><c- p>(</c-><c- n>get</c-><c- p>())</c-></code> is not a valid expression, <code class="highlight"><c- o>-</c-><c- mi>1</c-></code> is
returned. If <code class="highlight"><c- n>get</c-><c- p>()</c-> <c- o>==</c-> <c- k>nullptr</c-></code>, <code class="highlight"><c- mi>0</c-></code> is returned.</p>
   <p><em>Remarks</em>: Unless otherwise specified, the value returned should be considered
stale.</p>
   <h4 class="heading settled" data-level="7.4.5" id="wording-pointer-modifiers"><span class="secno">7.4.5. </span><span class="content"><code class="highlight"><c- n>retain_ptr</c-></code> modifiers</span><a class="self-link" href="#wording-pointer-modifiers"></a></h4>
   <blockquote>
<pre class="language-cpp highlight"><c- p>[[</c-><c- n>nodiscard</c-><c- p>]]</c-> <c- n>pointer</c-> <c- n>release</c-> <c- p>()</c-> <c- k>noexcept</c-><c- p>;</c->
</pre>
   </blockquote>
   <p><em>Postconditions</em>: <code class="highlight"><c- n>get</c-><c- p>()</c-> <c- o>==</c-> <c- k>nullptr</c-></code> <em>Returns</em>: The value <code class="highlight"><c- n>get</c-><c- p>()</c-></code> had at the start of the call to <code class="highlight"><c- n>release</c-><c- p>()</c-></code>.</p>
   <blockquote>
<pre class="language-cpp highlight"><c- b>void</c-> <c- nf>reset</c-> <c- p>(</c-><c- n>pointer</c-> <c- n>p</c-><c- p>,</c-> <c- n>retain_object_t</c-><c- p>);</c->
</pre>
   </blockquote>
   <p><em>Effects</em>: Assigns <code class="highlight"><c- n>p</c-></code> to the stored pointer, and then if the old value of
stored pointer <code class="highlight"><c- n>old_p</c-></code>, was not equal to <code class="highlight"><c- k>nullptr</c-></code>, calls <code class="highlight"><c- n>traits_type</c-><c- o>::</c-><c- n>decrement</c-></code>. Then if <code class="highlight"><c- n>p</c-></code> is not equal to <code class="highlight"><c- k>nullptr</c-></code>, <code class="highlight"><c- n>traits_type</c-><c- o>::</c-><c- n>increment</c-></code> is called. <em>Postconditions</em>: <code class="highlight"><c- n>get</c-><c- p>()</c-> <c- o>==</c-> <c- n>p</c-></code></p>
   <blockquote>
<pre class="language-cpp highlight"><c- b>void</c-> <c- nf>reset</c-><c- p>(</c-><c- n>pointer</c-> <c- n>p</c-><c- p>,</c-> <c- n>adopt_object_t</c-><c- p>);</c->
</pre>
   </blockquote>
   <p><em>Effects</em>: Assigns <code class="highlight"><c- n>p</c-></code> to the stored pointer, and then if the old value of
stored pointer <code class="highlight"><c- n>old_p</c-></code>, was not equal to <code class="highlight"><c- k>nullptr</c-></code>, calls <code class="highlight"><c- n>traits_type</c-><c- o>::</c-><c- n>decrement</c-></code>. <em>Postconditions</em>: <code class="highlight"><c- n>get</c-><c- p>()</c-> <c- o>==</c-> <c- n>p</c-></code></p>
   <blockquote>
<pre class="language-cpp highlight"><c- b>void</c-> <c- n>reset</c-> <c- p>(</c-><c- n>pointer</c-> <c- n>p</c-> <c- o>=</c-> <c- n>pointer</c-> <c- p>{</c-> <c- p>})</c->
</pre>
   </blockquote>
   <p><em>Effects</em>: Delegates assignment of <code class="highlight"><c- n>p</c-></code> to the stored pointer via <code class="highlight"><c- n>reset</c-><c- p>(</c-><c- n>p</c-><c- p>,</c-> <c- n>traits_type</c-><c- o>::</c-><c- n>default_action</c-><c- p>())</c-></code>. <em>Postconditions</em>: <code class="highlight"><c- n>get</c-><c- p>()</c-> <c- o>==</c-> <c- n>p</c-></code></p>
   <blockquote>
<pre class="language-cpp highlight"><c- b>void</c-> <c- nf>swap</c-> <c- p>(</c-><c- n>retain_ptr</c-><c- o>&amp;</c-> <c- n>r</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c->
</pre>
   </blockquote>
   <p><em>Effects</em>: Invokes <code class="highlight"><c- n>swap</c-></code> on the stored pointers of <code class="highlight"><c- o>*</c-><c- k>this</c-></code> and <code class="highlight"><c- n>r</c-></code>.</p>
   <h4 class="heading settled" data-level="7.4.6" id="wording-pointer-algorithms"><span class="secno">7.4.6. </span><span class="content"><code class="highlight"><c- n>retain_ptr</c-></code> specialized algorithms</span><a class="self-link" href="#wording-pointer-algorithms"></a></h4>
   <blockquote>
<pre class="language-cpp highlight"><c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- p>,</c-> <c- k>class</c-> <c- nc>R</c-><c- o>></c->
<c- b>void</c-> <c- n>swap</c-> <c- p>(</c-><c- n>retain_ptr</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- n>R</c-><c- o>>&amp;</c-> <c- n>x</c-><c- p>,</c-> <c- n>retain_ptr</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- n>R</c-><c- o>>&amp;</c-> <c- n>y</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c->
</pre>
   </blockquote>
   <p><em>Effects</em>: Calls <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>swap</c-><c- p>(</c-><c- n>y</c-><c- p>)</c-></code></p>
   <blockquote>
<pre class="language-cpp highlight"><c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- p>,</c-> <c- k>class</c-> <c- nc>R</c-><c- o>></c->
<c- k>auto</c-> <c- k>operator</c-> <c- o>&lt;=></c-> <c- p>(</c-><c- n>retain_ptr</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- n>R</c-><c- o>></c-> <c- k>const</c-><c- o>&amp;</c-><c- p>,</c-> <c- n>retain_ptr</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- n>R</c-><c- o>></c-> <c- k>const</c-><c- o>&amp;</c-><c- p>)</c-> <c- k>noexcept</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c->
</pre>
   </blockquote>
   <p><em>Returns</em>: <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>get</c-><c- p>()</c-> <c- o>&lt;=></c-> <c- n>y</c-><c- p>.</c-><c- n>get</c-><c- p>()</c-></code></p>
   <blockquote>
<pre class="language-cpp highlight"><c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- p>,</c-> <c- k>class</c-> <c- nc>R</c-><c- o>></c->
<c- k>auto</c-> <c- k>operator</c-> <c- o>&lt;=></c-> <c- p>(</c-><c- n>retain_ptr</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- n>R</c-><c- o>></c-> <c- k>const</c-><c- o>&amp;</c-><c- p>,</c-> <c- n>nullptr_t</c-><c- p>)</c-> <c- k>noexcept</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c->
</pre>
   </blockquote>
   <p><em>Returns</em>: <code class="highlight"><c- n>x</c-><c- p>.</c-><c- n>get</c-><c- p>()</c-> <c- o>&lt;=></c-> <c- k>nullptr</c-></code></p>
   <blockquote>
<pre class="language-cpp highlight"><c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- p>,</c-> <c- k>class</c-> <c- nc>R</c-><c- o>></c->
<c- n>strong_ordering</c-> <c- k>operator</c-> <c- o>&lt;=></c-> <c- p>(</c-><c- n>nullptr_t</c-><c- p>,</c-> <c- n>retain_ptr</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- n>R</c-><c- o>></c-> <c- k>const</c-><c- o>&amp;</c-> <c- n>y</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c->
</pre>
   </blockquote>
   <p><em>Returns</em>: <code class="highlight"><c- k>nullptr</c-> <c- o>&lt;=></c-> <c- n>y</c-><c- p>.</c-><c- n>get</c-><c- p>()</c-></code></p>
  </main>
<script>
(function() {
  "use strict";
  var collapseSidebarText = '<span aria-hidden="true">←</span> '
                          + '<span>Collapse Sidebar</span>';
  var expandSidebarText   = '<span aria-hidden="true">→</span> '
                          + '<span>Pop Out Sidebar</span>';
  var tocJumpText         = '<span aria-hidden="true">↑</span> '
                          + '<span>Jump to Table of Contents</span>';

  var sidebarMedia = window.matchMedia('screen and (min-width: 78em)');
  var autoToggle   = function(e){ toggleSidebar(e.matches) };
  if(sidebarMedia.addListener) {
    sidebarMedia.addListener(autoToggle);
  }

  function toggleSidebar(on) {
    if (on == undefined) {
      on = !document.body.classList.contains('toc-sidebar');
    }

    /* Don’t scroll to compensate for the ToC if we’re above it already. */
    var headY = 0;
    var head = document.querySelector('.head');
    if (head) {
      // terrible approx of "top of ToC"
      headY += head.offsetTop + head.offsetHeight;
    }
    var skipScroll = window.scrollY < headY;

    var toggle = document.getElementById('toc-toggle');
    var tocNav = document.getElementById('toc');
    if (on) {
      var tocHeight = tocNav.offsetHeight;
      document.body.classList.add('toc-sidebar');
      document.body.classList.remove('toc-inline');
      toggle.innerHTML = collapseSidebarText;
      if (!skipScroll) {
        window.scrollBy(0, 0 - tocHeight);
      }
      tocNav.focus();
      sidebarMedia.addListener(autoToggle); // auto-collapse when out of room
    }
    else {
      document.body.classList.add('toc-inline');
      document.body.classList.remove('toc-sidebar');
      toggle.innerHTML = expandSidebarText;
      if (!skipScroll) {
        window.scrollBy(0, tocNav.offsetHeight);
      }
      if (toggle.matches(':hover')) {
        /* Unfocus button when not using keyboard navigation,
           because I don’t know where else to send the focus. */
        toggle.blur();
      }
    }
  }

  function createSidebarToggle() {
    /* Create the sidebar toggle in JS; it shouldn’t exist when JS is off. */
    var toggle = document.createElement('a');
      /* This should probably be a button, but appearance isn’t standards-track.*/
    toggle.id = 'toc-toggle';
    toggle.class = 'toc-toggle';
    toggle.href = '#toc';
    toggle.innerHTML = collapseSidebarText;

    sidebarMedia.addListener(autoToggle);
    var toggler = function(e) {
      e.preventDefault();
      sidebarMedia.removeListener(autoToggle); // persist explicit off states
      toggleSidebar();
      return false;
    }
    toggle.addEventListener('click', toggler, false);


    /* Get <nav id=toc-nav>, or make it if we don’t have one. */
    var tocNav = document.getElementById('toc-nav');
    if (!tocNav) {
      tocNav = document.createElement('p');
      tocNav.id = 'toc-nav';
      /* Prepend for better keyboard navigation */
      document.body.insertBefore(tocNav, document.body.firstChild);
    }
    /* While we’re at it, make sure we have a Jump to Toc link. */
    var tocJump = document.getElementById('toc-jump');
    if (!tocJump) {
      tocJump = document.createElement('a');
      tocJump.id = 'toc-jump';
      tocJump.href = '#toc';
      tocJump.innerHTML = tocJumpText;
      tocNav.appendChild(tocJump);
    }

    tocNav.appendChild(toggle);
  }

  var toc = document.getElementById('toc');
  if (toc) {
    createSidebarToggle();
    toggleSidebar(sidebarMedia.matches);

    /* If the sidebar has been manually opened and is currently overlaying the text
       (window too small for the MQ to add the margin to body),
       then auto-close the sidebar once you click on something in there. */
    toc.addEventListener('click', function(e) {
      if(e.target.tagName.toLowerCase() == "a" && document.body.classList.contains('toc-sidebar') && !sidebarMedia.matches) {
        toggleSidebar(false);
      }
    }, false);
  }
  else {
    console.warn("Can’t find Table of Contents. Please use <nav id='toc'> around the ToC.");
  }

  /* Wrap tables in case they overflow */
  var tables = document.querySelectorAll(':not(.overlarge) > table.data, :not(.overlarge) > table.index');
  var numTables = tables.length;
  for (var i = 0; i < numTables; i++) {
    var table = tables[i];
    var wrapper = document.createElement('div');
    wrapper.className = 'overlarge';
    table.parentNode.insertBefore(wrapper, table);
    wrapper.appendChild(table);
  }

})();
</script>
  <h2 class="no-num no-ref heading settled" id="references"><span class="content">References</span><a class="self-link" href="#references"></a></h2>
  <h3 class="no-num no-ref heading settled" id="informative"><span class="content">Informative References</span><a class="self-link" href="#informative"></a></h3>
  <dl>
   <dt id="biblio-implementation">[IMPLEMENTATION]
   <dd>Isabella Muerte. <a href="https://github.com/slurps-mad-rips/retain-ptr">retain_ptr</a>. URL: <a href="https://github.com/slurps-mad-rips/retain-ptr">https://github.com/slurps-mad-rips/retain-ptr</a>
   <dt id="biblio-p1132">[P1132]
   <dd>JeanHeyd Meneide; Todor Buyukliev; Isabella Muerte. <a href="https://wg21.link/p1132r0">out_ptr - a scalable output pointer abstraction</a>. URL: <a href="https://wg21.link/p1132r0">https://wg21.link/p1132r0</a>
  </dl>
