
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