is_clamped

180 views
Skip to first unread message

Johel Ernesto Guerrero Peña

unread,
Jan 9, 2019, 12:55:43 PM1/9/19
to ISO C++ Standard - Future Proposals
Greetings.

I have written a proposal to add is_clamped to the standard, and would appreciate any feedback on it.


Abstract
Introduce `std::is_clamped(v, lo, hi)` to mean `lo <= v && v <= hi`, except that `v` is only evaluated once.

| Now                                                | Proposed alternative                             |
| -------------------------------------------------- | ------------------------------------------------ |
| `Axis::x <= Coord::axis && Coord::axis <= Axis::z` | `std::is_clamped(Coord::axis, Axis::x, Axis::z)` |

| Now                                          | Proposed alternative + P0330 [4]           |
| -------------------------------------------- | ------------------------------------------ |
| `1u <= digits.size() && digits.size() <= 7u` | `std::is_clamped(digits.size(), 1uz, 7uz)` |



If everything's well, I'll ask for a document number and submit it to the next mailing list.
In that case, I'd appreciate if somebody could offer presenting it at the meeting.

Thank you.

Ray Hamel

unread,
Jan 9, 2019, 1:22:52 PM1/9/19
to ISO C++ Standard - Future Proposals
Might it be more useful to return an ordering instead of a bool?

-Ray

Message has been deleted

Andrew Giese

unread,
Jan 10, 2019, 7:23:43 AM1/10/19
to std-pr...@isocpp.org
I like the abstraction this provides.

It's possible that Type1 v is comparable to Type2 lo and Type3 hi. Restricting all types of is_clamped to T may be needlessly restrictive. See how range based for loops evolved in a similar way (allowing begin and end to return different types so long as they were comparable).

Regards,
Andy

On Wed, Jan 9, 2019, 12:22 PM Ray Hamel <rayg...@gmail.com wrote:
Might it be more useful to return an ordering instead of a bool?

-Ray

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/d0ca7efb-febb-4f2d-ba28-daf987ff4a79%40isocpp.org.

Jake Arkinstall

unread,
Jan 10, 2019, 7:47:34 AM1/10/19
to std-pr...@isocpp.org
I agree that this is something that will be very useful.

The issues I have are:

- The name. It makes sense in the context of clamped values, but it has uses outside of that (generically checking if the value is between two others), and so "is_between", or more simply "between", would be more suitable IMO. In many cases, clamping is a type-level restriction rather than a value check (e.g. a wrapper around a variable which either refuses values outside a range, or which uses a modulus to alter a provided value to lie between the range).

- It covers one use case out of 4 (a<b<c, a<b<=c, a<=b<c, a<=b<=c). It makes sense, given the primary use case of clamping and the most common usage of "between" in English, for the one you've chosen to be the default (although having a default is often the cause of bugs - the line between usability and assumption is often a blurry one).

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.

Matthew Woehlke

unread,
Jan 10, 2019, 10:34:17 AM1/10/19
to std-pr...@isocpp.org, Jake Arkinstall
On 10/01/2019 07.47, Jake Arkinstall wrote:
> - The name. It makes sense in the context of clamped values, but it has
> uses outside of that (generically checking if the value is between two
> others), and so "is_between", or more simply "between", would be more
> suitable IMO.

Have we learned nothing from decades of Qt having a beautiful, intuitive
API and STL having an ugly, confusing API?

*is*_between, please! Let's not repeat the mistake that is empty() yet
again.

Although if it returns a comparator (and I like that idea),
compare_between might be a better name. (Depending on if an implicit
bool conversion does what you expect. If it does, than is_between is okay.)

> - It covers one use case out of 4 (a<b<c, a<b<=c, a<=b<c, a<=b<=c). It
> makes sense, given the primary use case of clamping and the most common
> usage of "between" in English, for the one you've chosen to be the default
> (although having a default is often the cause of bugs - the line between
> usability and assumption is often a blurry one).

That could be fixed by the addition of an optional parameter to specify
which bounds (upper, lower, both) are inclusive, with the default being
"neither". That may be a good addition.

--
Matthew

Barry Revzin

unread,
Jan 10, 2019, 11:16:59 AM1/10/19
to ISO C++ Standard - Future Proposals, jake.ar...@gmail.com
On Thursday, January 10, 2019 at 9:34:17 AM UTC-6, Matthew Woehlke wrote:
> - It covers one use case out of 4 (a<b<c, a<b<=c, a<=b<c, a<=b<=c). It
> makes sense, given the primary use case of clamping and the most common
> usage of "between" in English, for the one you've chosen to be the default
> (although having a default is often the cause of bugs - the line between
> usability and assumption is often a blurry one).

That could be fixed by the addition of an optional parameter to specify
which bounds (upper, lower, both) are inclusive, with the default being
"neither". That may be a good addition.

 I feel like in case where my middle is an expression, I'd much rather write:

[&]{
   
auto&& e = some-complex-expr;
   
return lo < e && e < hi;
}();


Than whatever I would have to do:

is_between(some-complex-expr, lo, hi, exclusive_lo, excusive_hi); // this?
is_between(some-complex-expr, exclusive{lo}, exclusive{hi}); // or this?
// or something else?

