<!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="2021-11-07" />
  <title>`stride_view`</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>
  <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"><code class="sourceCode default">stride_view</code></h1>

<table style="border:none;float:right">
  <tr>
    <td>Document #:</td>
    <td>P1899R1</td>
  </tr>
  <tr>
    <td>Date:</td>
    <td>2021-11-07</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>
      Ranges Study Group, Library Evolution Working Group<br>
    </td>
  </tr>
  <tr>
    <td style="vertical-align:top">Reply-to:</td>
    <td>
      Christopher Di Bella<br>&lt;<a href="mailto:cjdb.ns@gmail.com" class="email">cjdb.ns@gmail.com</a>&gt;<br>
    </td>
  </tr>
</table>

</header>
<div style="clear:both">
<div id="TOC" role="doc-toc">
<h1 id="toctitle">Contents</h1>
<ul>
<li><a href="#abstract"><span class="toc-section-number">1</span> Abstract<span></span></a></li>
<li><a href="#revision-history"><span class="toc-section-number">2</span> Revision history<span></span></a>
<ul>
<li><a href="#r1"><span class="toc-section-number">2.1</span> R1<span></span></a></li>
<li><a href="#r0"><span class="toc-section-number">2.2</span> R0<span></span></a></li>
</ul></li>
<li><a href="#motivation"><span class="toc-section-number">3</span> Motivation<span></span></a>
<ul>
<li><a href="#risk-of-not-having-stride_view"><span class="toc-section-number">3.1</span> Risk of not having <code class="sourceCode default">stride_view</code><span></span></a></li>
</ul></li>
<li><a href="#implementation-experience"><span class="toc-section-number">4</span> Implementation experience<span></span></a></li>
<li><a href="#design-notes"><span class="toc-section-number">5</span> Design notes<span></span></a>
<ul>
<li><a href="#preconditions"><span class="toc-section-number">5.1</span> Preconditions<span></span></a></li>
<li><a href="#complex-iteration-model"><span class="toc-section-number">5.2</span> Complex iteration model<span></span></a></li>
</ul></li>
<li><a href="#proposed-wording"><span class="toc-section-number">6</span> Proposed wording<span></span></a>
<ul>
<li><a href="#range-adaptors-range.adaptors"><span class="toc-section-number">6.1</span> Range adaptors [range.adaptors]<span></span></a>
<ul>
<li><a href="#header-ranges-synopsis-ranges.syn"><span class="toc-section-number">6.1.1</span> Header <code class="sourceCode default">&lt;ranges&gt;</code> synopsis [ranges.syn]<span></span></a></li>
<li><a href="#stride-view-range.stride"><span class="toc-section-number">6.1.2</span> Stride view [range.stride]<span></span></a></li>
</ul></li>
<li><a href="#feature-test-macro"><span class="toc-section-number">6.2</span> Feature-test macro<span></span></a></li>
</ul></li>
<li><a href="#acknowledgements"><span class="toc-section-number">7</span> Acknowledgements<span></span></a></li>
</ul>
</div>
<section id="abstract" data-number="1">
<h1 data-number="1"><span class="header-section-number">1</span> Abstract<a href="#abstract" class="self-link"></a></h1>
<p>The ability to use algorithms over an evenly-spaced subset of a range has been missed in the STL for a quarter of a century. Given that there’s no way to compose a strided range adaptor in C++20, this should be adopted for C++23.</p>
</section>
<section id="revision-history" data-number="2">
<h1 data-number="2"><span class="header-section-number">2</span> Revision history<a href="#revision-history" class="self-link"></a></h1>
<section id="r1" data-number="2.1">
<h2 data-number="2.1"><span class="header-section-number">2.1</span> R1<a href="#r1" class="self-link"></a></h2>
<ul>
<li>PDF -&gt; HTML.</li>
<li>Adds a section discussing the design.</li>
<li>Adds feature-test macro.</li>
<li>Cleans up some stuff that was ported in from the implementation by mistake.</li>
<li>Adds <code class="sourceCode default">iterator_concept</code>, and corrects <code class="sourceCode default">iterator_category</code> so it can’t be contiguous.</li>
<li>Fixes calls to <em><code class="sourceCode default">compute-distace</code></em> so they pass in size of underlying range instead of themselves.</li>
<li>Adds precondition to ensure stride is positive.</li>
<li>Makes multi-arg constructors non-explicit.</li>
</ul>
</section>
<section id="r0" data-number="2.2">
<h2 data-number="2.2"><span class="header-section-number">2.2</span> R0<a href="#r0" class="self-link"></a></h2>
<p>Initial revision.</p>
</section>
</section>
<section id="motivation" data-number="3">
<h1 data-number="3"><span class="header-section-number">3</span> Motivation<a href="#motivation" class="self-link"></a></h1>
<p>The ability to use algorithms over an evenly-spaced subset of a range has been missed in the STL for a quarter of a century. This is, in part, due to the complexity required to use an iterator that can safely describe such a range. It also means that the following examples cannot be transformed from raw loops into algorithms, due to a lacking iterator.</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb1-1"><a href="#cb1-1"></a><span class="kw">namespace</span> stdr <span class="op">=</span> std<span class="op">::</span>ranges;</span>
<span id="cb1-2"><a href="#cb1-2"></a><span class="kw">namespace</span> stdv <span class="op">=</span> std<span class="op">::</span>views;</span>
<span id="cb1-3"><a href="#cb1-3"></a></span>
<span id="cb1-4"><a href="#cb1-4"></a><span class="cf">for</span> <span class="op">(</span><span class="kw">auto</span> i <span class="op">=</span> <span class="dv">0</span>; i <span class="op">&lt;</span> ssize<span class="op">(</span>v<span class="op">)</span>; i <span class="op">+=</span> <span class="dv">2</span><span class="op">)</span> <span class="op">{</span></span>
<span id="cb1-5"><a href="#cb1-5"></a>  v<span class="op">[</span>i<span class="op">]</span> <span class="op">=</span> <span class="dv">42</span>; <span class="co">// fill</span></span>
<span id="cb1-6"><a href="#cb1-6"></a><span class="op">}</span></span>
<span id="cb1-7"><a href="#cb1-7"></a></span>
<span id="cb1-8"><a href="#cb1-8"></a><span class="cf">for</span> <span class="op">(</span><span class="kw">auto</span> i <span class="op">=</span> <span class="dv">0</span>; i <span class="op">&lt;</span> ssize<span class="op">(</span>v<span class="op">)</span>; i <span class="op">+=</span> <span class="dv">3</span><span class="op">)</span> <span class="op">{</span></span>
<span id="cb1-9"><a href="#cb1-9"></a>  v<span class="op">[</span>i<span class="op">]</span> <span class="op">=</span> f<span class="op">()</span>; <span class="co">// transform</span></span>
<span id="cb1-10"><a href="#cb1-10"></a><span class="op">}</span></span>
<span id="cb1-11"><a href="#cb1-11"></a></span>
<span id="cb1-12"><a href="#cb1-12"></a><span class="cf">for</span> <span class="op">(</span><span class="kw">auto</span> i <span class="op">=</span> <span class="dv">0</span>; i <span class="op">&lt;</span> ssize<span class="op">(</span>v<span class="op">)</span>; i <span class="op">+=</span> <span class="dv">3</span><span class="op">)</span> <span class="op">{</span></span>
<span id="cb1-13"><a href="#cb1-13"></a>  <span class="cf">for</span> <span class="op">(</span><span class="kw">auto</span> j <span class="op">=</span> i; j <span class="op">&lt;</span> ssize<span class="op">(</span>v<span class="op">)</span>; i <span class="op">+=</span> <span class="dv">3</span><span class="op">)</span> <span class="op">{</span></span>
<span id="cb1-14"><a href="#cb1-14"></a>    <span class="cf">if</span> <span class="op">(</span>v<span class="op">[</span>j<span class="op">]</span> <span class="op">&lt;</span> v<span class="op">[</span>i<span class="op">])</span> <span class="op">{</span></span>
<span id="cb1-15"><a href="#cb1-15"></a>      stdr<span class="op">::</span>swap<span class="op">(</span>v<span class="op">[</span>i<span class="op">]</span>, v<span class="op">[</span>j<span class="op">])</span>; <span class="co">// selection sort, but hopefully the idea is conveyed</span></span>
<span id="cb1-16"><a href="#cb1-16"></a>    <span class="op">}</span></span>
<span id="cb1-17"><a href="#cb1-17"></a>  <span class="op">}</span></span>
<span id="cb1-18"><a href="#cb1-18"></a><span class="op">}</span></span></code></pre></div>
<p>Boost.Range 2.0 introduced a range adaptor called <code class="sourceCode default">strided</code>, and range-v3’s equivalent is <code class="sourceCode default">stride_view</code>, both of which make striding far easier than when using iterators:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb2-1"><a href="#cb2-1"></a>stdr<span class="op">::</span>fill<span class="op">(</span>v <span class="op">|</span> stdv<span class="op">::</span>stride<span class="op">(</span><span class="dv">2</span><span class="op">)</span>, <span class="dv">42</span><span class="op">)</span>;</span>
<span id="cb2-2"><a href="#cb2-2"></a></span>
<span id="cb2-3"><a href="#cb2-3"></a><span class="kw">auto</span> strided_v <span class="op">=</span> v <span class="op">|</span> stdv<span class="op">::</span>stride<span class="op">(</span><span class="dv">3</span><span class="op">)</span>;</span>
<span id="cb2-4"><a href="#cb2-4"></a>stdr<span class="op">::</span>transform<span class="op">(</span>strided_v, stdr<span class="op">::</span>begin<span class="op">(</span>strided_v<span class="op">)</span> f<span class="op">)</span>;</span>
<span id="cb2-5"><a href="#cb2-5"></a></span>
<span id="cb2-6"><a href="#cb2-6"></a>stdr<span class="op">::</span>stable_sort<span class="op">(</span>strided_v<span class="op">)</span>; <span class="co">// order restored!</span></span></code></pre></div>
<p>Given that there’s no way to compose a strided range adaptor in C++20, this should be one of the earliest range adaptors put into C++23.</p>
<section id="risk-of-not-having-stride_view" data-number="3.1">
<h2 data-number="3.1"><span class="header-section-number">3.1</span> Risk of not having <code class="sourceCode default">stride_view</code><a href="#risk-of-not-having-stride_view" class="self-link"></a></h2>
<p>Although it isn’t possible to compose <code class="sourceCode default">stride_view</code> in C++20, someone inexperienced with the ranges design space might mistake <code class="sourceCode default">filter_view</code> as a suitable way to “compose” <code class="sourceCode default">stride_view</code>:</p>
<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">auto</span> bad_stride <span class="op">=</span> <span class="op">[](</span><span class="kw">auto</span> <span class="kw">const</span> step<span class="op">)</span> <span class="op">{</span></span>
<span id="cb3-2"><a href="#cb3-2"></a>  <span class="cf">return</span> views<span class="op">::</span>filter<span class="op">([</span>n <span class="op">=</span> <span class="dv">0</span>, step<span class="op">](</span><span class="kw">auto</span><span class="op">&amp;&amp;)</span> <span class="kw">mutable</span> <span class="op">{</span></span>
<span id="cb3-3"><a href="#cb3-3"></a>    <span class="cf">return</span> n<span class="op">++</span> <span class="op">%</span> step <span class="op">==</span> <span class="dv">0</span>;</span>
<span id="cb3-4"><a href="#cb3-4"></a>  <span class="op">})</span>;</span>
<span id="cb3-5"><a href="#cb3-5"></a><span class="op">}</span>;</span></code></pre></div>
<p>This implementation is broken for two reasons:</p>
<ol type="1">
<li><code class="sourceCode default">filter_view</code> expects a <code class="sourceCode default">predicate</code> as its input, but the lambda we have provided does not model <code class="sourceCode default">predicate</code> (a call to <code class="sourceCode default">invoke</code> on a <code class="sourceCode default">predicate</code> mustn’t modify the function object, yet we clearly are).</li>
<li>The lambda provided doesn’t account for moving backward, so despite <em>satisfying</em> <code class="sourceCode default">bidirectional_iterator</code>, it does not model the concept, thus rendering any program containing it ill-formed, with no diagnostic being required.</li>
</ol>
<p>For these reasons, the author regrets not proposing this in the C++20 design space.</p>
</section>
</section>
<section id="implementation-experience" data-number="4">
<h1 data-number="4"><span class="header-section-number">4</span> Implementation experience<a href="#implementation-experience" class="self-link"></a></h1>
<p>Both Boost.Range 2.0 and range-v3 are popular ranges libraries that support a striding range adaptor. The proposed wording has mostly been implemented in cmcstl2 and in a CppCon main session.</p>
</section>
<section id="design-notes" data-number="5">
<h1 data-number="5"><span class="header-section-number">5</span> Design notes<a href="#design-notes" class="self-link"></a></h1>
<section id="preconditions" data-number="5.1">
<h2 data-number="5.1"><span class="header-section-number">5.1</span> Preconditions<a href="#preconditions" class="self-link"></a></h2>
<p>Boost.Range 2.0’s <code class="sourceCode default">strided</code> has a precondition that <code class="sourceCode default">0 &lt;= n</code>, but this isn’t strong enough: we need <code class="sourceCode default">n</code> to be <em>positive</em>.</p>
<p>The stride needs to be positive since a negative stride doesn’t really make sense, and a semantic requirement of <code class="sourceCode default">std::weakly_incrementable</code> (<span>23.3.4.4
 <a href="https://wg21.link/iterator.concept.winc">[iterator.concept.winc]</a></span>) is that incrementing actually moves the iterator to the next element: this means a zero-stride isn’t allowed either.</p>
