<!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>P1207R0: Movability of Single-pass Iterators</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>
  <meta content="Bikeshed version a04b880cde96bf0ae2d14a0edcf2bcdcb631548b" name="generator">
  <link href="https://isocpp.org/favicon.ico" rel="icon">
  <meta content="e3e09cd9810b42abeb4c1e4ff5750d71393fe29f" name="document-revision">
<style>

.tony-table table {
    width:100%;
}

.tony-table th {
    text-align: center;
    padding-right:20px;
}

.tony-table  td {
    vertical-align:top;
}

.wording-add {
    background-color: #F6F9ED;
}


/* Table */
.data-table {
	border-collapse: collapse;
	font-size: 14px;
	min-width: 573px;
}
.data-table th {
	color: #5a5a5a;
}

.data-table th,
.data-table td {
	padding: 7px 17px;
}
.data-table caption {
	margin: 7px;
}

/* Table Header */
.data-table thead th {
    border-bottom: 2px solid #CCCCCC;
}

/* Table Body */
.data-table tbody td {
	color: #353535;
	border-bottom: 1px solid #dcdcdc;
	text-align: right;
}

.data-table tbody tr:last-child td {
	border: 0;
}

.data-table tbody tr:hover td {
	background-color: #f7f7f7;
	transition: all .2s;
}

/* Table Footer */
.data-table tfoot th {
	border-top: 1px solid #c7c7c7;
	text-align: right;
}

.array_row {
    outline: thin solid #008000
}

</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">P1207R0<br>Movability of Single-pass Iterators</h1>
   <h2 class="no-num no-toc no-ref heading settled" id="subtitle"><span class="content">Published Proposal, <time class="dt-updated" datetime="2018-08-20">2018-08-20</time></span></h2>
   <div data-fill-with="spec-metadata">
    <dl>
     <dt>Author:
     <dd>
      <dd class="editor p-author h-card vcard"><a class="p-name fn u-email email" href="mailto:corentin.jabot@gmail.com">Corentin Jabot</a>
     <dt>Audience:
     <dd>LEWG
     <dt>Project:
     <dd>ISO/IEC JTC1/SC22/WG21 14882: Programming Language — C++
    </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>We propose move-only non-forward iterators in the ranges namespace along with a refined, tag-less iterator taxonomy with the express intent to increase safety and expressiveness of programmes handling input iterators.</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="#introduction"><span class="secno">1</span> <span class="content">Introduction</span></a>
    <li><a href="#terminology"><span class="secno">2</span> <span class="content">Terminology</span></a>
    <li>
     <a href="#scope"><span class="secno">3</span> <span class="content">Scope</span></a>
     <ol class="toc">
      <li><a href="#non-goal"><span class="secno">3.1</span> <span class="content">Non-Goal</span></a>
     </ol>
    <li>
     <a href="#motivation"><span class="secno">4</span> <span class="content">Motivation</span></a>
     <ol class="toc">
      <li><a href="#move-only-state"><span class="secno">4.1</span> <span class="content">Move-only state</span></a>
      <li><a href="#implicitly-destructive-operations"><span class="secno">4.2</span> <span class="content">Implicitly destructive operations</span></a>
      <li><a href="#performance-optimization"><span class="secno">4.3</span> <span class="content">Performance optimization</span></a>
     </ol>
    <li><a href="#what-is-a-move-only-iterator"><span class="secno">5</span> <span class="content">What is a move-only iterator?</span></a>
    <li>
     <a href="#a-holistic-approach-to-iterators"><span class="secno">6</span> <span class="content">A Holistic Approach to Iterators</span></a>
     <ol class="toc">
      <li>
       <a href="#an-holistic-approach-to-iterator-tags-and-iterator-concepts"><span class="secno">6.1</span> <span class="content">An Holistic Approach to Iterator Tags and Iterator Concepts</span></a>
       <ol class="toc">
        <li><a href="#tags-as-an-opt-in-opt-out-mechanism"><span class="secno">6.1.1</span> <span class="content">Tags as an opt-in opt-out mechanism</span></a>
       </ol>
     </ol>
    <li>
     <a href="#q-a"><span class="secno">7</span> <span class="content">Q/A</span></a>
     <ol class="toc">
      <li><a href="#non-regular-iterators-really"><span class="secno">7.1</span> <span class="content">Non-regular iterators, really?</span></a>
      <li><a href="#what-about-equality-of-input-iterators"><span class="secno">7.2</span> <span class="content">What about Equality of Input Iterators?</span></a>
      <li><a href="#but-moved-from-objects-are-still-objects"><span class="secno">7.3</span> <span class="content">But... Moved-from objects are still objects!</span></a>
      <li><a href="#does-iterators-default-constructability-needs-revisiting"><span class="secno">7.4</span> <span class="content">Does iterators default-constructability needs revisiting?</span></a>
      <li><a href="#what-about-p0902r0"><span class="secno">7.5</span> <span class="content">What about <span>[P0902R0]</span>?</span></a>
      <li><a href="#why-do-you-want-to-take-my-copyable-inputiterators-away-from-me-i-like-them"><span class="secno">7.6</span> <span class="content">Why do you want to take my Copyable InputIterators away from me, I like them?!</span></a>
      <li><a href="#will-this-break-existing-code"><span class="secno">7.7</span> <span class="content">Will this break existing code ?!</span></a>
      <li><a href="#wont-that-implicit-categorization-lead-to-miss-categorization"><span class="secno">7.8</span> <span class="content">Won’t that implicit categorization lead to miss-categorization?</span></a>
      <li><a href="#post-increment-on-non-copyable-iterators"><span class="secno">7.9</span> <span class="content">Post Increment on non-copyable iterators</span></a>
     </ol>
    <li><a href="#questions-for-lewg"><span class="secno">8</span> <span class="content">Questions for LEWG</span></a>
    <li>
     <a href="#list-of-proposed-changes"><span class="secno">9</span> <span class="content">List of proposed changes</span></a>
     <ol class="toc">
      <li>
       <a href="#changes-to-iterator"><span class="secno">9.1</span> <span class="content">Changes to &lt;iterator></span></a>
       <ol class="toc">
        <li><a href="#weaklyincrementable"><span class="secno">9.1.1</span> <span class="content">WeaklyIncrementable</span></a>
        <li><a href="#iterator"><span class="secno">9.1.2</span> <span class="content">Iterator</span></a>
        <li><a href="#inputiterator"><span class="secno">9.1.3</span> <span class="content">InputIterator</span></a>
        <li><a href="#forwarditerator"><span class="secno">9.1.4</span> <span class="content"><code class="highlight"><c- n>ForwardIterator</c-></code></span></a>
        <li><a href="#outputiterator"><span class="secno">9.1.5</span> <span class="content">OutputIterator</span></a>
        <li><a href="#contiguousiterator"><span class="secno">9.1.6</span> <span class="content">ContiguousIterator</span></a>
       </ol>
      <li>
       <a href="#changes-to-ranges"><span class="secno">9.2</span> <span class="content">Changes to &lt;ranges></span></a>
       <ol class="toc">
        <li><a href="#views"><span class="secno">9.2.1</span> <span class="content">Views</span></a>
        <li>
         <a href="#inserters"><span class="secno">9.2.2</span> <span class="content">Inserters</span></a>
         <ol class="toc">
          <li><a href="#back_insert_iterator"><span class="secno">9.2.2.1</span> <span class="content">back_insert_iterator</span></a>
          <li><a href="#front_insert_iterator"><span class="secno">9.2.2.2</span> <span class="content">front_insert_iterator</span></a>
          <li><a href="#insert_iterator"><span class="secno">9.2.2.3</span> <span class="content">insert_iterator</span></a>
         </ol>
       </ol>
      <li>
       <a href="#changes-to-algorithms"><span class="secno">9.3</span> <span class="content">Changes to &lt;algorithms></span></a>
       <ol class="toc">
        <li><a href="#rangescopy"><span class="secno">9.3.1</span> <span class="content"><code class="highlight"><c- n>ranges</c-><c- o>::</c-><c- n>copy</c-></code></span></a>
       </ol>
     </ol>
    <li>
     <a href="#impact-on-other-proposals"><span class="secno">10</span> <span class="content">Impact on other proposals</span></a>
     <ol class="toc">
      <li><a href="#view-proposals"><span class="secno">10.1</span> <span class="content">View proposals</span></a>
      <li><a href="#iterator-facade"><span class="secno">10.2</span> <span class="content">Iterator facade</span></a>
      <li><a href="#acknowledgments"><span class="secno">10.3</span> <span class="content">Acknowledgments</span></a>
     </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>
   <div style="text-align:right"><em>I want to move(it), move(it), y’all want to move(it); </em></div>
   <h2 class="heading settled" data-level="1" id="introduction"><span class="secno">1. </span><span class="content">Introduction</span><a class="self-link" href="#introduction"></a></h2>
   <p>Non-forward Input iterators and output iterators, also known as "Single-pass iterators" are semantically move-only.
The standard states:</p>
   <p class="note" role="note"><span>Note:</span> For input iterators, a == b does not imply ++a == ++b (Equality does not guarantee the substitution property or referential transparency.)
Algorithms on input iterators should never attempt to pass through the same iterator twice. They should be single pass algorithms.</p>
   <p>This means that once an iterator is copied, only one of the copies can meaningfully be used.
Deferencing multiple copies of a single pass iterator often exposes undefined or invalid behavior.</p>
   <p>It would, therefore, make sense that classes satisfying the <code class="highlight"><c- n>InputIterator</c-></code> concept shall only be required to be movable.</p>
   <p>Alas, Single-pass iterators and many classes satisfying its requirements predate C++11, they do therefore have move only semantic with copy syntax.