And in the case where I have a variable and not a complex expression, I have a hard time seeing the benefit. I find the "Now" versions of this proposal easier to understand than the "Proposed alternative" versions. Maybe it's just me.

I guess on top of that, do we need to standardize something that can be pretty easily implemented in a couple lines?
Message has been deleted
Message has been deleted

Matthew Woehlke

unread,
Jan 11, 2019, 12:13:39 PM1/11/19
to std-pr...@isocpp.org
On 10/01/2019 11.16, Barry Revzin wrote:
> On Thursday, January 10, 2019 at 9:34:17 AM UTC-6, Matthew Woehlke wrote:
>> That could be fixed by the addition of an optional parameter to specify
>> which bounds (upper, lower, both) are inclusive, with the default being
>> "neither". That may be a good addition.
>
> I feel like in case where my middle is an expression, I'd much rather
> write:
>
> [&]{
> auto&& e = some-complex-expr;
> return lo < e && e < hi;
> }();
>
> Than whatever I would have to do:
>
> is_between(some-complex-expr, lo, hi, exclusive_lo, excusive_hi); // this?
> is_between(some-complex-expr, exclusive{lo}, exclusive{hi}); // or this?
> // or something else?

I was thinking more along the lines of:

is_between(lo, expr, hi) // note: default == std::exclusive
is_between(lo, expr, hi, std::lower_inclusive)
is_between(lo, expr, hi, std::upper_inclusive)
is_between(lo, expr, hi, std::inclusive)

...although having an std::inclusive{bound} is an interesting idea.

> I guess on top of that, do we need to standardize something that can be
> pretty easily implemented in a couple lines?

Well, we have std::min, std::max, std::clamp... I guess it comes down to
whether this is something that's needed often enough to justify
standardizing. I'll punt on trying to answer that :-).

--
Matthew

Johel Ernesto Guerrero Peña

unread,
Jan 12, 2019, 12:26:33 PM1/12/19
to ISO C++ Standard - Future Proposals
On Wednesday, January 9, 2019 at 2:22:52 PM UTC-4, Ray Hamel wrote:
Might it be more useful to return an ordering instead of a bool?

-Ray


Sounds sensible. I have posed it as a poll. There are still papers inflight about changing those, like https://wg21.link/P1307, and new additions like the concept-constrained comparisons (https://wg21.link/range.cmp) that don't use them. For the latter, I have opened CaseyCarter/papers#1.

As for using clamp in the name, or the bounds being a closed range, I believe this was set in stone once C++17 was published as an official ISO standard with the clamp algorithm (https://wg21.link/alg.clamp) as proposed by https://wg21.link/P0025. is_clamped is to clamp what is_sorted is to sort.

Thanks for your answers. I have reflected them and my conclusion in the proposal. And sorry for the delay, but my replies were being filtered.

marc....@gmail.com

unread,
Jan 13, 2019, 9:15:45 AM1/13/19
to ISO C++ Standard - Future Proposals
On Saturday, January 12, 2019 at 6:26:33 PM UTC+1, Johel Ernesto Guerrero Peña wrote:
On Wednesday, January 9, 2019 at 2:22:52 PM UTC-4, Ray Hamel wrote:
Might it be more useful to return an ordering instead of a bool?

-Ray


Sounds sensible. I have posed it as a poll. There are still papers inflight about changing those, like https://wg21.link/P1307, and new additions like the concept-constrained comparisons (https://wg21.link/range.cmp) that don't use them. For the latter, I have opened CaseyCarter/papers#1.

As for using clamp in the name, or the bounds being a closed range, I believe this was set in stone once C++17 was published as an official ISO standard with the clamp algorithm (https://wg21.link/alg.clamp) as proposed by https://wg21.link/P0025. is_clamped is to clamp what is_sorted is to sort.

Is there any difference between is_clamped(b,a,c) and ranges::is_sorted({a,b,c})? Just the name? Using operator<= instead of negating operator<? is_sorted also lets you specify comp/proj.

Barry Revzin

unread,
Jan 13, 2019, 10:14:45 AM1/13/19
to ISO C++ Standard - Future Proposals
There is no ranges::is_sorted. At least not yet? But if such a thing were to compile, it'd probably take an initializer_list<T>, which means you're copying a, b, and c there - which we don't necessarily want to do.  That's a win for is_clamped(). 

Ville Voutilainen

unread,
Jan 13, 2019, 10:18:22 AM1/13/19
to ISO C++ Standard - Future Proposals
On Sun, 13 Jan 2019 at 17:14, Barry Revzin <barry....@gmail.com> wrote:

>> Is there any difference between is_clamped(b,a,c) and ranges::is_sorted({a,b,c})? Just the name? Using operator<= instead of negating operator<? is_sorted also lets you specify comp/proj.
> There is no ranges::is_sorted. At least not yet?

[is.sorted] in the current working draft disagrees with you.

Barry Revzin

unread,
Jan 13, 2019, 10:56:42 AM1/13/19
to std-pr...@isocpp.org
That's some reading comprehension fail right there :facepalm:

Lemme rephrase. ranges::is_sorted({a,b c}) doesn't compile. In order for it to, either we'd have to add an overload for initializer_list<T> or you'd have to explicitly create one. And then the rest of my comment still holds.
Reply all
Reply to author
Forward
Message has been deleted
Message has been deleted
0 new messages