<p>LEWG unanimously agreed that this was the correct decision in Prague.</p>
</section>
<section id="complex-iteration-model" data-number="5.2">
<h2 data-number="5.2"><span class="header-section-number">5.2</span> Complex iteration model<a href="#complex-iteration-model" class="self-link"></a></h2>
<p>A simple implementation of <code class="sourceCode default">stride_view</code> would be similar to what’s in Boost.Range 2.0: a single-pass range adaptor. With some effort, we can go all the way to a random-access range adaptor, which is what this section mainly covers.</p>
<p>A naive random-access range adaptor would be implemented by simply moving the iterator forward or backward by <code class="sourceCode default">n</code> positions (where <code class="sourceCode default">n</code> is the stride length). While this produce a correct iterator when moving forward, its <code class="sourceCode default">operator--</code> will be incorrect whenever <code class="sourceCode default">n</code> doesn’t evenly divide the underlying range’s length. For example:</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb4-1"><a href="#cb4-1"></a><span class="kw">auto</span> x <span class="op">=</span> std<span class="op">::</span>vector<span class="op">{</span><span class="dv">0</span>, <span class="dv">1</span>, <span class="dv">2</span>, <span class="dv">3</span>, <span class="dv">4</span>, <span class="dv">5</span>, <span class="dv">6</span>, <span class="dv">7</span>, <span class="dv">8</span>, <span class="dv">9</span>, <span class="dv">10</span>, <span class="dv">11</span><span class="op">}</span>;</span>
<span id="cb4-2"><a href="#cb4-2"></a></span>
<span id="cb4-3"><a href="#cb4-3"></a><span class="co">// prints 0 3 6 9</span></span>
<span id="cb4-4"><a href="#cb4-4"></a>stdr<span class="op">::</span>copy<span class="op">(</span>stdv<span class="op">::</span>stride<span class="op">(</span>x, <span class="dv">3</span><span class="op">)</span>, std<span class="op">::</span>ostream_iterator<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;(</span>std<span class="op">::</span>cout, <span class="st">&quot; &quot;</span><span class="op">))</span>;</span>
<span id="cb4-5"><a href="#cb4-5"></a></span>
<span id="cb4-6"><a href="#cb4-6"></a><span class="co">// prints 9 6 3 0</span></span>
<span id="cb4-7"><a href="#cb4-7"></a>stdr<span class="op">::</span>copy<span class="op">(</span>stdv<span class="op">::</span>stride<span class="op">(</span>x, <span class="dv">3</span><span class="op">)</span> <span class="op">|</span> stdv<span class="op">::</span>reverse, std<span class="op">::</span>ostream_iterator<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;(</span>std<span class="op">::</span>cout, <span class="st">&quot; &quot;</span><span class="op">))</span>;</span>
<span id="cb4-8"><a href="#cb4-8"></a></span>
<span id="cb4-9"><a href="#cb4-9"></a><span class="kw">auto</span> y <span class="op">=</span> std<span class="op">::</span>vector<span class="op">{</span><span class="dv">0</span>, <span class="dv">1</span>, <span class="dv">2</span>, <span class="dv">3</span>, <span class="dv">4</span>, <span class="dv">5</span>, <span class="dv">6</span>, <span class="dv">7</span>, <span class="dv">8</span>, <span class="dv">9</span>, <span class="dv">10</span><span class="op">}</span>;</span>
<span id="cb4-10"><a href="#cb4-10"></a></span>
<span id="cb4-11"><a href="#cb4-11"></a><span class="co">// prints 0 3 6 9</span></span>
<span id="cb4-12"><a href="#cb4-12"></a>stdr<span class="op">::</span>copy<span class="op">(</span>stdv<span class="op">::</span>stride<span class="op">(</span>y, <span class="dv">3</span><span class="op">)</span>, std<span class="op">::</span>ostream_iterator<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;(</span>std<span class="op">::</span>cout, <span class="st">&quot; &quot;</span><span class="op">))</span>;</span>
<span id="cb4-13"><a href="#cb4-13"></a></span>
<span id="cb4-14"><a href="#cb4-14"></a><span class="co">// prints 8 5 2: not the same range in reverse!?</span></span>
<span id="cb4-15"><a href="#cb4-15"></a>stdr<span class="op">::</span>copy<span class="op">(</span>stdv<span class="op">::</span>stride<span class="op">(</span>y, <span class="dv">3</span><span class="op">)</span> <span class="op">|</span> stdv<span class="op">::</span>reverse, std<span class="op">::</span>ostream_iterator<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;(</span>std<span class="op">::</span>cout, <span class="st">&quot; &quot;</span><span class="op">))</span>;</span></code></pre></div>
<p>The problem here is that the range has lost all information by the time we’ve reached the end of the sequence. In order to correctly iterate backwards, we need to cache our step value and do some fancy computation:</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb5-1"><a href="#cb5-1"></a><span class="co">// `stride_` is the number of elements we&#39;re supposed to skip over</span></span>
<span id="cb5-2"><a href="#cb5-2"></a><span class="co">// `n` is the number of strides we take</span></span>
<span id="cb5-3"><a href="#cb5-3"></a><span class="cf">if</span> <span class="op">(</span>moving_forward<span class="op">)</span> <span class="op">{</span></span>
<span id="cb5-4"><a href="#cb5-4"></a>  <span class="kw">auto</span> remaining <span class="op">=</span> ranges<span class="op">::</span>advance<span class="op">(</span>current_, n <span class="op">*</span> stride_, ranges<span class="op">::</span>end<span class="op">(</span>underlying_range_<span class="op">))</span>;</span>
<span id="cb5-5"><a href="#cb5-5"></a>  step_ <span class="op">=</span> stride_ <span class="op">-</span> remaining;</span>
<span id="cb5-6"><a href="#cb5-6"></a>  <span class="cf">return</span> <span class="op">*</span><span class="kw">this</span>;</span>
<span id="cb5-7"><a href="#cb5-7"></a><span class="op">}</span></span></code></pre></div>
<p>When moving forward, we update our <code class="sourceCode default">step_</code> cache. In most cases, this will be zero, since we’ll usually be taking a stride of length <code class="sourceCode default">stride_</code>. The only case where this <code class="sourceCode default">step_</code> is a number is when there are fewer elements left to skip than our stride length. This is important for preserving the range when iterating backward.</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb6-1"><a href="#cb6-1"></a><span class="cf">if</span> <span class="op">(</span>moving_backward<span class="op">)</span> <span class="op">{</span></span>
<span id="cb6-2"><a href="#cb6-2"></a>  <span class="kw">auto</span> stride <span class="op">=</span> step_ <span class="op">==</span> <span class="dv">0</span> <span class="op">?</span> n <span class="op">*</span> stride_</span>
<span id="cb6-3"><a href="#cb6-3"></a>                           <span class="op">:</span> <span class="op">(</span>n <span class="op">+</span> <span class="dv">1</span><span class="op">)</span> <span class="op">*</span> stride_ <span class="op">-</span> step_;</span>
<span id="cb6-4"><a href="#cb6-4"></a>  step_ <span class="op">=</span> ranges<span class="op">::</span>advance<span class="op">(</span>current_, stride, ranges<span class="op">::</span>begin<span class="op">(</span>underlying_range_<span class="op">))</span>;</span>
<span id="cb6-5"><a href="#cb6-5"></a><span class="op">}</span></span></code></pre></div>
<p>When we move backward, we consider the value of <code class="sourceCode default">step_</code>. If it’s zero, then we skip over <code class="sourceCode default">n * stride_</code> elements in the same way as moving forward. If <code class="sourceCode default">step_</code> is nonzero, then we need to skip over fewer elements in its first step, to make up the distance. In the example above, to print out <code class="sourceCode default">9 6 3 0</code>, <code class="sourceCode default">y</code>’s iterator needs to pretend there’s one extra value between the end of the underlying range and <code class="sourceCode default">10</code> so that the first value of our <code class="sourceCode default">stdv::stride(y, 3) | stdv::reverse</code> is <code class="sourceCode default">9</code>.</p>
</section>
</section>
<section id="proposed-wording" data-number="6">
<h1 data-number="6"><span class="header-section-number">6</span> Proposed wording<a href="#proposed-wording" class="self-link"></a></h1>
<section id="range-adaptors-range.adaptors" data-number="6.1">
<h2 data-number="6.1"><span class="header-section-number">6.1</span> Range adaptors [range.adaptors]<a href="#range-adaptors-range.adaptors" class="self-link"></a></h2>
<section id="header-ranges-synopsis-ranges.syn" data-number="6.1.1">
<h3 data-number="6.1.1"><span class="header-section-number">6.1.1</span> Header <code class="sourceCode default">&lt;ranges&gt;</code> synopsis [ranges.syn]<a href="#header-ranges-synopsis-ranges.syn" class="self-link"></a></h3>
<p>Add the following to <span>24.2
 <a href="https://wg21.link/ranges.syn">[ranges.syn]</a></span>:</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb7-1"><a href="#cb7-1"></a></span>