In that regard, they are similar to <code class="highlight"><c- n>auto_ptr</c-></code>.</p>
   <h2 class="heading settled" data-level="2" id="terminology"><span class="secno">2. </span><span class="content">Terminology</span><a class="self-link" href="#terminology"></a></h2>
   <p>This paper redefines the requirements of some concepts proposed by the Ranges TS (and the deep merge proposal).
In the rest of this paper</p>
   <ul>
    <li data-md>
     <p><code class="highlight"><c- n>InputIterator</c-></code> designs the <code class="highlight"><c- n>InputIterator</c-></code> concept as proposed by this paper</p>
    <li data-md>
     <p><code class="highlight"><c- n>RangesTSInputIterator</c-></code> designs the <code class="highlight"><c- n>InputIterator</c-></code> concept as proposed by the Ranges TS</p>
    <li data-md>
     <p><code class="highlight"><c- n>Cpp17InputIterator</c-></code> design the <strong>requirements</strong> of input iterators compatible with the STL as specified by the C++17 standard</p>
    <li data-md>
     <p><code class="highlight"><c- n>OutputIterator</c-></code> designs the <code class="highlight"><c- n>OutputIterator</c-></code> concept as proposed by this paper</p>
    <li data-md>
     <p><code class="highlight"><c- n>RangesTSOutputIterator</c-></code> designs the <code class="highlight"><c- n>OutputIterator</c-></code> concept as proposed by the Ranges TS</p>
    <li data-md>
     <p><code class="highlight"><c- n>Cpp17OutputIterator</c-></code> design the <strong>requirements</strong> of output iterators compatible with the STL as specified by the C++17 standard</p>
   </ul>
   <h2 class="heading settled" data-level="3" id="scope"><span class="secno">3. </span><span class="content">Scope</span><a class="self-link" href="#scope"></a></h2>
   <p>This paper proposes changes to the Ranges TS and <a data-link-type="biblio" href="#biblio-p0896r2">[P0896R2]</a> both targeting C++20. Because the modifications proposed here changes some requirements and concepts as presented
by <a data-link-type="biblio" href="#biblio-p0896r2">[P0896R2]</a>, the authors strongly suggest they are considered for the inclusion in the same version of the standard.
Indeed, <a data-link-type="biblio" href="#biblio-p0896r2">[P0896R2]</a> gives us a unique opportunity to make the modifications proposed, as they might, in some cases, break code, if introduced after the publication
of C++20 (with ranges).</p>
   <h3 class="heading settled" data-level="3.1" id="non-goal"><span class="secno">3.1. </span><span class="content">Non-Goal</span><a class="self-link" href="#non-goal"></a></h3>
   <p>As a large amount of code depends on the Input/Output iterators requirements as specified by C++17, this paper does not propose any modifications to the <code class="highlight"><c- n>Cpp17InputIterator</c-></code> or
any class that depends on it.
Specifically, we do not propose to change the requirements or wording of <code class="highlight"><c- n>istream_iterator</c-></code>, <code class="highlight"><c- n>ostream_iterator</c-></code>, <code class="highlight"><c- n>istreambuf_iterator</c-></code> or <code class="highlight"><c- n>ostreambuf_iterator</c-></code>.
Furthermore, we do not propose modifications to algorithms in the namespace <code class="highlight"><c- n>std</c-></code>. The new iterators we propose here are in fact mostly incompatible with existing algorithms.
They are meant to be used in the <code class="highlight"><c- n>ranges</c-></code> namespace and as basic building blocks of range-based views.</p>
   <p>While the ability to use move-only iterators with the algorithms defined in the <code class="highlight"><c- n>std</c-></code> namespace would certainly be welcomed, doing so would weaken the <code class="highlight"><c- n>RangesTSInputIterator</c-></code> concept and leads to other issues (namely, <code class="highlight"><c- n>std</c-></code> based algorithms require iterators to be <code class="highlight"><c- n>EqualityComparable</c-></code>, which the <code class="highlight"><c- n>RangesTSInputIterator</c-></code> is not).</p>
   <p>In practice, that means that types satisfying the <code class="highlight"><c- n>Cpp17InputIterator</c-></code> requirements continue to work unaffected with algorithms defined in the <code class="highlight"><c- n>std</c-></code> namespace. They may not be compatible with algorithms defined in the ranges namespace, or with new code using the <code class="highlight"><c- n>InputIterator</c-></code> concept as proposed here.</p>
   <p>Inversely, types satisfying the <code class="highlight"><c- n>InputIterator</c-></code> concepts may not be compatible with algorithms in <code class="highlight"><c- n>std</c-></code> as they may not be able to satisfy the <code class="highlight"><c- n>Cpp17InputIterator</c-></code> requirements.</p>
   <p>Because it hardly makes sense to copy an Input Iterator (more on that later), it would be possible to add support for move-only iterators to the <code class="highlight"><c- n>std</c-></code> namespace without much change to the standard.
However, because implementers may copy iterators within the implementation of the standard library, along with existing third-party libraries, a lot of code would need to be adapted.
And there is little pressure to do so as existing iterators types cannot be changed.</p>
   <h2 class="heading settled" data-level="4" id="motivation"><span class="secno">4. </span><span class="content">Motivation</span><a class="self-link" href="#motivation"></a></h2>
   <h3 class="heading settled" data-level="4.1" id="move-only-state"><span class="secno">4.1. </span><span class="content">Move-only state</span><a class="self-link" href="#move-only-state"></a></h3>
   <p>It may be desirable for an iterator to hold a move-only object, becoming itself move-only, which is not possible with iterators modeling Cpp17Iterator.
A real-world example of such iterator is described in <a data-link-type="biblio" href="#biblio-p0902r0">[P0902R0]</a>.
While syntactically copyable in the current design, a <code class="highlight"><c- n>coroutine_handle</c-></code> such as used by a <code class="highlight"><c- n>generator</c-></code> input iterator ought to be move-only.</p>
   <h3 class="heading settled" data-level="4.2" id="implicitly-destructive-operations"><span class="secno">4.2. </span><span class="content">Implicitly destructive operations</span><a class="self-link" href="#implicitly-destructive-operations"></a></h3>
   <p>Reading from an input sequence is a destructive operation. But that destruction is reflected nowhere in the API.
Less experienced developers may not be aware of the destructive / single-pass nature of non-forward Iterators
By making <code class="highlight"><c- n>InputIterator</c-></code> move only, developers will have to explicitly move them, which both signals the invalidation
of the move-from object, but, more importantly, that the underlying data will be destroyed.</p>
   <h3 class="heading settled" data-level="4.3" id="performance-optimization"><span class="secno">4.3. </span><span class="content">Performance optimization</span><a class="self-link" href="#performance-optimization"></a></h3>
   <p>Move-only iterators are an optimization opportunity.
For example, in the presence of <code class="highlight"><c- n>InputIterator</c-></code>s, <code class="highlight"><c- n>ranges</c-><c- o>::</c-><c- n>copy</c-></code> could perform a move rather than a copy of the elements since iteration is destructive.
We will explore more of these opportunities later on.</p>
   <h2 class="heading settled" data-level="5" id="what-is-a-move-only-iterator"><span class="secno">5. </span><span class="content">What is a move-only iterator?</span><a class="self-link" href="#what-is-a-move-only-iterator"></a></h2>
   <p>Unlike <a data-link-type="biblio" href="#biblio-p0902r0">[P0902R0]</a>, we do not propose to introduce a new iterator category.</p>
   <p>A move-only Iterator is a non-forward iterator (either input or output depending on whether is it writable).
This means that a move-only iterator has <em>almost</em> the same semantic requirements as an <code class="highlight"><c- n>InputIterator</c-></code>,
and offers the same operations.
In other words, everything that can be expressed and done with a <code class="highlight"><c- n>RangesTSInputIterator</c-></code> can
be equally expressed and done with a move-only/non-copyable <code class="highlight"><c- n>InputIterator</c-></code>.</p>
   <p>Therefore, this paper does not propose to introduce a new iterator category,
new named-requirement, concept name or iterator tag.</p>
   <p>Furthermore, there is no <code class="highlight"><c- n>ForwardIterator</c-></code> that is only movable, as a <code class="highlight"><c- n>ForwardIterator</c-></code> is by definition
an iterator that can be copied. We will expand on this later.</p>
   <h2 class="heading settled" data-level="6" id="a-holistic-approach-to-iterators"><span class="secno">6. </span><span class="content">A Holistic Approach to Iterators</span><a class="self-link" href="#a-holistic-approach-to-iterators"></a></h2>
   <p>While the first part of this paper focuses on making move-only iterators possible, as means to get some code to compile,
it is important to take a step back and to think about what movability means for Iterators, from first principles.</p>
   <p>An iterator denotes a position into a sequence of elements (whether that sequence maps to memory or not is, for our purpose, irrelevant).</p>
   <p>A most basic iterator can be incremented, which means it can move to the next position in the sequence.
An iterator does not own the sequence iterated over (there are exceptions, ie: generators), which means the salient property of an iterator is its position in that sequence.</p>
   <p>In fact, in Elements of Programming <a data-link-type="biblio" href="#biblio-eop">[EOP]</a>, an iterator is exactly defined by its distance from the start of the
sequence.</p>
   <p>Iterators categories then represent the way an iterator can move along that sequence.</p>
   <ul>
    <li data-md>
     <p>Input and FordwardIterator: sequentially, one direction</p>
    <li data-md>
     <p>BidirectionalIterator: sequentially, both directions</p>
    <li data-md>
     <p>RandomAccess: both directions in O(1)</p>
   </ul>
   <p>ContiguousIterator is an optimization of RandomAccessIterator specific to the C++ memory model that
