
AMDG On 09/25/2011 02:56 PM, Jeffrey Lee Hellrung, Jr. wrote:
On Sun, Sep 25, 2011 at 10:48 AM, Dave Abrahams <dave@boostpro.com> wrote:
So, do the exercise. And, BTW, which of the types involved is "the same type" in this case?
Okay, I'll try.
clamp(T x, L lo, H hi) -> common_type<T,L,H>::type
Let U = common_type<T,L,H>::type.
I think I prefer the signature in your earlier post: template< class T, class L, class U > typename common_type< T const &, L const &, U const & >::type clamp(T const & x, L const & lower, U const & upper); It would be better to end up with an l-value and avoid copying when possible.
Precondition: operator< defines an ordering on objects of type U. For any 2 objects a and b of types A and B, respectively, where A and B are each one of {T,L,H}, a < b is equivalent to (U)a < (U)b. !(hi < lo).
This should be !(U(hi) < U(lo)). Your restrictions on the comparison are too strict. You don't want to constrain (lo < lo), (hi < hi), (hi < lo), or (lo < hi), because that would exclude T = std::string, L = H = const char*.
[Note: I'm not sure yet precisely what "ordering" would be desired here (probably a "strict weak ordering" is sufficient, as for many other STL algorithms, but I confess I'm a bit rusty on various ordering properties), and it should certainly be specified if you want to be precise, but it's the same ordering as would be required for clamp(T,T,T), so it's somewhat tangential to this exercise.] Returns: If x < lo or hi < x (these are mutually exclusive assuming an appropriate precise ordering), returns (U)lo or (U)hi, respectively. Otherwise, returns (U)x. [Note: I believe the above requirements yield at least 2 nontrivially different implementations: (x < lo ? lo : hi < x : hi ? x) or (hi < x ? hi : x < lo ? lo : x).]
Is this what you had in mind?
In Christ, Steven Watanabe