<span id="cb7-2"><a href="#cb7-2"></a><span class="co">// [...]</span></span>
<span id="cb7-3"><a href="#cb7-3"></a><span class="kw">namespace</span> std<span class="op">::</span>ranges <span class="op">{</span></span>
<span id="cb7-4"><a href="#cb7-4"></a>  <span class="co">// [...]</span></span>
<span id="cb7-5"><a href="#cb7-5"></a></span>
<span id="cb7-6"><a href="#cb7-6"></a>  <span class="co">// [range.stride]</span></span>
<span id="cb7-7"><a href="#cb7-7"></a>  <span class="kw">template</span><span class="op">&lt;</span>input_range R<span class="op">&gt;</span></span>
<span id="cb7-8"><a href="#cb7-8"></a>    <span class="kw">requires</span> view<span class="op">&lt;</span>R<span class="op">&gt;</span></span>
<span id="cb7-9"><a href="#cb7-9"></a>  <span class="kw">class</span> stride_view;</span>
<span id="cb7-10"><a href="#cb7-10"></a></span>
<span id="cb7-11"><a href="#cb7-11"></a>  <span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> R<span class="op">&gt;</span></span>
<span id="cb7-12"><a href="#cb7-12"></a>    <span class="kw">inline</span> <span class="kw">constexpr</span> <span class="dt">bool</span> enable_borrowed_range<span class="op">&lt;</span>stride_view<span class="op">&lt;</span>R<span class="op">&gt;&gt;</span> <span class="op">=</span></span>
<span id="cb7-13"><a href="#cb7-13"></a>      forward_range<span class="op">&lt;</span>R<span class="op">&gt;</span> <span class="op">&amp;&amp;</span> enable_borrowed_range<span class="op">&lt;</span>R<span class="op">&gt;</span>;</span>
<span id="cb7-14"><a href="#cb7-14"></a></span>
<span id="cb7-15"><a href="#cb7-15"></a>  <span class="kw">namespace</span> views <span class="op">{</span> <span class="kw">inline</span> <span class="kw">constexpr</span> <em>unspecified</em> stride <span class="op">=</span> <em>unspecified</em>; <span class="op">}</span></span>
<span id="cb7-16"><a href="#cb7-16"></a></span>
<span id="cb7-17"><a href="#cb7-17"></a>  <span class="co">// [...]</span></span>
<span id="cb7-18"><a href="#cb7-18"></a><span class="op">}</span></span></code></pre></div>
</section>
<section id="stride-view-range.stride" data-number="6.1.2">
<h3 data-number="6.1.2"><span class="header-section-number">6.1.2</span> Stride view [range.stride]<a href="#stride-view-range.stride" class="self-link"></a></h3>
<p>Add the contents of this subsection as a subclause to <span>24.7
 <a href="https://wg21.link/range.adaptors">[range.adaptors]</a></span>.</p>
<section id="overview-range.stride.overview" data-number="6.1.2.1">
<h4 data-number="6.1.2.1"><span class="header-section-number">6.1.2.1</span> Overview [range.stride.overview]<a href="#overview-range.stride.overview" class="self-link"></a></h4>
<p><span class="marginalizedparent"><a class="marginalized">1</a></span> <code class="sourceCode default">stride_view</code> presents a view of an underlying sequence, advancing over <code class="sourceCode default">n</code> elements at a time, as opposed to the usual single-step succession.</p>
<p><span class="marginalizedparent"><a class="marginalized">2</a></span> The name <code class="sourceCode default">views::stride</code> denotes a range adaptor object <span>24.7.2
 <a href="https://wg21.link/range.adaptor.object">[range.adaptor.object]</a></span>. Given subexpressions <code class="sourceCode default">E</code> and <code class="sourceCode default">N</code>, the expression <code class="sourceCode default">views::stride(E, N)</code> is expression-equivalent to <code class="sourceCode default">stride_view(E, N)</code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">3</a></span> [<em>Example</em>:</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb8-1"><a href="#cb8-1"></a><span class="kw">auto</span> input <span class="op">=</span> views<span class="op">::</span>iota<span class="op">(</span><span class="dv">0</span>, <span class="dv">12</span><span class="op">)</span> <span class="op">|</span> views<span class="op">::</span>stride<span class="op">(</span><span class="dv">3</span><span class="op">)</span>;</span>