further, constrain the underlying sequence to be laid out contiguously in memory.</p>
   <p>Stepanov theorized an additional category, "Index iterator", which has O(1) access
but in a single direction.</p>
   <p>Further work was made on iterator categories, notably the Boost.Iterator library
focused on separating traversal (how the iterator moves along the sequence) from
access (whether dereferencing an iterator allows the pointed element to be read, written or both).
While a very interesting concept, it falls outside the scope of this paper.
Just keep in mind that everything that applies to non-forward <code class="highlight"><c- n>InputIterator</c-></code> usually
applies to OutputIterator - which are always non-Forward, the standard lacking that symmetry between
read access and write access.</p>
   <p>However, focusing on traversal, the set of iterators categories is actually
rather closed, there are only so many ways a sequence can be traversed. An
important point of Stepanov design is that each category is a refinement of the preceeding one. <code class="highlight"><c- n>RandomAccessIterator</c-></code> is a <code class="highlight"><c- n>BidirectionalIterator</c-></code> which in turn is a <code class="highlight"><c- n>ForwardIterator</c-></code>.
Every algorithm applicable to a <code class="highlight"><c- n>ForwardIterator</c-></code> can be equally applied to a <code class="highlight"><c- n>BidirectionalIterator</c-></code>, etc.</p>
   <p>So, what separates <code class="highlight"><c- n>InputIterator</c-></code> from <code class="highlight"><c- n>ForwardIterator</c-></code> if they are both "forward" in that they can
both traverse a sequence in one direction?</p>
   <p><code class="highlight"><c- n>ForwardIterator</c-></code> is defined as being "multi-pass". Meaning it can traverse a sequence multiple times.
That, in turn, implies <code class="highlight"><c- n>ForwardIterator</c-></code> is copyable, because if a sequence can be traversed multiple times,
it can also be traversed multiple times at the same time and therefore there can be multiple <code class="highlight"><c- n>ForwardIterator</c-></code> pointing at different elements in the sequence.
ForwardIterator is also always <code class="highlight"><c- n>EquallyComparable</c-></code>.
Two <code class="highlight"><c- n>ForwardIterator</c-></code> compare equal if they point to the same elements in the sequence (remember, that in the general case, the position of an iterator in a sequence is its sole salient property).
And so <code class="highlight"><c- n>ForwardIterator</c-></code>, being both <code class="highlight"><c- n>EquallyComparable</c-></code> and <code class="highlight"><c- n>Copyable</c-></code> is Regular.</p>
   <p>The standard defines the "multi pass" guarantee by stating: <em></em></p>
   <em> </em>
   <blockquote>
    <em> </em>
    <p><em>a == b implies ++a == ++b <br> Given X is a pointer type or the expression (void)++X(a), <em>a is equivalent to the expression </em>a. </em></p>
   </blockquote>
   <p>In other words:
Two identical objects to which is applied the same transformation are identical.
Copying a <code class="highlight"><c- n>FordwardIterator</c-></code> copies the salient properties of that value and incrementing it does
not modify the underlying sequence.
So <code class="highlight"><c- n>ForwardIterator</c-></code> is required to be a regular type behaving like a regular type.</p>
   <p>Which bring us to <code class="highlight"><c- n>InputIterator</c-></code>.
InputIterator is a "single pass" iterator. The underlying sequence can on only be traversed once.
The existence of an Iterator at the nth position in the sequence implies there can be no valid iterator at the position n-1 in that same sequence.</p>
<pre class="highlight"><c- c1>//Given an InputIterator a</c->
<c- n>b</c-> <c- o>=</c-> <c- n>a</c-><c- p>;</c->
<c- n>a</c-><c- o>++</c-><c- p>;</c->
<c- n>b</c-><c- p>;</c-> <c- c1>// is invalid.</c->
</pre>
   <p>However, remember that the sole salient property of an iterator is its distance to the start of the sequence.
Incrementing an iterator only mutates that property (again, conceptually, independently of implementation).
And the only operation that mutates that property is the increment operation (which Stepanov calls <code class="highlight"><c- n>successor</c-></code>).</p>
   <p>This implies that as a non-forward iterator moves from one element of the sequence to the next,
that element is destroyed.</p>
   <p>All of this is well known and is basically rephrasing "Input iterators are single pass".</p>
   <p>An important point to make is that how an iterator can traverse a sequence is derived from the nature of the sequence
rather than from the iterator itself.
The point could be made that there is no such thing as an "Input iterator" Or a "Forward Iterator" because what we really
mean is "Iterator over an Input Sequence" or "Iterator over a Forward Sequence".</p>
   <p>This is saying that, to be able to reason properly about iterators and traversal,
we must assume that the iterator type associated with a sequence is the most specialized possible for that sequence.</p>
   <p>The problem is, of course, that we do not have, in the general case, a more meaningful way to express the traversability
of a sequence than by defining what type of iterator is used to iterate over it.</p>
   <p>It is then the responsibility of the developer providing the sequence to
define the most appropriate -- the most specialized -- iterator for that sequence.</p>
   <p>In practice, because <code class="highlight"><c- n>InputIterator</c-></code> and <code class="highlight"><c- n>ForwardIterator</c-></code> are syntactically identical and because of the single-pass / multi-passes guarantees are poorly taught,
it is common for iterators to be miss-categorized.
Other iterator categories do not have these problems as each subsequent refining category adds syntax requirements:
BidirectionalIiterator require decrement operators, RandomAccessIterator further requires more methods, etc.
And while ContiguousIterator is currently not syntactically differentiated from RandomAccessIterator,
it would be possible to require that ContiguousIterator be convertible to a pointer of the type of the underlying sequence’s
elements.</p>
   <p>But then, is there a set of operations and semantic requirements, translating to actual C++ syntax, that could allow for
InputIterator to be easily distinguished from each other?
Can we avoid requiring a tag system?
Is there a defining operation that distinguishes <code class="highlight"><c- n>InputIterator</c-></code> from <code class="highlight"><c- n>ForwardIterator</c-></code> in such a way that it would both not require
an explicit category tagging while at the same time offering a better understanding of iterator categories as well as a less surprising and
safer API for non-forward iterators?</p>
   <p>In fact, there is. We established that <code class="highlight"><c- n>ForwardIterator</c-></code> are semantically copyable, while <code class="highlight"><c- n>InputIterator</c-></code>s are not.
So the requirement that promotes an <code class="highlight"><c- n>InputIterator</c-></code> into a <code class="highlight"><c- n>ForwardIterator</c-></code> is indeed copyability - which translate in C++ to a copy constructor.
We can, therefore, consider that, in the absence of a tag, all non-copyable iterators are <code class="highlight"><c- n>InputIterator</c-></code>,
while all copyable iterators are <code class="highlight"><c- n>ForwardIterator</c-></code>.</p>
   <p>This model, however, deviates slightly from Stepanov’s work and <code class="highlight"><c- n>Cpp17InputIterator</c-></code>:
Copying a <code class="highlight"><c- n>Cpp17InputIterator</c-></code> does not invalidate either copy.
In fact it is quite valid to deference multiple copies of a <code class="highlight"><c- n>Cpp17InputIterator</c-></code>.</p>
   <p>Elements Of Programming has the notion of <code class="highlight"><c- n>Regular</c-></code> types (and in Stepanov’s work all Iterators are regular), but also the notion of regular transformations
(aka pure functions) - which, given the same input, always give the same output.
Given a <code class="highlight"><c- n>ForwardIterator</c-></code> <code class="highlight"><c- n>fi</c-></code>, there is a <code class="highlight"><c- n>successor</c-></code> function returning an incremented copy of <code class="highlight"><c- n>fi</c-></code> such as <code class="highlight"><c- n>sucessor</c-><c- p>(</c-><c- n>fi</c-><c- p>)</c-> <c- o>==</c-> <c- n>sucessor</c-><c- p>(</c-><c- n>fi</c-><c- p>)</c-></code>.
In C++, that regular <code class="highlight"><c- n>sucessor</c-></code> function is <code class="highlight"><c- n>ForwardIterator</c-><c- o>::</c-><c- k>operator</c-><c- o>++</c-><c- p>(</c-><c- b>int</c-><c- p>);</c-></code>, in that <code class="highlight"><c- p>(</c-><c- n>it</c-><c- o>++</c-><c- p>)</c-> <c- o>==</c-> <c- p>(</c-><c- n>it</c-><c- o>++</c-><c- p>)</c-></code> for any given <code class="highlight"><c- n>ForwardIterator</c-></code>.</p>
   <p>For <code class="highlight"><c- n>InputIterator</c-></code>, Stepanov specifies that the <code class="highlight"><c- n>successor</c-></code> is a pseudo transformation or a non-regular transformation that look like a regular one.
And therein lies the rub.</p>
   <p>Like a pointer, <code class="highlight"><c- n>InputIterator</c-></code> is Regular, up until the point a transformation of an instance affects all copies.</p>
<pre class="highlight"><c- n>InputIterator</c-> <c- n>i</c-> <c- o>=</c-> <c- d>/*...*/</c->
<c- o>*</c-><c- n>i</c->    <c- c1>//ok</c->
<c- n>a</c-> <c- o>=</c-> <c- n>i</c-> <c- c1>//ok</c->
<c- o>*</c-><c- n>i</c->    <c- c1>//ok</c->
<c- n>i</c-><c- o>++</c-><c- p>;</c->  <c- c1>// a now invalid</c->
</pre>
   <p>This design accurately models the nature of iterators. Because an iterator represents a position in a sequence, it is natural that multiple iterators could point
