<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang xml:lang>
<head>
  <meta charset="utf-8" />
  <meta name="generator" content="mpark/wg21" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
  <meta name="dcterms.date" content="2023-01-31" />
  <title>Stashing stashing iterators for proper flattening</title>
  <style>
      code{white-space: pre-wrap;}
      span.smallcaps{font-variant: small-caps;}
      span.underline{text-decoration: underline;}
      div.column{display: inline-block; vertical-align: top; width: 50%;}
      div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
      ul.task-list{list-style: none;}
      pre > code.sourceCode { white-space: pre; position: relative; }
      pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }
      pre > code.sourceCode > span:empty { height: 1.2em; }
      code.sourceCode > span { color: inherit; text-decoration: inherit; }
      div.sourceCode { margin: 1em 0; }
      pre.sourceCode { margin: 0; }
      @media screen {
      div.sourceCode { overflow: auto; }
      }
      @media print {
      pre > code.sourceCode { white-space: pre-wrap; }
      pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; }
      }
      pre.numberSource code
        { counter-reset: source-line 0; }
      pre.numberSource code > span
        { position: relative; left: -4em; counter-increment: source-line; }
      pre.numberSource code > span > a:first-child::before
        { content: counter(source-line);
          position: relative; left: -1em; text-align: right; vertical-align: baseline;
          border: none; display: inline-block;
          -webkit-touch-callout: none; -webkit-user-select: none;
          -khtml-user-select: none; -moz-user-select: none;
          -ms-user-select: none; user-select: none;
          padding: 0 4px; width: 4em;
          color: #aaaaaa;
        }
      pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa;  padding-left: 4px; }
      div.sourceCode
        {  background-color: #f6f8fa; }
      @media screen {
      pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
      }
      code span. { } /* Normal */
      code span.al { color: #ff0000; } /* Alert */
      code span.an { } /* Annotation */
      code span.at { } /* Attribute */
      code span.bn { color: #9f6807; } /* BaseN */
      code span.bu { color: #9f6807; } /* BuiltIn */
      code span.cf { color: #00607c; } /* ControlFlow */
      code span.ch { color: #9f6807; } /* Char */
      code span.cn { } /* Constant */
      code span.co { color: #008000; font-style: italic; } /* Comment */
      code span.cv { color: #008000; font-style: italic; } /* CommentVar */
      code span.do { color: #008000; } /* Documentation */
      code span.dt { color: #00607c; } /* DataType */
      code span.dv { color: #9f6807; } /* DecVal */
      code span.er { color: #ff0000; font-weight: bold; } /* Error */
      code span.ex { } /* Extension */
      code span.fl { color: #9f6807; } /* Float */
      code span.fu { } /* Function */
      code span.im { } /* Import */
      code span.in { color: #008000; } /* Information */
      code span.kw { color: #00607c; } /* Keyword */
      code span.op { color: #af1915; } /* Operator */
      code span.ot { } /* Other */
      code span.pp { color: #6f4e37; } /* Preprocessor */
      code span.re { } /* RegionMarker */
      code span.sc { color: #9f6807; } /* SpecialChar */
      code span.ss { color: #9f6807; } /* SpecialString */
      code span.st { color: #9f6807; } /* String */
      code span.va { } /* Variable */
      code span.vs { color: #9f6807; } /* VerbatimString */
      code span.wa { color: #008000; font-weight: bold; } /* Warning */
      code.diff {color: #898887}
      code.diff span.va {color: #006e28}
      code.diff span.st {color: #bf0303}
  </style>
  <style type="text/css">
body {
margin: 5em;
font-family: serif;

hyphens: auto;
line-height: 1.35;
}
div.wrapper {
max-width: 60em;
margin: auto;
}
ul {
list-style-type: none;
padding-left: 2em;
margin-top: -0.2em;
margin-bottom: -0.2em;
}
a {
text-decoration: none;
color: #4183C4;
}
a.hidden_link {
text-decoration: none;
color: inherit;
}
li {
margin-top: 0.6em;
margin-bottom: 0.6em;
}
h1, h2, h3, h4 {
position: relative;
line-height: 1;
}
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;
font-family: sans-serif;
font-weight: normal;
font-size: 83%;
}
a.self-link:hover { opacity: 1; }
a.self-link::before { content: "§"; }
ul > li:before {
content: "\2014";
position: absolute;
margin-left: -1.5em;
}
:target { background-color: #C9FBC9; }
:target .codeblock { background-color: #C9FBC9; }
:target ul { background-color: #C9FBC9; }
.abbr_ref { float: right; }
.folded_abbr_ref { float: right; }
:target .folded_abbr_ref { display: none; }
:target .unfolded_abbr_ref { float: right; display: inherit; }
.unfolded_abbr_ref { display: none; }
.secnum { display: inline-block; min-width: 35pt; }
.header-section-number { display: inline-block; min-width: 35pt; }
.annexnum { display: block; }
div.sourceLinkParent {
float: right;
}
a.sourceLink {
position: absolute;
opacity: 0;
margin-left: 10pt;
}
a.sourceLink:hover {
opacity: 1;
}
a.itemDeclLink {
position: absolute;
font-size: 75%;
text-align: right;
width: 5em;
opacity: 0;
}
a.itemDeclLink:hover { opacity: 1; }
span.marginalizedparent {
position: relative;
left: -5em;
}
li span.marginalizedparent { left: -7em; }
li ul > li span.marginalizedparent { left: -9em; }
li ul > li ul > li span.marginalizedparent { left: -11em; }
li ul > li ul > li ul > li span.marginalizedparent { left: -13em; }
div.footnoteNumberParent {
position: relative;
left: -4.7em;
}
a.marginalized {
position: absolute;
font-size: 75%;
text-align: right;
width: 5em;
}
a.enumerated_item_num {
position: relative;
left: -3.5em;
display: inline-block;
margin-right: -3em;
text-align: right;
width: 3em;
}
div.para { margin-bottom: 0.6em; margin-top: 0.6em; text-align: justify; }
div.section { text-align: justify; }
div.sentence { display: inline; }
span.indexparent {
display: inline;
position: relative;
float: right;
right: -1em;
}
a.index {
position: absolute;
display: none;
}
a.index:before { content: "⟵"; }

a.index:target {
display: inline;
}
.indexitems {
margin-left: 2em;
text-indent: -2em;
}
div.itemdescr {
margin-left: 3em;
}
.bnf {
font-family: serif;
margin-left: 40pt;
margin-top: 0.5em;
margin-bottom: 0.5em;
}
.ncbnf {
font-family: serif;
margin-top: 0.5em;
margin-bottom: 0.5em;
margin-left: 40pt;
}
.ncsimplebnf {
font-family: serif;
font-style: italic;
margin-top: 0.5em;
margin-bottom: 0.5em;
margin-left: 40pt;
background: inherit; 
}
span.textnormal {
font-style: normal;
font-family: serif;
white-space: normal;
display: inline-block;
}
span.rlap {
display: inline-block;
width: 0px;
}
span.descr { font-style: normal; font-family: serif; }
span.grammarterm { font-style: italic; }
span.term { font-style: italic; }
span.terminal { font-family: monospace; font-style: normal; }
span.nonterminal { font-style: italic; }
span.tcode { font-family: monospace; font-style: normal; }
span.textbf { font-weight: bold; }
span.textsc { font-variant: small-caps; }
a.nontermdef { font-style: italic; font-family: serif; }
span.emph { font-style: italic; }
span.techterm { font-style: italic; }
span.mathit { font-style: italic; }
span.mathsf { font-family: sans-serif; }
span.mathrm { font-family: serif; font-style: normal; }
span.textrm { font-family: serif; }
span.textsl { font-style: italic; }
span.mathtt { font-family: monospace; font-style: normal; }
span.mbox { font-family: serif; font-style: normal; }
span.ungap { display: inline-block; width: 2pt; }
span.textit { font-style: italic; }
span.texttt { font-family: monospace; }
span.tcode_in_codeblock { font-family: monospace; font-style: normal; }
span.phantom { color: white; }

span.math { font-style: normal; }
span.mathblock {
display: block;
margin-left: auto;
margin-right: auto;
margin-top: 1.2em;
margin-bottom: 1.2em;
text-align: center;
}
span.mathalpha {
font-style: italic;
}
span.synopsis {
font-weight: bold;
margin-top: 0.5em;
display: block;
}
span.definition {
font-weight: bold;
display: block;
}
.codeblock {
margin-left: 1.2em;
line-height: 127%;
}
.outputblock {
margin-left: 1.2em;
line-height: 127%;
}
div.itemdecl {
margin-top: 2ex;
}
code.itemdeclcode {
white-space: pre;
display: block;
}
span.textsuperscript {
vertical-align: super;
font-size: smaller;
line-height: 0;
}
.footnotenum { vertical-align: super; font-size: smaller; line-height: 0; }
.footnote {
font-size: small;
margin-left: 2em;
margin-right: 2em;
margin-top: 0.6em;
margin-bottom: 0.6em;
}
div.minipage {
display: inline-block;
margin-right: 3em;
}
div.numberedTable {
text-align: center;
margin: 2em;
}
div.figure {
text-align: center;
margin: 2em;
}
table {
border: 1px solid black;
border-collapse: collapse;
margin-left: auto;
margin-right: auto;
margin-top: 0.8em;
text-align: left;
hyphens: none; 
}
td, th {
padding-left: 1em;
padding-right: 1em;
vertical-align: top;
}
td.empty {
padding: 0px;
padding-left: 1px;
}
td.left {
text-align: left;
}
td.right {
text-align: right;
}
td.center {
text-align: center;
}
td.justify {
text-align: justify;
}
td.border {
border-left: 1px solid black;
}
tr.rowsep, td.cline {
border-top: 1px solid black;
}
tr.even, tr.odd {
border-bottom: 1px solid black;
}
tr.capsep {
border-top: 3px solid black;
border-top-style: double;
}
tr.header {
border-bottom: 3px solid black;
border-bottom-style: double;
}
th {
border-bottom: 1px solid black;
}
span.centry {
font-weight: bold;
}
div.table {
display: block;
margin-left: auto;
margin-right: auto;
text-align: center;
width: 90%;
}
span.indented {
display: block;
margin-left: 2em;
margin-bottom: 1em;
margin-top: 1em;
}
ol.enumeratea { list-style-type: none; background: inherit; }
ol.enumerate { list-style-type: none; background: inherit; }

code.sourceCode > span { display: inline; }
</style>
  <style type="text/css">a {
color : #4183C4;
text-decoration: underline;
}
a.marginalized {
text-decoration: none;
}
a.self-link {
text-decoration: none;
}
h1#toctitle {
border-bottom: 1px solid #cccccc;
}
#TOC li {
margin-top: 1px;
margin-bottom: 1px;
}
#TOC ul>li:before { display: none; }
h3.subtitle { margin-top: -15px; }
h1:target { background-color: transparent; }
h2:target { background-color: transparent; }
h3:target { background-color: transparent; }
h4:target { background-color: transparent; }
h5:target { background-color: transparent; }
h6:target { background-color: transparent; }
.marginalized:target { background-color: transparent; }
code span.co { font-family: monospace; }
table tr {
background-color: white;
}
table tr:nth-child(2n) {
background-color: #f6f8fa;
}
#title-block-header > table tr:nth-child(2n) {
background-color: white;
}
td > div.sourceCode {
background-color: inherit;
}
table {
border-collapse: collapse;
}
table td, table th {
border: 1px solid #cccccc;
}
table th {
border-bottom: 1px solid black;
text-align: center;
}
table tr:first-child th {
border-top: 0;
}
table tr:last-child td {
border-bottom: 0;
}
table tr td:first-child,
table tr th:first-child {
border-left: 0;
}
table tr td:last-child,
table tr th:last-child {
border-right: 0;
}
table tbody tr:first-child td {
border-top: 1px solid black;
}
#title-block-header td { border: 0; }
@media all {
body {
margin: 2em;
}
}
@media screen and (min-width: 480px) {
body {
margin: 5em;
}
}
#refs code{padding-left: 0px; text-indent: 0px;}
:root {
--diff-ins: #e6ffed;
--diff-strongins: #acf2bd;
--diff-del: #ffdddd;
--diff-strongdel: #ff8888;
}
span.diffins {
background-color: var(--diff-strongins);
}
span.diffdel {
background-color: var(--diff-strongdel);
}
div.rm { text-decoration: line-through; }
div.rm code.sourceCode { text-decoration: line-through; }
div.addu, span.addu {
color: #006e28;
background-color: var(--diff-ins);
}

div.rm pre, div.add pre { background-color: #f6f8fa; }
div.addu pre { background-color: var(--diff-ins); }
div.add, div.add pre, div.add blockquote { background-color: var(--diff-ins); }
div.addu blockquote {
border-left: 4px solid #00a000;
padding: 0 15px;
color: #006e28;
text-decoration: none;
}
div.addu blockquote code.sourceCode { text-decoration: none; }
div.addu blockquote pre { text-decoration: none; }
div.addu blockquote pre code { text-decoration: none; }
code.diff span.va { color: #000000; background-color: var(--diff-ins); }
code.diff span.st { color: #000000; background-color: var(--diff-del); }
blockquote { background-color: #f6f8fa; }
@media (prefers-color-scheme: dark) {
:root {
--diff-ins: #225522;
--diff-strongins: #225522;
--diff-del: #662222;
--diff-strongdel: #662222;
}
body {
background-color: #171717;
color: #b0b0b0;
}
table tr {
background-color: #171717;
}
table tr:nth-child(2n) {
background-color: #252525;
}
#title-block-header > table tr:nth-child(2n) {
background-color: #171717;
}
tr.header {
border-bottom: 3px solid #b0b0b0;
border-bottom-style: double;
}
tr.even, tr.odd {
border-bottom: 1px solid #b0b0b0;
}
table th {
border-bottom: 1px solid #b0b0b0;
}
table tbody tr:first-child td {
border-top: 1px solid #b0b0b0;
}
blockquote { background-color: rgba(255, 255, 255, .03); }
a { color: #549df2; }
div.sourceCode
{ background-color: rgba(255, 255, 255, .03); }
table { border-color: #b0b0b0; }
td.border { border-color: #b0b0b0; }
td.border { border-left-color: #b0b0b0; }
tr.rowsep, td.cline { border-top-color: #b0b0b0; }
tr.capsep { border-top-color: #b0b0b0; }
th { border-bottom-color: #b0b0b0; }
code span.kw { color: #12cabe; }
code span.cf { color: #12cabe; }
code span.op { color: #cf1915; }
code span.pp { color: #b27c58; }
code span.co { color: #35ba00; }
code.diff span.va {
color: #b0b0b0;
}
code.diff span.vd {
color: #b0b0b0;
}
code.diff span.st {
color: #b0b0b0;
}
div.add {
color: #d0fddd !important
}
div.rm {
color: #8f3131 !important
}
div.rm pre, div.add pre { background-color: rgba(255, 255, 255, .03); }
}
</style>
  <link href="data:image/x-icon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AIJEAACCRAAAgkQAAIJEAACCRAAAgkQAVoJEAN6CRADegkQAWIJEAACCRAAAgkQAAIJEAACCRAAA////AP///wCCRAAAgkQAAIJEAACCRAAsgkQAvoJEAP+CRAD/gkQA/4JEAP+CRADAgkQALoJEAACCRAAAgkQAAP///wD///8AgkQAAIJEABSCRACSgkQA/IJEAP99PQD/dzMA/3czAP99PQD/gkQA/4JEAPyCRACUgkQAFIJEAAD///8A////AHw+AFiBQwDqgkQA/4BBAP9/PxP/uZd6/9rJtf/bybX/upd7/39AFP+AQQD/gkQA/4FDAOqAQgBc////AP///wDKklv4jlEa/3o7AP+PWC//8+3o///////////////////////z7un/kFox/35AAP+GRwD/mVYA+v///wD///8A0Zpk+NmibP+0d0T/8evj///////+/fv/1sKz/9bCs//9/fr//////+/m2/+NRwL/nloA/5xYAPj///8A////ANKaZPjRmGH/5cKh////////////k149/3UwAP91MQD/lmQ//86rhv+USg3/m1YA/5hSAP+bVgD4////AP///wDSmmT4zpJY/+/bx///////8+TV/8mLT/+TVx//gkIA/5lVAP+VTAD/x6B//7aEVv/JpH7/s39J+P///wD///8A0ppk+M6SWP/u2sf///////Pj1f/Nj1T/2KFs/8mOUv+eWhD/lEsA/8aee/+0glT/x6F7/7J8Rvj///8A////ANKaZPjRmGH/48Cf///////+/v7/2qt//82PVP/OkFX/37KJ/86siv+USg7/mVQA/5hRAP+bVgD4////AP///wDSmmT40ppk/9CVXP/69O////////7+/v/x4M//8d/P//7+/f//////9u7n/6tnJf+XUgD/nFgA+P///wD///8A0ppk+NKaZP/RmWL/1qNy//r07///////////////////////+vXw/9akdP/Wnmn/y5FY/6JfFvj///8A////ANKaZFTSmmTo0ppk/9GYYv/Ql1//5cWm//Hg0P/x4ND/5cWm/9GXYP/RmGH/0ppk/9KaZOjVnmpY////AP///wDSmmQA0ppkEtKaZI7SmmT60ppk/9CWX//OkVb/zpFW/9CWX//SmmT/0ppk/NKaZJDSmmQS0ppkAP///wD///8A0ppkANKaZADSmmQA0ppkKtKaZLrSmmT/0ppk/9KaZP/SmmT/0ppkvNKaZCrSmmQA0ppkANKaZAD///8A////ANKaZADSmmQA0ppkANKaZADSmmQA0ppkUtKaZNzSmmTc0ppkVNKaZADSmmQA0ppkANKaZADSmmQA////AP5/AAD4HwAA4AcAAMADAACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAMADAADgBwAA+B8AAP5/AAAoAAAAIAAAAEAAAAABACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wCCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAAyCRACMgkQA6oJEAOqCRACQgkQAEIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAA////AP///wD///8A////AIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRABigkQA5oJEAP+CRAD/gkQA/4JEAP+CRADqgkQAZoJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAAD///8A////AP///wD///8AgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAA4gkQAwoJEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQAxIJEADyCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAP///wD///8A////AP///wCCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAWgkQAmIJEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAJyCRAAYgkQAAIJEAACCRAAAgkQAAIJEAACCRAAA////AP///wD///8A////AIJEAACCRAAAgkQAAIJEAACCRAAAgkQAdIJEAPCCRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAPSCRAB4gkQAAIJEAACCRAAAgkQAAIJEAAD///8A////AP///wD///8AgkQAAIJEAACCRAAAgkQASoJEANKCRAD/gkQA/4JEAP+CRAD/g0YA/39AAP9zLgD/bSQA/2shAP9rIQD/bSQA/3MuAP9/PwD/g0YA/4JEAP+CRAD/gkQA/4JEAP+CRADUgkQAToJEAACCRAAAgkQAAP///wD///8A////AP///wB+PwAAgkUAIoJEAKiCRAD/gkQA/4JEAP+CRAD/hEcA/4BBAP9sIwD/dTAA/5RfKv+viF7/vp56/76ee/+wiF7/lWAr/3YxAP9sIwD/f0AA/4RHAP+CRAD/gkQA/4JEAP+CRAD/gkQArIJEACaBQwAA////AP///wD///8A////AIBCAEBzNAD6f0EA/4NFAP+CRAD/gkQA/4VIAP92MwD/bSUA/6N1Tv/ezsL/////////////////////////////////38/D/6V3Uv9uJgD/dTEA/4VJAP+CRAD/gkQA/4JEAP+BQwD/fUAA/4FDAEj///8A////AP///wD///8AzJRd5qBlKf91NgD/dDUA/4JEAP+FSQD/cy4A/3YyAP/PuKP//////////////////////////////////////////////////////9K7qP94NQD/ciwA/4VJAP+CRAD/fkEA/35BAP+LSwD/mlYA6v///wD///8A////AP///wDdpnL/4qx3/8KJUv+PUhf/cTMA/3AsAP90LgD/4dK+/////////////////////////////////////////////////////////////////+TYxf91MAD/dTIA/31CAP+GRwD/llQA/6FcAP+gWwD8////AP///wD///8A////ANGZY/LSm2X/4ap3/92mcP+wdT3/byQA/8mwj////////////////////////////////////////////////////////////////////////////+LYxv9zLgP/jUoA/59bAP+hXAD/nFgA/5xYAPL///8A////AP///wD///8A0ppk8tKaZP/RmWL/1p9q/9ubXv/XqXj////////////////////////////7+fD/vZyG/6BxS/+gcUr/vJuE//r37f//////////////////////3MOr/5dQBf+dVQD/nVkA/5xYAP+cWAD/nFgA8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/SmWP/yohJ//jo2P//////////////////////4NTG/4JDFf9lGAD/bSQA/20kAP9kGAD/fz8S/+Xb0f//////5NG9/6txN/+LOgD/m1QA/51aAP+cWAD/m1cA/5xYAP+cWADy////AP///wD///8A////ANKaZPLSmmT/0ppk/8+TWf/Unmv//v37//////////////////////+TWRr/VwsA/35AAP+ERgD/g0UA/4JGAP9lHgD/kFga/8KXX/+TRwD/jT4A/49CAP+VTQD/n10A/5xYAP+OQQD/lk4A/55cAPL///8A////AP///wD///8A0ppk8tKaZP/SmmT/y4tO/92yiP//////////////////////8NnE/8eCQP+rcTT/ez0A/3IyAP98PgD/gEMA/5FSAP+USwD/jj8A/5lUAP+JNwD/yqV2/694Mf+HNQD/jkAA/82rf/+laBj/jT4A8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/LiUr/4byY///////////////////////gupX/0I5P/+Wuev/Lklz/l1sj/308AP+QSwD/ol0A/59aAP+aVQD/k0oA/8yoh///////+fXv/6pwO//Lp3v///////Pr4f+oay7y////AP///wD///8A////ANKaZPLSmmT/0ppk/8uJSv/hvJj//////////////////////+G7l//Jhkb/0ppk/96nc//fqXX/x4xO/6dkFP+QSQD/llEA/5xXAP+USgD/yaOA///////38uv/qG05/8ijdv//////8efb/6ZpLPL///8A////AP///wD///8A0ppk8tKaZP/SmmT/zIxO/9yxh///////////////////////7dbA/8iEQf/Sm2X/0Zlj/9ScZv/eqHf/2KJv/7yAQf+XTgD/iToA/5lSAP+JNgD/yKFv/611LP+HNQD/jT8A/8qmeP+kZRT/jT4A8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/Pk1n/1J5q//78+//////////////////+/fv/1aFv/8iEQv/Tm2b/0ppl/9GZY//Wn2z/1pZc/9eldf/Bl2b/kUcA/4w9AP+OQAD/lUwA/59eAP+cWQD/jT8A/5ZOAP+eXADy////AP///wD///8A////ANKaZPLSmmT/0ppk/9KZY//KiEn/8d/P///////////////////////47+f/05tm/8iCP//KiEj/yohJ/8eCP//RmGH//vfy///////n1sP/rXQ7/4k4AP+TTAD/nVoA/5xYAP+cVwD/nFgA/5xYAPL///8A////AP///wD///8A0ppk8tKaZP/SmmT/0ptl/8uLTf/aq37////////////////////////////+/fz/6c2y/961jv/etY7/6Myx//78+v//////////////////////3MWv/5xXD/+ORAD/mFQA/51ZAP+cWAD/nFgA8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/SmmT/0ppk/8mFRP/s1b//////////////////////////////////////////////////////////////////////////////+PD/0JFU/7NzMv+WUQD/kUsA/5tXAP+dWQDy////AP///wD///8A////ANKaZP/SmmT/0ppk/9KaZP/Sm2X/z5NZ/8yMT//z5NX/////////////////////////////////////////////////////////////////9Ofa/8yNUP/UmGH/36p5/8yTWv+qaSD/kksA/5ROAPz///8A////AP///wD///8A0ppk5NKaZP/SmmT/0ppk/9KaZP/TnGf/zY9T/82OUv/t1sD//////////////////////////////////////////////////////+7Yw//OkFX/zI5R/9OcZ//SmmP/26V0/9ymdf/BhUf/ol8R6P///wD///8A////AP///wDSmmQ80ppk9tKaZP/SmmT/0ppk/9KaZP/TnGj/zpFW/8qJSv/dson/8uHS//////////////////////////////////Lj0//etIv/y4lL/86QVf/TnGj/0ppk/9KaZP/RmWP/05xn/9ymdfjUnWdC////AP///wD///8A////ANKaZADSmmQc0ppkotKaZP/SmmT/0ppk/9KaZP/Tm2b/0Zli/8qJSf/NjlH/16Z3/+G8mP/myKr/5siq/+G8mP/Xp3f/zY5S/8qISf/RmGH/05tm/9KaZP/SmmT/0ppk/9KaZP/SmmSm0pljINWdaQD///8A////AP///wD///8A0ppkANKaZADSmmQA0ppkQtKaZMrSmmT/0ppk/9KaZP/SmmT/0ptl/9GYYf/Nj1P/y4lL/8qISP/KiEj/y4lK/82PU//RmGH/0ptl/9KaZP/SmmT/0ppk/9KaZP/SmmTO0ppkRtKaZADSmmQA0ppkAP///wD///8A////AP///wDSmmQA0ppkANKaZADSmmQA0ppkANKaZGzSmmTu0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmTw0ppkcNKaZADSmmQA0ppkANKaZADSmmQA////AP///wD///8A////ANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZBLSmmSQ0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppklNKaZBTSmmQA0ppkANKaZADSmmQA0ppkANKaZAD///8A////AP///wD///8A0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQy0ppkutKaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppkvtKaZDbSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkAP///wD///8A////AP///wDSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkXNKaZODSmmT/0ppk/9KaZP/SmmT/0ppk5NKaZGDSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA////AP///wD///8A////ANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkBtKaZIbSmmTo0ppk6tKaZIrSmmQK0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZAD///8A////AP/8P///+B///+AH//+AAf//AAD//AAAP/AAAA/gAAAHwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA+AAAAfwAAAP/AAAP/8AAP//gAH//+AH///4H////D//" rel="icon" />
  <!--[if lt IE 9]>
    <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
  <![endif]-->
  
</head>
<body>
<div class="wrapper">
<header id="title-block-header">
<h1 class="title" style="text-align:center">Stashing stashing iterators for proper flattening</h1>
<h3 class="subtitle" style="text-align:center">Resolving LWG 3698</h3>

<table style="border:none;float:right">
  <tr>
    <td>Document #:</td>
    <td>P2770R0</td>
  </tr>
  <tr>
    <td>Date:</td>
    <td>2023-01-31</td>
  </tr>
  <tr>
    <td style="vertical-align:top">Project:</td>
    <td>Programming Language C++</td>
  </tr>
  <tr>
    <td style="vertical-align:top">Audience:</td>
    <td>
      LWG<br>
    </td>
  </tr>
  <tr>
    <td style="vertical-align:top">Reply-to:</td>
    <td>
      Tim Song<br>&lt;<a href="mailto:t.canens.cpp@gmail.com" class="email">t.canens.cpp@gmail.com</a>&gt;<br>
    </td>
  </tr>
</table>

</header>
<div style="clear:both">
<h1 data-number="1" style="border-bottom:1px solid #cccccc" id="abstract"><span class="header-section-number">1</span> Abstract<a href="#abstract" class="self-link"></a></h1>
<p>This paper provides wording to resolve <span class="citation" data-cites="LWG3698">[<a href="#ref-LWG3698" role="doc-biblioref">LWG3698</a>]</span>, <span class="citation" data-cites="LWG3700">[<a href="#ref-LWG3700" role="doc-biblioref">LWG3700</a>]</span>, <span class="citation" data-cites="LWG3791">[<a href="#ref-LWG3791" role="doc-biblioref">LWG3791</a>]</span>, and NB comment <a href="https://github.com/cplusplus/nbballot/issues/539">US 61-126</a>.</p>
<h1 data-number="2" style="border-bottom:1px solid #cccccc" id="discussion"><span class="header-section-number">2</span> Discussion<a href="#discussion" class="self-link"></a></h1>
<p>A <em>stashing iterator</em> is an iterator that returns a reference to something within itself (or more generally, <em>something</em> that is tied to the lifetime of the iterator). Such iterators can only be of the input category; forward iterators are not allowed to be stashing (<span>25.3.4.11 <a href="https://wg21.link/iterator.concept.forward">[iterator.concept.forward]</a></span> p3; <span>25.3.5.5 <a href="https://wg21.link/forward.iterators">[forward.iterators]</a></span> p6).</p>
<p>There are two parts to <span class="citation" data-cites="LWG3698">[<a href="#ref-LWG3698" role="doc-biblioref">LWG3698</a>]</span>:</p>
<ul>
<li><code class="sourceCode cpp">regex_iterator</code> and <code class="sourceCode cpp">regex_token_iterator</code></li>
</ul>
<p>These are stashing iterators that lie about their category. It is probably too breaking at this point to change their <code class="sourceCode cpp">iterator_category</code>, but we should add <code class="sourceCode cpp">iterator_concept</code> so that they give the correct answer for C++20 iterator concepts.</p>
<ul>
<li><code class="sourceCode cpp">join</code> and <code class="sourceCode cpp">join_with</code></li>
</ul>
<p>These don’t handle stashing iterators properly.</p>
<p>As currently specified, the <code class="sourceCode cpp">join_view</code> iterator holds a) an iterator <code class="sourceCode cpp">outer</code> into the range being joined and b) an iterator <code class="sourceCode cpp">inner</code> into the current element that is being iterated over (that is, <code class="sourceCode cpp"><span class="op">*</span>outer</code>).</p>
<p>When <code class="sourceCode cpp">outer</code> is stashing, then, <code class="sourceCode cpp">inner</code> actually refers into <code class="sourceCode cpp"><span class="op">*</span>outer</code>. In such a case, making a copy of the <code class="sourceCode cpp">join_view</code> iterator would produce an iterator that holds:</p>
<ul>
<li>a copy of <code class="sourceCode cpp">outer</code>, and</li>
<li>a copy of <code class="sourceCode cpp">inner</code>, but this copy is pointing into the original <code class="sourceCode cpp">outer</code>, not the copy.</li>
</ul>
<p>Hilarity ensues when we try to continue to iterate using this copy.</p>
<p>The fix is to cache the outer iterator within the view, similar to what we do for a number of other views (<code class="sourceCode cpp">lazy_split</code>, for instance). This way, copying the <code class="sourceCode cpp">join_view</code> iterator only copies the inner iterator. Because there is no dedicated “stashing” trait, we need to do this for all input iterators.</p>
<p>While in the vicinity, this paper also resolves <span class="citation" data-cites="LWG3700">[<a href="#ref-LWG3700" role="doc-biblioref">LWG3700</a>]</span> and <span class="citation" data-cites="LWG3791">[<a href="#ref-LWG3791" role="doc-biblioref">LWG3791</a>]</span>, two relatively minor issues concerning <code class="sourceCode cpp">join_view</code> and <code class="sourceCode cpp">join_with_view</code>.</p>
<p>The wording below has been implemented and tested on top of libstdc++ master.</p>
<h1 data-number="3" style="border-bottom:1px solid #cccccc" id="wording"><span class="header-section-number">3</span> Wording<a href="#wording" class="self-link"></a></h1>
<p>This wording is relative to <span class="citation" data-cites="N4928">[<a href="#ref-N4928" role="doc-biblioref">N4928</a>]</span>.</p>
<div>
<ol type="1">
<li>Edit <span>32.11.1.1 <a href="https://wg21.link/re.regiter.general">[re.regiter.general]</a></span>, class template <code class="sourceCode cpp">regex_iterator</code> synopsis, as indicated:</li>
</ol>
<blockquote>
<div>
<div class="sourceCode" id="cb1"><pre class="sourceCode diff"><code class="sourceCode diff"><span id="cb1-1"><a href="#cb1-1"></a> namespace std {</span>
<span id="cb1-2"><a href="#cb1-2"></a>   template&lt;class BidirectionalIterator,</span>
<span id="cb1-3"><a href="#cb1-3"></a>             class charT = typename iterator_traits&lt;BidirectionalIterator&gt;::value_type,</span>
<span id="cb1-4"><a href="#cb1-4"></a>             class traits = regex_traits&lt;charT&gt;&gt;</span>
<span id="cb1-5"><a href="#cb1-5"></a>     class regex_iterator {</span>
<span id="cb1-6"><a href="#cb1-6"></a>     public:</span>
<span id="cb1-7"><a href="#cb1-7"></a>       using regex_type        = basic_regex&lt;charT, traits&gt;;</span>
<span id="cb1-8"><a href="#cb1-8"></a>       using iterator_category = forward_iterator_tag;</span>
<span id="cb1-9"><a href="#cb1-9"></a><span class="va">+      using iterator_concept  = input_iterator_tag;</span></span>
<span id="cb1-10"><a href="#cb1-10"></a>       using value_type        = match_results&lt;BidirectionalIterator&gt;;</span>
<span id="cb1-11"><a href="#cb1-11"></a>       using difference_type   = ptrdiff_t;</span>
<span id="cb1-12"><a href="#cb1-12"></a>       using pointer           = const value_type*;</span>
<span id="cb1-13"><a href="#cb1-13"></a>       using reference         = const value_type&amp;;</span>
<span id="cb1-14"><a href="#cb1-14"></a></span>
<span id="cb1-15"><a href="#cb1-15"></a>       […]</span>
<span id="cb1-16"><a href="#cb1-16"></a>     };</span>
<span id="cb1-17"><a href="#cb1-17"></a> }</span></code></pre></div>
</div>
</blockquote>
<ol start="2" type="1">
<li>Edit <span>32.11.2.1 <a href="https://wg21.link/re.tokiter.general">[re.tokiter.general]</a></span>, class template <code class="sourceCode cpp">regex_token_iterator</code> synopsis, as indicated:</li>
</ol>
<blockquote>
<div>
<div class="sourceCode" id="cb2"><pre class="sourceCode diff"><code class="sourceCode diff"><span id="cb2-1"><a href="#cb2-1"></a> namespace std {</span>
<span id="cb2-2"><a href="#cb2-2"></a>   template&lt;class BidirectionalIterator,</span>
<span id="cb2-3"><a href="#cb2-3"></a>             class charT = typename iterator_traits&lt;BidirectionalIterator&gt;::value_type,</span>
<span id="cb2-4"><a href="#cb2-4"></a>             class traits = regex_traits&lt;charT&gt;&gt;</span>
<span id="cb2-5"><a href="#cb2-5"></a>     class regex_token_iterator {</span>
<span id="cb2-6"><a href="#cb2-6"></a>     public:</span>
<span id="cb2-7"><a href="#cb2-7"></a>       using regex_type        = basic_regex&lt;charT, traits&gt;;</span>
<span id="cb2-8"><a href="#cb2-8"></a>       using iterator_category = forward_iterator_tag;</span>
<span id="cb2-9"><a href="#cb2-9"></a><span class="va">+      using iterator_concept  = input_iterator_tag;</span></span>
<span id="cb2-10"><a href="#cb2-10"></a>       using value_type        = sub_match&lt;BidirectionalIterator&gt;;</span>
<span id="cb2-11"><a href="#cb2-11"></a>       using difference_type   = ptrdiff_t;</span>
<span id="cb2-12"><a href="#cb2-12"></a>       using pointer           = const value_type*;</span>
<span id="cb2-13"><a href="#cb2-13"></a>       using reference         = const value_type&amp;;</span>
<span id="cb2-14"><a href="#cb2-14"></a></span>
<span id="cb2-15"><a href="#cb2-15"></a>       […]</span>
<span id="cb2-16"><a href="#cb2-16"></a>     };</span>
<span id="cb2-17"><a href="#cb2-17"></a> }</span></code></pre></div>
</div>
</blockquote>
<ol start="3" type="1">
<li>Add the following function template to <span>26.7.5 <a href="https://wg21.link/range.adaptor.tuple">[range.adaptor.tuple]</a></span>, and change the stable name to [range.adaptor.helpers]:</li>
</ol>
<blockquote>
<div class="sourceCode" id="cb3"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb3-1"><a href="#cb3-1"></a><span class="kw">namespace</span> std<span class="op">::</span>ranges <span class="op">{</span></span>
<span id="cb3-2"><a href="#cb3-2"></a>  <span class="op">[...]</span></span>
<span id="cb3-3"><a href="#cb3-3"></a></span>
<span id="cb3-4"><a href="#cb3-4"></a></span>
<span id="cb3-5"><a href="#cb3-5"></a>  <span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> T<span class="op">&gt;</span></span>
<span id="cb3-6"><a href="#cb3-6"></a>  <span class="kw">constexpr</span> T<span class="op">&amp;</span> <em>as-lvalue</em><span class="op">(</span>T<span class="op">&amp;&amp;</span> t<span class="op">)</span> <span class="op">{</span>     <span class="co">// exposition only</span></span>
<span id="cb3-7"><a href="#cb3-7"></a>    <span class="cf">return</span> <span class="kw">static_cast</span><span class="op">&lt;</span>T<span class="op">&amp;&gt;(</span>t<span class="op">)</span>;</span>
<span id="cb3-8"><a href="#cb3-8"></a>  <span class="op">}</span></span>
<span id="cb3-9"><a href="#cb3-9"></a><span class="op">}</span></span></code></pre></div>
</blockquote>
<ol start="4" type="1">
<li>Edit <span>26.7.14.2 <a href="https://wg21.link/range.join.view">[range.join.view]</a></span>, class template <code class="sourceCode cpp">join_view</code> synopsis, as indicated:</li>
</ol>
<blockquote>
<div>
<div class="sourceCode" id="cb4"><pre class="sourceCode diff"><code class="sourceCode diff"><span id="cb4-1"><a href="#cb4-1"></a> namespace std::ranges {</span>
<span id="cb4-2"><a href="#cb4-2"></a>   template&lt;input_range V&gt;</span>
<span id="cb4-3"><a href="#cb4-3"></a>     requires view&lt;V&gt; &amp;&amp; input_range&lt;range_reference_t&lt;V&gt;&gt;</span>
<span id="cb4-4"><a href="#cb4-4"></a>   class join_view : public view_interface&lt;join_view&lt;V&gt;&gt; {</span>
<span id="cb4-5"><a href="#cb4-5"></a>   private:</span>
<span id="cb4-6"><a href="#cb4-6"></a>     using <em>InnerRng</em> = range_reference_t&lt;V&gt;;                  // exposition only</span>
<span id="cb4-7"><a href="#cb4-7"></a></span>
<span id="cb4-8"><a href="#cb4-8"></a>     // <span>26.7.14.3 <a href="https://wg21.link/range.join.iterator">[range.join.iterator]</a></span>, class template join_view::<em>iterator</em></span>
<span id="cb4-9"><a href="#cb4-9"></a>     template&lt;bool Const&gt;</span>
<span id="cb4-10"><a href="#cb4-10"></a>       struct <em>iterator</em>;                                      // exposition only</span>
<span id="cb4-11"><a href="#cb4-11"></a></span>
<span id="cb4-12"><a href="#cb4-12"></a>     // <span>26.7.14.4 <a href="https://wg21.link/range.join.sentinel">[range.join.sentinel]</a></span>, class template join_view::<em>sentinel</em></span>
<span id="cb4-13"><a href="#cb4-13"></a>     template&lt;bool Const&gt;</span>
<span id="cb4-14"><a href="#cb4-14"></a>       struct <em>sentinel</em>;                                      // exposition only</span>
<span id="cb4-15"><a href="#cb4-15"></a></span>
<span id="cb4-16"><a href="#cb4-16"></a>     V <em>base_</em> = V();                                          // exposition only</span>
<span id="cb4-17"><a href="#cb4-17"></a></span>
<span id="cb4-18"><a href="#cb4-18"></a><span class="va">+    <em>non-propagating-cache</em>&lt;iterator_t&lt;V&gt;&gt; <em>outer_</em>;            // exposition only, present only</span></span>
<span id="cb4-19"><a href="#cb4-19"></a><span class="va">+                                                            // when !forward_range&lt;V&gt;</span></span>
<span id="cb4-20"><a href="#cb4-20"></a></span>
<span id="cb4-21"><a href="#cb4-21"></a>     <em>non-propagating-cache</em>&lt;remove_cv_t&lt;<em>InnerRng</em>&gt;&gt; <em>inner_</em>;    // exposition only, present  only</span>
<span id="cb4-22"><a href="#cb4-22"></a>                                                             // when !is_reference_v&lt;<em>InnerRng</em>&gt;</span>
<span id="cb4-23"><a href="#cb4-23"></a></span>
<span id="cb4-24"><a href="#cb4-24"></a>   public:</span>
<span id="cb4-25"><a href="#cb4-25"></a>     join_view() requires default_initializable&lt;V&gt; = default;</span>
<span id="cb4-26"><a href="#cb4-26"></a>     constexpr explicit join_view(V base);</span>
<span id="cb4-27"><a href="#cb4-27"></a></span>
<span id="cb4-28"><a href="#cb4-28"></a>     constexpr V base() const &amp; requires copy_constructible&lt;V&gt; { return <em>base_</em>; }</span>
<span id="cb4-29"><a href="#cb4-29"></a>     constexpr V base() &amp;&amp; { return std::move(<em>base_</em>); }</span>
<span id="cb4-30"><a href="#cb4-30"></a></span>
<span id="cb4-31"><a href="#cb4-31"></a>     constexpr auto begin() {</span>
<span id="cb4-32"><a href="#cb4-32"></a><span class="va">+      if constexpr (forward_range&lt;V&gt;) {</span></span>
<span id="cb4-33"><a href="#cb4-33"></a>         constexpr bool use_const = <em>simple-view</em>&lt;V&gt; &amp;&amp;</span>
<span id="cb4-34"><a href="#cb4-34"></a>                                    is_reference_v&lt;<em>InnerRng</em>&gt;;</span>
<span id="cb4-35"><a href="#cb4-35"></a>         return <em>iterator</em>&lt;use_const&gt;{*this, ranges::begin(<em>base_</em>)};</span>
<span id="cb4-36"><a href="#cb4-36"></a><span class="va">+      }</span></span>
<span id="cb4-37"><a href="#cb4-37"></a><span class="va">+      else {</span></span>
<span id="cb4-38"><a href="#cb4-38"></a><span class="va">+        <em>outer_</em> = ranges::begin(<em>base_</em>);</span></span>
<span id="cb4-39"><a href="#cb4-39"></a><span class="va">+        return <em>iterator</em>&lt;false&gt;{*this};</span></span>
<span id="cb4-40"><a href="#cb4-40"></a><span class="va">+      }</span></span>
<span id="cb4-41"><a href="#cb4-41"></a>     }</span>
<span id="cb4-42"><a href="#cb4-42"></a></span>
<span id="cb4-43"><a href="#cb4-43"></a>     constexpr auto begin() const</span>
<span id="cb4-44"><a href="#cb4-44"></a>       requires <span><span class="diffins">forward</span><span class="diffdel">input</span></span>_range&lt;const V&gt; &amp;&amp;</span>
<span id="cb4-45"><a href="#cb4-45"></a>                is_reference_v&lt;range_reference_t&lt;const V&gt;&gt; <span class="diffins">&amp;&amp;</span></span>
<span id="cb4-46"><a href="#cb4-46"></a><span class="va">+               input_range&lt;range_reference_t&lt;const V&gt;&gt;</span></span>
<span id="cb4-47"><a href="#cb4-47"></a>     { return <em>iterator</em>&lt;true&gt;{*this, ranges::begin(<em>base_</em>)}; }</span>
<span id="cb4-48"><a href="#cb4-48"></a></span>
<span id="cb4-49"><a href="#cb4-49"></a>     constexpr auto end() {</span>
<span id="cb4-50"><a href="#cb4-50"></a>       if constexpr (forward_range&lt;V&gt; &amp;&amp;</span>
<span id="cb4-51"><a href="#cb4-51"></a>                     is_reference_v&lt;<em>InnerRng</em>&gt; &amp;&amp; forward_range&lt;<em>InnerRng</em>&gt; &amp;&amp;</span>
<span id="cb4-52"><a href="#cb4-52"></a>                     common_range&lt;V&gt; &amp;&amp; common_range&lt;<em>InnerRng</em>&gt;)</span>
<span id="cb4-53"><a href="#cb4-53"></a>         return <em>iterator</em>&lt;<em>simple-view</em>&lt;V&gt;&gt;{*this, ranges::end(<em>base_</em>)};</span>
<span id="cb4-54"><a href="#cb4-54"></a>       else</span>
<span id="cb4-55"><a href="#cb4-55"></a>         return <em>sentinel</em>&lt;<em>simple-view</em>&lt;V&gt;&gt;{*this};</span>
<span id="cb4-56"><a href="#cb4-56"></a>     }</span>
<span id="cb4-57"><a href="#cb4-57"></a></span>
<span id="cb4-58"><a href="#cb4-58"></a>     constexpr auto end() const</span>
<span id="cb4-59"><a href="#cb4-59"></a>       requires <span><span class="diffins">forward</span><span class="diffdel">input</span></span>_range&lt;const V&gt; &amp;&amp;</span>
<span id="cb4-60"><a href="#cb4-60"></a>                is_reference_v&lt;range_reference_t&lt;const V&gt;&gt; <span class="diffins">&amp;&amp;</span></span>
<span id="cb4-61"><a href="#cb4-61"></a><span class="va">+               input_range&lt;range_reference_t&lt;const V&gt;&gt;</span></span>
<span id="cb4-62"><a href="#cb4-62"></a>     {</span>
<span id="cb4-63"><a href="#cb4-63"></a>       if constexpr (<span class="diffdel">forward_range&lt;const V&gt; &amp;&amp;</span></span>
<span id="cb4-64"><a href="#cb4-64"></a>                     forward_range&lt;range_reference_t&lt;const V&gt;&gt; &amp;&amp;</span>
<span id="cb4-65"><a href="#cb4-65"></a>                     common_range&lt;const V&gt; &amp;&amp;</span>
<span id="cb4-66"><a href="#cb4-66"></a>                     common_range&lt;range_reference_t&lt;const V&gt;&gt;)</span>
<span id="cb4-67"><a href="#cb4-67"></a>         return <em>iterator</em>&lt;true&gt;{*this, ranges::end(<em>base_</em>)};</span>
<span id="cb4-68"><a href="#cb4-68"></a>       else</span>
<span id="cb4-69"><a href="#cb4-69"></a>         return <em>sentinel</em>&lt;true&gt;{*this};</span>
<span id="cb4-70"><a href="#cb4-70"></a>     }</span>
<span id="cb4-71"><a href="#cb4-71"></a>   };</span>
<span id="cb4-72"><a href="#cb4-72"></a></span>
<span id="cb4-73"><a href="#cb4-73"></a>   template&lt;class R&gt;</span>
<span id="cb4-74"><a href="#cb4-74"></a>     explicit join_view(R&amp;&amp;) -&gt; join_view&lt;views::all_t&lt;R&gt;&gt;;</span>
<span id="cb4-75"><a href="#cb4-75"></a> }</span></code></pre></div>
</div>
</blockquote>
<ol start="5" type="1">
<li>Edit <span>26.7.14.3 <a href="https://wg21.link/range.join.iterator">[range.join.iterator]</a></span> as indicated:</li>
</ol>
<blockquote>
<div>
<div class="sourceCode" id="cb5"><pre class="sourceCode diff"><code class="sourceCode diff"><span id="cb5-1"><a href="#cb5-1"></a> namespace std::ranges {</span>
<span id="cb5-2"><a href="#cb5-2"></a>   template&lt;input_range V&gt;</span>
<span id="cb5-3"><a href="#cb5-3"></a>     requires view&lt;V&gt; &amp;&amp; input_range&lt;range_reference_t&lt;V&gt;&gt;</span>
<span id="cb5-4"><a href="#cb5-4"></a>   template&lt;bool Const&gt;</span>
<span id="cb5-5"><a href="#cb5-5"></a>   struct join_view&lt;V&gt;::<em>iterator</em> {</span>
<span id="cb5-6"><a href="#cb5-6"></a>   private:</span>
<span id="cb5-7"><a href="#cb5-7"></a>     using <em>Parent</em>    = <em>maybe-const</em>&lt;Const, join_view&gt;;            // exposition only</span>
<span id="cb5-8"><a href="#cb5-8"></a>     using <em>Base</em>      = <em>maybe-const</em>&lt;Const, V&gt;;                    // exposition only</span>
<span id="cb5-9"><a href="#cb5-9"></a>     using <em>OuterIter</em> = iterator_t&lt;<em>Base</em>&gt;;                         // exposition only</span>
<span id="cb5-10"><a href="#cb5-10"></a>     using <em>InnerIter</em> = iterator_t&lt;range_reference_t&lt;<em>Base</em>&gt;&gt;;      // exposition only</span>
<span id="cb5-11"><a href="#cb5-11"></a></span>
<span id="cb5-12"><a href="#cb5-12"></a>     static constexpr bool <em>ref-is-glvalue</em> =                      // exposition only</span>
<span id="cb5-13"><a href="#cb5-13"></a>       is_reference_v&lt;range_reference_t&lt;<em>Base</em>&gt;&gt;;</span>
<span id="cb5-14"><a href="#cb5-14"></a></span>
<span id="cb5-15"><a href="#cb5-15"></a>     <em>OuterIter</em> <em>outer_</em> = <em>OuterIter</em>();                             // exposition only<span class="diffins">,</span></span>
<span id="cb5-16"><a href="#cb5-16"></a><span class="va">+                                                                // present only if <em>Base</em> models forward_range</span></span>
<span id="cb5-17"><a href="#cb5-17"></a>     optional&lt;<em>InnerIter</em>&gt; <em>inner_</em>;                                 // exposition only</span>
<span id="cb5-18"><a href="#cb5-18"></a>     <em>Parent</em>* <em>parent_</em>  = nullptr;                                 // exposition only</span>
<span id="cb5-19"><a href="#cb5-19"></a></span>
<span id="cb5-20"><a href="#cb5-20"></a>     constexpr void <em>satisfy</em>();                                   // exposition only</span>
<span id="cb5-21"><a href="#cb5-21"></a></span>
<span id="cb5-22"><a href="#cb5-22"></a><span class="va">+    constexpr <em>OuterIter</em>&amp; <em>outer</em>();                               // exposition only</span></span>
<span id="cb5-23"><a href="#cb5-23"></a><span class="va">+    constexpr const <em>OuterIter</em>&amp; <em>outer</em>() const;                   // exposition only</span></span>
<span id="cb5-24"><a href="#cb5-24"></a></span>
<span id="cb5-25"><a href="#cb5-25"></a><span class="va">+    constexpr <em>iterator</em>(<em>Parent</em>&amp; parent, <em>OuterIter</em> outer)</span></span>
<span id="cb5-26"><a href="#cb5-26"></a><span class="va">+      requires forward_range&lt;<em>Base</em>&gt;;                             // exposition only</span></span>
<span id="cb5-27"><a href="#cb5-27"></a><span class="va">+    constexpr explicit <em>iterator</em>(<em>Parent</em>&amp; parent)</span></span>
<span id="cb5-28"><a href="#cb5-28"></a><span class="va">+      requires (!forward_range&lt;<em>Base</em>&gt;);                          // exposition only</span></span>
<span id="cb5-29"><a href="#cb5-29"></a></span>
<span id="cb5-30"><a href="#cb5-30"></a>   public:</span>
<span id="cb5-31"><a href="#cb5-31"></a>     using iterator_concept  = <em>see below</em>;</span>
<span id="cb5-32"><a href="#cb5-32"></a>     using iterator_category = <em>see below</em>;                        // not always present</span>
<span id="cb5-33"><a href="#cb5-33"></a>     using value_type        = range_value_t&lt;range_reference_t&lt;<em>Base</em>&gt;&gt;;</span>
<span id="cb5-34"><a href="#cb5-34"></a>     using difference_type   = <em>see below</em>;</span>
<span id="cb5-35"><a href="#cb5-35"></a></span>
<span id="cb5-36"><a href="#cb5-36"></a>     <em>iterator</em>() <span class="diffdel">requires default_initializable&lt;<span class="math inline"><em>O</em><em>u</em><em>t</em><em>e</em><em>r</em><em>I</em><em>t</em><em>e</em><em>r</em></span>&gt;</span> = default;</span>
<span id="cb5-37"><a href="#cb5-37"></a><span class="st">-    constexpr <em>iterator</em>(<em>Parent</em>&amp; parent, <em>OuterIter</em> outer);</span></span>
<span id="cb5-38"><a href="#cb5-38"></a>     constexpr <em>iterator</em>(<em>iterator</em>&lt;!Const&gt; i)</span>
<span id="cb5-39"><a href="#cb5-39"></a>       requires Const &amp;&amp;</span>
<span id="cb5-40"><a href="#cb5-40"></a>                convertible_to&lt;iterator_t&lt;V&gt;, <em>OuterIter</em>&gt; &amp;&amp;</span>
<span id="cb5-41"><a href="#cb5-41"></a>                convertible_to&lt;iterator_t&lt;<em>InnerRng</em>&gt;, <em>InnerIter</em>&gt;;</span>
<span id="cb5-42"><a href="#cb5-42"></a></span>
<span id="cb5-43"><a href="#cb5-43"></a>     [...]</span>
<span id="cb5-44"><a href="#cb5-44"></a></span>
<span id="cb5-45"><a href="#cb5-45"></a>     friend constexpr bool operator==(const <em>iterator</em>&amp; x, const <em>iterator</em>&amp; y)</span>
<span id="cb5-46"><a href="#cb5-46"></a>      requires <em>ref-is-glvalue</em> &amp;&amp; <span><span class="diffins"><code class="sourceCode cpp">forward_range<span class="op">&lt;</span><em>Base</em><span class="op">&gt;</span></code></span><span class="diffdel"><code class="sourceCode cpp">equality_­comparable<span class="op">&lt;</span>iterator_t<span class="op">&lt;</span>Base<span class="op">&gt;&gt;</span></code></span></span> &amp;&amp;</span>
<span id="cb5-47"><a href="#cb5-47"></a>               equality_­comparable&lt;iterator_t&lt;range_reference_t&lt;Base&gt;&gt;&gt;;</span>
<span id="cb5-48"><a href="#cb5-48"></a></span>
<span id="cb5-49"><a href="#cb5-49"></a>     [...]</span>
<span id="cb5-50"><a href="#cb5-50"></a>   };</span>
<span id="cb5-51"><a href="#cb5-51"></a> }</span></code></pre></div>
</div>
<p>[…]</p>
<div>
<div class="add">
<blockquote>

</blockquote>
<div class="sourceCode" id="cb6"><pre class="sourceCode default cpp"><code class="sourceCode default"><span id="cb6-1"><a href="#cb6-1"></a>    constexpr <em>OuterIter</em>&amp; <em>outer</em>();</span>
<span id="cb6-2"><a href="#cb6-2"></a>    constexpr const <em>OuterIter</em>&amp; <em>outer</em>() const;</span></code></pre></div>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_1" id="pnum_1">?</a></span> <em>Returns:</em> <code class="sourceCode default"><em>outer_</em></code> if <code class="sourceCode default"><em>Base</em></code> models <code class="sourceCode default">forward_range</code>; otherwise, <code class="sourceCode default">*<em>parent_</em>-&gt;<em>outer_</em></code>.</p>
</blockquote>
</div>
<div class="sourceCode" id="cb7"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb7-1"><a href="#cb7-1"></a>    <span class="kw">constexpr</span> <span class="dt">void</span> <em>satisfy</em><span class="op">()</span>;</span></code></pre></div>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_2" id="pnum_2">5</a></span> <em>Effects:</em> Equivalent to:</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode cpp nonitem"><code class="sourceCode cpp"><span id="cb8-1"><a href="#cb8-1"></a><span class="kw">auto</span> update_inner <span class="op">=</span> <span class="op">[</span><span class="kw">this</span><span class="op">](</span><span class="kw">const</span> iterator_t<span class="op">&lt;</span><em>Base</em><span class="op">&gt;&amp;</span> x<span class="op">)</span> <span class="op">-&gt;</span> <span class="kw">auto</span><span class="op">&amp;&amp;</span> <span class="op">{</span></span>
<span id="cb8-2"><a href="#cb8-2"></a>  <span class="cf">if</span> <span class="kw">constexpr</span> <span class="op">(</span><em>ref-is-glvalue</em><span class="op">)</span>     <span class="co">// *x is a reference</span></span>
<span id="cb8-3"><a href="#cb8-3"></a>    <span class="cf">return</span> <span class="op">*</span>x;</span>
<span id="cb8-4"><a href="#cb8-4"></a>  <span class="cf">else</span></span>
<span id="cb8-5"><a href="#cb8-5"></a>    <span class="cf">return</span> <em>parent_</em><span class="op">-&gt;</span><em>inner_</em><span class="op">.</span><em>emplace-deref</em><span class="op">(</span>x<span class="op">)</span>;</span>
<span id="cb8-6"><a href="#cb8-6"></a><span class="op">}</span>;</span>
<span id="cb8-7"><a href="#cb8-7"></a><span class="cf">for</span> <span class="op">(</span>; <span><span class="diffins"><span class="math inline"><em>o</em><em>u</em><em>t</em><em>e</em><em>r</em></span>()</span><span class="diffdel"><em>outer_</em></span></span> <span class="op">!=</span> ranges<span class="op">::</span>end<span class="op">(</span><em>parent_</em><span class="op">-&gt;</span><em>base_</em><span class="op">)</span>; <span class="op">++</span><span><span class="diffins"><span class="math inline"><em>o</em><em>u</em><em>t</em><em>e</em><em>r</em></span>()</span><span class="diffdel"><em>outer_</em></span></span><span class="op">)</span> <span class="op">{</span></span>
<span id="cb8-8"><a href="#cb8-8"></a>  <span class="kw">auto</span><span class="op">&amp;&amp;</span> inner <span class="op">=</span> update_inner<span class="op">(</span><span><span class="diffins"><span class="math inline"><em>o</em><em>u</em><em>t</em><em>e</em><em>r</em></span>()</span><span class="diffdel"><em>outer_</em></span></span><span class="op">)</span>;</span>
<span id="cb8-9"><a href="#cb8-9"></a>  <em>inner_</em> <span class="op">=</span> ranges<span class="op">::</span>begin<span class="op">(</span>inner<span class="op">)</span>;</span>
<span id="cb8-10"><a href="#cb8-10"></a>  <span class="cf">if</span> <span class="op">(</span><em>inner_</em> <span class="op">!=</span> ranges<span class="op">::</span>end<span class="op">(</span>inner<span class="op">))</span></span>
<span id="cb8-11"><a href="#cb8-11"></a>    <span class="cf">return</span>;</span>
<span id="cb8-12"><a href="#cb8-12"></a><span class="op">}</span></span>
<span id="cb8-13"><a href="#cb8-13"></a><span class="cf">if</span> <span class="kw">constexpr</span> <span class="op">(</span><em>ref-is-glvalue</em><span class="op">)</span></span>
<span id="cb8-14"><a href="#cb8-14"></a>  <em>inner_</em><span class="op">.</span>reset<span class="op">()</span>;</span></code></pre></div>
</blockquote>
<div class="sourceCode" id="cb9"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb9-1"><a href="#cb9-1"></a><span class="kw">constexpr</span> <em>iterator</em><span class="op">(</span><em>Parent</em><span class="op">&amp;</span> parent, <em>OuterIter</em> outer<span class="op">)</span> <span class="diffins">requires forward_range&lt;<span class="math inline"><em>B</em><em>a</em><em>s</em><em>e</em></span>&gt;</span>;</span></code></pre></div>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_3" id="pnum_3">6</a></span> <em>Effects:</em> Initializes <code class="sourceCode cpp"><em>outer_</em></code> with <code class="sourceCode cpp">std<span class="op">::</span>move<span class="op">(</span>outer<span class="op">)</span></code> and <code class="sourceCode cpp"><em>parent_</em></code> with <code class="sourceCode cpp">addressof<span class="op">(</span>parent<span class="op">)</span></code>; then calls <code class="sourceCode cpp"><em>satisfy</em><span class="op">()</span></code>.</p>
</blockquote>
<div class="add">
<blockquote>

</blockquote>
<div class="sourceCode" id="cb10"><pre class="sourceCode default cpp"><code class="sourceCode default"><span id="cb10-1"><a href="#cb10-1"></a>constexpr explicit <em>iterator</em>(<em>Parent</em>&amp; parent) requires (!forward_range&lt;<em>Base</em>&gt;);</span></code></pre></div>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_4" id="pnum_4">?</a></span> <em>Effects:</em> Initializes <code class="sourceCode default"><em>parent_</em></code> with <code class="sourceCode default">addressof(parent)</code>; then calls <code class="sourceCode default"><em>satisfy</em>()</code>.</p>
</blockquote>
</div>
<div class="sourceCode" id="cb11"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb11-1"><a href="#cb11-1"></a><span class="kw">constexpr</span> <em>iterator</em><span class="op">(</span><em>iterator</em><span class="op">&lt;!</span>Const<span class="op">&gt;</span> i<span class="op">)</span></span>
<span id="cb11-2"><a href="#cb11-2"></a>  <span class="kw">requires</span> Const <span class="op">&amp;&amp;</span></span>
<span id="cb11-3"><a href="#cb11-3"></a>           convertible_to<span class="op">&lt;</span>iterator_t<span class="op">&lt;</span>V<span class="op">&gt;</span>, <em>OuterIter</em><span class="op">&gt;</span> <span class="op">&amp;&amp;</span></span>
<span id="cb11-4"><a href="#cb11-4"></a>           convertible_to<span class="op">&lt;</span>iterator_t<span class="op">&lt;</span><em>InnerRng</em><span class="op">&gt;</span>, <em>InnerIter</em><span class="op">&gt;</span>;</span></code></pre></div>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_5" id="pnum_5">7</a></span> <em>Effects:</em> Initializes <code class="sourceCode cpp"><em>outer_</em></code> with <code class="sourceCode cpp">std<span class="op">::</span>move<span class="op">(</span>i<span class="op">.</span><em>outer_</em><span class="op">)</span></code>, <code class="sourceCode cpp"><em>inner_</em></code> with <code class="sourceCode cpp">std<span class="op">::</span>move<span class="op">(</span>i<span class="op">.</span><em>inner_</em><span class="op">)</span></code>, and <code class="sourceCode cpp"><em>parent_</em></code> with <code class="sourceCode cpp">i<span class="op">.</span><em>parent_</em></code>.</p>
</blockquote>
<div class="add">
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_6" id="pnum_6">?</a></span> <span class="note-"><span>[ <em>Note ?:</em> </span><code class="sourceCode default">Const</code> can only be <code class="sourceCode default">true</code> when <code class="sourceCode default"><em>Base</em></code> models <code class="sourceCode default">forward_range</code>.<span> — <em>end note</em> ]</span></span></p>
</blockquote>
</div>
<div class="sourceCode" id="cb12"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb12-1"><a href="#cb12-1"></a><span class="kw">constexpr</span> <em>InnerIter</em> <span class="kw">operator</span><span class="op">-&gt;()</span> <span class="kw">const</span></span>
<span id="cb12-2"><a href="#cb12-2"></a>  <span class="kw">requires</span> <em>has-arrow</em><span class="op">&lt;</span><em>InnerIter</em><span class="op">&gt;</span> <span class="op">&amp;&amp;</span> copyable<span class="op">&lt;</span><em>InnerIter</em><span class="op">&gt;</span>;</span></code></pre></div>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_7" id="pnum_7">8</a></span> <em>Effects:</em> Equivalent to <code class="sourceCode cpp"><span class="cf">return</span> <em>inner_</em>;</code></p>
</blockquote>
<div class="sourceCode" id="cb13"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb13-1"><a href="#cb13-1"></a><span class="kw">constexpr</span> <em>iterator</em><span class="op">&amp;</span> <span class="kw">operator</span><span class="op">++()</span>;</span></code></pre></div>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_8" id="pnum_8">9</a></span> Let <code class="sourceCode cpp"><em>inner-range</em></code> be:</p>
<ul>
<li><span class="marginalizedparent"><a class="marginalized" href="#pnum_9" id="pnum_9">(9.1)</a></span> If <code class="sourceCode cpp"><em>ref-is-glvalue</em></code> is true, <code class="sourceCode cpp"><span class="op">*</span><span><span class="diffins"><span class="math inline"><em>o</em><em>u</em><em>t</em><em>e</em><em>r</em></span>()</span><span class="diffdel"><em>outer_</em></span></span></code>.</li>
<li><span class="marginalizedparent"><a class="marginalized" href="#pnum_10" id="pnum_10">(9.2)</a></span> Otherwise, <code class="sourceCode cpp"><span class="op">*</span><em>parent_</em><span class="op">-&gt;</span><em>inner_</em></code>.</li>
</ul>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_11" id="pnum_11">10</a></span> <em>Effects:</em> Equivalent to:</p>
<div class="sourceCode" id="cb14"><pre class="sourceCode cpp nonitem"><code class="sourceCode cpp"><span id="cb14-1"><a href="#cb14-1"></a><span class="diffdel">auto&amp;&amp; inner_rng = <em>inner-range</em>;</span></span>
<span id="cb14-2"><a href="#cb14-2"></a><span class="cf">if</span> <span class="op">(++</span><em>inner_</em> <span class="op">==</span> ranges<span class="op">::</span>end<span class="op">(</span><span><span class="diffins"><em>as-lvalue</em>(<em>inner-range</em>)</span><span class="diffdel">inner_rng</span></span><span class="op">))</span> <span class="op">{</span></span>
<span id="cb14-3"><a href="#cb14-3"></a>  <span class="op">++</span><span><span class="diffins"><span class="math inline"><em>o</em><em>u</em><em>t</em><em>e</em><em>r</em></span>()</span><span class="diffdel"><em>outer_</em></span></span>;</span>
<span id="cb14-4"><a href="#cb14-4"></a>  <em>satisfy</em><span class="op">()</span>;</span>
<span id="cb14-5"><a href="#cb14-5"></a><span class="op">}</span></span>
<span id="cb14-6"><a href="#cb14-6"></a><span class="cf">return</span> <span class="op">*</span><span class="kw">this</span>;</span></code></pre></div>
</blockquote>
<div class="sourceCode" id="cb15"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb15-1"><a href="#cb15-1"></a><span class="kw">constexpr</span> <span class="dt">void</span> <span class="kw">operator</span><span class="op">++(</span><span class="dt">int</span><span class="op">)</span>;</span></code></pre></div>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_12" id="pnum_12">11</a></span> <em>Effects:</em> Equivalent to: <code class="sourceCode cpp"><span class="op">++*</span><span class="kw">this</span></code>.</p>
</blockquote>
<div class="sourceCode" id="cb16"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb16-1"><a href="#cb16-1"></a><span class="kw">constexpr</span> <em>iterator</em> <span class="kw">operator</span><span class="op">++(</span><span class="dt">int</span><span class="op">)</span></span>
<span id="cb16-2"><a href="#cb16-2"></a>  <span class="kw">requires</span> <em>ref-is-glvalue</em> <span class="op">&amp;&amp;</span> forward_range<span class="op">&lt;</span><em>Base</em><span class="op">&gt;</span> <span class="op">&amp;&amp;</span></span>
<span id="cb16-3"><a href="#cb16-3"></a>           forward_range<span class="op">&lt;</span>range_reference_t<span class="op">&lt;</span><em>Base</em><span class="op">&gt;&gt;</span>;</span></code></pre></div>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_13" id="pnum_13">12</a></span> <em>Effects:</em> Equivalent to:</p>
<div class="sourceCode" id="cb17"><pre class="sourceCode cpp nonitem"><code class="sourceCode cpp"><span id="cb17-1"><a href="#cb17-1"></a><span class="kw">auto</span> tmp <span class="op">=</span> <span class="op">*</span><span class="kw">this</span>;</span>
<span id="cb17-2"><a href="#cb17-2"></a><span class="op">++*</span><span class="kw">this</span>;</span>
<span id="cb17-3"><a href="#cb17-3"></a><span class="cf">return</span> tmp;</span></code></pre></div>
</blockquote>
<div class="sourceCode" id="cb18"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb18-1"><a href="#cb18-1"></a><span class="kw">constexpr</span> <em>iterator</em><span class="op">&amp;</span> <span class="kw">operator</span><span class="op">--()</span></span>
<span id="cb18-2"><a href="#cb18-2"></a>  <span class="kw">requires</span> <em>ref-is-glvalue</em> <span class="op">&amp;&amp;</span> bidirectional_range<span class="op">&lt;</span><em>Base</em><span class="op">&gt;</span> <span class="op">&amp;&amp;</span></span>
<span id="cb18-3"><a href="#cb18-3"></a>           bidirectional_range<span class="op">&lt;</span>range_reference_t<span class="op">&lt;</span><em>Base</em><span class="op">&gt;&gt;</span> <span class="op">&amp;&amp;</span></span>
<span id="cb18-4"><a href="#cb18-4"></a>           common_range<span class="op">&lt;</span>range_reference_t<span class="op">&lt;</span><em>Base</em><span class="op">&gt;&gt;</span>;</span></code></pre></div>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_14" id="pnum_14">13</a></span> <em>Effects:</em> Equivalent to:</p>
<div class="sourceCode" id="cb19"><pre class="sourceCode cpp nonitem"><code class="sourceCode cpp"><span id="cb19-1"><a href="#cb19-1"></a><span class="cf">if</span> <span class="op">(</span><em>outer_</em> <span class="op">==</span> ranges<span class="op">::</span>end<span class="op">(</span><em>parent_</em><span class="op">-&gt;</span><em>Base</em>_<span class="op">))</span></span>
<span id="cb19-2"><a href="#cb19-2"></a>  <em>inner_</em> <span class="op">=</span> ranges<span class="op">::</span>end<span class="op">(</span><span class="diffins"><em>as-lvalue</em>(</span><span class="op">*--</span><em>outer_</em><span class="diffins">)</span><span class="op">)</span>;</span>
<span id="cb19-3"><a href="#cb19-3"></a><span class="cf">while</span> <span class="op">(</span><em>inner_</em> <span class="op">==</span> ranges<span class="op">::</span>begin<span class="op">(</span><span class="diffins"><em>as-lvalue</em>(</span><span class="op">*</span><em>outer_</em><span class="diffins">)</span><span class="op">))</span></span>
<span id="cb19-4"><a href="#cb19-4"></a>  <em>inner_</em> <span class="op">=</span> ranges<span class="op">::</span>end<span class="op">(</span><span class="diffins"><em>as-lvalue</em>(</span><span class="op">*--</span><em>outer_</em><span class="diffins">)</span><span class="op">)</span>;</span>
<span id="cb19-5"><a href="#cb19-5"></a><span class="op">--</span><em>inner_</em>;</span>
<span id="cb19-6"><a href="#cb19-6"></a><span class="cf">return</span> <span class="op">*</span><span class="kw">this</span>;</span></code></pre></div>
</blockquote>
<div class="sourceCode" id="cb20"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb20-1"><a href="#cb20-1"></a><span class="kw">constexpr</span> <em>iterator</em> <span class="kw">operator</span><span class="op">--(</span><span class="dt">int</span><span class="op">)</span></span>
<span id="cb20-2"><a href="#cb20-2"></a>  <span class="kw">requires</span> <em>ref-is-glvalue</em> <span class="op">&amp;&amp;</span> bidirectional_range<span class="op">&lt;</span><em>Base</em><span class="op">&gt;</span> <span class="op">&amp;&amp;</span></span>
<span id="cb20-3"><a href="#cb20-3"></a>           bidirectional_range<span class="op">&lt;</span>range_reference_t<span class="op">&lt;</span><em>Base</em><span class="op">&gt;&gt;</span> <span class="op">&amp;&amp;</span></span>
<span id="cb20-4"><a href="#cb20-4"></a>           common_range<span class="op">&lt;</span>range_reference_t<span class="op">&lt;</span><em>Base</em><span class="op">&gt;&gt;</span>;</span></code></pre></div>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_15" id="pnum_15">14</a></span> <em>Effects:</em> Equivalent to:</p>
<div class="sourceCode" id="cb21"><pre class="sourceCode cpp nonitem"><code class="sourceCode cpp"><span id="cb21-1"><a href="#cb21-1"></a><span class="kw">auto</span> tmp <span class="op">=</span> <span class="op">*</span><span class="kw">this</span>;</span>
<span id="cb21-2"><a href="#cb21-2"></a><span class="op">--*</span><span class="kw">this</span>;</span>
<span id="cb21-3"><a href="#cb21-3"></a><span class="cf">return</span> tmp;</span></code></pre></div>
</blockquote>
<div class="sourceCode" id="cb22"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb22-1"><a href="#cb22-1"></a><span class="kw">friend</span> <span class="kw">constexpr</span> <span class="dt">bool</span> <span class="kw">operator</span><span class="op">==(</span><span class="kw">const</span> <em>iterator</em><span class="op">&amp;</span> x, <span class="kw">const</span> <em>iterator</em><span class="op">&amp;</span> y<span class="op">)</span></span>
<span id="cb22-2"><a href="#cb22-2"></a>  <span class="kw">requires</span> <em>ref-is-glvalue</em> <span class="op">&amp;&amp;</span> <span><span class="diffins"><code class="sourceCode cpp">forward_range<span class="op">&lt;</span><em>Base</em><span class="op">&gt;</span></code></span><span class="diffdel"><code class="sourceCode cpp">equality_­comparable<span class="op">&lt;</span>iterator_t<span class="op">&lt;</span>Base<span class="op">&gt;&gt;</span></code></span></span> <span class="op">&amp;&amp;</span></span>
<span id="cb22-3"><a href="#cb22-3"></a>           equality_comparable<span class="op">&lt;</span>iterator_t<span class="op">&lt;</span>range_reference_t<span class="op">&lt;</span><em>Base</em><span class="op">&gt;&gt;&gt;</span>;</span></code></pre></div>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_16" id="pnum_16">15</a></span> <em>Effects:</em> Equivalent to: <code class="sourceCode cpp"><span class="cf">return</span> x<span class="op">.</span><em>outer_</em> <span class="op">==</span> y<span class="op">.</span><em>outer_</em> <span class="op">&amp;&amp;</span> x<span class="op">.</span><em>inner_</em> <span class="op">==</span> y<span class="op">.</span><em>inner_</em>;</code></p>
</blockquote>
<div class="sourceCode" id="cb23"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb23-1"><a href="#cb23-1"></a><span class="kw">friend</span> <span class="kw">constexpr</span> <span class="dt">void</span> iter_swap<span class="op">(</span><span class="kw">const</span> <em>iterator</em><span class="op">&amp;</span> x, <span class="kw">const</span> <em>iterator</em><span class="op">&amp;</span> y<span class="op">)</span></span>
<span id="cb23-2"><a href="#cb23-2"></a>  <span class="kw">noexcept</span><span class="op">(</span><span class="kw">noexcept</span><span class="op">(</span>ranges<span class="op">::</span>iter_swap<span class="op">(</span>x<span class="op">.</span><em>inner_</em>, y<span class="op">.</span><em>inner_</em><span class="op">)))</span></span>
<span id="cb23-3"><a href="#cb23-3"></a>  <span class="kw">requires</span> indirectly_swappable<span class="op">&lt;</span><em>InnerIter</em><span class="op">&gt;</span>;</span></code></pre></div>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_17" id="pnum_17">16</a></span> <em>Effects:</em> Equivalent to: <code class="sourceCode cpp"><span class="cf">return</span> ranges<span class="op">::</span>iter_swap<span class="op">(</span>x<span class="op">.</span><em>inner_</em>, y<span class="op">.</span><em>inner_</em><span class="op">)</span>;</code></p>
</blockquote>
</div>
</blockquote>
<ol start="6" type="1">
<li>Edit <span>26.7.14.4 <a href="https://wg21.link/range.join.sentinel">[range.join.sentinel]</a></span> p3 as indicated:</li>
</ol>
<blockquote>
<div>
<div class="sourceCode" id="cb24"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb24-1"><a href="#cb24-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="dt">bool</span> OtherConst<span class="op">&gt;</span></span>
<span id="cb24-2"><a href="#cb24-2"></a>  <span class="kw">requires</span> sentinel_for<span class="op">&lt;</span>sentinel_t<span class="op">&lt;</span><em>Base</em><span class="op">&gt;</span>, iterator_t<span class="op">&lt;</span><em>maybe-const</em><span class="op">&lt;</span>OtherConst, V<span class="op">&gt;&gt;&gt;</span></span>
<span id="cb24-3"><a href="#cb24-3"></a><span class="kw">friend</span> <span class="kw">constexpr</span> <span class="dt">bool</span> <span class="kw">operator</span><span class="op">==(</span><span class="kw">const</span> <em>iterator</em><span class="op">&lt;</span>OtherConst<span class="op">&gt;&amp;</span> x, <span class="kw">const</span> <em>sentinel</em><span class="op">&amp;</span> y<span class="op">)</span>;</span></code></pre></div>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_18" id="pnum_18">3</a></span> <em>Effects:</em> Equivalent to: <code class="sourceCode cpp"><span class="cf">return</span> x<span class="op">.</span><span><span class="diffins"><span class="math inline"><em>o</em><em>u</em><em>t</em><em>e</em><em>r</em></span>()</span><span class="diffdel"><em>outer_</em></span></span> <span class="op">==</span> y<span class="op">.</span><em>end_</em>;</code></p>
</blockquote>
</div>
</blockquote>
<ol start="7" type="1">
<li>Edit <span>26.7.15.2 <a href="https://wg21.link/range.join.with.view">[range.join.with.view]</a></span>, class template <code class="sourceCode cpp">join_with_view</code> synopsis, as indicated:</li>
</ol>
<blockquote>
<div>
<div class="sourceCode" id="cb25"><pre class="sourceCode diff"><code class="sourceCode diff"><span id="cb25-1"><a href="#cb25-1"></a> namespace std::ranges {</span>
<span id="cb25-2"><a href="#cb25-2"></a>   [...]</span>
<span id="cb25-3"><a href="#cb25-3"></a></span>
<span id="cb25-4"><a href="#cb25-4"></a>   template&lt;input_range V, forward_range Pattern&gt;</span>
<span id="cb25-5"><a href="#cb25-5"></a>     requires view&lt;V&gt; &amp;&amp; input_range&lt;range_reference_t&lt;V&gt;&gt;</span>
<span id="cb25-6"><a href="#cb25-6"></a>           &amp;&amp; view&lt;Pattern&gt;</span>
<span id="cb25-7"><a href="#cb25-7"></a>           &amp;&amp; <em>compatible-joinable-ranges</em>&lt;range_reference_t&lt;V&gt;, Pattern&gt;</span>
<span id="cb25-8"><a href="#cb25-8"></a>   class join_with_view : public view_interface&lt;join_with_view&lt;V, Pattern&gt;&gt; {</span>
<span id="cb25-9"><a href="#cb25-9"></a>     using <em>InnerRng</em> = range_reference_t&lt;V&gt;;                  // exposition only</span>
<span id="cb25-10"><a href="#cb25-10"></a></span>
<span id="cb25-11"><a href="#cb25-11"></a>     V <em>base_</em> = V();                                          // exposition only</span>
<span id="cb25-12"><a href="#cb25-12"></a><span class="va">+    <em>non-propagating-cache</em>&lt;iterator_t&lt;V&gt;&gt; <em>outer_it_</em>;         // exposition only, present only</span></span>
<span id="cb25-13"><a href="#cb25-13"></a><span class="va">+                                                            // when !forward_range&lt;V&gt;</span></span>
<span id="cb25-14"><a href="#cb25-14"></a>     <em>non-propagating-cache</em>&lt;remove_cv_t&lt;<em>InnerRng</em>&gt;&gt; <em>inner_</em>;    // exposition only, present only</span>
<span id="cb25-15"><a href="#cb25-15"></a>                                                             // when !is_reference_v&lt;<em>InnerRng</em>&gt;</span>
<span id="cb25-16"><a href="#cb25-16"></a>     Pattern <em>pattern_</em> = Pattern();                           // exposition only</span>
<span id="cb25-17"><a href="#cb25-17"></a></span>
<span id="cb25-18"><a href="#cb25-18"></a>     // <span>26.7.15.3 <a href="https://wg21.link/range.join.with.iterator">[range.join.with.iterator]</a></span>, class template join_with_view::<em>iterator</em></span>
<span id="cb25-19"><a href="#cb25-19"></a>     template&lt;bool Const&gt; struct <em>iterator</em>;                   // exposition only</span>
<span id="cb25-20"><a href="#cb25-20"></a></span>
<span id="cb25-21"><a href="#cb25-21"></a>     // <span>26.7.15.4 <a href="https://wg21.link/range.join.with.sentinel">[range.join.with.sentinel]</a></span>, class template join_with_view::<em>sentinel</em></span>
<span id="cb25-22"><a href="#cb25-22"></a>     template&lt;bool Const&gt; struct <em>sentinel</em>;                   // exposition only</span>
<span id="cb25-23"><a href="#cb25-23"></a></span>
<span id="cb25-24"><a href="#cb25-24"></a>   public:</span>
<span id="cb25-25"><a href="#cb25-25"></a>     [...]</span>
<span id="cb25-26"><a href="#cb25-26"></a></span>
<span id="cb25-27"><a href="#cb25-27"></a>     constexpr auto begin() {</span>
<span id="cb25-28"><a href="#cb25-28"></a><span class="va">+      if constexpr (forward_range&lt;V&gt;) {</span></span>
<span id="cb25-29"><a href="#cb25-29"></a>         constexpr bool use_const =</span>
<span id="cb25-30"><a href="#cb25-30"></a>           <em>simple-view</em>&lt;V&gt; &amp;&amp; is_reference_v&lt;<em>InnerRng</em>&gt; &amp;&amp; <em>simple-view</em>&lt;Pattern&gt;;</span>
<span id="cb25-31"><a href="#cb25-31"></a>         return <em>iterator</em>&lt;use_const&gt;{*this, ranges::begin(<em>base_</em>)};</span>
<span id="cb25-32"><a href="#cb25-32"></a><span class="va">+      }</span></span>
<span id="cb25-33"><a href="#cb25-33"></a><span class="va">+      else {</span></span>
<span id="cb25-34"><a href="#cb25-34"></a><span class="va">+        <em>outer_it_</em> = ranges::begin(<em>base_</em>);</span></span>
<span id="cb25-35"><a href="#cb25-35"></a><span class="va">+        return <em>iterator</em>&lt;false&gt;{*this};</span></span>
<span id="cb25-36"><a href="#cb25-36"></a><span class="va">+      }</span></span>
<span id="cb25-37"><a href="#cb25-37"></a>     }</span>
<span id="cb25-38"><a href="#cb25-38"></a></span>
<span id="cb25-39"><a href="#cb25-39"></a>     constexpr auto begin() const</span>
<span id="cb25-40"><a href="#cb25-40"></a>       requires <span><span class="diffins">forward</span><span class="diffdel">input</span></span>_range&lt;const V&gt; &amp;&amp;</span>
<span id="cb25-41"><a href="#cb25-41"></a>                forward_range&lt;const Pattern&gt; &amp;&amp;</span>
<span id="cb25-42"><a href="#cb25-42"></a>                is_reference_v&lt;range_reference_t&lt;const V&gt;&gt; <span class="diffins">&amp;&amp;</span></span>
<span id="cb25-43"><a href="#cb25-43"></a><span class="va">+               input_range&lt;range_reference_t&lt;const V&gt;&gt;</span></span>
<span id="cb25-44"><a href="#cb25-44"></a>     { return <em>iterator</em>&lt;true&gt;{*this, ranges::begin(<em>base_</em>)}; }</span>
<span id="cb25-45"><a href="#cb25-45"></a></span>
<span id="cb25-46"><a href="#cb25-46"></a>     constexpr auto end() {</span>
<span id="cb25-47"><a href="#cb25-47"></a>       if constexpr (forward_range&lt;V&gt; &amp;&amp;</span>
<span id="cb25-48"><a href="#cb25-48"></a>                     is_reference_v&lt;<em>InnerRng</em>&gt; &amp;&amp; forward_range&lt;<em>InnerRng</em>&gt; &amp;&amp;</span>
<span id="cb25-49"><a href="#cb25-49"></a>                     common_range&lt;V&gt; &amp;&amp; common_range&lt;<em>InnerRng</em>&gt;)</span>
<span id="cb25-50"><a href="#cb25-50"></a>         return <em>iterator</em>&lt;<em>simple-view</em>&lt;V&gt; &amp;&amp; <em>simple-view</em>&lt;Pattern&gt;&gt;{*this, ranges::end(<em>base_</em>)};</span>
<span id="cb25-51"><a href="#cb25-51"></a>       else</span>
<span id="cb25-52"><a href="#cb25-52"></a>         return <em>sentinel</em>&lt;<em>simple-view</em>&lt;V&gt; &amp;&amp; <em>simple-view</em>&lt;Pattern&gt;&gt;{*this};</span>
<span id="cb25-53"><a href="#cb25-53"></a>     }</span>
<span id="cb25-54"><a href="#cb25-54"></a></span>
<span id="cb25-55"><a href="#cb25-55"></a>     constexpr auto end() const</span>
<span id="cb25-56"><a href="#cb25-56"></a>       requires <span><span class="diffins">forward</span><span class="diffdel">input</span></span>_range&lt;const V&gt; &amp;&amp; forward_range&lt;const Pattern&gt; &amp;&amp;</span>
<span id="cb25-57"><a href="#cb25-57"></a>                is_reference_v&lt;range_reference_t&lt;const V&gt;&gt; <span class="diffins">&amp;&amp;</span></span>
<span id="cb25-58"><a href="#cb25-58"></a><span class="va">+               input_range&lt;range_reference_t&lt;const V&gt;&gt;</span></span>
<span id="cb25-59"><a href="#cb25-59"></a>     {</span>
<span id="cb25-60"><a href="#cb25-60"></a>       using InnerConstRng = range_reference_t&lt;const V&gt;;</span>
<span id="cb25-61"><a href="#cb25-61"></a>       if constexpr (<span class="diffdel">forward_range&lt;const V&gt; &amp;&amp;</span> forward_range&lt;InnerConstRng&gt; &amp;&amp;</span>
<span id="cb25-62"><a href="#cb25-62"></a>                     common_range&lt;const V&gt; &amp;&amp; common_range&lt;InnerConstRng&gt;)</span>
<span id="cb25-63"><a href="#cb25-63"></a>         return <em>iterator</em>&lt;true&gt;{*this, ranges::end(<em>base_</em>)};</span>
<span id="cb25-64"><a href="#cb25-64"></a>       else</span>
<span id="cb25-65"><a href="#cb25-65"></a>         return <em>sentinel</em>&lt;true&gt;{*this};</span>
<span id="cb25-66"><a href="#cb25-66"></a>     }</span>
<span id="cb25-67"><a href="#cb25-67"></a>   };</span>
<span id="cb25-68"><a href="#cb25-68"></a></span>
<span id="cb25-69"><a href="#cb25-69"></a>   [...]</span>
<span id="cb25-70"><a href="#cb25-70"></a> }</span></code></pre></div>
</div>
</blockquote>
<ol start="8" type="1">
<li>Edit <span>26.7.15.3 <a href="https://wg21.link/range.join.with.iterator">[range.join.with.iterator]</a></span> as indicated:</li>
</ol>
<blockquote>
<div>
<div class="sourceCode" id="cb26"><pre class="sourceCode diff"><code class="sourceCode diff"><span id="cb26-1"><a href="#cb26-1"></a> namespace std::ranges {</span>
<span id="cb26-2"><a href="#cb26-2"></a>   template&lt;input_range V, forward_range Pattern&gt;</span>
<span id="cb26-3"><a href="#cb26-3"></a>     requires view&lt;V&gt; &amp;&amp; input_range&lt;range_reference_t&lt;V&gt;&gt;</span>
<span id="cb26-4"><a href="#cb26-4"></a>           &amp;&amp; view&lt;Pattern&gt; &amp;&amp; <em>compatible-joinable-ranges</em>&lt;range_reference_t&lt;V&gt;, Pattern&gt;</span>
<span id="cb26-5"><a href="#cb26-5"></a>   template&lt;bool Const&gt;</span>
<span id="cb26-6"><a href="#cb26-6"></a>   class join_with_view&lt;V, Pattern&gt;::<em>iterator</em> {</span>
<span id="cb26-7"><a href="#cb26-7"></a>     using <em>Parent</em> = <em>maybe-const</em>&lt;Const, join_with_view&gt;;                  // exposition only</span>
<span id="cb26-8"><a href="#cb26-8"></a>     using <em>Base</em> = <em>maybe-const</em>&lt;Const, V&gt;;                                 // exposition only</span>
<span id="cb26-9"><a href="#cb26-9"></a>     using <em>InnerBase</em> = range_reference_t&lt;<em>Base</em>&gt;;                          // exposition only</span>
<span id="cb26-10"><a href="#cb26-10"></a>     using <em>PatternBase</em> = <em>maybe-const</em>&lt;Const, Pattern&gt;;                    // exposition only</span>
<span id="cb26-11"><a href="#cb26-11"></a></span>
<span id="cb26-12"><a href="#cb26-12"></a>     using <em>OuterIter</em> = iterator_t&lt;<em>Base</em>&gt;;                                 // exposition only</span>
<span id="cb26-13"><a href="#cb26-13"></a>     using <em>InnerIter</em> = iterator_t&lt;<em>InnerBase</em>&gt;;                            // exposition only</span>
<span id="cb26-14"><a href="#cb26-14"></a>     using <em>PatternIter</em> = iterator_t&lt;<em>PatternBase</em>&gt;;                        // exposition only</span>
<span id="cb26-15"><a href="#cb26-15"></a></span>
<span id="cb26-16"><a href="#cb26-16"></a>     static constexpr bool <em>ref-is-glvalue</em> = is_reference_v&lt;<em>InnerBase</em>&gt;;   // exposition only</span>
<span id="cb26-17"><a href="#cb26-17"></a></span>
<span id="cb26-18"><a href="#cb26-18"></a>     <em>Parent</em>* <em>parent_</em> = nullptr;                                          // exposition only</span>
<span id="cb26-19"><a href="#cb26-19"></a>     <em>OuterIter</em> <em>outer_it_</em> = <em>OuterIter</em>();                                  // exposition only<span class="diffins">,</span></span>
<span id="cb26-20"><a href="#cb26-20"></a><span class="va">+                                                                        // present only if <em>Base</em> models forward_range</span></span>
<span id="cb26-21"><a href="#cb26-21"></a>     variant&lt;<em>PatternIter</em>, <em>InnerIter</em>&gt; <em>inner_it_</em>;                          // exposition only</span>
<span id="cb26-22"><a href="#cb26-22"></a></span>
<span id="cb26-23"><a href="#cb26-23"></a><span class="st">-    constexpr <em>iterator</em>(<em>Parent</em>&amp; parent, iterator_t&lt;<em>Base</em>&gt; outer);         // exposition only</span></span>
<span id="cb26-24"><a href="#cb26-24"></a><span class="va">+    constexpr <em>iterator</em>(<em>Parent</em>&amp; parent, <em>OuterIter</em> outer)</span></span>
<span id="cb26-25"><a href="#cb26-25"></a><span class="va">+      requires forward_range&lt;<em>Base</em>&gt;;                                     // exposition only</span></span>
<span id="cb26-26"><a href="#cb26-26"></a><span class="va">+    constexpr explicit <em>iterator</em>(<em>Parent</em>&amp; parent)</span></span>
<span id="cb26-27"><a href="#cb26-27"></a><span class="va">+      requires (!forward_range&lt;<em>Base</em>&gt;);                                  // exposition only</span></span>
<span id="cb26-28"><a href="#cb26-28"></a><span class="va">+    constexpr <em>OuterIter</em>&amp; <em>outer</em>();                                       // exposition only</span></span>
<span id="cb26-29"><a href="#cb26-29"></a><span class="va">+    constexpr const <em>OuterIter</em>&amp; <em>outer</em>() const;                           // exposition only</span></span>
<span id="cb26-30"><a href="#cb26-30"></a>     constexpr auto&amp;<span class="diffdel">&amp;</span> <em>update-inner</em>(<span class="diffdel">const <span class="math inline"><em>O</em><em>u</em><em>t</em><em>e</em><em>r</em><em>I</em><em>t</em><em>e</em><em>r</em></span>&amp;</span>);                    // exposition only</span>
<span id="cb26-31"><a href="#cb26-31"></a>     constexpr auto&amp;<span class="diffdel">&amp;</span> <em>get-inner</em>(<span class="diffdel">const <span class="math inline"><em>O</em><em>u</em><em>t</em><em>e</em><em>r</em><em>I</em><em>t</em><em>e</em><em>r</em></span>&amp;</span>);                       // exposition only</span>
<span id="cb26-32"><a href="#cb26-32"></a>     constexpr void <em>satisfy</em>();                                           // exposition only</span>
<span id="cb26-33"><a href="#cb26-33"></a></span>
<span id="cb26-34"><a href="#cb26-34"></a>   public:</span>
<span id="cb26-35"><a href="#cb26-35"></a>     using iterator_concept  = <em>see below</em>;</span>
<span id="cb26-36"><a href="#cb26-36"></a>     using iterator_category = <em>see below</em>;                                // not always present</span>
<span id="cb26-37"><a href="#cb26-37"></a>     using value_type        = <em>see below</em>;</span>
<span id="cb26-38"><a href="#cb26-38"></a>     using difference_type   = <em>see below</em>;</span>
<span id="cb26-39"><a href="#cb26-39"></a></span>
<span id="cb26-40"><a href="#cb26-40"></a>     <em>iterator</em>() <span class="diffdel">requires default_initializable&lt;<span class="math inline"><em>O</em><em>u</em><em>t</em><em>e</em><em>r</em><em>I</em><em>t</em><em>e</em><em>r</em></span>&gt;</span> = default;</span>
<span id="cb26-41"><a href="#cb26-41"></a>     constexpr <em>iterator</em>(<em>iterator</em>&lt;!Const&gt; i)</span>
<span id="cb26-42"><a href="#cb26-42"></a>       requires Const &amp;&amp; convertible_to&lt;iterator_t&lt;V&gt;, <em>OuterIter</em>&gt; &amp;&amp;</span>
<span id="cb26-43"><a href="#cb26-43"></a>               convertible_to&lt;iterator_t&lt;<em>InnerRng</em>&gt;, <em>InnerIter</em>&gt; &amp;&amp;</span>
<span id="cb26-44"><a href="#cb26-44"></a>               convertible_to&lt;iterator_t&lt;Pattern&gt;, <em>PatternIter</em>&gt;;</span>
<span id="cb26-45"><a href="#cb26-45"></a></span>
<span id="cb26-46"><a href="#cb26-46"></a>     [...]</span>
<span id="cb26-47"><a href="#cb26-47"></a></span>
<span id="cb26-48"><a href="#cb26-48"></a>     friend constexpr bool operator==(const <em>iterator</em>&amp; x, const <em>iterator</em>&amp; y)</span>
<span id="cb26-49"><a href="#cb26-49"></a>        requires <em>ref-is-glvalue</em> &amp;&amp; <span><span class="diffins"><code class="sourceCode cpp">forward_range<span class="op">&lt;</span><em>Base</em><span class="op">&gt;</span></code></span><span class="diffdel"><code class="sourceCode cpp">equality_­comparable<span class="op">&lt;</span><em>OuterIter</em><span class="op">&gt;</span></code></span></span> &amp;&amp;</span>
<span id="cb26-50"><a href="#cb26-50"></a>                 equality_­comparable&lt;<em>InnerIter</em>&gt;;</span>
<span id="cb26-51"><a href="#cb26-51"></a></span>
<span id="cb26-52"><a href="#cb26-52"></a>     [...]</span>
<span id="cb26-53"><a href="#cb26-53"></a>   };</span>
<span id="cb26-54"><a href="#cb26-54"></a> }</span></code></pre></div>
</div>
<p>[…]</p>
<div>
<div class="add">
<blockquote>

</blockquote>
<div class="sourceCode" id="cb27"><pre class="sourceCode default cpp"><code class="sourceCode default"><span id="cb27-1"><a href="#cb27-1"></a>    constexpr <em>OuterIter</em>&amp; <em>outer</em>();</span>
<span id="cb27-2"><a href="#cb27-2"></a>    constexpr const <em>OuterIter</em>&amp; <em>outer</em>() const;</span></code></pre></div>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_19" id="pnum_19">?</a></span> <em>Returns:</em> <code class="sourceCode default"><em>outer_it_</em></code> if <code class="sourceCode default"><em>Base</em></code> models <code class="sourceCode default">forward_range</code>; otherwise, <code class="sourceCode default">*<em>parent_</em>-&gt;<em>outer_it_</em></code>.</p>
</blockquote>
</div>
<div class="sourceCode" id="cb28"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb28-1"><a href="#cb28-1"></a><span class="kw">constexpr</span> <span class="kw">auto</span><span class="op">&amp;</span><span class="diffdel">&amp;</span> <em>update-inner</em><span class="op">(</span><span class="diffdel">const <span class="math inline"><em>O</em><em>u</em><em>t</em><em>e</em><em>r</em><em>I</em><em>t</em><em>e</em><em>r</em></span>&amp; x</span><span class="op">)</span>;</span></code></pre></div>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_20" id="pnum_20">5</a></span> <em>Effects</em>: Equivalent to:</p>
<div class="sourceCode" id="cb29"><pre class="sourceCode cpp nonitem"><code class="sourceCode cpp"><span id="cb29-1"><a href="#cb29-1"></a><span class="cf">if</span> <span class="kw">constexpr</span> <span class="op">(</span><em>ref-is-glvalue</em><span class="op">)</span></span>
<span id="cb29-2"><a href="#cb29-2"></a>  <span class="cf">return</span> <span class="diffins"><em>as-lvalue</em>(</span>*<span><span class="diffins"><span class="math inline"><em>o</em><em>u</em><em>t</em><em>e</em><em>r</em></span>()</span><span class="diffdel">x</span></span><span class="diffins">)</span>;</span>
<span id="cb29-3"><a href="#cb29-3"></a><span class="cf">else</span></span>
<span id="cb29-4"><a href="#cb29-4"></a>  <span class="cf">return</span> <em>parent_</em><span class="op">-&gt;</span><em>inner_</em><span class="op">.</span><em>emplace-deref</em><span class="op">(</span><span><span class="diffins"><span class="math inline"><em>o</em><em>u</em><em>t</em><em>e</em><em>r</em></span>()</span><span class="diffdel">x</span></span><span class="op">)</span>;</span></code></pre></div>
</blockquote>
<div class="sourceCode" id="cb30"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb30-1"><a href="#cb30-1"></a><span class="kw">constexpr</span> <span class="kw">auto</span><span class="op">&amp;</span><span class="diffdel">&amp;</span> <em>get-inner</em><span class="op">(</span><span class="diffdel">const <span class="math inline"><em>O</em><em>u</em><em>t</em><em>e</em><em>r</em><em>I</em><em>t</em><em>e</em><em>r</em></span>&amp; x</span><span class="op">)</span>;</span></code></pre></div>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_21" id="pnum_21">6</a></span> <em>Effects</em>: Equivalent to:</p>
<div class="sourceCode" id="cb31"><pre class="sourceCode cpp nonitem"><code class="sourceCode cpp"><span id="cb31-1"><a href="#cb31-1"></a><span class="cf">if</span> <span class="kw">constexpr</span> <span class="op">(</span><em>ref-is-glvalue</em><span class="op">)</span></span>
<span id="cb31-2"><a href="#cb31-2"></a>  <span class="cf">return</span> <span class="diffins"><em>as-lvalue</em>(</span>*<span><span class="diffins"><span class="math inline"><em>o</em><em>u</em><em>t</em><em>e</em><em>r</em></span>()</span><span class="diffdel">x</span></span><span class="diffins">)</span>;</span>
<span id="cb31-3"><a href="#cb31-3"></a><span class="cf">else</span></span>
<span id="cb31-4"><a href="#cb31-4"></a>  <span class="cf">return</span> <span class="op">*</span><em>parent_</em><span class="op">-&gt;</span><em>inner_</em>;</span></code></pre></div>
</blockquote>
<div class="sourceCode" id="cb32"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb32-1"><a href="#cb32-1"></a>    <span class="kw">constexpr</span> <span class="dt">void</span> <em>satisfy</em><span class="op">()</span>;</span></code></pre></div>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_22" id="pnum_22">5</a></span> <em>Effects:</em> Equivalent to:</p>
<div class="sourceCode" id="cb33"><pre class="sourceCode cpp nonitem"><code class="sourceCode cpp"><span id="cb33-1"><a href="#cb33-1"></a><span class="cf">while</span> <span class="op">(</span><span class="kw">true</span><span class="op">)</span> <span class="op">{</span></span>
<span id="cb33-2"><a href="#cb33-2"></a>  <span class="cf">if</span> <span class="op">(</span><em>inner_it_</em><span class="op">.</span>index<span class="op">()</span> <span class="op">==</span> <span class="dv">0</span><span class="op">)</span> <span class="op">{</span></span>
<span id="cb33-3"><a href="#cb33-3"></a>    <span class="cf">if</span> <span class="op">(</span>std<span class="op">::</span>get<span class="op">&lt;</span><span class="dv">0</span><span class="op">&gt;(</span><em>inner_it_</em><span class="op">)</span> <span class="op">!=</span> ranges<span class="op">::</span>end<span class="op">(</span><em>parent_</em><span class="op">-&gt;</span><em>pattern_</em><span class="op">))</span></span>
<span id="cb33-4"><a href="#cb33-4"></a>      <span class="cf">break</span>;</span>
<span id="cb33-5"><a href="#cb33-5"></a>    <span class="diffdel"><code class="sourceCode cpp"><span class="kw">auto</span><span class="op">&amp;&amp;</span> inner <span class="op">=</span> <em>update-inner</em><span class="op">(</span><em>outer_it_</em><span class="op">)</span>;</code></span></span>
<span id="cb33-6"><a href="#cb33-6"></a>    <em>inner_it_</em><span class="op">.</span>emplace<span class="op">&lt;</span><span class="dv">1</span><span class="op">&gt;(</span>ranges<span class="op">::</span>begin<span class="op">(</span><span><span class="diffins"><code class="sourceCode cpp"><em>update-inner</em><span class="op">()</span></code></span><span class="diffdel">inner</span></span><span class="op">))</span>;</span>
<span id="cb33-7"><a href="#cb33-7"></a>  <span class="op">}</span> <span class="cf">else</span> <span class="op">{</span></span>
<span id="cb33-8"><a href="#cb33-8"></a>    <span class="diffdel"><code class="sourceCode cpp"><span class="kw">auto</span><span class="op">&amp;&amp;</span> inner <span class="op">=</span> <em>get-inner</em><span class="op">(</span><em>outer_it_</em><span class="op">)</span>;</code></span></span>
<span id="cb33-9"><a href="#cb33-9"></a>    <span class="cf">if</span> <span class="op">(</span>std<span class="op">::</span>get<span class="op">&lt;</span><span class="dv">1</span><span class="op">&gt;(</span><em>inner_it_</em><span class="op">)</span> <span class="op">!=</span> ranges<span class="op">::</span>end<span class="op">(</span><span><span class="diffins"><code class="sourceCode cpp"><em>get-inner</em><span class="op">()</span></code></span><span class="diffdel">inner</span></span><span class="op">))</span></span>
<span id="cb33-10"><a href="#cb33-10"></a>      <span class="cf">break</span>;</span>
<span id="cb33-11"><a href="#cb33-11"></a>    <span class="cf">if</span> <span class="op">(++</span><span><span class="diffins"><span class="math inline"><em>o</em><em>u</em><em>t</em><em>e</em><em>r</em></span>()</span><span class="diffdel"><em>outer_it_</em></span></span> <span class="op">==</span> ranges<span class="op">::</span>end<span class="op">(</span><em>parent_</em><span class="op">-&gt;</span><em>base_</em><span class="op">))</span> <span class="op">{</span></span>
<span id="cb33-12"><a href="#cb33-12"></a>      <span class="cf">if</span> <span class="kw">constexpr</span> <span class="op">(</span><em>ref-is-glvalue</em><span class="op">)</span></span>
<span id="cb33-13"><a href="#cb33-13"></a>        <em>inner_it_</em><span class="op">.</span>emplace<span class="op">&lt;</span><span class="dv">0</span><span class="op">&gt;()</span>;</span>
<span id="cb33-14"><a href="#cb33-14"></a>      <span class="cf">break</span>;</span>
<span id="cb33-15"><a href="#cb33-15"></a>    <span class="op">}</span></span>
<span id="cb33-16"><a href="#cb33-16"></a>    <em>inner_it_</em><span class="op">.</span>emplace<span class="op">&lt;</span><span class="dv">0</span><span class="op">&gt;(</span>ranges<span class="op">::</span>begin<span class="op">(</span><em>parent_</em><span class="op">-&gt;</span><em>pattern_</em><span class="op">))</span>;</span>
<span id="cb33-17"><a href="#cb33-17"></a>  <span class="op">}</span></span>
<span id="cb33-18"><a href="#cb33-18"></a><span class="op">}</span></span></code></pre></div>
<p><span class="note1"><span>[ <em>Note 1:</em> </span><code class="sourceCode cpp">join_­with_­view</code> iterators use the <code class="sourceCode cpp"><em>satisfy</em></code> function to skip over empty inner ranges.<span> — <em>end note</em> ]</span></span></p>
</blockquote>
<div class="sourceCode" id="cb34"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb34-1"><a href="#cb34-1"></a><span class="kw">constexpr</span> <em>iterator</em><span class="op">(</span><em>Parent</em><span class="op">&amp;</span> parent, <span><span class="diffins"><span class="math inline"><em>O</em><em>u</em><em>t</em><em>e</em><em>r</em><em>I</em><em>t</em><em>e</em><em>r</em></span></span><span class="diffdel">iterator_t&lt;<span class="math inline"><em>B</em><em>a</em><em>s</em><em>e</em></span>&gt;</span></span> outer<span class="op">)</span> <span class="diffins">requires forward_range&lt;<span class="math inline"><em>B</em><em>a</em><em>s</em><em>e</em></span>&gt;</span>;</span>
<span id="cb34-2"><a href="#cb34-2"></a><span class="diffins"><code class="sourceCode cpp"><span class="kw">constexpr</span> <span class="kw">explicit</span> <em>iterator</em><span class="op">(</span><em>Parent</em><span class="op">&amp;</span> parent<span class="op">)</span> <span class="kw">requires</span> <span class="op">(!</span>forward_range<span class="op">&lt;</span><em>Base</em><span class="op">&gt;)</span>;</code></span></span></code></pre></div>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_23" id="pnum_23">6</a></span> <em>Effects:</em> Initializes <code class="sourceCode cpp"><em>parent_</em></code> with <code class="sourceCode cpp">addressof<span class="op">(</span>parent<span class="op">)</span></code><span><span class="diffins">. For the first overload, also initializes</span><span class="diffdel">and</span></span> <code class="sourceCode cpp"><em>outer_it_</em></code> with <code class="sourceCode cpp">std<span class="op">::</span>move<span class="op">(</span>outer<span class="op">)</span></code>. Then, equivalent to:</p>
<div class="sourceCode" id="cb35"><pre class="sourceCode cpp nonitem"><code class="sourceCode cpp"><span id="cb35-1"><a href="#cb35-1"></a><span class="cf">if</span> <span class="op">(</span><span><span class="diffins"><span class="math inline"><em>o</em><em>u</em><em>t</em><em>e</em><em>r</em></span>()</span><span class="diffdel"><em>outer_it_</em></span></span> <span class="op">!=</span> ranges<span class="op">::</span>end<span class="op">(</span><em>parent_</em><span class="op">-&gt;</span><em>base_</em><span class="op">))</span> <span class="op">{</span></span>
<span id="cb35-2"><a href="#cb35-2"></a>  <span class="diffdel"><code class="sourceCode cpp"><span class="kw">auto</span><span class="op">&amp;&amp;</span> inner <span class="op">=</span> <em>update-inner</em><span class="op">(</span><em>outer_it_</em><span class="op">)</span>;</code></span></span>
<span id="cb35-3"><a href="#cb35-3"></a>  <em>inner_it_</em><span class="op">.</span>emplace<span class="op">&lt;</span><span class="dv">1</span><span class="op">&gt;(</span>ranges<span class="op">::</span>begin<span class="op">(</span><span><span class="diffins"><code class="sourceCode cpp"><em>update-inner</em><span class="op">()</span></code></span><span class="diffdel">inner</span></span><span class="op">))</span>;</span>
<span id="cb35-4"><a href="#cb35-4"></a>  <em>satisfy</em><span class="op">()</span>;</span>
<span id="cb35-5"><a href="#cb35-5"></a><span class="op">}</span></span></code></pre></div>
</blockquote>
<div class="sourceCode" id="cb36"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb36-1"><a href="#cb36-1"></a><span class="kw">constexpr</span> <em>iterator</em><span class="op">(</span><em>iterator</em><span class="op">&lt;!</span>Const<span class="op">&gt;</span> i<span class="op">)</span></span>
<span id="cb36-2"><a href="#cb36-2"></a>  <span class="kw">requires</span> Const <span class="op">&amp;&amp;</span> convertible_to<span class="op">&lt;</span>iterator_t<span class="op">&lt;</span>V<span class="op">&gt;</span>, <em>OuterIter</em><span class="op">&gt;</span> <span class="op">&amp;&amp;</span></span>
<span id="cb36-3"><a href="#cb36-3"></a>          convertible_to<span class="op">&lt;</span>iterator_t<span class="op">&lt;</span><em>InnerRng</em><span class="op">&gt;</span>, <em>InnerIter</em><span class="op">&gt;</span> <span class="op">&amp;&amp;</span></span>
<span id="cb36-4"><a href="#cb36-4"></a>          convertible_to<span class="op">&lt;</span>iterator_t<span class="op">&lt;</span>Pattern<span class="op">&gt;</span>, <em>PatternIter</em><span class="op">&gt;</span>;</span></code></pre></div>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_24" id="pnum_24">7</a></span> <em>Effects:</em> Initializes <code class="sourceCode cpp"><em>outer_it_</em></code> with <code class="sourceCode cpp">std<span class="op">::</span>move<span class="op">(</span>i<span class="op">.</span><em>outer_it_</em><span class="op">)</span></code> and <code class="sourceCode cpp"><em>parent_</em></code> with <code class="sourceCode cpp">i<span class="op">.</span><em>parent_</em></code>. Then, equivalent to:</p>
<div class="sourceCode" id="cb37"><pre class="sourceCode cpp nonitem"><code class="sourceCode cpp"><span id="cb37-1"><a href="#cb37-1"></a><span class="cf">if</span> <span class="op">(</span>i<span class="op">.</span><em>inner_it_</em><span class="op">.</span>index<span class="op">()</span> <span class="op">==</span> <span class="dv">0</span><span class="op">)</span></span>
<span id="cb37-2"><a href="#cb37-2"></a>  <em>inner_it_</em><span class="op">.</span>emplace<span class="op">&lt;</span><span class="dv">0</span><span class="op">&gt;(</span>std<span class="op">::</span>get<span class="op">&lt;</span><span class="dv">0</span><span class="op">&gt;(</span>std<span class="op">::</span>move<span class="op">(</span>i<span class="op">.</span><em>inner_it_</em><span class="op">)))</span>;</span>
<span id="cb37-3"><a href="#cb37-3"></a><span class="cf">else</span></span>
<span id="cb37-4"><a href="#cb37-4"></a>  <em>inner_it_</em><span class="op">.</span>emplace<span class="op">&lt;</span><span class="dv">1</span><span class="op">&gt;(</span>std<span class="op">::</span>get<span class="op">&lt;</span><span class="dv">1</span><span class="op">&gt;(</span>std<span class="op">::</span>move<span class="op">(</span>i<span class="op">.</span><em>inner_it_</em><span class="op">)))</span>;</span></code></pre></div>
</blockquote>
<div class="add">
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_25" id="pnum_25">?</a></span> <span class="note-"><span>[ <em>Note ?:</em> </span><code class="sourceCode default">Const</code> can only be <code class="sourceCode default">true</code> when <code class="sourceCode default"><em>Base</em></code> models <code class="sourceCode default">forward_range</code>.<span> — <em>end note</em> ]</span></span></p>
</blockquote>
</div>
<div class="nonitem">
<p>[…]</p>
<p><span class="draftnote" style="color: #01796F">[ Drafting note: The specification of <code class="sourceCode cpp"><span class="kw">operator</span><span class="op">--</span></code> in paragraph 14 can be editorially simplified using the new <code class="sourceCode cpp"><em>as-lvalue</em></code> helper; that cleanup is not included in this paper as there is no normative impact. ]</span></p>
</div>
<div class="sourceCode" id="cb38"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb38-1"><a href="#cb38-1"></a><span class="kw">friend</span> <span class="kw">constexpr</span> <span class="dt">bool</span> <span class="kw">operator</span><span class="op">==(</span><span class="kw">const</span> <em>iterator</em><span class="op">&amp;</span> x, <span class="kw">const</span> <em>iterator</em><span class="op">&amp;</span> y<span class="op">)</span></span>
<span id="cb38-2"><a href="#cb38-2"></a>  <span class="kw">requires</span> <em>ref-is-glvalue</em> <span class="op">&amp;&amp;</span> <span><span class="diffins"><code class="sourceCode cpp">forward_range<span class="op">&lt;</span><em>Base</em><span class="op">&gt;</span></code></span><span class="diffdel"><code class="sourceCode cpp">equality_­comparable<span class="op">&lt;</span><em>OuterIter</em><span class="op">&gt;</span></code></span></span> <span class="op">&amp;&amp;</span></span>
<span id="cb38-3"><a href="#cb38-3"></a>           equality_comparable<span class="op">&lt;</span>iterator_t<span class="op">&lt;</span>range_reference_t<span class="op">&lt;</span><em>Base</em><span class="op">&gt;&gt;&gt;</span>;</span></code></pre></div>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_26" id="pnum_26">16</a></span> <em>Effects:</em> Equivalent to: <code class="sourceCode cpp"><span class="cf">return</span> x<span class="op">.</span><em>outer_it_</em> <span class="op">==</span> y<span class="op">.</span><em>outer_it_</em> <span class="op">&amp;&amp;</span> x<span class="op">.</span><em>inner_</em> <span class="op">==</span> y<span class="op">.</span><em>inner_</em>;</code></p>
</blockquote>
</div>
</blockquote>
<ol start="9" type="1">
<li>Edit <span>26.7.15.4 <a href="https://wg21.link/range.join.with.sentinel">[range.join.with.sentinel]</a></span> p3 as indicated:</li>
</ol>
<blockquote>
<div>
<div class="sourceCode" id="cb39"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb39-1"><a href="#cb39-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="dt">bool</span> OtherConst<span class="op">&gt;</span></span>
<span id="cb39-2"><a href="#cb39-2"></a>  <span class="kw">requires</span> sentinel_for<span class="op">&lt;</span>sentinel_t<span class="op">&lt;</span><em>Base</em><span class="op">&gt;</span>, iterator_t<span class="op">&lt;</span><em>maybe-const</em><span class="op">&lt;</span>OtherConst, V<span class="op">&gt;&gt;&gt;</span></span>
<span id="cb39-3"><a href="#cb39-3"></a><span class="kw">friend</span> <span class="kw">constexpr</span> <span class="dt">bool</span> <span class="kw">operator</span><span class="op">==(</span><span class="kw">const</span> <em>iterator</em><span class="op">&lt;</span>OtherConst<span class="op">&gt;&amp;</span> x, <span class="kw">const</span> <em>sentinel</em><span class="op">&amp;</span> y<span class="op">)</span>;</span></code></pre></div>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_27" id="pnum_27">3</a></span> <em>Effects:</em> Equivalent to: <code class="sourceCode cpp"><span class="cf">return</span> x<span class="op">.</span><span><span class="diffins"><span class="math inline"><em>o</em><em>u</em><em>t</em><em>e</em><em>r</em></span>()</span><span class="diffdel"><em>outer_it_</em></span></span> <span class="op">==</span> y<span class="op">.</span><em>end_</em>;</code></p>
</blockquote>
</div>
</blockquote>
</div>
<h1 data-number="4" style="border-bottom:1px solid #cccccc" id="bibliography"><span class="header-section-number">4</span> References<a href="#bibliography" class="self-link"></a></h1>
<div id="refs" class="references hanging-indent" role="doc-bibliography">
<div id="ref-LWG3698">
<p>[LWG3698] Barry Revzin. regex_iterator and join_view don’t work together very well. <br />
<a href="https://wg21.link/lwg3698">https://wg21.link/lwg3698</a></p>
</div>
<div id="ref-LWG3700">
<p>[LWG3700] Hewill Kang. The const begin of the join_view family does not require InnerRng to be a range. <br />
<a href="https://wg21.link/lwg3700">https://wg21.link/lwg3700</a></p>
</div>
<div id="ref-LWG3791">
<p>[LWG3791] Hewill Kang. join_view::iterator::operator– may be ill-formed. <br />
<a href="https://wg21.link/lwg3791">https://wg21.link/lwg3791</a></p>
</div>
<div id="ref-N4928">
<p>[N4928] Thomas Köppe. 2022-12-18. Working Draft, Standard for Programming Language C++. <br />
<a href="https://wg21.link/n4928">https://wg21.link/n4928</a></p>
</div>
</div>
</div>
</div>
</body>
</html>