<span id="cb8-2"><a href="#cb8-2"></a>ranges<span class="op">::</span>copy<span class="op">(</span>input, ostream_iterator<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;(</span>cout, <span class="st">&quot; &quot;</span><span class="op">))</span>; <span class="co">// prints 0 3 6 9</span></span>
<span id="cb8-3"><a href="#cb8-3"></a>ranges<span class="op">::</span>copy<span class="op">(</span>input <span class="op">|</span> views<span class="op">::</span>reverse, ostream_iterator<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;(</span>cout, <span class="st">&quot; &quot;</span><span class="op">))</span>; <span class="co">// prints 9 6 3 0</span></span></code></pre></div>
<p>— <em>end example</em>]</p>
</section>
<section id="class-stride_view-range.stride.view" data-number="6.1.2.2">
<h4 data-number="6.1.2.2"><span class="header-section-number">6.1.2.2</span> Class <code class="sourceCode default">stride_view</code> [range.stride.view]<a href="#class-stride_view-range.stride.view" class="self-link"></a></h4>
<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">namespace</span> std<span class="op">::</span>ranges <span class="op">{</span></span>
<span id="cb9-2"><a href="#cb9-2"></a>  <span class="kw">template</span><span class="op">&lt;</span>input_range R<span class="op">&gt;</span></span>
<span id="cb9-3"><a href="#cb9-3"></a>    <span class="kw">requires</span> view<span class="op">&lt;</span>R<span class="op">&gt;</span></span>
<span id="cb9-4"><a href="#cb9-4"></a>  <span class="kw">class</span> stride_view <span class="op">:</span> <span class="kw">public</span> view_interface<span class="op">&lt;</span>stride_view<span class="op">&lt;</span>R<span class="op">&gt;&gt;</span> <span class="op">{</span></span>
<span id="cb9-5"><a href="#cb9-5"></a>    <span class="kw">template</span><span class="op">&lt;</span><span class="dt">bool</span> Const<span class="op">&gt;</span> <span class="kw">class</span> <em>iterator</em>; <span class="co">// exposition only</span></span>
<span id="cb9-6"><a href="#cb9-6"></a>  <span class="kw">public</span><span class="op">:</span></span>
<span id="cb9-7"><a href="#cb9-7"></a>    stride_view<span class="op">()</span> <span class="op">=</span> <span class="cf">default</span>;</span>
<span id="cb9-8"><a href="#cb9-8"></a>    <span class="kw">constexpr</span> stride_view<span class="op">(</span>R base, range_difference_t<span class="op">&lt;</span>R<span class="op">&gt;</span> stride<span class="op">)</span>;</span>
<span id="cb9-9"><a href="#cb9-9"></a></span>
<span id="cb9-10"><a href="#cb9-10"></a>    <span class="kw">constexpr</span> R base<span class="op">()</span> <span class="kw">const</span><span class="op">&amp;</span> <span class="kw">requires</span> copy_constructible<span class="op">&lt;</span>R<span class="op">&gt;</span> <span class="op">{</span> <span class="cf">return</span> base_; <span class="op">}</span></span>
<span id="cb9-11"><a href="#cb9-11"></a>    <span class="kw">constexpr</span> R base<span class="op">()</span> <span class="op">&amp;&amp;</span> <span class="op">{</span> <span class="cf">return</span> std<span class="op">::</span>move<span class="op">(</span>base_<span class="op">)</span>; <span class="op">}</span></span>
<span id="cb9-12"><a href="#cb9-12"></a></span>
<span id="cb9-13"><a href="#cb9-13"></a>    <span class="kw">constexpr</span> range_difference_t<span class="op">&lt;</span>R<span class="op">&gt;</span> stride<span class="op">()</span> <span class="kw">const</span> <span class="kw">noexcept</span>;</span>
<span id="cb9-14"><a href="#cb9-14"></a></span>
<span id="cb9-15"><a href="#cb9-15"></a>    <span class="kw">constexpr</span> <em>iterator</em><span class="op">&lt;</span><span class="kw">false</span><span class="op">&gt;</span> begin<span class="op">()</span> <span class="kw">requires</span> <span class="op">(!</span><em>simple-view</em><span class="op">&lt;</span>R<span class="op">&gt;)</span>;</span>
<span id="cb9-16"><a href="#cb9-16"></a>    <span class="kw">constexpr</span> <em>iterator</em><span class="op">&lt;</span><span class="kw">true</span><span class="op">&gt;</span> begin<span class="op">()</span> <span class="kw">const</span> <span class="kw">requires</span> range<span class="op">&lt;</span><span class="kw">const</span> R<span class="op">&gt;</span>;</span>
<span id="cb9-17"><a href="#cb9-17"></a></span>
<span id="cb9-18"><a href="#cb9-18"></a>    <span class="kw">constexpr</span> <span class="kw">auto</span> end<span class="op">()</span> <span class="kw">requires</span> <span class="op">(!</span><em>simple-view</em><span class="op">&lt;</span>R<span class="op">&gt;)</span> <span class="op">{</span></span>
<span id="cb9-19"><a href="#cb9-19"></a>      <span class="cf">if</span> <span class="kw">constexpr</span> <span class="op">(!</span>bidirectional_range<span class="op">&lt;</span>R<span class="op">&gt;</span> <span class="op">||</span> <span class="op">(</span>sized_range<span class="op">&lt;</span>R<span class="op">&gt;</span> <span class="op">&amp;&amp;</span> common_range<span class="op">&lt;</span>R<span class="op">&gt;))</span> <span class="op">{</span></span>
<span id="cb9-20"><a href="#cb9-20"></a>        <span class="cf">return</span> <em>iterator</em><span class="op">&lt;</span><span class="kw">false</span><span class="op">&gt;(*</span><span class="kw">this</span>, ranges<span class="op">::</span>end<span class="op">(</span>base_<span class="op">)</span>, ranges<span class="op">::</span>distance<span class="op">(</span>base_<span class="op">)</span> <span class="op">%</span> stride_<span class="op">)</span>;</span>
<span id="cb9-21"><a href="#cb9-21"></a>      <span class="op">}</span></span>
<span id="cb9-22"><a href="#cb9-22"></a>      <span class="cf">else</span> <span class="op">{</span></span>
<span id="cb9-23"><a href="#cb9-23"></a>        <span class="cf">return</span> default_sentinel;</span>
<span id="cb9-24"><a href="#cb9-24"></a>      <span class="op">}</span></span>
<span id="cb9-25"><a href="#cb9-25"></a>    <span class="op">}</span></span>
<span id="cb9-26"><a href="#cb9-26"></a></span>
<span id="cb9-27"><a href="#cb9-27"></a>    <span class="kw">constexpr</span> <span class="kw">auto</span> end<span class="op">()</span> <span class="kw">const</span> <span class="kw">requires</span> range<span class="op">&lt;</span><span class="kw">const</span> R<span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb9-28"><a href="#cb9-28"></a>      <span class="cf">if</span> <span class="kw">constexpr</span> <span class="op">(!</span>bidirectional_range<span class="op">&lt;</span>R<span class="op">&gt;</span> <span class="op">||</span> <span class="op">(</span>sized_range<span class="op">&lt;</span>R<span class="op">&gt;</span> <span class="op">&amp;&amp;</span> common_range<span class="op">&lt;</span>R<span class="op">&gt;))</span> <span class="op">{</span></span>
<span id="cb9-29"><a href="#cb9-29"></a>        <span class="cf">return</span> <em>iterator</em><span class="op">&lt;</span><span class="kw">true</span><span class="op">&gt;(*</span><span class="kw">this</span>, ranges<span class="op">::</span>end<span class="op">(</span>base_<span class="op">)</span>, ranges<span class="op">::</span>distance<span class="op">(</span>base_<span class="op">)</span> <span class="op">%</span> stride_<span class="op">)</span>;</span>
<span id="cb9-30"><a href="#cb9-30"></a>      <span class="op">}</span></span>
<span id="cb9-31"><a href="#cb9-31"></a>      <span class="cf">else</span> <span class="op">{</span></span>
<span id="cb9-32"><a href="#cb9-32"></a>        <span class="cf">return</span> default_sentinel;</span>
<span id="cb9-33"><a href="#cb9-33"></a>      <span class="op">}</span></span>
<span id="cb9-34"><a href="#cb9-34"></a>    <span class="op">}</span></span>
<span id="cb9-35"><a href="#cb9-35"></a></span>
<span id="cb9-36"><a href="#cb9-36"></a>    <span class="kw">constexpr</span> <span class="kw">auto</span> size<span class="op">()</span> <span class="kw">requires</span> <span class="op">(</span>sized_range<span class="op">&lt;</span>R<span class="op">&gt;</span> <span class="op">&amp;&amp;</span> <span class="op">!</span><em>simple-view</em><span class="op">&lt;</span>R<span class="op">&gt;)</span> <span class="op">{</span></span>
<span id="cb9-37"><a href="#cb9-37"></a>      <span class="cf">return</span> <em>compute-distance</em><span class="op">(</span>ranges<span class="op">::</span>size<span class="op">(</span>base_<span class="op">))</span>;</span>
<span id="cb9-38"><a href="#cb9-38"></a>    <span class="op">}</span></span>
<span id="cb9-39"><a href="#cb9-39"></a></span>
<span id="cb9-40"><a href="#cb9-40"></a>    <span class="kw">constexpr</span> <span class="kw">auto</span> size<span class="op">()</span> <span class="kw">const</span> <span class="kw">requires</span> sized_range<span class="op">&lt;</span><span class="kw">const</span> R<span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb9-41"><a href="#cb9-41"></a>      <span class="cf">return</span> <em>compute-distance</em><span class="op">(</span>ranges<span class="op">::</span>size<span class="op">(</span>base_<span class="op">))</span>;</span>
<span id="cb9-42"><a href="#cb9-42"></a>    <span class="op">}</span></span>
<span id="cb9-43"><a href="#cb9-43"></a>  <span class="kw">private</span><span class="op">:</span></span>
<span id="cb9-44"><a href="#cb9-44"></a>    R base_;                           <span class="co">// exposition only</span></span>
<span id="cb9-45"><a href="#cb9-45"></a>    range_difference_t<span class="op">&lt;</span>R<span class="op">&gt;</span> stride_ <span class="op">=</span> <span class="dv">1</span>; <span class="co">// exposition only</span></span>
<span id="cb9-46"><a href="#cb9-46"></a></span>
<span id="cb9-47"><a href="#cb9-47"></a>    <span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> I<span class="op">&gt;</span></span>
<span id="cb9-48"><a href="#cb9-48"></a>    <span class="kw">constexpr</span> I <em>compute-distance</em><span class="op">(</span>I distance<span class="op">)</span> <span class="kw">const</span> <span class="op">{</span> <span class="co">// exposition only</span></span>
<span id="cb9-49"><a href="#cb9-49"></a>      <span class="kw">const</span> <span class="kw">auto</span> quotient <span class="op">=</span> distance <span class="op">/</span> <span class="kw">static_cast</span><span class="op">&lt;</span>I<span class="op">&gt;(</span>stride_<span class="op">)</span>;</span>
<span id="cb9-50"><a href="#cb9-50"></a>      <span class="kw">const</span> <span class="kw">auto</span> remainder <span class="op">=</span> distance <span class="op">%</span> <span class="kw">static_cast</span><span class="op">&lt;</span>I<span class="op">&gt;(</span>stride_<span class="op">)</span>;</span>
<span id="cb9-51"><a href="#cb9-51"></a>      <span class="cf">return</span> quotient <span class="op">+</span> <span class="kw">static_cast</span><span class="op">&lt;</span>I<span class="op">&gt;(</span>remainder <span class="op">&gt;</span> <span class="dv">0</span><span class="op">)</span>;</span>
<span id="cb9-52"><a href="#cb9-52"></a>    <span class="op">}</span></span>
<span id="cb9-53"><a href="#cb9-53"></a>  <span class="op">}</span>;</span>
<span id="cb9-54"><a href="#cb9-54"></a></span>
<span id="cb9-55"><a href="#cb9-55"></a>  <span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> R<span class="op">&gt;</span></span>
<span id="cb9-56"><a href="#cb9-56"></a>    stride_view<span class="op">(</span>R<span class="op">&amp;&amp;</span>, range_difference_t<span class="op">&lt;</span>R<span class="op">&gt;)</span> <span class="op">-&gt;</span> stride_view<span class="op">&lt;</span>views<span class="op">::</span>all_t<span class="op">&lt;</span>R<span class="op">&gt;&gt;</span>;</span>
<span id="cb9-57"><a href="#cb9-57"></a><span class="op">}</span></span></code></pre></div>
<div class="sourceCode" id="cb10"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb10-1"><a href="#cb10-1"></a><span class="kw">constexpr</span> stride_view<span class="op">(</span>R base, range_difference_t<span class="op">&lt;</span>R<span class="op">&gt;</span> stride<span class="op">)</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">1</a></span> <em>Preconditions</em>: <code class="sourceCode default">stride &gt; 0</code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">2</a></span> <em>Effects</em>: Initializes <code class="sourceCode default">base_</code> with <code class="sourceCode default">base</code> and <code class="sourceCode default">stride_</code> with <code class="sourceCode default">stride</code>.</p>
<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> R base<span class="op">()</span> <span class="kw">const</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">3</a></span> <em>Effects</em>: Equivalent to <code class="sourceCode default">return base_;</code></p>
<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> range_difference_t<span class="op">&lt;</span>R<span class="op">&gt;</span> stride<span class="op">()</span> <span class="kw">const</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">4</a></span> <em>Effects</em>: Equivalent to <code class="sourceCode default">return stride_;</code></p>
<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">&lt;</span><span class="kw">false</span><span class="op">&gt;</span> begin<span class="op">()</span> <span class="kw">requires</span> <span class="op">(!</span><em>simple-view</em><span class="op">&lt;</span>R<span class="op">&gt;)</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">5</a></span> <em>Effects</em>: Equivalent to <code class="sourceCode default">return <em>iterator</em>&lt;false&gt;(*this);</code></p>
<div class="sourceCode" id="cb14"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb14-1"><a href="#cb14-1"></a><span class="kw">constexpr</span> <em>iterator</em><span class="op">&lt;</span><span class="kw">true</span><span class="op">&gt;</span> begin<span class="op">()</span> <span class="kw">requires</span> <span class="op">(!</span><em>simple-view</em><span class="op">&lt;</span>R<span class="op">&gt;)</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">6</a></span> <em>Effects</em>: Equivalent to <code class="sourceCode default">return <em>iterator</em>&lt;true&gt;(*this);</code></p>
</section>
<section id="class-stride_viewiterator-range.stride.iterator" data-number="6.1.2.3">
<h4 data-number="6.1.2.3"><span class="header-section-number">6.1.2.3</span> Class <code class="sourceCode default">stride_view::iterator</code> [range.stride.iterator]<a href="#class-stride_viewiterator-range.stride.iterator" class="self-link"></a></h4>
<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">namespace</span> std<span class="op">::</span>ranges <span class="op">{</span></span>
<span id="cb15-2"><a href="#cb15-2"></a>  <span class="kw">template</span><span class="op">&lt;</span>input_range R<span class="op">&gt;</span></span>
<span id="cb15-3"><a href="#cb15-3"></a>    <span class="kw">requires</span> view<span class="op">&lt;</span>R<span class="op">&gt;</span></span>
<span id="cb15-4"><a href="#cb15-4"></a>  <span class="kw">template</span><span class="op">&lt;</span><span class="dt">bool</span> Const<span class="op">&gt;</span></span>
<span id="cb15-5"><a href="#cb15-5"></a>  <span class="kw">class</span> stride_view<span class="op">&lt;</span>R<span class="op">&gt;::</span><em>iterator</em> <span class="op">{</span></span>
<span id="cb15-6"><a href="#cb15-6"></a>    <span class="kw">using</span> Parent <span class="op">=</span> conditional_t<span class="op">&lt;</span>Const, <span class="kw">const</span> stride_view, stride_view<span class="op">&gt;</span>; <span class="co">// exposition only</span></span>
<span id="cb15-7"><a href="#cb15-7"></a>    <span class="kw">using</span> Base <span class="op">=</span> conditional_t<span class="op">&lt;</span>Const, <span class="kw">const</span> R, R<span class="op">&gt;</span>;                       <span class="co">// exposition only</span></span>
<span id="cb15-8"><a href="#cb15-8"></a></span>
<span id="cb15-9"><a href="#cb15-9"></a>    <span class="kw">friend</span> <em>iterator</em><span class="op">&lt;!</span>Const<span class="op">&gt;</span>;</span>
<span id="cb15-10"><a href="#cb15-10"></a></span>
<span id="cb15-11"><a href="#cb15-11"></a>    Parent<span class="op">*</span> parent_;                <span class="co">// exposition only</span></span>
<span id="cb15-12"><a href="#cb15-12"></a>    iterator_t<span class="op">&lt;</span>Base<span class="op">&gt;</span> current_;      <span class="co">// exposition only</span></span>
<span id="cb15-13"><a href="#cb15-13"></a>    range_difference_t<span class="op">&lt;</span>Base<span class="op">&gt;</span> step_; <span class="co">// exposition only</span></span>
<span id="cb15-14"><a href="#cb15-14"></a>  <span class="kw">public</span><span class="op">:</span></span>
<span id="cb15-15"><a href="#cb15-15"></a>    <span class="kw">using</span> difference_type <span class="op">=</span> range_difference_t<span class="op">&lt;</span>Base<span class="op">&gt;</span>;</span>
<span id="cb15-16"><a href="#cb15-16"></a>    <span class="kw">using</span> value_type <span class="op">=</span> range_value_t<span class="op">&lt;</span>Base<span class="op">&gt;</span>;</span>
<span id="cb15-17"><a href="#cb15-17"></a>    <span class="kw">using</span> iterator_concept <span class="op">=</span> <em>see below</em>;</span>
<span id="cb15-18"><a href="#cb15-18"></a>    <span class="kw">using</span> iterator_category <span class="op">=</span> <em>see below</em>; <span class="co">// not always present</span></span>
<span id="cb15-19"><a href="#cb15-19"></a></span>
<span id="cb15-20"><a href="#cb15-20"></a>    <em>iterator</em><span class="op">()</span> <span class="op">=</span> <span class="cf">default</span>;</span>
<span id="cb15-21"><a href="#cb15-21"></a></span>
<span id="cb15-22"><a href="#cb15-22"></a>    <span class="kw">constexpr</span> <span class="kw">explicit</span> <em>iterator</em><span class="op">(</span>Parent<span class="op">&amp;</span> parent<span class="op">)</span>;</span>
<span id="cb15-23"><a href="#cb15-23"></a>    <span class="kw">constexpr</span> <em>iterator</em><span class="op">(</span>Parent<span class="op">&amp;</span> parent, iterator_t<span class="op">&lt;</span>Base<span class="op">&gt;</span> end, difference_type step<span class="op">)</span>;</span>
<span id="cb15-24"><a href="#cb15-24"></a>    <span class="kw">constexpr</span> <span class="kw">explicit</span> <em>iterator</em><span class="op">(</span><em>iterator</em><span class="op">&lt;!</span>Const<span class="op">&gt;</span> other<span class="op">)</span></span>
<span id="cb15-25"><a href="#cb15-25"></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>R<span class="op">&gt;</span>, iterator_t<span class="op">&lt;</span>Base<span class="op">&gt;&gt;</span>;</span>
<span id="cb15-26"><a href="#cb15-26"></a></span>
<span id="cb15-27"><a href="#cb15-27"></a>    <span class="kw">constexpr</span> iterator_t<span class="op">&lt;</span>Base<span class="op">&gt;</span> base<span class="op">()</span> <span class="kw">const</span>;</span>
<span id="cb15-28"><a href="#cb15-28"></a></span>
<span id="cb15-29"><a href="#cb15-29"></a>    <span class="kw">constexpr</span> <span class="kw">decltype</span><span class="op">(</span><span class="kw">auto</span><span class="op">)</span> <span class="kw">operator</span><span class="op">*()</span> <span class="kw">const</span> <span class="op">{</span> <span class="cf">return</span> <span class="op">*</span>current_; <span class="op">}</span></span>
<span id="cb15-30"><a href="#cb15-30"></a></span>
<span id="cb15-31"><a href="#cb15-31"></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="cb15-32"><a href="#cb15-32"></a></span>
<span id="cb15-33"><a href="#cb15-33"></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>
<span id="cb15-34"><a href="#cb15-34"></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 class="kw">requires</span> forward_range<span class="op">&lt;</span>Base<span class="op">&gt;</span>;</span>
<span id="cb15-35"><a href="#cb15-35"></a></span>
<span id="cb15-36"><a href="#cb15-36"></a>    <span class="kw">constexpr</span> <em>iterator</em><span class="op">&amp;</span> <span class="kw">operator</span><span class="op">--()</span> <span class="kw">requires</span> bidirectional_range<span class="op">&lt;</span>Base<span class="op">&gt;</span>;</span>
<span id="cb15-37"><a href="#cb15-37"></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 class="kw">requires</span> bidirectional_range<span class="op">&lt;</span>Base<span class="op">&gt;</span>;</span>
<span id="cb15-38"><a href="#cb15-38"></a></span>
<span id="cb15-39"><a href="#cb15-39"></a>    <span class="kw">constexpr</span> <em>iterator</em><span class="op">&amp;</span> <span class="kw">operator</span><span class="op">+=(</span>difference_type n<span class="op">)</span> <span class="kw">requires</span> random_access_range<span class="op">&lt;</span>Base<span class="op">&gt;</span>;</span>
<span id="cb15-40"><a href="#cb15-40"></a>    <span class="kw">constexpr</span> <em>iterator</em><span class="op">&amp;</span> <span class="kw">operator</span><span class="op">-=(</span>difference_type n<span class="op">)</span> <span class="kw">requires</span> random_access_range<span class="op">&lt;</span>Base<span class="op">&gt;</span>;</span>
<span id="cb15-41"><a href="#cb15-41"></a></span>
<span id="cb15-42"><a href="#cb15-42"></a>    <span class="kw">constexpr</span> <span class="kw">decltype</span><span class="op">(</span><span class="kw">auto</span><span class="op">)</span> <span class="kw">operator</span><span class="op">[](</span>difference_type n<span class="op">)</span> <span class="kw">const</span></span>
<span id="cb15-43"><a href="#cb15-43"></a>      <span class="kw">requires</span> random_access_range<span class="op">&lt;</span>Base<span class="op">&gt;</span></span>
<span id="cb15-44"><a href="#cb15-44"></a>    <span class="op">{</span> <span class="cf">return</span> <span class="op">*(*</span><span class="kw">this</span> <span class="op">+</span> n<span class="op">)</span>; <span class="op">}</span></span>
<span id="cb15-45"><a href="#cb15-45"></a></span>
<span id="cb15-46"><a href="#cb15-46"></a>    <span class="kw">constexpr</span> <em>iterator</em><span class="op">&amp;</span> <span class="kw">operator</span><span class="op">+(</span><span class="kw">const</span> <em>iterator</em><span class="op">&amp;</span> x, difference_type n<span class="op">)</span></span>
<span id="cb15-47"><a href="#cb15-47"></a>      <span class="kw">requires</span> random_access_range<span class="op">&lt;</span>Base<span class="op">&gt;</span>;</span>
<span id="cb15-48"><a href="#cb15-48"></a></span>
<span id="cb15-49"><a href="#cb15-49"></a>    <span class="kw">constexpr</span> <em>iterator</em><span class="op">&amp;</span> <span class="kw">operator</span><span class="op">+(</span>difference_type n, <span class="kw">const</span> <em>iterator</em><span class="op">&amp;</span> x<span class="op">)</span></span>
<span id="cb15-50"><a href="#cb15-50"></a>      <span class="kw">requires</span> random_access_range<span class="op">&lt;</span>Base<span class="op">&gt;</span>;</span>
<span id="cb15-51"><a href="#cb15-51"></a></span>
<span id="cb15-52"><a href="#cb15-52"></a>    <span class="kw">constexpr</span> <em>iterator</em><span class="op">&amp;</span> <span class="kw">operator</span><span class="op">-(</span><span class="kw">const</span> <em>iterator</em><span class="op">&amp;</span> x, difference_type n<span class="op">)</span></span>
<span id="cb15-53"><a href="#cb15-53"></a>      <span class="kw">requires</span> random_access_range<span class="op">&lt;</span>Base<span class="op">&gt;</span>;</span>
<span id="cb15-54"><a href="#cb15-54"></a></span>
<span id="cb15-55"><a href="#cb15-55"></a>    <span class="kw">constexpr</span> difference_type <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="cb15-56"><a href="#cb15-56"></a>      <span class="kw">requires</span> random_access_range<span class="op">&lt;</span>Base<span class="op">&gt;</span>;</span>
<span id="cb15-57"><a href="#cb15-57"></a></span>
<span id="cb15-58"><a href="#cb15-58"></a>    <span class="kw">constexpr</span> <span class="kw">friend</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, default_sentinel<span class="op">)</span>;</span>
<span id="cb15-59"><a href="#cb15-59"></a></span>
<span id="cb15-60"><a href="#cb15-60"></a>    <span class="kw">constexpr</span> <span class="kw">friend</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="cb15-61"><a href="#cb15-61"></a>      <span class="kw">requires</span> equality_comparable<span class="op">&lt;</span>iterator_t<span class="op">&lt;</span>Base<span class="op">&gt;&gt;</span>;</span>
<span id="cb15-62"><a href="#cb15-62"></a></span>
<span id="cb15-63"><a href="#cb15-63"></a>    <span class="kw">constexpr</span> <span class="kw">friend</span> <span class="dt">bool</span> <span class="kw">operator</span><span class="op">&lt;(</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="cb15-64"><a href="#cb15-64"></a>      <span class="kw">requires</span> random_access_range<span class="op">&lt;</span>Base<span class="op">&gt;</span>;</span>
<span id="cb15-65"><a href="#cb15-65"></a></span>
<span id="cb15-66"><a href="#cb15-66"></a>    <span class="kw">constexpr</span> <span class="kw">friend</span> <span class="dt">bool</span> <span class="kw">operator</span><span class="op">&gt;(</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="cb15-67"><a href="#cb15-67"></a>      <span class="kw">requires</span> random_access_range<span class="op">&lt;</span>Base<span class="op">&gt;</span>;</span>
<span id="cb15-68"><a href="#cb15-68"></a></span>
<span id="cb15-69"><a href="#cb15-69"></a>    <span class="kw">constexpr</span> <span class="kw">friend</span> <span class="dt">bool</span> <span class="kw">operator</span><span class="op">&lt;=(</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="cb15-70"><a href="#cb15-70"></a>      <span class="kw">requires</span> random_access_range<span class="op">&lt;</span>Base<span class="op">&gt;</span>;</span>
<span id="cb15-71"><a href="#cb15-71"></a></span>
<span id="cb15-72"><a href="#cb15-72"></a>    <span class="kw">constexpr</span> <span class="kw">friend</span> <span class="dt">bool</span> <span class="kw">operator</span><span class="op">&gt;=(</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="cb15-73"><a href="#cb15-73"></a>      <span class="kw">requires</span> random_access_range<span class="op">&lt;</span>Base<span class="op">&gt;</span>;</span>
<span id="cb15-74"><a href="#cb15-74"></a></span>
<span id="cb15-75"><a href="#cb15-75"></a>    <span class="kw">constexpr</span> <span class="kw">friend</span> compare_three_way_result_t<span class="op">&lt;</span>iterator_t<span class="op">&lt;</span>Base<span class="op">&gt;&gt;</span></span>
<span id="cb15-76"><a href="#cb15-76"></a>      <span class="kw">operator</span><span class="op">&lt;=&gt;(</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="cb15-77"><a href="#cb15-77"></a>        <span class="kw">requires</span> random_access_range<span class="op">&lt;</span>Base<span class="op">&gt;</span> <span class="op">&amp;&amp;</span> three_way_comparable<span class="op">&lt;</span>iterator_t<span class="op">&lt;</span>Base<span class="op">&gt;&gt;</span>;</span>
<span id="cb15-78"><a href="#cb15-78"></a></span>
<span id="cb15-79"><a href="#cb15-79"></a>    <span class="kw">constexpr</span> <span class="kw">friend</span> range_rvalue_reference_t<span class="op">&lt;</span>R<span class="op">&gt;</span> iter_move<span class="op">(</span><span class="kw">const</span> <em>iterator</em><span class="op">&amp;</span> i<span class="op">)</span></span>
<span id="cb15-80"><a href="#cb15-80"></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_move<span class="op">(</span>i<span class="op">.</span>current_<span class="op">)))</span>;</span>
<span id="cb15-81"><a href="#cb15-81"></a></span>
<span id="cb15-82"><a href="#cb15-82"></a>    <span class="kw">constexpr</span> <span class="kw">friend</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="cb15-83"><a href="#cb15-83"></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>current_, y<span class="op">.</span>current_<span class="op">)))</span></span>
<span id="cb15-84"><a href="#cb15-84"></a>      <span class="kw">requires</span> indirectly_swappable<span class="op">&lt;</span>iterator_t<span class="op">&lt;</span>R<span class="op">&gt;&gt;</span>;</span>
<span id="cb15-85"><a href="#cb15-85"></a>  <span class="kw">private</span><span class="op">:</span></span>
<span id="cb15-86"><a href="#cb15-86"></a>    <span class="kw">constexpr</span> <em>iterator&amp;</em> advance<span class="op">(</span>difference_type n<span class="op">)</span> <span class="op">{</span> <span class="co">// exposition only</span></span>
<span id="cb15-87"><a href="#cb15-87"></a>      <span class="cf">if</span> <span class="kw">constexpr</span> <span class="op">(!</span>bidirectional_range<span class="op">&lt;</span>Parent<span class="op">&gt;)</span> <span class="op">{</span></span>
<span id="cb15-88"><a href="#cb15-88"></a>        ranges<span class="op">::</span>advance<span class="op">(</span>current_, n <span class="op">*</span> parent_<span class="op">-&gt;</span>stride_, ranges<span class="op">::</span>end<span class="op">(</span>parent_<span class="op">-&gt;</span>base_<span class="op">))</span>;</span>
<span id="cb15-89"><a href="#cb15-89"></a>        <span class="cf">return</span> <span class="op">*</span><span class="kw">this</span>;</span>
<span id="cb15-90"><a href="#cb15-90"></a>      <span class="op">}</span></span>
<span id="cb15-91"><a href="#cb15-91"></a>      <span class="cf">else</span> <span class="op">{</span></span>
<span id="cb15-92"><a href="#cb15-92"></a>        <span class="cf">if</span> <span class="op">(</span>n <span class="op">&gt;</span> <span class="dv">0</span><span class="op">)</span> <span class="op">{</span></span>
<span id="cb15-93"><a href="#cb15-93"></a>          <span class="kw">auto</span> remaining <span class="op">=</span> ranges<span class="op">::</span>advance<span class="op">(</span>current_, n <span class="op">*</span> parent_<span class="op">-&gt;</span>stride_, ranges<span class="op">::</span>end<span class="op">(</span>parent_<span class="op">-&gt;</span>base_<span class="op">))</span>;</span>
<span id="cb15-94"><a href="#cb15-94"></a>          step_ <span class="op">=</span> parent_<span class="op">-&gt;</span>stride_ <span class="op">-</span> remaining;</span>
<span id="cb15-95"><a href="#cb15-95"></a>          <span class="cf">return</span> <span class="op">*</span><span class="kw">this</span>;</span>
<span id="cb15-96"><a href="#cb15-96"></a>        <span class="op">}</span></span>
<span id="cb15-97"><a href="#cb15-97"></a></span>
<span id="cb15-98"><a href="#cb15-98"></a>        <span class="cf">if</span> <span class="op">(</span>n <span class="op">&lt;</span> <span class="dv">0</span><span class="op">)</span> <span class="op">{</span></span>
<span id="cb15-99"><a href="#cb15-99"></a>          <span class="kw">auto</span> stride <span class="op">=</span> step_ <span class="op">==</span> <span class="dv">0</span> <span class="op">?</span> n <span class="op">*</span> parent_<span class="op">-&gt;</span>stride_</span>
<span id="cb15-100"><a href="#cb15-100"></a>                                   <span class="op">:</span> <span class="op">(</span>n <span class="op">+</span> <span class="dv">1</span><span class="op">)</span> <span class="op">*</span> parent_<span class="op">-&gt;</span>stride_ <span class="op">-</span> step_;</span>
<span id="cb15-101"><a href="#cb15-101"></a>          ranges<span class="op">::</span>advance<span class="op">(</span>current_, stride<span class="op">)</span>;</span>
<span id="cb15-102"><a href="#cb15-102"></a>          stride_ <span class="op">=</span> <span class="dv">0</span>;</span>
<span id="cb15-103"><a href="#cb15-103"></a>          <span class="cf">return</span> <span class="op">*</span><span class="kw">this</span>;</span>
<span id="cb15-104"><a href="#cb15-104"></a>        <span class="op">}</span></span>
<span id="cb15-105"><a href="#cb15-105"></a></span>
<span id="cb15-106"><a href="#cb15-106"></a>        <span class="cf">return</span> <span class="op">*</span><span class="kw">this</span>;</span>
<span id="cb15-107"><a href="#cb15-107"></a>      <span class="op">}</span></span>
<span id="cb15-108"><a href="#cb15-108"></a>    <span class="op">}</span></span>
<span id="cb15-109"><a href="#cb15-109"></a>  <span class="op">}</span>;</span>
<span id="cb15-110"><a href="#cb15-110"></a><span class="op">}</span></span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">1</a></span> <code class="sourceCode default"><em>iterator</em>::iterator_concept</code> is defined as follows:</p>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">(1.1)</a></span> If <code class="sourceCode default">R</code> models <code class="sourceCode default">random_access_range</code>, then <code class="sourceCode default">iterator_concept</code> denotes <code class="sourceCode default">random_access_iterator_tag</code>.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(1.2)</a></span> Otherwise, if <code class="sourceCode default">R</code> models <code class="sourceCode default">bidirectional_range</code>, then <code class="sourceCode default">iterator_concept</code> denotes <code class="sourceCode default">bidirectional_iterator_tag</code>.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(1.3)</a></span> Otherwise, if <code class="sourceCode default">R</code> models <code class="sourceCode default">forward_range</code>, then <code class="sourceCode default">iterator_concept</code> denotes <code class="sourceCode default">forward_iterator_tag</code>.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(1.3)</a></span> Otherwise, <code class="sourceCode default">iterator_concept</code> denotes <code class="sourceCode default">input_iterator_tag</code>.</p></li>
</ul>
<p><span class="marginalizedparent"><a class="marginalized">2</a></span> The member <em>typedef-name</em> <code class="sourceCode default">iterator_category</code> is defined if and only if <code class="sourceCode default">R</code> models <code class="sourceCode default">forward_range</code>. In that case, <code class="sourceCode default"><em>iterator</em>::iterator_category</code> is defined as follows:</p>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">(2.1)</a></span> Let <code class="sourceCode default">C</code> denote the type <code class="sourceCode default">iterator_traits&lt;iterator_t&lt;R&gt;&gt;::iterator_category</code>.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(2.2)</a></span> If <code class="sourceCode default">C</code> models <code class="sourceCode default">derived_from&lt;random_access_iterator_tag&gt;</code>, then <code class="sourceCode default">iterator_category</code> denotes <code class="sourceCode default">random_access_iterator_tag</code>.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(2.3)</a></span> Otherwise, <code class="sourceCode default">iterator_category</code> denotes <code class="sourceCode default">C</code>.</p></li>
</ul>
<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> <span class="kw">explicit</span> <em>iterator</em><span class="op">(</span>Parent<span class="op">&amp;</span> parent<span class="op">)</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">3</a></span> <em>Effects</em>: Initializes <code class="sourceCode default">parent_</code> with <code class="sourceCode default">addressof(parent)</code> and <code class="sourceCode default">current_</code> with <code class="sourceCode default">ranges::begin(parent)</code>.</p>
<div class="sourceCode" id="cb17"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb17-1"><a href="#cb17-1"></a><span class="kw">constexpr</span> <em>iterator</em><span class="op">(</span>Parent<span class="op">&amp;</span> parent, iterator_t<span class="op">&lt;</span>Base<span class="op">&gt;</span> end, difference_type step<span class="op">)</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">4</a></span> <em>Effects</em>: Initializes <code class="sourceCode default">parent_</code> with <code class="sourceCode default">addressof(parent)</code> and <code class="sourceCode default">current_</code> with <code class="sourceCode default">std::move(end)</code>, and <code class="sourceCode default">step_</code> with <code class="sourceCode default">step</code>.</p>
<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> <span class="kw">explicit</span> <em>iterator</em><span class="op">(</span><em>iterator</em><span class="op">&lt;!</span>Const<span class="op">&gt;</span> other<span class="op">)</span></span>
<span id="cb18-2"><a href="#cb18-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>R<span class="op">&gt;</span>, iterator_t<span class="op">&lt;</span>Base<span class="op">&gt;&gt;</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">5</a></span> <em>Effects</em>: Initializes <code class="sourceCode default">parent_</code> with <code class="sourceCode default">other.parent_</code> and <code class="sourceCode default">current_</code> with <code class="sourceCode default">std::move(other.current_)</code>, and <code class="sourceCode default">step_</code> with <code class="sourceCode default">other.step_</code>.</p>
<div class="sourceCode" id="cb19"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb19-1"><a href="#cb19-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>
<p><span class="marginalizedparent"><a class="marginalized">6</a></span> <em>Effects</em>: Equivalent to: <code class="sourceCode default">return advance(1);</code></p>
<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> <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>
<p><span class="marginalizedparent"><a class="marginalized">7</a></span> <em>Effects</em>: Equivalent to: <code class="sourceCode default">advance(1);</code></p>
<div class="sourceCode" id="cb21"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb21-1"><a href="#cb21-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 class="kw">requires</span> forward_range<span class="op">&lt;</span>Base<span class="op">&gt;</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">8</a></span> <em>Effects</em>: Equivalent to:</p>
<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">auto</span> temp <span class="op">=</span> <span class="op">*</span><span class="kw">this</span>;</span>
<span id="cb22-2"><a href="#cb22-2"></a><span class="op">++*</span><span class="kw">this</span>;</span>
<span id="cb22-3"><a href="#cb22-3"></a><span class="cf">return</span> temp;</span></code></pre></div>
<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">constexpr</span> <em>iterator</em><span class="op">&amp;</span> <span class="kw">operator</span><span class="op">--()</span> <span class="kw">requires</span> bidirectional_range<span class="op">&lt;</span>Base<span class="op">&gt;</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">9</a></span> <em>Effects</em>: Equivalent to: <code class="sourceCode default">return advance(-1);</code></p>
<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">constexpr</span> <em>iterator</em> <span class="kw">operator</span><span class="op">--(</span><span class="dt">int</span><span class="op">)</span> <span class="kw">requires</span> bidirectional_range<span class="op">&lt;</span>Base<span class="op">&gt;</span>;</span></code></pre></div>
<div class="sourceCode" id="cb25"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb25-1"><a href="#cb25-1"></a><span class="kw">auto</span> temp <span class="op">=</span> <span class="op">*</span><span class="kw">this</span>;</span>
<span id="cb25-2"><a href="#cb25-2"></a><span class="op">--*</span><span class="kw">this</span>;</span>
<span id="cb25-3"><a href="#cb25-3"></a><span class="cf">return</span> temp;</span></code></pre></div>
<div class="sourceCode" id="cb26"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb26-1"><a href="#cb26-1"></a><span class="kw">constexpr</span> <em>iterator</em><span class="op">&amp;</span> <span class="kw">operator</span><span class="op">+=(</span>difference_type n<span class="op">)</span> <span class="kw">requires</span> random_access_range<span class="op">&lt;</span>Base<span class="op">&gt;</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">10</a></span> <em>Effects</em>: Equivalent to: <code class="sourceCode default">return advance(n);</code></p>
<div class="sourceCode" id="cb27"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb27-1"><a href="#cb27-1"></a><span class="kw">constexpr</span> <em>iterator</em><span class="op">&amp;</span> <span class="kw">operator</span><span class="op">-=(</span>difference_type n<span class="op">)</span> <span class="kw">requires</span> random_access_range<span class="op">&lt;</span>Base<span class="op">&gt;</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">11</a></span> <em>Effects</em>: Equivalent to: <code class="sourceCode default">return advance(-n);</code></p>
<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> <em>iterator</em><span class="op">&amp;</span> <span class="kw">operator</span><span class="op">+(</span><em>iterator</em> x, difference_type n<span class="op">)</span></span>
<span id="cb28-2"><a href="#cb28-2"></a>  <span class="kw">requires</span> random_access_range<span class="op">&lt;</span>Base<span class="op">&gt;</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">12</a></span> <em>Effects</em>: Equivalent to: <code class="sourceCode default">return x += n;</code></p>
<div class="sourceCode" id="cb29"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb29-1"><a href="#cb29-1"></a><span class="kw">constexpr</span> <em>iterator</em><span class="op">&amp;</span> <span class="kw">operator</span><span class="op">+(</span>difference_type n, <em>iterator</em> x<span class="op">)</span></span>
<span id="cb29-2"><a href="#cb29-2"></a>  <span class="kw">requires</span> random_access_range<span class="op">&lt;</span>Base<span class="op">&gt;</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">13</a></span> <em>Effects</em>: Equivalent to: <code class="sourceCode default">return x += n;</code></p>
<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> <em>iterator</em><span class="op">&amp;</span> <span class="kw">operator</span><span class="op">-(</span><span class="kw">const</span> <em>iterator</em><span class="op">&amp;</span> x, difference_type n<span class="op">)</span></span>
<span id="cb30-2"><a href="#cb30-2"></a>  <span class="kw">requires</span> random_access_range<span class="op">&lt;</span>Base<span class="op">&gt;</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">14</a></span> <em>Effects</em>: Equivalent to: <code class="sourceCode default">return x -= n;</code></p>
<div class="sourceCode" id="cb31"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb31-1"><a href="#cb31-1"></a><span class="kw">constexpr</span> difference_type <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="cb31-2"><a href="#cb31-2"></a>  <span class="kw">requires</span> random_access_range<span class="op">&lt;</span>Base<span class="op">&gt;</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">15</a></span> <em>Effects</em>: Equivalent to: <code class="sourceCode default">return x.parent_-&gt;<em>compute-distance</em>(x.current_ - y.current_);</code></p>
<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="kw">friend</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, default_sentinel<span class="op">)</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">16</a></span> <em>Effects</em>: Equivalent to: <code class="sourceCode default">return x.current_ == ranges::end(x.parent_-&gt;base_);</code></p>
<div class="sourceCode" id="cb33"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb33-1"><a href="#cb33-1"></a><span class="kw">constexpr</span> <span class="kw">friend</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="cb33-2"><a href="#cb33-2"></a>      <span class="kw">requires</span> equality_comparable<span class="op">&lt;</span>iterator_t<span class="op">&lt;</span>Base<span class="op">&gt;&gt;</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">16</a></span> <em>Effects</em>: Equivalent to: <code class="sourceCode default">return x.current_ == y.current_;</code></p>
<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> <span class="kw">friend</span> <span class="dt">bool</span> <span class="kw">operator</span><span class="op">&lt;(</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="cb34-2"><a href="#cb34-2"></a>  <span class="kw">requires</span> random_access_range<span class="op">&lt;</span>Base<span class="op">&gt;</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">17</a></span> <em>Effects</em>: Equivalent to: <code class="sourceCode default">return x.current_ &lt; y.current_;</code></p>
<div class="sourceCode" id="cb35"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb35-1"><a href="#cb35-1"></a><span class="kw">constexpr</span> <span class="kw">friend</span> <span class="dt">bool</span> <span class="kw">operator</span><span class="op">&gt;(</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="cb35-2"><a href="#cb35-2"></a>  <span class="kw">requires</span> random_access_range<span class="op">&lt;</span>Base<span class="op">&gt;</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">18</a></span> <em>Effects</em>: Equivalent to: <code class="sourceCode default">return y &lt; x;</code></p>
<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> <span class="kw">friend</span> <span class="dt">bool</span> <span class="kw">operator</span><span class="op">&lt;=(</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="cb36-2"><a href="#cb36-2"></a>  <span class="kw">requires</span> random_access_range<span class="op">&lt;</span>Base<span class="op">&gt;</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">19</a></span> <em>Effects</em>: Equivalent to: <code class="sourceCode default">return !(y &lt; x);</code></p>
<div class="sourceCode" id="cb37"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb37-1"><a href="#cb37-1"></a><span class="kw">constexpr</span> <span class="kw">friend</span> <span class="dt">bool</span> <span class="kw">operator</span><span class="op">&gt;=(</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="cb37-2"><a href="#cb37-2"></a>  <span class="kw">requires</span> random_access_range<span class="op">&lt;</span>Base<span class="op">&gt;</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">20</a></span> <em>Effects</em>: Equivalent to: <code class="sourceCode default">return !(x &lt; y);</code></p>
<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">constexpr</span> <span class="kw">friend</span> compare_three_way_result_t<span class="op">&lt;</span>iterator_t<span class="op">&lt;</span>Base<span class="op">&gt;&gt;</span></span>
<span id="cb38-2"><a href="#cb38-2"></a>  <span class="kw">operator</span><span class="op">&lt;=&gt;(</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-3"><a href="#cb38-3"></a>    <span class="kw">requires</span> random_access_range<span class="op">&lt;</span>Base<span class="op">&gt;</span> <span class="op">&amp;&amp;</span> three_way_comparable<span class="op">&lt;</span>iterator_t<span class="op">&lt;</span>Base<span class="op">&gt;&gt;</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">21</a></span> <em>Effects</em>: Equivalent to: <code class="sourceCode default">return x.current_ &lt;=&gt; y.current_;</code></p>
<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">constexpr</span> <span class="kw">friend</span> range_rvalue_reference_t<span class="op">&lt;</span>R<span class="op">&gt;</span> iter_move<span class="op">(</span><span class="kw">const</span> <em>iterator</em><span class="op">&amp;</span> i<span class="op">)</span></span>
<span id="cb39-2"><a href="#cb39-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_move<span class="op">(</span>i<span class="op">.</span>current_<span class="op">)))</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">22</a></span> <em>Effects</em>: Equivalent to: <code class="sourceCode default">return ranges::iter_move(i);</code></p>
<div class="sourceCode" id="cb40"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb40-1"><a href="#cb40-1"></a><span class="kw">constexpr</span> <span class="kw">friend</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> x<span class="op">)</span></span>
<span id="cb40-2"><a href="#cb40-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>current_, y<span class="op">.</span>current_<span class="op">)))</span></span>
<span id="cb40-3"><a href="#cb40-3"></a>  <span class="kw">requires</span> indirectly_swappable<span class="op">&lt;</span>iterator_t<span class="op">&lt;</span>R<span class="op">&gt;&gt;</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">23</a></span> <em>Effects</em>: Equivalent to: <code class="sourceCode default">ranges::iter_swap(x.current_, y.current_);</code></p>
</section>
</section>
</section>
<section id="feature-test-macro" data-number="6.2">
<h2 data-number="6.2"><span class="header-section-number">6.2</span> Feature-test macro<a href="#feature-test-macro" class="self-link"></a></h2>
<p>Add the following macro definition to <span>17.3.2
 <a href="https://wg21.link/version.syn">[version.syn]</a></span>, header <code class="sourceCode default">&lt;version&gt;</code> synopsis, with the value selected by the editor to reflect the date of adoption of this paper:</p>
<div class="sourceCode" id="cb41"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb41-1"><a href="#cb41-1"></a><span class="pp">#define __cpp_lib_ranges_stride </span><span class="dv">20</span><span class="er">XXXXL</span><span class="pp"> </span><span class="co">// also in &lt;ranges&gt;</span></span></code></pre></div>
</section>
</section>
<section id="acknowledgements" data-number="7">
<h1 data-number="7"><span class="header-section-number">7</span> Acknowledgements<a href="#acknowledgements" class="self-link"></a></h1>
<p>The author would like to thank Tristan Brindle for providing editorial commentary on P1899, and also those who reviewed material for, or attended the aforementioned CppCon session or post-conference class, for their input on the design of the proposed <code class="sourceCode default">stride_view</code>.</p>
</section>
</div>
</div>
</body>
</html>