to the same position.
After one copy is incremented, in Stepanov’s model, other copies are in a partially formed state and cannot be used (but they can be assigned to, or destroyed).</p>
   <p>Let’s consider the case where we move from an iterator instead of copying it</p>
<pre class="highlight"><c- n>InputIterator</c-> <c- n>i</c-> <c- o>=</c-> <c- d>/*...*/</c->
<c- o>*</c-><c- n>i</c->           <c- c1>//ok</c->
<c- n>a</c-> <c- o>=</c-> <c- n>move</c-><c- p>(</c-><c- n>i</c-><c- p>);</c-> <c- c1>//ok</c->
<c- o>*</c-><c- n>i</c-><c- p>;</c->          <c- c1>//invalid</c->
<c- n>a</c-><c- o>++</c-><c- p>;</c->         <c- c1>//ok</c->
<c- n>i</c-><c- o>++</c-><c- p>;</c->         <c- c1>//invalid</c->
</pre>
   <p>Moving from an iterator invalidates it early, albeit artificially. As per standard, the moved-from iterator is in a valid, but unspecified state,
and cannot be used (but can be assigned to, or destroyed).
Notice the similarity between "a valid, but unspecified state" and "a partially formed state".</p>
   <p>The difference is slim. Notably, both models are equally expressive. References can be used, should multiple names be necessary.
In Stepanov’s model iterators are made invalid by the natural mutation of the sequence upon increment rather than by artificially
preventing multiple copies.</p>
   <p>The second model in which the iterator is moved from, the one we think should be the default way to handle non-forward iterators,
is however a much better fit for the C++ model, and offers much stronger guarantees to both the human developer as well as static analysis tools.</p>
   <p>In the "increment invalidates" model, objects are spiritually moved-from at a distance, which neither the theory of special relativity nor the C++ memory, model are equipped to handle.
This makes it hard for tools to detect invalid uses - although it might become possible with better tools (See Herb Sutter’s CppCon2018 talk).
But most concerning, there is no way for a developer to know that the iterators are entangled.</p>
<pre class="highlight"><c- k>auto</c-> <c- n>i</c-> <c- o>=</c-> <c- n>troubles</c-><c- p>.</c-><c- n>begin</c-><c- p>();</c->
<c- k>auto</c-> <c- n>schrodingers_iterator</c-> <c- o>=</c-> <c- n>i</c-><c- p>;</c->
<c- n>i</c-><c- o>++</c-><c- p>;</c->
<c- k>auto</c-> <c- n>nasal_demon</c-> <c- o>=</c-> <c- o>*</c-><c- n>schrodingers_iterator</c-><c- p>;</c->
</pre>
   <p>The code above might be perfectly fine.
Indeed whether it is well defined or not depends on whether the iterator return by <code class="highlight"><c- n>troubles</c-><c- p>.</c-><c- n>begin</c-><c- p>();</c-></code> is forward or not.
It is undecidable in these 4 lines of slide-code.
It is not much more obvious in a complex program that may pass iterators to other functions or store them in containers, etc.
There are, after all, no theoretical limits to the distance in time and space over which entanglement perdures.</p>
   <p>Even worse, should the type of <code class="highlight"><c- n>troubles</c-><c- p>.</c-><c- n>begin</c-><c- p>();</c-></code> be changed from Forward to Input, the code would change from perfectly fine to
UB, with no warning.</p>
   <p>Moving non-forward iterators, therefore, better expresses intent, is safer and less surprising.
Move-only non-forward Iterators also express the destructive nature of incrementation and give a better sense of the difference between <code class="highlight"><c- n>InputIterator</c-></code> and <code class="highlight"><c- n>ForwardIterator</c-></code>.</p>
   <h3 class="heading settled" data-level="6.1" id="an-holistic-approach-to-iterator-tags-and-iterator-concepts"><span class="secno">6.1. </span><span class="content">An Holistic Approach to Iterator Tags and Iterator Concepts</span><a class="self-link" href="#an-holistic-approach-to-iterator-tags-and-iterator-concepts"></a></h3>
   <p>Missing the notion of movability pre-c++11 and lacking concepts, <code class="highlight"><c- n>Cpp17Iterator</c-></code>s are syntactically distinguished by tags.
a <code class="highlight"><c- n>Cpp17InputIterator</c-></code> is one which has an <code class="highlight"><c- n>input_iterator_tag</c-></code> tag, while a <code class="highlight"><c- n>Cpp17ForwardIterator</c-></code> is one which has a <code class="highlight"><c- n>forward_iterator_tag</c-></code> tag.
This creates a sort of circular, self-referential definition.
This has carried over to the RangesTS’s <code class="highlight"><c- n>Iterator</c-></code> concepts definitions.
Iterators concepts then</p>
   <ul>
    <li data-md>
     <p>Have semantic requirements not expressed through syntax and therefore not enforceable at compile time</p>
    <li data-md>
     <p>Need syntax to artificially subscribe to the correct, most refined concept</p>
   </ul>
   <p>Of course, it is not always possible to express all of a type’s semantic requirements through syntax, and in some cases, tags are an unfortunate necessity.
However, they should be the mechanism of last recourse, and whenever possible, the semantic requirements should be reflected in the syntax.
The idea is that hidden requirements not expressed as code lead to easier-to-misuse types, which inevitably translates to runtime bugs. <strong>Ultimately, requirements that can neither be checked at compile time (concepts) or runtime (contracts) are bound to be ignored</strong>.
Rooted in the belief that not all birds quack like a duck, this proposal leverages meaningful syntactic requirements to increase the type safety of the iterator taxonomy.</p>
   <p>In the case of iterators, all requirements of all iterators categories can be expressed syntactically:</p>
<pre class="highlight"><c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>I</c-><c- o>></c-> <c- n>concept</c-> <c- b>bool</c-> <c- n>InputIterator</c-> <c- o>=</c->
    <c- n>Readable</c-><c- o>&lt;</c-><c- n>I</c-><c- o>></c-> <c- o>&amp;&amp;</c->
    <c- n>Iterator</c-><c- o>&lt;</c-><c- n>I</c-><c- o>></c-> <c- p>;</c->

<c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>I</c-><c- o>></c-> <c- n>concept</c-> <c- b>bool</c-> <c- n>ForwardIterator</c-> <c- o>=</c->
    <c- n>InputIterator</c-><c- o>&lt;</c-><c- n>I</c-><c- o>></c-> <c- o>&amp;&amp;</c->
    <c- n>Copyable</c-><c- o>&lt;</c-><c- n>I</c-><c- o>></c-> <c- o>&amp;&amp;</c->
    <c- n>EqualityComparable</c-><c- o>&lt;</c-><c- n>I</c-><c- o>></c-><c- p>;</c->

<c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>I</c-><c- o>></c-> <c- n>concept</c-> <c- b>bool</c-> <c- n>BidirectionalIterator</c-> <c- o>=</c->
    <c- n>ForwardIterator</c-><c- o>&lt;</c-><c- n>I</c-><c- o>></c-> <c- o>&amp;&amp;</c->
    <c- n>Decrementable</c-><c- o>&lt;</c-><c- n>I</c-><c- o>></c-><c- p>;</c->

<c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>I</c-><c- o>></c-> <c- n>concept</c-> <c- b>bool</c-> <c- n>RandomAccessIterator</c-> <c- o>=</c->
    <c- n>BidirectionalIterator</c-><c- o>&lt;</c-><c- n>I</c-><c- o>></c-> <c- o>&amp;&amp;</c->
    <c- n>RandomAccessIncrementable</c-><c- o>&lt;</c-><c- n>I</c-><c- o>></c-><c- p>;</c->

<c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>I</c-><c- o>></c-> <c- n>concept</c-> <c- b>bool</c-> <c- n>ContiguousIterator</c-> <c- o>=</c->
    <c- n>BidirectionalIterator</c-><c- o>&lt;</c-><c- n>I</c-><c- o>></c-> <c- o>&amp;&amp;</c->
    <c- n>Convertible</c-><c- o>&lt;</c-><c- n>I</c-><c- p>,</c-> <c- n>iter_reference_t</c-><c- o>&lt;</c-><c- n>I</c-><c- o>>></c-><c- p>;</c->
</pre>
   <p>This is of course simplified but shows that each iterator category subsumes the last and adds a single, cohesive set of requirement enforceable at compile-time.
In this design, there is no risk of a type satisfying the wrong concept because of a poorly chosen tag.</p>
   <h4 class="heading settled" data-level="6.1.1" id="tags-as-an-opt-in-opt-out-mechanism"><span class="secno">6.1.1. </span><span class="content">Tags as an opt-in opt-out mechanism</span><a class="self-link" href="#tags-as-an-opt-in-opt-out-mechanism"></a></h4>
   <p>Because of a desire to be compatible with the legacy <code class="highlight"><c- n>std</c-></code> algorithms and the amount of code depending on iterators as they have
been defined since the inception of the STL, we propose that tags be *<em>optionally</em> definable on <code class="highlight"><c- n>Iterators</c-></code> types.</p>
   <p>Notably, we propose that a type that otherwise meets the requirements of <code class="highlight"><c- n>FordwardIterator</c-></code>, but does define an <code class="highlight"><c- n>input_iterator_tag</c-></code>,
