Boost logo

Boost :

From: Robert Bell (belvis_at_[hidden])
Date: 2004-05-16 18:02:30


christopher diggins wrote:
>>should this be using numeric_limits<T>::epsilon() (instead of DBL_EPSILON)
>>and would that even work for numbers larger than 2.0?
>
>
> Good point, I am working on fixing that.

This doesn't seem like the best way to get this result. If I try to
create an interval of [0, 1e100), this won't work; 1e100 -
numeric_limits<T>::epsilon() is very likely to be 1e100, which would let
me (incorrectly) assign 1e100 to such a constrained value.

It seems to me that whether one end of an interval is open or closed
corresponds to whether or not you use strict less-than/greater than, or
less-than-or-equal/greater-than-or-equal. A value is in [0, 1e100) if

(0 <= value && value < 1e100)

is true. This is correct regardless of the type of value (assuming it
provides < and <=, which is reasonable to assume for any type you're
going to build an interval out of).

To implement this, you could introduce another policy that controls how
the min and max values are compared to the value.

// prototype of the interval policy:
template<typename T>
struct interval_policy {
    static bool check_min(T value, T min);
    static bool check_max(T value, T max);
};

// concrete cases:
template<typename T>
struct open_policy {
    static bool check_min(T value, T min) { return value > min; }
    static bool check_max(T value, T max) { return value < max; }
};

template<typename T>
struct closed_policy {
    static bool check_min(T value, T min) { return value >= min; }
    static bool check_max(T value, T max) { return value <= max; }
};

You let the user specify an interval policy for the upper part and the
lower part of the interval. Then your error check becomes:

    if (!lower_policy::check_min(value, min())) {
       // min_violation handler here
    }
    if (!upper_policy::check_max(value, max())) {
       // max_violation handler here
    }

(A variation might revolve around letting a user specify std::less or
std::less_equal.)

But doing it this way we introduce two new polic arguments; maybe that's
not so good.

Another approach might be to change the definition of the
constraints_policy itself so that it is responsible for the validation.
You give it a member function called validate() which is expected to
return true if the value is good, false otherwise. A variation on this
approach would have it a return a value. The advantage of this variation
would be that a policy could change a value to something legal and
return it. For example, I could specify the interval [0, 10], and set it
up so that if I assigned 11 to a variable of this type, it could clamp
it to 10 rather than signal an error. (So far, the option to change an
illegal value to a legal one and continue has not been mentioned, but it
seems like a reasonable thing to want to do.)

This approach also allows things that weren't part of the original idea,
so I'm not sure what you'd think of them. For example, I could create a
policy that allows even numbers only (not sure why I'd want that, but it
would be possible).

What do you think?

Bob


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk