Boost logo

Boost :

Subject: Re: [boost] [Review:Algorithms] Order of args to clamp
From: Andrew Sutton (asutton.list_at_[hidden])
Date: 2011-09-26 09:30:08

>> Fair enough; it is a natural requirement to start with given the "obvious"
>> implementation using conditionals.
> Yeah, but now we're back at implementation-driven requirements.

Right, but all type requirements are implementation-driven. We just
shouldn't state them in terms of the implementation.

>> Then clamp(x, lo, hi) and clamp((U)x, (U)lo, (U)hi) will give the same
>> result (which, I think, is what you want anyway), and the latter is as
>> defined above.  Indeed, whatever ordering is decided upon should imply
>> that clamp(x, lo, hi) and clamp((U)x, (U)lo, (U)hi) give the same
>> result, and I think this almost necessitates that (a < b) == ((U)a <
>> (U)b).
> I think you can strike "almost" :-)

The equivalence of comparisons makes the algorithm meaningful. That's
what I was looking for. If you skip that requirement, then your
algorithm could mean anything.

The only potential problem is that you should be writing U(a) instead
of U(b). I'm not sure that common_type, if one exists guarantees the
equivalence of C casts and initialization.

>> A problem that I see is that (a < b) == ((U)a < (U)b) fails for some common
>> use cases (e.g., char const * and std::string) where the clamp
>> implementation still works and does what you'd expect.

I don't think this fails for C-strings and std::string. Last I checked
std::string overloaded < for C-strings and it definitely has a
non-explicit constructor taking a C-string.

>> clamp(x, lo, hi)
>> and
>> clamp((U)x, (U)low, (U)hi)
>> should give the same result.
> ...right... so now should every algorithm be generalized that way, with
> the attendant complications in specification?  Do we need the same
> interface for, say, GCD?  Why not just ask the caller to cast to the
> common type first?

Good question. There seems to be a lot of precedence in the std
library for multi-type generalization. I'm not suggesting that this is
good or bad, only a decision to be considered. Unifying type arguments
leads to much simpler requirements at the cost of generality and, as
Phil demonstrates, performance. Generalization gets us into these

Choose your poison :)

Boost list run by bdawes at, gregod at, cpdaniel at, john at