should not satisfy <code class="highlight"><c- n>ForwardIterator</c-></code>.
This can be achieved by defined <code class="highlight"><c- n>ForwardIterator</c-></code> as follow:</p>
<pre class="highlight"><c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>I</c-><c- o>></c-> <c- n>concept</c-> <c- b>bool</c-> <c- n>ForwardIterator</c-> <c- o>=</c->
    <c- n>InputIterator</c-><c- o>&lt;</c-><c- n>I</c-><c- o>></c-> <c- o>&amp;&amp;</c->
    <c- n>Copyable</c-><c- o>&lt;</c-><c- n>I</c-><c- o>></c-> <c- o>&amp;&amp;</c->
    <c- n>EqualityComparable</c-><c- o>&lt;</c-><c- n>I</c-><c- o>></c-> <c- o>&amp;&amp;</c->
    <c- p>(</c-> <c- n>has_no_iterator_category</c-><c- o>&lt;</c-><c- n>I</c-><c- o>></c-> <c- o>||</c->
        <c- n>DerivedFrom</c-><c- o>&lt;</c-><c- n>iterator_category_t</c-><c- o>&lt;</c-><c- n>I</c-><c- o>></c-><c- p>,</c-> <c- n>forward_iterator_tag</c-><c- o>></c-><c- p>);</c->
</pre>
   <h2 class="heading settled" data-level="7" id="q-a"><span class="secno">7. </span><span class="content">Q/A</span><a class="self-link" href="#q-a"></a></h2>
   <h3 class="heading settled" data-level="7.1" id="non-regular-iterators-really"><span class="secno">7.1. </span><span class="content">Non-regular iterators, really?</span><a class="self-link" href="#non-regular-iterators-really"></a></h3>
   <p>This proposal advocates for Non-Regular Iterators, and weakens <code class="highlight"><c- n>WeaklyIncrementable</c-></code> requirements to that effect.
Non-Regularity is best avoided, so this might feel like going backwards.</p>
   <p>However, <strong>non-regular types are easier to reason about than types that just pretend to be regular</strong>.
Because <code class="highlight"><c- n>InputIterator</c-></code> is meant to iterate over a non-regular sequence, it is not regular (whether we like it or not), and the best we can do is
make sure the syntax matches the semantic.
It would be accurate to say that <code class="highlight"><c- n>InputIterator</c-></code> is locally regular, but this doesn’t help much in the context of the c++ memory model.
This paper is in part motivated by the conviction that exposing <strong>a false sense of (Semi-)regularity is much more detrimental to code robustness
than non-regularity</strong>.</p>
   <h3 class="heading settled" data-level="7.2" id="what-about-equality-of-input-iterators"><span class="secno">7.2. </span><span class="content">What about Equality of Input Iterators?</span><a class="self-link" href="#what-about-equality-of-input-iterators"></a></h3>
   <p>A first, misguided, version of this paper attempted to prevent comparability of types meeting the <code class="highlight"><c- n>InputIterator</c-></code> requirements. <code class="highlight"><c- n>InputIterator</c-></code> should, in general, not be <code class="highlight"><c- n>EqualityComparable</c-></code>, since they cannot be copied and a fundamental
idea in Stepanov’s teachings is that copy and equality are two sides of the same coin.</p>
   <p>However, preventing <code class="highlight"><c- n>Equality</c-></code> requires dramatic changes to the design and the author was reminded that negative-requirements
are in general a terrible idea.</p>
   <p>Early feedback suggested a desire to be able to compare non-forward iterators. Consider the following:</p>
<pre class="highlight"><c- k>auto</c-> <c- n>a</c-> <c- o>=</c-> <c- n>stream</c-><c- p>.</c-><c- n>begin</c-><c- p>();</c->
<c- k>auto</c-> <c- n>b</c-> <c- o>=</c-> <c- n>stream</c-><c- p>.</c-><c- n>begin</c-><c- p>();</c->
<c- p>...</c->
<c- k>if</c-><c- p>(</c-><c- n>a</c-> <c- o>==</c-> <c- n>b</c-><c- p>)</c-> <c- p>{</c->

<c- p>}</c->
</pre>
   <p>This code will inevitably lead to suffering at some point.
However, we cannot prevent people from constructing multiple non-forward iterators,
and these iterators will compare equal until one of them invalidate the other.</p>
   <p>Two non-forward iterators compare equal if-and-only-if they point to the same position of the same sequence
(and only one such position can be referred to at any given time).</p>
   <p>Allowing <code class="highlight"><c- n>EqualityComparable</c-></code> on non-forward iterators also simplify the interoperability of <code class="highlight"><c- n>std</c-><c- o>::</c-></code> and <code class="highlight"><c- n>ranges</c-><c- o>::</c-></code> iterators.
However, the author would like to recommend that all future non-forward iterators introduced in the standard be <em>not</em> <code class="highlight"><c- n>EqualityComparable</c-></code>.
Instead, non-forward iterator should compare to a Sentinel, which is a much better model. <code class="highlight"><c- n>common_iterator</c-></code> can be used to ease migration and interoperability.</p>
   <h3 class="heading settled" data-level="7.3" id="but-moved-from-objects-are-still-objects"><span class="secno">7.3. </span><span class="content">But... Moved-from objects are still objects!</span><a class="self-link" href="#but-moved-from-objects-are-still-objects"></a></h3>
   <p>Sure, moving-from leaves a trail of objects in an unspecified state.
However, it is much more easy for tools and humans alike to understand that moved-from objects should
not be used, and in fact, all majors compilers can warn about these patterns.
We think that for the case at hand, focusing on the proper handling of values -- as opposed to objects —<wbr>is a sufficient approximation to reduce the potential for iterators misuse while not weakening the stronger
mathematical underpinning of the STL.</p>
   <h3 class="heading settled" data-level="7.4" id="does-iterators-default-constructability-needs-revisiting"><span class="secno">7.4. </span><span class="content">Does iterators default-constructability needs revisiting?</span><a class="self-link" href="#does-iterators-default-constructability-needs-revisiting"></a></h3>
   <p>Default-constructability of iterator seems to have been added, removed and added back
to the Ranges TS and the One Ranges Proposal several times.
To the best of my knowledge, this was done for the sake of Semiregularity.
Given that this proposal strikes semi-regularity, should this question be revisited?</p>
   <p>The authors want to point out that default-constructed iterators are almost never in a specified
state and are almost always unsafe to use.
Moreover, DefaultConstructible is not a requirement of any algorithm using ranges and ultimately, we think enforcing
DefaultConstructibility weakens the better <code class="highlight"><c- n>Sentinel</c-></code> model introduced by ranges.</p>
   <h3 class="heading settled" data-level="7.5" id="what-about-p0902r0"><span class="secno">7.5. </span><span class="content">What about <a data-link-type="biblio" href="#biblio-p0902r0">[P0902R0]</a>?</span><a class="self-link" href="#what-about-p0902r0"></a></h3>
   <p>Andrew Hunter’s "Move-only iterators" paper proposes a design to introduce Move-Only iterators in the taxonomy of <code class="highlight"><c- n>Cpp17Iterator</c-></code>.
However, this design does not offer a solution to use these move-only iterators with existing algorithms, limiting their usefulness.
The iterators proposed by P0902 are additionally <code class="highlight"><c- n>EqualityComparable</c-></code>. The advantage of that is that they are compatible with algorithms
designed with C++17 downward. That’s, however, a potential source of bugs and confusion.</p>
   <p>However, if LEWG feels strongly about a solution compatible with existing algorithms it would be possible
to relax the requirements of concerned algorithms to accept move-only iterators. along with the introduction of a new <code class="highlight"><c- n>move_iterator_tag</c-></code> trait.</p>
   <p>Such algorithms would then be compatible with types satisfying <code class="highlight"><c- n>InputIterator</c-></code> (as proposed by this paper) through a <code class="highlight"><c- n>common_iterator</c-></code> adaptor.</p>
   <p>If proven with enough confidence that requirements of existing algorithms in the <code class="highlight"><c- n>std</c-></code> namespace can be relaxed to handle move-only iterator, the necessary
modifications can be applied in a subsequent standard version.</p>
   <p>So while there would definitively be value in supporting move-only iterators everywhere it makes sense, and the potential for breakage is relatively low,
we do not propose it for lack of visibility on the consequences of such changes.</p>
   <h3 class="heading settled" data-level="7.6" id="why-do-you-want-to-take-my-copyable-inputiterators-away-from-me-i-like-them"><span class="secno">7.6. </span><span class="content">Why do you want to take my Copyable InputIterators away from me, I like them?!</span><a class="self-link" href="#why-do-you-want-to-take-my-copyable-inputiterators-away-from-me-i-like-them"></a></h3>
   <p>We do not propose anything of the sort. But, we propose that</p>
   <ul>
    <li data-md>
     <p>Any <code class="highlight"><c- n>InputIterator</c-></code> that happens to be <code class="highlight"><c- n>Copyable</c-></code> is also a <code class="highlight"><c- n>ForwardIterator</c-></code>.</p>
    <li data-md>
     <p>It remains possible to opt-out of that behavior by defining <code class="highlight"><c- n>iterator_concept</c-></code> to be <code class="highlight"><c- n>input_iterator_tag</c-></code>. Which has to be done in the current standard.</p>
   </ul>
   <table class="tony-table">
    <tbody>
     <tr>
      <th> Non-copyable Iterator 
      <th> Copyable Iterator
      <th> Copyable Iterator with a tag
     <tr>
      <td>
<pre class="highlight"><c- k>struct</c-> <c- n>It</c-> <c- p>{</c->
    <c- n>It</c-><c- p>(</c-><c- n>It</c-><c- o>&amp;&amp;</c-><c- p>)</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c->
    <c- n>It</c-><c- p>(</c-><c- k>const</c-> <c- n>It</c-><c- o>&amp;</c-><c- p>)</c-> <c- o>=</c-> <c- k>delete</c-><c- p>;</c->
    <c- c1>//...</c->
<c- p>};</c->
</pre>
      <td>
