<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><style>@font-face {
  font-family: octicons-anchor;
  src: url(https://cdnjs.cloudflare.com/ajax/libs/octicons/4.4.0/font/octicons.woff) format('woff');
}

* {
    box-sizing: border-box;
}

body {
    width: 980px;
    margin-right: auto;
    margin-left: auto;
}

body .markdown-body {
    padding: 45px;
    border: 1px solid #ddd;
    border-radius: 3px;
    word-wrap: break-word;
}

pre {
    font: 12px Consolas, "Liberation Mono", Menlo, Courier, monospace;
}

.markdown-body {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  color: #333;
  font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
  font-size: 16px;
  line-height: 1.6;
  word-wrap: break-word;
}

.markdown-body a {
  background-color: transparent;
}

.markdown-body a:active,
.markdown-body a:hover {
  outline: 0;
}

.markdown-body strong {
  font-weight: bold;
}

.markdown-body h1 {
  font-size: 2em;
  margin: 0.67em 0;
}

.markdown-body img {
  border: 0;
}

.markdown-body hr {
  box-sizing: content-box;
  height: 0;
}

.markdown-body pre {
  overflow: auto;
}

.markdown-body code,
.markdown-body kbd,
.markdown-body pre {
  font-family: monospace, monospace;
  font-size: 1em;
}

.markdown-body input {
  color: inherit;
  font: inherit;
  margin: 0;
}

.markdown-body html input[disabled] {
  cursor: default;
}

.markdown-body input {
  line-height: normal;
}

.markdown-body input[type="checkbox"] {
  box-sizing: border-box;
  padding: 0;
}

.markdown-body table {
  border-collapse: collapse;
  border-spacing: 0;
}

.markdown-body td,
.markdown-body th {
  padding: 0;
}

.markdown-body input {
  font: 13px / 1.4 Helvetica, arial, nimbussansl, liberationsans, freesans, clean, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
}

.markdown-body a {
  color: #4078c0;
  text-decoration: none;
}

.markdown-body a:hover,
.markdown-body a:active {
  text-decoration: underline;
}

.markdown-body hr {
  height: 0;
  margin: 15px 0;
  overflow: hidden;
  background: transparent;
  border: 0;
  border-bottom: 1px solid #ddd;
}

.markdown-body hr:before {
  display: table;
  content: "";
}

.markdown-body hr:after {
  display: table;
  clear: both;
  content: "";
}

.markdown-body h1,
.markdown-body h2,
.markdown-body h3,
.markdown-body h4,
.markdown-body h5,
.markdown-body h6 {
  margin-top: 15px;
  margin-bottom: 15px;
  line-height: 1.1;
}

.markdown-body h1 {
  font-size: 30px;
}

.markdown-body h2 {
  font-size: 21px;
}

.markdown-body h3 {
  font-size: 16px;
}

.markdown-body h4 {
  font-size: 14px;
}

.markdown-body h5 {
  font-size: 12px;
}

.markdown-body h6 {
  font-size: 11px;
}

.markdown-body blockquote {
  margin: 0;
}

.markdown-body ul,
.markdown-body ol {
  padding: 0;
  margin-top: 0;
  margin-bottom: 0;
}

.markdown-body ol ol,
.markdown-body ul ol {
  list-style-type: lower-roman;
}

.markdown-body ul ul ol,
.markdown-body ul ol ol,
.markdown-body ol ul ol,
.markdown-body ol ol ol {
  list-style-type: lower-alpha;
}

.markdown-body dd {
  margin-left: 0;
}

.markdown-body code {
  font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace;
  font-size: 12px;
}

.markdown-body pre {
  margin-top: 0;
  margin-bottom: 0;
  font: 12px Consolas, "Liberation Mono", Menlo, Courier, monospace;
}

.markdown-body .select::-ms-expand {
  opacity: 0;
}

.markdown-body .octicon {
  font: normal normal normal 16px/1 octicons-anchor;
  display: inline-block;
  text-decoration: none;
  text-rendering: auto;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}

.markdown-body .octicon-link:before {
  content: '\f05c';
}

.markdown-body:before {
  display: table;
  content: "";
}

.markdown-body:after {
  display: table;
  clear: both;
  content: "";
}

.markdown-body>*:first-child {
  margin-top: 0 !important;
}

.markdown-body>*:last-child {
  margin-bottom: 0 !important;
}

.markdown-body a:not([href]) {
  color: inherit;
  text-decoration: none;
}

.markdown-body .anchor {
  display: inline-block;
  padding-right: 2px;
  margin-left: -18px;
}

.markdown-body .anchor:focus {
  outline: none;
}

.markdown-body h1,
.markdown-body h2,
.markdown-body h3,
.markdown-body h4,
.markdown-body h5,
.markdown-body h6 {
  margin-top: 1em;
  margin-bottom: 16px;
  font-weight: bold;
  line-height: 1.4;
}

.markdown-body h1 .octicon-link,
.markdown-body h2 .octicon-link,
.markdown-body h3 .octicon-link,
.markdown-body h4 .octicon-link,
.markdown-body h5 .octicon-link,
.markdown-body h6 .octicon-link {
  color: #000;
  vertical-align: middle;
  visibility: hidden;
}

.markdown-body h1:hover .anchor,
.markdown-body h2:hover .anchor,
.markdown-body h3:hover .anchor,
.markdown-body h4:hover .anchor,
.markdown-body h5:hover .anchor,
.markdown-body h6:hover .anchor {
  text-decoration: none;
}

.markdown-body h1:hover .anchor .octicon-link,
.markdown-body h2:hover .anchor .octicon-link,
.markdown-body h3:hover .anchor .octicon-link,
.markdown-body h4:hover .anchor .octicon-link,
.markdown-body h5:hover .anchor .octicon-link,
.markdown-body h6:hover .anchor .octicon-link {
  visibility: visible;
}

.markdown-body h1 {
  padding-bottom: 0.3em;
  font-size: 2.25em;
  line-height: 1.2;
  border-bottom: 1px solid #eee;
}

.markdown-body h1 .anchor {
  line-height: 1;
}

.markdown-body h2 {
  padding-bottom: 0.3em;
  font-size: 1.75em;
  line-height: 1.225;
  border-bottom: 1px solid #eee;
}

.markdown-body h2 .anchor {
  line-height: 1;
}

.markdown-body h3 {
  font-size: 1.5em;
  line-height: 1.43;
}

.markdown-body h3 .anchor {
  line-height: 1.2;
}

.markdown-body h4 {
  font-size: 1.25em;
}

.markdown-body h4 .anchor {
  line-height: 1.2;
}

.markdown-body h5 {
  font-size: 1em;
}

.markdown-body h5 .anchor {
  line-height: 1.1;
}

.markdown-body h6 {
  font-size: 1em;
  color: #777;
}

.markdown-body h6 .anchor {
  line-height: 1.1;
}

.markdown-body p,
.markdown-body blockquote,
.markdown-body ul,
.markdown-body ol,
.markdown-body dl,
.markdown-body table,
.markdown-body pre {
  margin-top: 0;
  margin-bottom: 16px;
}

.markdown-body hr {
  height: 4px;
  padding: 0;
  margin: 16px 0;
  background-color: #e7e7e7;
  border: 0 none;
}

.markdown-body ul,
.markdown-body ol {
  padding-left: 2em;
}

.markdown-body ul ul,
.markdown-body ul ol,
.markdown-body ol ol,
.markdown-body ol ul {
  margin-top: 0;
  margin-bottom: 0;
}

.markdown-body li>p {
  margin-top: 16px;
}

.markdown-body dl {
  padding: 0;
}

.markdown-body dl dt {
  padding: 0;
  margin-top: 16px;
  font-size: 1em;
  font-style: italic;
  font-weight: bold;
}

.markdown-body dl dd {
  padding: 0 16px;
  margin-bottom: 16px;
}

.markdown-body blockquote {
  padding: 0 15px;
  color: #777;
  border-left: 4px solid #ddd;
}

.markdown-body blockquote>:first-child {
  margin-top: 0;
}

.markdown-body blockquote>:last-child {
  margin-bottom: 0;
}

.markdown-body table {
  display: block;
  width: 100%;
  overflow: auto;
  word-break: normal;
  word-break: keep-all;
}

.markdown-body table th {
  font-weight: bold;
}

.markdown-body table th,
.markdown-body table td {
  padding: 6px 13px;
  border: 1px solid #ddd;
}

.markdown-body table tr {
  background-color: #fff;
  border-top: 1px solid #ccc;
}

.markdown-body table tr:nth-child(2n) {
  background-color: #f8f8f8;
}

.markdown-body img {
  max-width: 100%;
  box-sizing: content-box;
  background-color: #fff;
}

.markdown-body code {
  padding: 0;
  padding-top: 0.2em;
  padding-bottom: 0.2em;
  margin: 0;
  font-size: 85%;
  background-color: rgba(0,0,0,0.04);
  border-radius: 3px;
}

.markdown-body code:before,
.markdown-body code:after {
  letter-spacing: -0.2em;
  content: "\00a0";
}

.markdown-body pre>code {
  padding: 0;
  margin: 0;
  font-size: 100%;
  word-break: normal;
  white-space: pre;
  background: transparent;
  border: 0;
}

.markdown-body .highlight {
  margin-bottom: 16px;
}

.markdown-body .highlight pre,
.markdown-body pre {
  padding: 16px;
  overflow: auto;
  font-size: 85%;
  line-height: 1.45;
  background-color: #f7f7f7;
  border-radius: 3px;
}

.markdown-body .highlight pre {
  margin-bottom: 0;
  word-break: normal;
}

.markdown-body pre {
  word-wrap: normal;
}

.markdown-body pre code {
  display: inline;
  max-width: initial;
  padding: 0;
  margin: 0;
  overflow: initial;
  line-height: inherit;
  word-wrap: normal;
  background-color: transparent;
  border: 0;
}

.markdown-body pre code:before,
.markdown-body pre code:after {
  content: normal;
}

.markdown-body kbd {
  display: inline-block;
  padding: 3px 5px;
  font-size: 11px;
  line-height: 10px;
  color: #555;
  vertical-align: middle;
  background-color: #fcfcfc;
  border: solid 1px #ccc;
  border-bottom-color: #bbb;
  border-radius: 3px;
  box-shadow: inset 0 -1px 0 #bbb;
}

.markdown-body .pl-c {
  color: #969896;
}

.markdown-body .pl-c1,
.markdown-body .pl-s .pl-v {
  color: #0086b3;
}

.markdown-body .pl-e,
.markdown-body .pl-en {
  color: #795da3;
}

.markdown-body .pl-s .pl-s1,
.markdown-body .pl-smi {
  color: #333;
}

.markdown-body .pl-ent {
  color: #63a35c;
}

.markdown-body .pl-k {
  color: #a71d5d;
}

.markdown-body .pl-pds,
.markdown-body .pl-s,
.markdown-body .pl-s .pl-pse .pl-s1,
.markdown-body .pl-sr,
.markdown-body .pl-sr .pl-cce,
.markdown-body .pl-sr .pl-sra,
.markdown-body .pl-sr .pl-sre {
  color: #183691;
}

.markdown-body .pl-v {
  color: #ed6a43;
}

.markdown-body .pl-id {
  color: #b52a1d;
}

.markdown-body .pl-ii {
  background-color: #b52a1d;
  color: #f8f8f8;
}

.markdown-body .pl-sr .pl-cce {
  color: #63a35c;
  font-weight: bold;
}

.markdown-body .pl-ml {
  color: #693a17;
}

.markdown-body .pl-mh,
.markdown-body .pl-mh .pl-en,
.markdown-body .pl-ms {
  color: #1d3e81;
  font-weight: bold;
}

.markdown-body .pl-mq {
  color: #008080;
}

.markdown-body .pl-mi {
  color: #333;
  font-style: italic;
}

.markdown-body .pl-mb {
  color: #333;
  font-weight: bold;
}

.markdown-body .pl-md {
  background-color: #ffecec;
  color: #bd2c00;
}

.markdown-body .pl-mi1 {
  background-color: #eaffea;
  color: #55a532;
}

.markdown-body .pl-mdr {
  color: #795da3;
  font-weight: bold;
}

.markdown-body .pl-mo {
  color: #1d3e81;
}

.markdown-body kbd {
  display: inline-block;
  padding: 3px 5px;
  font: 11px Consolas, "Liberation Mono", Menlo, Courier, monospace;
  line-height: 10px;
  color: #555;
  vertical-align: middle;
  background-color: #fcfcfc;
  border: solid 1px #ccc;
  border-bottom-color: #bbb;
  border-radius: 3px;
  box-shadow: inset 0 -1px 0 #bbb;
}

.markdown-body .plan-price-unit {
  color: #767676;
  font-weight: normal;
}

.markdown-body .task-list-item {
  list-style-type: none;
}

.markdown-body .task-list-item+.task-list-item {
  margin-top: 3px;
}

.markdown-body .task-list-item input {
  margin: 0 0.35em 0.25em -1.6em;
  vertical-align: middle;
}

.markdown-body .plan-choice {
  padding: 15px;
  padding-left: 40px;
  display: block;
  border: 1px solid #e0e0e0;
  position: relative;
  font-weight: normal;
  background-color: #fafafa;
}

.markdown-body .plan-choice.open {
  background-color: #fff;
}

.markdown-body .plan-choice.open .plan-choice-seat-breakdown {
  display: block;
}

.markdown-body .plan-choice-free {
  border-radius: 3px 3px 0 0;
}

.markdown-body .plan-choice-paid {
  border-radius: 0 0 3px 3px;
  border-top: 0;
  margin-bottom: 20px;
}

.markdown-body .plan-choice-radio {
  position: absolute;
  left: 15px;
  top: 18px;
}

.markdown-body .plan-choice-exp {
  color: #999;
  font-size: 12px;
  margin-top: 5px;
}

.markdown-body .plan-choice-seat-breakdown {
  margin-top: 10px;
  display: none;
}

.markdown-body :checked+.radio-label {
  z-index: 1;
  position: relative;
  border-color: #4078c0;
}

@media print {
  body .markdown-body {
    padding: 0;
    border: none;
  }
}
</style><title>is_clamped</title></head><body><article class="markdown-body"><p>Doc. no:  P1440R0 <br>
Date:     2019-01-19 <br>
Reply-to: Johel Guerrero <a href="mailto:johelegp@gmail.com">johelegp@gmail.com</a> <br>
Audience: Library Incubator <br>
Source:   <a href="https://github.com/johelegp/proposals/blob/master/is_clamped.md">https://github.com/johelegp/proposals/blob/master/is_clamped.md</a></p>
<h1>
<a id="user-content-is_clamped" class="anchor" href="#is_clamped" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a><code>is_clamped</code>
</h1>
<h2>
<a id="user-content-abstract" class="anchor" href="#abstract" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Abstract</h2>
<p>Introduce <code>std::is_clamped(v, lo, hi)</code> to mean <code>lo &lt;= v &amp;&amp; v &lt;= hi</code>,
except that <code>v</code> is only evaluated once.</p>
<table>
<thead>
<tr>
<th>Now</th>
<th>Proposed alternative</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>Axis::x &lt;= Coord::axis &amp;&amp; Coord::axis &lt;= Axis::z</code></td>
<td><code>std::is_clamped(Coord::axis, Axis::x, Axis::z)</code></td>
</tr>
</tbody>
</table>
<table>
<thead>
<tr>
<th>Now</th>
<th>Proposed alternative + P0330 [4]</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>1u &lt;= digits.size() &amp;&amp; digits.size() &lt;= 7u</code></td>
<td><code>std::is_clamped(digits.size(), 1uz, 7uz)</code></td>
</tr>
</tbody>
</table>
<h2>
<a id="user-content-revision-history" class="anchor" href="#revision-history" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Revision history</h2>
<ul>
<li>
<em>cv</em> <code>void</code> -&gt; R0
<ul>
<li>
<code>2019y/January/19</code>, pre-Kona.</li>
</ul>
</li>
</ul>
<h2>
<a id="user-content-problem" class="anchor" href="#problem" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Problem</h2>
<p>Expressions equivalent to <code>lo &lt;= v &amp;&amp; v &lt;= hi</code> are common.
They are used to check whether <code>v</code> is within the range [<code>lo</code>, <code>hi</code>].
However, because <code>v</code> appears twice, they</p>
<ul>
<li>are error prone to type and update,</li>
<li>reduce readability as <code>v</code> gets longer, and</li>
<li>may degrade performance due to the repeated evaluation of <code>v</code>.</li>
</ul>
<p>We propose <code>std::is_clamped(v, lo, hi)</code> as an alternative spelling
that better captures intent and is potentially more performant.</p>
<h2>
<a id="user-content-alternatives" class="anchor" href="#alternatives" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Alternatives</h2>
<h3>
<a id="user-content-chaining-comparisons-rejected" class="anchor" href="#chaining-comparisons-rejected" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Chaining Comparisons (rejected)</h3>
<p>P0893 [1] would have allowed us to write <code>lo &lt;= v &lt;= hi</code>.
Its rejection made us write this proposal.</p>
<blockquote>
<p>There was no consensus on making comparison operators chain,
nor was there encouragement for further work in that area. <br>
-- P1018R2 [2]</p>
</blockquote>
<h3>
<a id="user-content-initialize-intermediate-variable-with-v" class="anchor" href="#initialize-intermediate-variable-with-v" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Initialize intermediate variable with <code>v</code>
</h3>
<p>It may be undesirable for some of the reasons
selection and iteration statements have been getting space for initialization.</p>
<p>In some contexts it is impossible,
such as member intializer lists and requires clauses.</p>
<h3>
<a id="user-content-immediately-invoked-lambda-expression" class="anchor" href="#immediately-invoked-lambda-expression" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Immediately invoked lambda expression</h3>
<p>This works, at the cost of much syntactical noise on par with repeating <code>v</code>:</p>
<ul>
<li>
<code>[&amp;] { const auto&amp; w{v}; return </code><em><code>what we actually care about</code></em><code>; }()</code>, or</li>
<li>
<code>[](const auto&amp; v) { return </code><em><code>what we actually care about</code></em><code>; }(v)</code>.</li>
</ul>
<h3>
<a id="user-content-safe-integral-comparisons-stdin_range" class="anchor" href="#safe-integral-comparisons-stdin_range" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Safe integral comparisons' <code>std::in_range</code>
</h3>
<p>Vicente J. Botet Escriba made us aware [6]
of <code>std::in_range</code> proposed in P0586 [7].
Its name suggests similarity to our proposed <code>std::is_clamped</code>.
However, it checks whether an integral value is in the range of an integral type
with safe integral comparisons proposed in the same paper.
Neither can subsume the other.</p>
<h3>
<a id="user-content-bikeshedding" class="anchor" href="#bikeshedding" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Bikeshedding</h3>
<p>The following have been suggested of the proposed <code>std::is_clamped</code> design:</p>
<ul>
<li>Different names.</li>
<li>Allowing arguments of different types.</li>
<li>Marking a bound as closed or half-open.</li>
</ul>
<p>However, we believe the proposed design was fixed
once ISO/IEC 14882:2017 (C++17) was published with <code>std::clamp</code>.
After all, we mean for <code>std::is_clamped</code> to complement <code>std::clamp</code>
in the same way <code>std::is_sorted</code> complements <code>std::sort</code>.</p>
<h2>
<a id="user-content-wording" class="anchor" href="#wording" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Wording</h2>
<p>Add the following declarations to [algorithm.syn] after those of <code>clamp</code>.</p>
<div class="highlight highlight-source-c++"><pre><span class="pl-k">template</span>&lt;<span class="pl-k">class</span> <span class="pl-en">T</span>&gt;
  <span class="pl-k">constexpr</span> <span class="pl-k">bool</span> <span class="pl-en">is_clamped</span>(<span class="pl-k">const</span> T&amp; v, <span class="pl-k">const</span> T&amp; lo, <span class="pl-k">const</span> T&amp; hi);
<span class="pl-k">template</span>&lt;<span class="pl-k">class</span> <span class="pl-en">T</span>, <span class="pl-k">class</span> <span class="pl-en">Compare</span>&gt;
  <span class="pl-k">constexpr</span> <span class="pl-k">bool</span> <span class="pl-en">is_clamped</span>(<span class="pl-k">const</span> T&amp; v, <span class="pl-k">const</span> T&amp; lo, <span class="pl-k">const</span> T&amp; hi, Compare comp);

<span class="pl-k">namespace</span> <span class="pl-en">ranges</span> {
  <span class="pl-k">template</span>&lt;<span class="pl-k">class</span> <span class="pl-en">T</span>, <span class="pl-k">class</span> <span class="pl-en">Proj</span> = identity,
           IndirectStrictWeakOrder&lt;projected&lt;<span class="pl-k">const</span> T*, Proj&gt;&gt; Comp = ranges::less&lt;&gt;&gt;
    <span class="pl-k">constexpr</span> <span class="pl-k">bool</span> <span class="pl-en">is_clamped</span>(<span class="pl-k">const</span> T&amp; v, <span class="pl-k">const</span> T&amp; lo, <span class="pl-k">const</span> T&amp; hi, Comp comp = {}, Proj proj = {});
}</pre></div>
<p>Add the following detailed specifications to [alg.clamp] after those of <code>clamp</code>.</p>
<div class="highlight highlight-source-c++"><pre><span class="pl-k">template</span>&lt;<span class="pl-k">class</span> <span class="pl-en">T</span>&gt;
  <span class="pl-k">constexpr</span> <span class="pl-k">bool</span> <span class="pl-en">is_clamped</span>(<span class="pl-k">const</span> T&amp; v, <span class="pl-k">const</span> T&amp; lo, <span class="pl-k">const</span> T&amp; hi);
<span class="pl-k">template</span>&lt;<span class="pl-k">class</span> <span class="pl-en">T</span>, <span class="pl-k">class</span> <span class="pl-en">Compare</span>&gt;
  <span class="pl-k">constexpr</span> <span class="pl-k">bool</span> <span class="pl-en">is_clamped</span>(<span class="pl-k">const</span> T&amp; v, <span class="pl-k">const</span> T&amp; lo, <span class="pl-k">const</span> T&amp; hi, Compare comp);

<span class="pl-k">namespace</span> <span class="pl-en">ranges</span> {
  <span class="pl-k">template</span>&lt;<span class="pl-k">class</span> <span class="pl-en">T</span>, <span class="pl-k">class</span> <span class="pl-en">Proj</span> = identity,
           IndirectStrictWeakOrder&lt;projected&lt;<span class="pl-k">const</span> T*, Proj&gt;&gt; Comp = ranges::less&lt;&gt;&gt;
    <span class="pl-k">constexpr</span> <span class="pl-k">bool</span> <span class="pl-en">is_clamped</span>(<span class="pl-k">const</span> T&amp; v, <span class="pl-k">const</span> T&amp; lo, <span class="pl-k">const</span> T&amp; hi, Comp comp = {}, Proj proj = {});
}</pre></div>
<p><em>Expects:</em> The value of <code>lo</code> is no greater than <code>hi</code>.
For the first form, type <code>T</code> shall be <em>Cpp17LessThanComparable</em> (Table 24).</p>
<p><em>Returns:</em> <code>true</code> if</p>
<ul>
<li>
<code>v</code> is not less than <code>lo</code>, and</li>
<li>
<code>hi</code> is not less than <code>v</code>. <br>
Otherwise, <code>false</code>.</li>
</ul>
<p>[ <em>Note:</em> If NaN is avoided, <code>T</code> can be a floating-point type. -- <em>end note</em> ]</p>
<p><em>Complexity:</em> At most two comparisons and
three applications of the projection, if any.</p>
<h2>
<a id="user-content-possible-implementation" class="anchor" href="#possible-implementation" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Possible implementation</h2>
<div class="highlight highlight-source-c++"><pre><span class="pl-k">template</span>&lt;<span class="pl-k">class</span> <span class="pl-en">T</span>&gt;
  <span class="pl-k">constexpr</span> <span class="pl-k">bool</span> <span class="pl-en">is_clamped</span>(<span class="pl-k">const</span> T&amp; v, <span class="pl-k">const</span> T&amp; lo, <span class="pl-k">const</span> T&amp; hi)
{
  <span class="pl-k">return</span> !(v &lt; lo) &amp;&amp; !(hi &lt; v);
}

<span class="pl-k">template</span>&lt;<span class="pl-k">class</span> <span class="pl-en">T</span>, <span class="pl-k">class</span> <span class="pl-en">Compare</span>&gt;
  <span class="pl-k">constexpr</span> <span class="pl-k">bool</span> <span class="pl-en">is_clamped</span>(<span class="pl-k">const</span> T&amp; v, <span class="pl-k">const</span> T&amp; lo, <span class="pl-k">const</span> T&amp; hi, Compare comp)
{
  <span class="pl-k">return</span> !<span class="pl-c1">comp</span>(v, lo) &amp;&amp; !<span class="pl-c1">comp</span>(hi, v);
}

<span class="pl-k">namespace</span> <span class="pl-en">ranges</span> {
  <span class="pl-k">template</span>&lt;<span class="pl-k">class</span> <span class="pl-en">T</span>, <span class="pl-k">class</span> <span class="pl-en">Proj</span> = identity,
           IndirectStrictWeakOrder&lt;projected&lt;<span class="pl-k">const</span> T*, Proj&gt;&gt; Comp = ranges::less&lt;&gt;&gt;
    <span class="pl-k">constexpr</span> <span class="pl-k">bool</span> <span class="pl-en">is_clamped</span>(<span class="pl-k">const</span> T&amp; v, <span class="pl-k">const</span> T&amp; lo, <span class="pl-k">const</span> T&amp; hi, Comp comp = {}, Proj proj = {})
  {
    <span class="pl-k">auto</span>&amp;&amp; pv{<span class="pl-c1">INVOKE</span>(proj, v)};
    <span class="pl-k">return</span> !<span class="pl-c1">INVOKE</span>(comp, pv, <span class="pl-c1">INVOKE</span>(proj, lo)) &amp;&amp;
           !<span class="pl-c1">INVOKE</span>(comp, <span class="pl-c1">INVOKE</span>(proj, hi), pv);
  }
}</pre></div>
<h2>
<a id="user-content-related-proposals" class="anchor" href="#related-proposals" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Related proposals</h2>
<table>
<thead>
<tr>
<th>Paper</th>
<th>Title</th>
<th>Relation</th>
</tr>
</thead>
<tbody>
<tr>
<td>P1243 [3]</td>
<td>Rangify New Algorithms</td>
<td>Introduces <code>std::ranges::clamp</code>.</td>
</tr>
</tbody>
</table>
<h2>
<a id="user-content-acknowledgements" class="anchor" href="#acknowledgements" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Acknowledgements</h2>
<p>Thanks to
Ray Hamel,
Vicente J. Botet Escriba,
and everyone else for their comments in the std-proposals thread [5].</p>
<h2>
<a id="user-content-references" class="anchor" href="#references" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>References</h2>
<p>[1] Chaining Comparisons, <a href="https://wg21.link/P0893" rel="nofollow">https://wg21.link/P0893</a> <br>
[2] Evolution status after San Diego 2018, <a href="https://wg21.link/P1018r2" rel="nofollow">https://wg21.link/P1018r2</a> <br>
[3] Rangify New Algorithms, <a href="https://wg21.link/P1243" rel="nofollow">https://wg21.link/P1243</a> <br>
[4] Literal Suffixes for ptrdiff_t and size_t, <a href="https://wg21.link/P0330" rel="nofollow">https://wg21.link/P0330</a> <br>
[5] is_clamped,
<a href="https://groups.google.com/a/isocpp.org/forum/?fromgroups#!topic/std-proposals/LDhzb-58sV4" rel="nofollow">https://groups.google.com/a/isocpp.org/forum/?fromgroups#!topic/std-proposals/LDhzb-58sV4</a> <br>
[6] Personal communications <br>
[7] Safe integral comparisons, <a href="https://wg21.link/P0586" rel="nofollow">https://wg21.link/P0586</a></p>
</article></body></html>