<!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-02-10" />
  <title>Prefer std::ranges::contains over std::basic\_string\_view::contains</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">Prefer std::ranges::contains over std::basic_string_view::contains</h1>

<table style="border:none;float:right">
  <tr>
    <td>Document #:</td>
    <td>P2302R0</td>
  </tr>
  <tr>
    <td>Date:</td>
    <td>2021-02-10</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>
      Library Evolution Working Group (LEWG)<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="#motivation"><span class="toc-section-number">2</span> Motivation<span></span></a></li>
<li><a href="#design"><span class="toc-section-number">3</span> Design<span></span></a>
<ul>
<li><a href="#api"><span class="toc-section-number">3.1</span> API<span></span></a></li>
</ul></li>
<li><a href="#changes-to-lewg-policy-standing-document"><span class="toc-section-number">4</span> Changes to LEWG Policy Standing Document<span></span></a></li>
<li><a href="#blunt-proposal"><span class="toc-section-number">5</span> Blunt proposal<span></span></a>
<ul>
<li><a href="#proposed-wording"><span class="toc-section-number">5.1</span> Proposed wording<span></span></a></li>
</ul></li>
<li><a href="#acknowledgements"><span class="toc-section-number">6</span> Acknowledgements<span></span></a></li>
<li><a href="#bibliography"><span class="toc-section-number">7</span> References<span></span></a></li>
</ul>
</div>
<h1 data-number="1" id="abstract"><span class="header-section-number">1</span> Abstract<a href="#abstract" class="self-link"></a></h1>
<p><span class="citation" data-cites="P1679R3">[<a href="#ref-P1679R3" role="doc-biblioref">P1679R3</a>]</span> paves the way for both <code class="sourceCode default">std::basic_string::contains</code> and <code class="sourceCode default">std::basic_string_view::contains</code> to be standardised in C++23, allowing for users to conveniently check whether or not a string contains a specific character or substring of characters. The author of P2302 rasied concerns about LEWG introducing member functions to a particular container in <span class="citation" data-cites="P1659R1">[<a href="#ref-P1659R1" role="doc-biblioref">P1659R1</a>]</span>, and seeks to repeal P1679 in favour of an algorithm that achieves the same effort.</p>
<h1 data-number="2" id="motivation"><span class="header-section-number">2</span> Motivation<a href="#motivation" class="self-link"></a></h1>
<p>As in P1659, the author is of the opinion that a member-wise operations are the wrong abstraction in C++, when an equivalent algorithm is available. For convenience, and because the motivation for P2302 is literally identical, it has been copied here below, with alterations to accommodate the current situation.</p>
<blockquote>
<p>C++23 introduces <code class="sourceCode default">basic_string_view::contains</code>. Both <code class="sourceCode default">basic_string</code> and <code class="sourceCode default">basic_string_view</code> are perculiar container-like types, with many member functions that duplicate algorithm functionality with minor interface changes (e.g. <code class="sourceCode default">compare</code>, <code class="sourceCode default">copy</code>, <code class="sourceCode default">find</code>, <code class="sourceCode default">rfind</code>, <code class="sourceCode default">find_first_of</code>, etc.). P1679. P1679 §4.2 notes that the decision to add <code class="sourceCode default">contains</code> as a member function was because P1679 agrees with <span class="citation" data-cites="N3609">[<a href="#ref-N3609" role="doc-biblioref">N3609</a>]</span> in that <code class="sourceCode default">contains(haystack, needle)</code> is ambiguous with <code class="sourceCode default">contains(needle, haystack)</code>.</p>
<p>Although there is prior art with respect to <code class="sourceCode default">basic_string</code>’s member functions, the author expresses concern that our string types have a large set of member functions that either duplicate the algorithms or are directly incompatible with them, and thus limit the amount of composition that’s possible. Templates are one of C++’s greatest strengths, and with iterators, we have an extremely extensible and powerful generic programming model. We should take advantage of this model wherever possible to ensure that we do not paint ourselves into a corner with a single type.</p>
<p>At present, it isn’t immediately possible to query whether or not any range —other than a C++23 standard string type— contains an element.</p>
<p>It is interesting to note that, since one of the overloads in the <code class="sourceCode default">contains</code> overload set can be implemented <code class="sourceCode default">search</code>, we are able to query more than just “does <code class="sourceCode default">haystack</code> contain <code class="sourceCode default">needle</code>?”: we’re also able to query “does <code class="sourceCode default">haystack</code> contain something that resembles <code class="sourceCode default">needle</code>?”. See below for examples. This is something that the string-based member functions are unable to do, although the author acknowledges that P1679 mentions case-insensitivity was discussed, and that when framed as a string-only operation, it would be irresponsible to incorporate into the design. By making <code class="sourceCode default">contains</code> an algorithm, we can sidestep this issue altogether, and the post-text revolution simply needs to expose codepoint-relevant operations.</p>
<p>Concerns were outlined in all of N3609, P0457, P1679 about the ambiguity of whether we are performing <code class="sourceCode default">contains(haystack, needle)</code> or <code class="sourceCode default">contains(needle, haystack)</code>. There is prior art in the algorithms library that makes the first range the subject of the operation: <code class="sourceCode default">mismatch</code>, <code class="sourceCode default">equal</code>, <code class="sourceCode default">search</code>, <code class="sourceCode default">find_first_of</code>, and <code class="sourceCode default">lexicographical_compare</code> all take the form <code class="sourceCode default">algorithm(haystack, needle)</code>, so the author remains unconvinced about the ambiguity. LEWG approved P1659 in the Cologne 2019 meeting: meaning that this working group agrees that there isn’t any ambiguity, or that LEWG is inconsistent in what it agrees upon.</p>
</blockquote>
<p>The author agrees with the authors of P1679 in principle: there should be algorithms that check for these kinds of functionality. Where we disagree is on their placement. Since this functionality is likely useful for vectors, deques, arrays, static vectors, small vectors, ropes, circular buffers, and an infinite subset of composable ranges, the author strongly argues that <code class="sourceCode default">contains</code> should be an algorithm, not a member function to be added to every type that needs it. Further evidence for the existence of a <code class="sourceCode default">contains</code> algorithm is that the STL gave C++98 a poorly-named <code class="sourceCode default">contains</code> algorithm called <code class="sourceCode default">binary_search</code>, and <code class="sourceCode default">any_of</code> is “<code class="sourceCode default">contains</code> with a predicate”, showing that there’s prior art for this <code class="sourceCode default">contains</code> to be an algorithm.</p>
<h1 data-number="3" id="design"><span class="header-section-number">3</span> Design<a href="#design" class="self-link"></a></h1>
<p>The proposed usage looks like this:</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="cf">if</span> <span class="op">(</span>std<span class="op">::</span>ranges<span class="op">::</span>contains<span class="op">(</span>haystack, <span class="ch">&#39;o&#39;</span><span class="op">))</span> <span class="op">{</span></span>
<span id="cb1-2"><a href="#cb1-2"></a>  <span class="co">// meow</span></span>
<span id="cb1-3"><a href="#cb1-3"></a><span class="op">}</span></span>
<span id="cb1-4"><a href="#cb1-4"></a></span>
<span id="cb1-5"><a href="#cb1-5"></a><span class="cf">if</span> <span class="op">(</span>std<span class="op">::</span>ranges<span class="op">::</span>contains<span class="op">(</span>haystack<span class="op">.</span>begin<span class="op">()</span>, haystack<span class="op">.</span>end<span class="op">()</span>, <span class="ch">&#39;c&#39;</span><span class="op">))</span> <span class="op">{</span></span>
<span id="cb1-6"><a href="#cb1-6"></a>  <span class="co">// purr</span></span>
<span id="cb1-7"><a href="#cb1-7"></a><span class="op">}</span></span>
<span id="cb1-8"><a href="#cb1-8"></a></span>
<span id="cb1-9"><a href="#cb1-9"></a><span class="cf">if</span> <span class="op">(</span>std<span class="op">::</span>ranges<span class="op">::</span>contains<span class="op">(</span>haystack<span class="op">.</span>begin<span class="op">()</span>, haystack<span class="op">.</span>end<span class="op">()</span>, long_needle<span class="op">.</span>begin<span class="op">()</span>, long_needle<span class="op">.</span>end<span class="op">()))</span> <span class="op">{</span></span>
<span id="cb1-10"><a href="#cb1-10"></a>  <span class="co">// hiss</span></span>
<span id="cb1-11"><a href="#cb1-11"></a><span class="op">}</span></span>
<span id="cb1-12"><a href="#cb1-12"></a></span>
<span id="cb1-13"><a href="#cb1-13"></a><span class="cf">if</span> <span class="op">(</span>std<span class="op">::</span>ranges<span class="op">::</span>contains<span class="op">(</span>haystack, long_needle<span class="op">))</span> <span class="op">{</span></span>
<span id="cb1-14"><a href="#cb1-14"></a>  <span class="co">// hiss again</span></span>
<span id="cb1-15"><a href="#cb1-15"></a><span class="op">}</span></span>
<span id="cb1-16"><a href="#cb1-16"></a></span>
<span id="cb1-17"><a href="#cb1-17"></a><span class="cf">if</span> <span class="op">(</span>std<span class="op">::</span>ranges<span class="op">::</span>contains<span class="op">(</span>haystack, long_needle, bind_back<span class="op">(</span>std<span class="op">::</span>modulo<span class="op">()</span>, <span class="dv">4</span><span class="op">)))</span> <span class="op">{</span></span>
<span id="cb1-18"><a href="#cb1-18"></a>  <span class="co">// double purr</span></span>
<span id="cb1-19"><a href="#cb1-19"></a><span class="op">}</span></span></code></pre></div>
<p>As this is an algorithm, the author suggests this be placed in namespace <code class="sourceCode default">std::ranges</code>, where new algorithms are currently destined to go. As usual with new algorithms, these ones will also have projections.</p>
<h2 data-number="3.1" id="api"><span class="header-section-number">3.1</span> API<a href="#api" class="self-link"></a></h2>
<p>The author notes that for an unsorted sequence, a <code class="sourceCode default">contains</code> algorithm is simply one of the following:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb2-1"><a href="#cb2-1"></a><span class="kw">auto</span> <span class="kw">const</span> haystack <span class="op">=</span> <span class="st">&quot;the quick brown fox jumps over the lazy dog&quot;</span><span class="bu">sv</span>;</span>
<span id="cb2-2"><a href="#cb2-2"></a></span>
<span id="cb2-3"><a href="#cb2-3"></a>stdr<span class="op">::</span>find<span class="op">(</span>haystack, <span class="ch">&#39;o&#39;</span><span class="op">)</span> <span class="op">!=</span> haystack<span class="op">.</span>end<span class="op">()</span>; <span class="co">// haystack.contains(&#39;o&#39;)</span></span>
<span id="cb2-4"><a href="#cb2-4"></a><span class="kw">not</span> stdr<span class="op">::</span>search<span class="op">(</span>haystack, <span class="st">&quot;red&quot;</span><span class="bu">sv</span><span class="op">).</span>empty<span class="op">()</span>; <span class="co">// haystack.contains(&quot;red&quot;sv)</span></span>
<span id="cb2-5"><a href="#cb2-5"></a></span>
<span id="cb2-6"><a href="#cb2-6"></a><span class="co">// See https://godbolt.org/z/vTendW</span></span></code></pre></div>
<p>As such, <code class="sourceCode default">contains</code> is a wrapper around these two algorithms:</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">namespace</span> std <span class="op">{</span></span>
<span id="cb3-2"><a href="#cb3-2"></a>  <span class="kw">template</span><span class="op">&lt;</span>input_­iterator I, sentinel_­for<span class="op">&lt;</span>I<span class="op">&gt;</span> S, <span class="kw">class</span> T, <span class="kw">class</span> Proj <span class="op">=</span> identity<span class="op">&gt;</span></span>
<span id="cb3-3"><a href="#cb3-3"></a>  <span class="kw">requires</span> indirect_­binary_­predicate<span class="op">&lt;</span>ranges<span class="op">::</span>equal_to, projected<span class="op">&lt;</span>I, Proj<span class="op">&gt;</span>, <span class="kw">const</span> T<span class="op">*&gt;</span></span>
<span id="cb3-4"><a href="#cb3-4"></a>  <span class="kw">constexpr</span> <span class="dt">bool</span> ranges<span class="op">::</span>contains<span class="op">(</span>I first, S last, <span class="kw">const</span> T<span class="op">&amp;</span> value, Proj proj <span class="op">=</span> <span class="op">{})</span>;</span>
<span id="cb3-5"><a href="#cb3-5"></a></span>
<span id="cb3-6"><a href="#cb3-6"></a>  <span class="kw">template</span><span class="op">&lt;</span>input_­range R, <span class="kw">class</span> T, <span class="kw">class</span> Proj <span class="op">=</span> identity<span class="op">&gt;</span></span>
<span id="cb3-7"><a href="#cb3-7"></a>  <span class="kw">requires</span> indirect_­binary_­predicate<span class="op">&lt;</span>ranges<span class="op">::</span>equal_to, projected<span class="op">&lt;</span>iterator_t<span class="op">&lt;</span>R<span class="op">&gt;</span>, Proj<span class="op">&gt;</span>, <span class="kw">const</span> T<span class="op">*&gt;</span></span>
<span id="cb3-8"><a href="#cb3-8"></a>  <span class="kw">constexpr</span> <span class="dt">bool</span> ranges<span class="op">::</span>contains<span class="op">(</span>R<span class="op">&amp;&amp;</span> r, <span class="kw">const</span> T<span class="op">&amp;</span> value, Proj proj <span class="op">=</span> <span class="op">{})</span>;</span>
<span id="cb3-9"><a href="#cb3-9"></a></span>
<span id="cb3-10"><a href="#cb3-10"></a>  <span class="kw">template</span><span class="op">&lt;</span>forward_­iterator I1, sentinel_­for<span class="op">&lt;</span>I1<span class="op">&gt;</span> S1, forward_­iterator I2,</span>
<span id="cb3-11"><a href="#cb3-11"></a>           sentinel_­for<span class="op">&lt;</span>I2<span class="op">&gt;</span> S2, <span class="kw">class</span> Pred <span class="op">=</span> ranges<span class="op">::</span>equal_to,</span>
<span id="cb3-12"><a href="#cb3-12"></a>           <span class="kw">class</span> Proj1 <span class="op">=</span> identity, <span class="kw">class</span> Proj2 <span class="op">=</span> identity<span class="op">&gt;</span></span>
<span id="cb3-13"><a href="#cb3-13"></a>    <span class="kw">requires</span> indirectly_­comparable<span class="op">&lt;</span>I1, I2, Pred, Proj1, Proj2<span class="op">&gt;</span></span>
<span id="cb3-14"><a href="#cb3-14"></a>    <span class="kw">constexpr</span> <span class="dt">bool</span></span>
<span id="cb3-15"><a href="#cb3-15"></a>      ranges<span class="op">::</span>contains<span class="op">(</span>I1 first1, S1 last1, I2 first2, S2 last2, Pred pred <span class="op">=</span> <span class="op">{}</span>,</span>
<span id="cb3-16"><a href="#cb3-16"></a>                       Proj1 proj1 <span class="op">=</span> <span class="op">{}</span>, Proj2 proj2 <span class="op">=</span> <span class="op">{})</span>;</span>
<span id="cb3-17"><a href="#cb3-17"></a></span>
<span id="cb3-18"><a href="#cb3-18"></a>  <span class="kw">template</span><span class="op">&lt;</span>forward_­range R1, forward_­range R2, <span class="kw">class</span> Pred <span class="op">=</span> ranges<span class="op">::</span>equal_to,</span>
<span id="cb3-19"><a href="#cb3-19"></a>           <span class="kw">class</span> Proj1 <span class="op">=</span> identity, <span class="kw">class</span> Proj2 <span class="op">=</span> identity<span class="op">&gt;</span></span>
<span id="cb3-20"><a href="#cb3-20"></a>    <span class="kw">requires</span> indirectly_­comparable<span class="op">&lt;</span>iterator_t<span class="op">&lt;</span>R1<span class="op">&gt;</span>, iterator_t<span class="op">&lt;</span>R2<span class="op">&gt;</span>, Pred, Proj1, Proj2<span class="op">&gt;</span></span>
<span id="cb3-21"><a href="#cb3-21"></a>    <span class="kw">constexpr</span> <span class="dt">bool</span></span>
<span id="cb3-22"><a href="#cb3-22"></a>      ranges<span class="op">::</span>contains<span class="op">(</span>R1<span class="op">&amp;&amp;</span> r1, R2<span class="op">&amp;&amp;</span> r2, Pred pred <span class="op">=</span> <span class="op">{}</span>,</span>
<span id="cb3-23"><a href="#cb3-23"></a>                       Proj1 proj1 <span class="op">=</span> <span class="op">{}</span>, Proj2 proj2 <span class="op">=</span> <span class="op">{})</span>;</span>
<span id="cb3-24"><a href="#cb3-24"></a><span class="op">}</span></span></code></pre></div>
<p>As previously noted, a predicate-based “<code class="sourceCode default">contains_if</code>” already exists as <code class="sourceCode default">any_of</code>.</p>
<h1 data-number="4" id="changes-to-lewg-policy-standing-document"><span class="header-section-number">4</span> Changes to LEWG Policy Standing Document<a href="#changes-to-lewg-policy-standing-document" class="self-link"></a></h1>
<p>P1659 notes:</p>
<blockquote>
<p>In response to the concerns outlined in the motivation section of this document, the author would like to request that LEWG consider discussing adopting in SD-8, a policy of ensuring that options for algorithms are preferred when a proposal to add a member function to a container-like type is considered.</p>
</blockquote>
<p>P1659 was discussed in the Cologne 2019 meeting, where it was noted that the requested change to SD-8 would be better placed in the LEWG Policy Standing Document. There was agreement for this document to be updated to reflect this, but the approval of P1679 indicates that it might have slipped through the cracks.</p>
<p>The author would like to request that the working group confirm the presence of this rule, and add it if it is missing. The problem was frustrating enough when we only needed to worry about standard containers, but is now exacerbated thanks to the standard library’s acknowledgement of ranges.</p>
<p>Since the concern about “ambiguity” regarding haystacks and needles tends to pop up on occasion, it would be worth considering the addition of some additional wording to make it clear this problem has been a non-issue since the very beginning of standard C++.</p>
<h1 data-number="5" id="blunt-proposal"><span class="header-section-number">5</span> Blunt proposal<a href="#blunt-proposal" class="self-link"></a></h1>
<p>Remove both <code class="sourceCode default">std::basic_string::contains</code> and <code class="sourceCode default">std::basic_string_view::contains</code>, and to add the following proposed wording to the algorithms clause.</p>
<h2 data-number="5.1" id="proposed-wording"><span class="header-section-number">5.1</span> Proposed wording<a href="#proposed-wording" class="self-link"></a></h2>
<p>Remove the wording added by P1679R3.</p>
<p>Add the following text to <span>25.4
 <a href="https://wg21.link/algorithm.syn">[algorithm.syn]</a></span>:</p>
<div class="add" style="color: #006e28">

<div class="sourceCode" id="cb4"><pre class="sourceCode default cpp"><code class="sourceCode default"><span id="cb4-1"><a href="#cb4-1"></a>  // [alg.none.of], none of</span>
<span id="cb4-2"><a href="#cb4-2"></a>  // ...</span>
<span id="cb4-3"><a href="#cb4-3"></a></span>
<span id="cb4-4"><a href="#cb4-4"></a>  // [alg.contains], contains</span>
<span id="cb4-5"><a href="#cb4-5"></a>  template&lt;input_­iterator I, sentinel_­for&lt;I&gt; S, class T, class Proj = identity&gt;</span>
<span id="cb4-6"><a href="#cb4-6"></a>    requires indirect_­binary_­predicate&lt;ranges::equal_to, projected&lt;I, Proj&gt;, const T*&gt;</span>
<span id="cb4-7"><a href="#cb4-7"></a>    constexpr bool ranges::contains(I first, S last, const T&amp; value, Proj proj = {});</span>
<span id="cb4-8"><a href="#cb4-8"></a>  template&lt;input_­range R, class T, class Proj = identity&gt;</span>
<span id="cb4-9"><a href="#cb4-9"></a>    requires indirect_­binary_­predicate&lt;ranges::equal_to, projected&lt;iterator_t&lt;R&gt;, Proj&gt;, const T*&gt;</span>
<span id="cb4-10"><a href="#cb4-10"></a>    constexpr bool ranges::contains(R&amp;&amp; r, const T&amp; value, Proj proj = {});</span>
<span id="cb4-11"><a href="#cb4-11"></a></span>
<span id="cb4-12"><a href="#cb4-12"></a>  template&lt;forward_­iterator I1, sentinel_­for&lt;I1&gt; S1, forward_­iterator I2,</span>
<span id="cb4-13"><a href="#cb4-13"></a>           sentinel_­for&lt;I2&gt; S2, class Pred = ranges::equal_to,</span>
<span id="cb4-14"><a href="#cb4-14"></a>           class Proj1 = identity, class Proj2 = identity&gt;</span>
<span id="cb4-15"><a href="#cb4-15"></a>    requires indirectly_­comparable&lt;I1, I2, Pred, Proj1, Proj2&gt;</span>
<span id="cb4-16"><a href="#cb4-16"></a>    constexpr bool ranges::contains(I1 first1, S1 last1, I2 first2, S2 last2,</span>
<span id="cb4-17"><a href="#cb4-17"></a>                                    Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {});</span>
<span id="cb4-18"><a href="#cb4-18"></a>  template&lt;forward_­range R1, forward_­range R2, class Pred = ranges::equal_to,</span>
<span id="cb4-19"><a href="#cb4-19"></a>           class Proj1 = identity, class Proj2 = identity&gt;</span>
<span id="cb4-20"><a href="#cb4-20"></a>    requires indirectly_­comparable&lt;iterator_t&lt;R1&gt;, iterator_t&lt;R2&gt;, Pred, Proj1, Proj2&gt;</span>
<span id="cb4-21"><a href="#cb4-21"></a>    constexpr bool ranges::contains(R1&amp;&amp; r1, R2&amp;&amp; r2, Pred pred = {},</span>
<span id="cb4-22"><a href="#cb4-22"></a>                                    Proj1 proj1 = {}, Proj2 proj2 = {});</span>
<span id="cb4-23"><a href="#cb4-23"></a></span>
<span id="cb4-24"><a href="#cb4-24"></a>  // [alg.foreach], for each</span></code></pre></div>

</div>
<p>Add the following to <span>25.6
 <a href="https://wg21.link/alg.nonmodifying">[alg.nonmodifying]</a></span>:</p>
<div class="add" style="color: #006e28">

<div class="sourceCode" id="cb5"><pre class="sourceCode default cpp"><code class="sourceCode default"><span id="cb5-1"><a href="#cb5-1"></a>template&lt;input_­iterator I, sentinel_­for&lt;I&gt; S, class T, class Proj = identity&gt;</span>
<span id="cb5-2"><a href="#cb5-2"></a>  requires indirect_­binary_­predicate&lt;ranges::equal_to, projected&lt;I, Proj&gt;, const T*&gt;</span>
<span id="cb5-3"><a href="#cb5-3"></a>  constexpr bool ranges::contains(I first, S last, const T&amp; value, Proj proj = {});</span>
<span id="cb5-4"><a href="#cb5-4"></a></span>
<span id="cb5-5"><a href="#cb5-5"></a>template&lt;input_­range R, class T, class Proj = identity&gt;</span>
<span id="cb5-6"><a href="#cb5-6"></a>  requires indirect_­binary_­predicate&lt;ranges::equal_to, projected&lt;iterator_t&lt;R&gt;, Proj&gt;, const T*&gt;</span>
<span id="cb5-7"><a href="#cb5-7"></a>  constexpr bool ranges::contains(R&amp;&amp; r, const T&amp; value, Proj proj = {});</span></code></pre></div>
<p><em>Returns</em>: <code class="sourceCode default">ranges::find(first, last, value, proj) != last</code>.</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode default cpp"><code class="sourceCode default"><span id="cb6-1"><a href="#cb6-1"></a>template&lt;forward_­iterator I1, sentinel_­for&lt;I1&gt; S1, forward_­iterator I2,</span>
<span id="cb6-2"><a href="#cb6-2"></a>         sentinel_­for&lt;I2&gt; S2, class Pred = ranges::equal_to,</span>
<span id="cb6-3"><a href="#cb6-3"></a>         class Proj1 = identity, class Proj2 = identity&gt;</span>
<span id="cb6-4"><a href="#cb6-4"></a>  requires indirectly_­comparable&lt;I1, I2, Pred, Proj1, Proj2&gt;</span>
<span id="cb6-5"><a href="#cb6-5"></a>  constexpr bool ranges::contains(I1 first1, S1 last1, I2 first2, S2 last2,</span>
<span id="cb6-6"><a href="#cb6-6"></a>                                  Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {});</span>
<span id="cb6-7"><a href="#cb6-7"></a>template&lt;forward_­range R1, forward_­range R2, class Pred = ranges::equal_to,</span>
<span id="cb6-8"><a href="#cb6-8"></a>         class Proj1 = identity, class Proj2 = identity&gt;</span>
<span id="cb6-9"><a href="#cb6-9"></a>  requires indirectly_­comparable&lt;iterator_t&lt;R1&gt;, iterator_t&lt;R2&gt;, Pred, Proj1, Proj2&gt;</span>
<span id="cb6-10"><a href="#cb6-10"></a>  constexpr bool ranges::contains(R1&amp;&amp; r1, R2&amp;&amp; r2, Pred pred = {},</span>
<span id="cb6-11"><a href="#cb6-11"></a>                                  Proj1 proj1 = {}, Proj2 proj2 = {});</span></code></pre></div>
<p><em>Returns</em>: <code class="sourceCode default">return ranges::search(first1, last1, first2, last2, pred, proj1, proj2).empty() == false</code>.</p>
</div>
<h1 data-number="6" id="acknowledgements"><span class="header-section-number">6</span> Acknowledgements<a href="#acknowledgements" class="self-link"></a></h1>
<p>The author would like to thank Corentin Jabot for reviewing this proposal.</p>
<h1 data-number="7" id="bibliography"><span class="header-section-number">7</span> References<a href="#bibliography" class="self-link"></a></h1>
<div id="refs" class="references hanging-indent" role="doc-bibliography">
<div id="ref-N3609">
<p>[N3609] Jeffrey Yasskin. 2013-03-15. string_view: a non-owning reference to a string, revision 3. <br />
<a href="https://wg21.link/n3609">https://wg21.link/n3609</a></p>
</div>
<div id="ref-P1659R1">
<p>[P1659R1] Christopher Di Bella. 2020-07-15. starts_with and ends_with. <br />
<a href="https://wg21.link/p1659r1">https://wg21.link/p1659r1</a></p>
</div>
<div id="ref-P1679R3">
<p>[P1679R3] Wim Leflere, Paul Fee. 2020-07-22. String Contains function. <br />
<a href="https://wg21.link/p1679r3">https://wg21.link/p1679r3</a></p>
</div>
</div>
</div>
</div>
</body>
</html>