<pre class="highlight"><c- k>struct</c-> <c- n>It</c-> <c- p>{</c->
    <c- n>It</c-><c- p>(</c-><c- k>const</c-> <c- n>It</c-><c- o>&amp;</c-><c- p>)</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c->
    <c- c1>//...</c->
<c- p>};</c->
       <br></pre>
      <td>
<pre class="highlight"><c- k>struct</c-> <c- n>It</c-> <c- p>{</c->
    <c- n>It</c-><c- p>(</c-><c- k>const</c-> <c- n>It</c-><c- o>&amp;</c-><c- p>)</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c->
    <c- k>using</c-> <c- n>iterator_concept</c-> <c- o>=</c-> <c- n>input_iterator_tag</c-><c- p>;</c->
    <c- c1>//...</c->
<c- p>};</c->
</pre>
     <tr>
      <td>
<pre class="highlight"><c- k>static_assert</c-><c- o>&lt;</c-><c- n>InputIterator</c-><c- o>&lt;</c-><c- n>It</c-><c- o>>></c->  <c- o>==</c-> true<c- p>;</c->
<c- k>static_assert</c-><c- o>&lt;</c-><c- n>ForwardIterator</c-><c- o>&lt;</c-><c- n>It</c-><c- o>>></c->  <c- o>==</c-> false<c- p>;</c->
</pre>
      <td>
<pre class="highlight"><c- k>static_assert</c-><c- o>&lt;</c-><c- n>InputIterator</c-><c- o>&lt;</c-><c- n>It</c-><c- o>>></c->  <c- o>==</c-> true<c- p>;</c->
<c- k>static_assert</c-><c- o>&lt;</c-><c- n>ForwardIterator</c-><c- o>&lt;</c-><c- n>It</c-><c- o>>></c->  <c- o>==</c-> true<c- p>;</c->
</pre>
      <td>
<pre class="highlight"><c- k>static_assert</c-><c- o>&lt;</c-><c- n>InputIterator</c-><c- o>&lt;</c-><c- n>It</c-><c- o>>></c->  <c- o>==</c-> true<c- p>;</c->
<c- k>static_assert</c-><c- o>&lt;</c-><c- n>ForwardIterator</c-><c- o>&lt;</c-><c- n>It</c-><c- o>>></c->  <c- o>==</c-> false<c- p>;</c->
</pre>
   </table>
   <h3 class="heading settled" data-level="7.7" id="will-this-break-existing-code"><span class="secno">7.7. </span><span class="content">Will this break existing code ?!</span><a class="self-link" href="#will-this-break-existing-code"></a></h3>
   <p>We want to reiterate(!) that all the changes proposed in this paper are only applicable to concepts, types, and requirements of the Ranges TS living
in the <code class="highlight"><c- n>ranges</c-></code> namespace and do not, in any way, impact code depending on types, requirements or algorithms as defined by the C++17 standard</p>
   <h3 class="heading settled" data-level="7.8" id="wont-that-implicit-categorization-lead-to-miss-categorization"><span class="secno">7.8. </span><span class="content">Won’t that implicit categorization lead to miss-categorization?</span><a class="self-link" href="#wont-that-implicit-categorization-lead-to-miss-categorization"></a></h3>
   <p>The only valid use cases for <code class="highlight"><c- n>InputIterator</c-></code> are streams or other input devices, and iterators that own a non-copyable generator.
Most views and iterators are Forward.
It turns out that C++ types are <code class="highlight"><c- n>Copyable</c-></code> by default, therefore, Iterators will be categorized as <code class="highlight"><c- n>ForwardIterator</c-></code> by default, which is correct in most cases.</p>
   <p>This proposal is also a teaching opportunity because the nature of <code class="highlight"><c- n>InputIterator</c-></code> is often poorly understood and misconstrued.
We suspect that these tweaks to the taxonomy of Iterator will make them easier to teach.</p>
   <h3 class="heading settled" data-level="7.9" id="post-increment-on-non-copyable-iterators"><span class="secno">7.9. </span><span class="content">Post Increment on non-copyable iterators</span><a class="self-link" href="#post-increment-on-non-copyable-iterators"></a></h3>
   <p>Post-incrementing move-only iterators would obviously be incorrect.
However, a satisfying solution was offered by <a data-link-type="biblio" href="#biblio-p0541r1">[P0541R1]</a>.</p>
   <h2 class="heading settled" data-level="8" id="questions-for-lewg"><span class="secno">8. </span><span class="content">Questions for LEWG</span><a class="self-link" href="#questions-for-lewg"></a></h2>
   <ul>
    <li data-md>
     <p>Does LEWG want to support non-copyable iterators in the <code class="highlight"><c- n>ranges</c-></code> namespace?</p>
    <li data-md>
     <p>Does LEWG agree that <strong>non-copyable</strong> iterators are always non-forward iterators and do not constitute a new category (ie: no new tag should be introduced)?</p>
    <li data-md>
     <p>Does LEWG agree that, in the absence of an explicit tag, a <strong>non-copyable</strong> iterator that otherwise meets the requirement of <code class="highlight"><c- n>InputIterator</c-></code>/<code class="highlight"><c- n>OutputIterator</c-></code> should be recognized as such?</p>
    <li data-md>
     <p>Does LEWG agree that, in the absence of an explicit tag, a <strong>copyable</strong> iterator that otherwise meets the requirement of <code class="highlight"><c- n>ForwardIterator</c-></code> should be recognized as such?</p>
    <li data-md>
     <p>Does LEWG want to recommend that future non-forward iterators considered for inclusion in the standard should not be copyable?</p>
    <li data-md>
     <p>Does LEWG think non-forward views should return <code class="highlight"><c- n>begin</c-><c- p>()</c-></code> by reference?</p>
    <li data-md>
     <p>Does LEWG agree that <code class="highlight"><c- n>ranges</c-><c- o>::</c-><c- n>copy</c-></code> can and should move from non-copyable input views?</p>
    <li data-md>
     <p>Does LEWG want to revisit the default constructability of iterators given <code class="highlight"><c- n>Regular</c-></code> is no longer a requirement of <code class="highlight"><c- n>Iterator</c-></code>?</p>
    <li data-md>
     <p>Does LEWG want to recognize <code class="highlight"><c- n>RandomAccessIterator</c-></code> providing a conversion operator to the <code class="highlight"><c- n>pointer</c-></code> type of the underlying sequence as <code class="highlight"><c- n>ContiguousIterator</c-></code> without the need for an explicit tag?</p>
    <li data-md>
     <p>Generally, does LEWG support the idea of a tag-less categorization of iterators in the ranges namespace, with tags still supported as an opt-in/opt-out mechanism.</p>
   </ul>
   <h2 class="heading settled" data-level="9" id="list-of-proposed-changes"><span class="secno">9. </span><span class="content">List of proposed changes</span><a class="self-link" href="#list-of-proposed-changes"></a></h2>
   <p>Because the ranges-related proposals are still in flux and will require merging multiple documents, we do not provide wording
at this time.
However, a number of concepts need to be modified in order to allow for iterators that are only movable.
This is a departure from the Ranges TS - which itself is grounded in Stepanov work - in which all iterator categories are Regular - or Semi-Regular,
which implies copyability.</p>
   <p>Note that "ForwardIterator" is defined in terms of its copyability, and so it shall remain regular.
The Copyability, and therefore Regularity of Iterator is therefore moved a few levels down from <code class="highlight"><c- n>ranges</c-><c- o>::</c-><c- n>Iterator</c-></code> to <code class="highlight"><c- n>ranges</c-><c- o>::</c-><c- n>ForwardIterator</c-></code></p>
   <h3 class="heading settled" data-level="9.1" id="changes-to-iterator"><span class="secno">9.1. </span><span class="content">Changes to &lt;iterator></span><a class="self-link" href="#changes-to-iterator"></a></h3>
   <h4 class="heading settled" data-level="9.1.1" id="weaklyincrementable"><span class="secno">9.1.1. </span><span class="content">WeaklyIncrementable</span><a class="self-link" href="#weaklyincrementable"></a></h4>
   <p><code class="highlight"><c- n>WeaklyIncrementable</c-></code> is a requirement of all <code class="highlight"><c- n>Iterator</c-></code>, including <code class="highlight"><c- n>RangesTSInputIterator</c-></code>. <code class="highlight"><c- n>WeaklyIncrementable</c-></code> is defined to be semi-regular.
Because WeaklyIncrementable, as it is described in <a data-link-type="biblio" href="#biblio-p0896r2">[P0896R2]</a>, accommodates for <code class="highlight"><c- n>RangesTSInputIterator</c-></code> and <code class="highlight"><c- n>Cpp17InputIterator</c-></code>, it suffers from the same issue (being copyable with move semantic).
We propose to strike the <code class="highlight"><c- n>Semiregular</c-></code> requirement as follow</p>
<pre class="highlight"><c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>I</c-><c- o>></c->
<c- n>concept</c-> <c- n>WeaklyIncrementable</c-> <c- o>=</c->
    <c- n>Movable</c-><c- o>&lt;</c-><c- n>I</c-><c- o>></c-> <c- o>&amp;&amp;</c->
    <c- n>requires</c-><c- p>(</c-><c- n>I</c-><c- o>&amp;</c-> <c- n>i</c-><c- p>)</c-> <c- p>{</c->
        <c- k>typename</c-> <c- n>iter_difference_t</c-><c- o>&lt;</c-><c- n>I</c-><c- o>></c-><c- p>;</c->
        <c- p>{</c-> <c- o>++</c-><c- n>i</c-> <c- p>}</c-> <c- o>-></c-> <c- n>Same</c-><c- o>&lt;</c-><c- n>I</c-><c- o>&amp;>&amp;&amp;</c-><c- p>;</c->
        <c- n>i</c-><c- o>++</c-><c- p>;</c->
    <c- p>};</c->
</pre>
   <h4 class="heading settled" data-level="9.1.2" id="iterator"><span class="secno">9.1.2. </span><span class="content">Iterator</span><a class="self-link" href="#iterator"></a></h4>
   <p><code class="highlight"><c- n>Iterator</c-></code> is left unmodified as merely changing <code class="highlight"><c- n>WeaklyIncrementable</c-></code> is enough to not
requiring it to be regular.</p>
   <h4 class="heading settled" data-level="9.1.3" id="inputiterator"><span class="secno">9.1.3. </span><span class="content">InputIterator</span><a class="self-link" href="#inputiterator"></a></h4>
   <p>Modify the <code class="highlight"><c- n>InputIterator</c-></code> concept as follow.</p>
<pre class="highlight"><c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>I</c-><c- o>></c->
<c- n>concept</c-> <c- n>InputIterator</c-> <c- o>=</c->
    <c- n>Readable</c-><c- o>&lt;</c-><c- n>I</c-><c- o>></c-> <c- o>&amp;&amp;</c->
    <c- n>Iterator</c-><c- o>&lt;</c-><c- n>I</c-><c- o>></c-><c- p>;</c->
</pre>
   <h4 class="heading settled" data-level="9.1.4" id="forwarditerator"><span class="secno">9.1.4. </span><span class="content"><code class="highlight"><c- n>ForwardIterator</c-></code></span><a class="self-link" href="#forwarditerator"></a></h4>
<pre class="highlight"><c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>I</c-><c- o>></c->
<c- n>concept</c-> <c- n>ForwardIterator</c-> <c- o>=</c->
    <c- n>InputIterator</c-> <c- o>&amp;&amp;</c->
    <c- n>EqualityComparable</c-><c- o>&lt;</c-><c- n>I</c-><c- o>></c-> <c- o>&amp;&amp;</c->
    <c- n>Incrementable</c-><c- o>&lt;</c-><c- n>I</c-><c- o>></c-> <c- o>&amp;&amp;</c->
    <c- p>(</c-> <c- n>has_no_iterator_category</c-><c- o>&lt;</c-><c- n>I</c-><c- o>></c-> <c- o>||</c->
        <c- n>DerivedFrom</c-><c- o>&lt;</c-><c- n>iterator_category_t</c-><c- o>&lt;</c-><c- n>I</c-><c- o>></c-><c- p>,</c-> <c- n>forward_iterator_tag</c-><c- o>></c-><c- p>)</c-> <c- o>&amp;&amp;</c->
    <c- n>Sentinel</c-><c- o>&lt;</c-><c- n>I</c-><c- p>,</c-> <c- n>I</c-><c- o>></c-><c- p>;</c->
</pre>
   <p>ForwardIterator is made <code class="highlight"><c- n>Regular</c-></code> through <code class="highlight"><c- n>Incrementable</c-></code>.
Concepts refining <code class="highlight"><c- n>ForwardIterator</c-></code> are left unchanged.</p>
   <h4 class="heading settled" data-level="9.1.5" id="outputiterator"><span class="secno">9.1.5. </span><span class="content">OutputIterator</span><a class="self-link" href="#outputiterator"></a></h4>
<pre class="highlight"><c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>I</c-><c- p>,</c-> <c- k>class</c-> <c- nc>T</c-><c- o>></c->
<c- n>concept</c-> <c- n>OutputIterator</c-> <c- o>=</c->
    <c- n>Iterator</c-><c- o>&lt;</c-><c- n>I</c-><c- o>></c-> <c- o>&amp;&amp;</c->
    <c- n>Writable</c-><c- o>&lt;</c-><c- n>I</c-><c- p>,</c-> <c- n>T</c-><c- o>></c->
    <c- n>requires</c-><c- p>(</c-><c- n>I</c-><c- o>&amp;</c-> <c- n>i</c-><c- p>,</c-> <c- n>T</c-><c- o>&amp;&amp;</c-> <c- n>t</c-><c- p>)</c-> <c- p>{</c->
        <c- o>*</c-><c- n>i</c-><c- o>++</c-> <c- o>=</c-> <c- n>std</c-><c- o>::</c-><c- n>forward</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-><c- p>(</c-><c- n>t</c-><c- p>);</c->
    <c- p>};</c->
</pre>
   <h4 class="heading settled" data-level="9.1.6" id="contiguousiterator"><span class="secno">9.1.6. </span><span class="content">ContiguousIterator</span><a class="self-link" href="#contiguousiterator"></a></h4>
<pre class="highlight"><c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>I</c-><c- p>,</c-> <c- k>class</c-> <c- nc>T</c-><c- o>></c->
<c- n>concept</c-> <c- n>OutputIterator</c-> <c- o>=</c->
   <c- n>RandomAccessIterator</c-><c- o>&lt;</c-><c- n>I</c-><c- o>></c-> <c- o>&amp;&amp;</c->
   <c- n>std</c-><c- o>::</c-><c- n>is_lvalue_reference</c-><c- o>&lt;</c-><c- n>iter_reference_t</c-><c- o>&lt;</c-><c- n>I</c-><c- o>>>::</c-><c- n>value</c-> <c- o>&amp;&amp;</c->
        <c- n>Same</c-><c- o>&lt;</c-><c- n>iter_value_t</c-><c- o>&lt;</c-><c- n>I</c-><c- o>></c-><c- p>,</c-> <c- n>__uncvref</c-><c- o>&lt;</c-><c- n>iter_reference_t</c-><c- o>&lt;</c-><c- n>I</c-><c- o>>>></c-> <c- o>&amp;&amp;</c->
   <c- n>ConvertibleTo</c-><c- o>&lt;</c-><c- n>iter_value_t</c-><c- o>&lt;</c-><c- n>I</c-><c- o>></c-><c- p>,</c-> <c- n>I</c-><c- o>></c->
</pre>
   <p>Requiring a conversion operator to <code class="highlight"><c- n>iter_value_t</c-><c- o>&lt;</c-><c- n>I</c-><c- o>></c-></code> (instead of a tag - It could also require a tag <strong>or</strong> a conversion operator)
allows the whole iterator taxonomy to be semantically and accurately constrainable without the need for tags.</p>
   <h3 class="heading settled" data-level="9.2" id="changes-to-ranges"><span class="secno">9.2. </span><span class="content">Changes to &lt;ranges></span><a class="self-link" href="#changes-to-ranges"></a></h3>
   <h4 class="heading settled" data-level="9.2.1" id="views"><span class="secno">9.2.1. </span><span class="content">Views</span><a class="self-link" href="#views"></a></h4>
    The <code class="highlight"><c- n>SemiRegular</c-></code> requirement is removed from <code class="highlight"><c- n>View</c-></code> over a non-semi-regular ranges
Indeed, views constituted of non-movable iterator are themselves move-only.
We propose that non-forward views in the Ranges TS and these proposed in pending papers can return <code class="highlight"><c- n>begin</c-><c- p>()</c-></code> by reference. 
   <h4 class="heading settled" data-level="9.2.2" id="inserters"><span class="secno">9.2.2. </span><span class="content">Inserters</span><a class="self-link" href="#inserters"></a></h4>
   <p>Because the <code class="highlight"><c- n>OutputIterator</c-></code> concept as proposed here is not compatible with the <code class="highlight"><c- n>Cpp17OutputIterator</c-></code> requirements, it would not be possible to
use <code class="highlight"><c- n>std</c-><c- o>::</c-></code> inserters with the <code class="highlight"><c- n>ranges</c-><c- o>::</c-></code> algorithms.</p>
   <p>It is, therefore, necessary to provide suitable inserters modeling <code class="highlight"><c- n>OutputIterator</c-></code></p>
   <h5 class="heading settled" data-level="9.2.2.1" id="back_insert_iterator"><span class="secno">9.2.2.1. </span><span class="content">back_insert_iterator</span><a class="self-link" href="#back_insert_iterator"></a></h5>
<pre class="highlight"><c- k>namespace</c-> <c- n>std</c-><c- o>::</c-><c- n>ranges</c-> <c- p>{</c->
<c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>Container</c-><c- o>></c->
<c- k>class</c-> <c- nc>back_insert_iterator</c-> <c- o>:</c-> <c- k>public</c-> <c- n>std</c-><c- o>::</c-><c- n>back_insert_iterator</c-><c- o>&lt;</c-><c- n>Container</c-><c- o>></c-> <c- p>{</c->
<c- k>public</c-><c- o>:</c->
    <c- k>using</c-> <c- n>std</c-><c- o>::</c-><c- n>back_insert_iterator</c-><c- o>&lt;</c-><c- n>Container</c-><c- o>>::</c-><c- n>back_insert_iterator</c-><c- p>;</c->
    <c- n>back_insert_iterator</c-><c- p>(</c-><c- k>const</c-> <c- n>back_insert_iterator</c-> <c- o>&amp;</c-> <c- n>other</c-><c- p>)</c-> <c- o>=</c-> <c- k>delete</c-><c- p>;</c->
    <c- n>back_insert_iterator</c-><c- p>(</c-><c- n>back_insert_iterator</c-> <c- o>&amp;&amp;</c-> <c- n>other</c-><c- p>)</c->

<c- p>};</c->
<c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>Container</c-><c- o>></c->
<c- n>back_insert_iterator</c-><c- o>&lt;</c-><c- n>Container</c-><c- o>></c-> <c- n>back_inserter</c-><c- p>(</c-><c- n>Container</c-><c- o>&amp;</c-> <c- n>x</c-><c- p>);</c->
<c- p>}</c->
</pre>
   <h5 class="heading settled" data-level="9.2.2.2" id="front_insert_iterator"><span class="secno">9.2.2.2. </span><span class="content">front_insert_iterator</span><a class="self-link" href="#front_insert_iterator"></a></h5>
<pre class="highlight"><c- k>namespace</c-> <c- n>std</c-><c- o>::</c-><c- n>ranges</c-> <c- p>{</c->
<c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>Container</c-><c- o>></c->
<c- k>class</c-> <c- nc>front_insert_iterator</c-> <c- o>:</c-> <c- k>public</c-> <c- n>std</c-><c- o>::</c-><c- n>front_insert_iterator</c-><c- o>&lt;</c-><c- n>Container</c-><c- o>></c-> <c- p>{</c->
<c- k>public</c-><c- o>:</c->
    <c- k>using</c-> <c- n>std</c-><c- o>::</c-><c- n>front_insert_iterator</c-><c- o>&lt;</c-><c- n>Container</c-><c- o>>::</c-><c- n>front_insert_iterator</c-><c- p>;</c->
    <c- n>front_insert_iterator</c-><c- p>(</c-><c- k>const</c-> <c- n>front_insert_iterator</c-> <c- o>&amp;</c-> <c- n>other</c-><c- p>)</c-> <c- o>=</c-> <c- k>delete</c-><c- p>;</c->
    <c- n>front_insert_iterator</c-><c- p>(</c-><c- n>front_insert_iterator</c-> <c- o>&amp;&amp;</c-> <c- n>other</c-><c- p>);</c->
<c- p>};</c->
<c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>Container</c-><c- o>></c->
<c- n>front_insert_iterator</c-><c- o>&lt;</c-><c- n>Container</c-><c- o>></c-> <c- n>front_inserter</c-><c- p>(</c-><c- n>Container</c-><c- o>&amp;</c-> <c- n>x</c-><c- p>);</c->
<c- p>}</c->
</pre>
   <h5 class="heading settled" data-level="9.2.2.3" id="insert_iterator"><span class="secno">9.2.2.3. </span><span class="content">insert_iterator</span><a class="self-link" href="#insert_iterator"></a></h5>
<pre class="highlight"><c- k>namespace</c-> <c- n>std</c-><c- o>::</c-><c- n>ranges</c-> <c- p>{</c->
<c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>Container</c-><c- o>></c->
<c- k>class</c-> <c- nc>insert_iterator</c-> <c- o>:</c-> <c- k>public</c-> <c- n>std</c-><c- o>::</c-><c- n>insert_iterator</c-><c- o>&lt;</c-><c- n>Container</c-><c- o>></c-> <c- p>{</c->
<c- k>public</c-><c- o>:</c->
    <c- k>using</c-> <c- n>std</c-><c- o>::</c-><c- n>insert_iterator</c-><c- o>&lt;</c-><c- n>Container</c-><c- o>>::</c-><c- n>insert_iterator</c-><c- p>;</c->
    <c- n>insert_iterator</c-><c- p>(</c-><c- k>const</c-> <c- n>insert_iterator</c-> <c- o>&amp;</c-> <c- n>other</c-><c- p>)</c-> <c- o>=</c-> <c- k>delete</c-><c- p>;</c->
    <c- n>insert_iterator</c-><c- p>(</c-><c- n>insert_iterator</c-> <c- o>&amp;&amp;</c-> <c- n>other</c-><c- p>);</c->
<c- p>};</c->
<c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>Container</c-><c- o>></c->
<c- n>insert_iterator</c-><c- o>&lt;</c-><c- n>Container</c-><c- o>></c-> <c- n>inserter</c-><c- p>(</c-><c- n>Container</c-><c- o>&amp;</c-> <c- n>x</c-><c- p>,</c-> <c- k>typename</c-> <c- n>Container</c-><c- o>::</c-><c- n>iterator</c-> <c- n>i</c-><c- p>);</c->
<c- p>}</c->
</pre>
   <h3 class="heading settled" data-level="9.3" id="changes-to-algorithms"><span class="secno">9.3. </span><span class="content">Changes to &lt;algorithms></span><a class="self-link" href="#changes-to-algorithms"></a></h3>
   <p>Should algorithms not satisfy <code class="highlight"><c- n>InputIterator</c-></code> (because they depend on copy-constructability) - they would need to be modified to
accept a <code class="highlight"><c- n>ForwardIterator</c-></code> instead.
Beyond that, there would be very little, if any, wording change required to ranges' algorithms.
However, implementers would have to never copy non-forward iterators within the implementation.</p>
   <h4 class="heading settled" data-level="9.3.1" id="rangescopy"><span class="secno">9.3.1. </span><span class="content"><code class="highlight"><c- n>ranges</c-><c- o>::</c-><c- n>copy</c-></code></span><a class="self-link" href="#rangescopy"></a></h4>
   <p>In the presence of an InputRange or an <code class="highlight"><c- n>InputIterator</c-></code> that is non-copyable (no <code class="highlight"><c- n>iterator_concept</c-></code> or <code class="highlight"><c- n>iterator_category</c-></code> is defined),
ranges::copy can and should behave like <code class="highlight"><c- n>ranges</c-><c- o>::</c-><c- n>move</c-></code>.</p>
   <h2 class="heading settled" data-level="10" id="impact-on-other-proposals"><span class="secno">10. </span><span class="content">Impact on other proposals</span><a class="self-link" href="#impact-on-other-proposals"></a></h2>
   <h3 class="heading settled" data-level="10.1" id="view-proposals"><span class="secno">10.1. </span><span class="content">View proposals</span><a class="self-link" href="#view-proposals"></a></h3>
   <p>We suggest that the various proposals introducing new non-forward views should have iterators that are neither copyable nor equally comparable.
Non-forward input views can further return <code class="highlight"><c- n>begin</c-><c- p>()</c-></code> by reference.
A candidate for such change would be <a data-link-type="biblio" href="#biblio-p1035r1">[P1035R1]</a>'s <code class="highlight"><c- n>istream_view</c-></code>.</p>
   <h3 class="heading settled" data-level="10.2" id="iterator-facade"><span class="secno">10.2. </span><span class="content">Iterator facade</span><a class="self-link" href="#iterator-facade"></a></h3>
   <p><a data-link-type="biblio" href="#biblio-p0186r0">[P0186R0]</a> describes a system for an iterator facade.
The changes proposed make defining iterators easier but we think there is still value in an iterator facade.
To accommodate and honor the changes proposed here, we suggest that:</p>
   <ul>
    <li data-md>
     <p>An iterator constructed from a move-only cursor, without an <code class="highlight"><c- n>equal</c-><c- p>(</c-><c- k>const</c-> <c- n>cursor</c-> <c- o>&amp;</c-><c- p>)</c-></code> member function models an <code class="highlight"><c- n>InputIterator</c-></code> (or <code class="highlight"><c- n>OutputIterator</c-></code> depending on whether a <code class="highlight"><c- n>write</c-></code> member function is defined)</p>
    <li data-md>
     <p>An iterator facade constructed from a Copyable cursor with an <code class="highlight"><c- n>equal</c-><c- p>(</c-><c- k>const</c-> <c- n>cursor</c-> <c- o>&amp;</c-><c- p>)</c-></code> member function models an <code class="highlight"><c- n>ForwardIterator</c-></code>,
  unless it defines a <code class="highlight"><c- n>single_pass</c-> <c- o>=</c-> true</code> trait.</p>
   </ul>
   <h3 class="heading settled" data-level="10.3" id="acknowledgments"><span class="secno">10.3. </span><span class="content">Acknowledgments</span><a class="self-link" href="#acknowledgments"></a></h3>
   <p>The authors like to thank Connor Waters, Tony Van Eerd, Eric Niebler, Casey Carter, Sean Parent and Arthur O’Dwyer who gave tremendously helpful feedbacks
during the writing of this paper.</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-eop">[EOP]
   <dd>Alexander Stepanov; Paul McJones. <a href="http://elementsofprogramming.com/">Elements of programming</a>. 2009. URL: <a href="http://elementsofprogramming.com/">http://elementsofprogramming.com/</a>
   <dt id="biblio-p0186r0">[P0186R0]
   <dd>Beman Dawes, Eric Niebler, Casey Carter. <a href="https://wg21.link/p0186r0">Iterator Facade Library Proposal for Ranges</a>. 11 February 2016. URL: <a href="https://wg21.link/p0186r0">https://wg21.link/p0186r0</a>
   <dt id="biblio-p0541r1">[P0541R1]
   <dd>Eric Niebler. <a href="https://wg21.link/p0541r1">Ranges TS: Post-Increment on Input and Output Iterators</a>. 10 July 2017. URL: <a href="https://wg21.link/p0541r1">https://wg21.link/p0541r1</a>
   <dt id="biblio-p0896r2">[P0896R2]
   <dd>Eric Niebler, Casey Carter, Christopher Di Bella. <a href="https://wg21.link/p0896r2">The One Ranges Proposal</a>. 25 June 2018. URL: <a href="https://wg21.link/p0896r2">https://wg21.link/p0896r2</a>
   <dt id="biblio-p0902r0">[P0902R0]
   <dd>Andrew Hunter. <a href="https://wg21.link/p0902r0">Move-only iterators</a>. 5 February 2018. URL: <a href="https://wg21.link/p0902r0">https://wg21.link/p0902r0</a>
   <dt id="biblio-p1035r1">[P1035R1]
   <dd>Christopher Di Bella. <a href="https://wg21.link/p1035">Input range adaptors</a>. URL: <a href="https://wg21.link/p1035">https://wg21.link/p1035</a>
  </dl>