After thinking about the both the exception issue, and the implicit conversion issue, I believe the best solution would be something like this:

Have an additional template parameter to CheckedInt!T which controls whether an implicit conversion to type T is available or not. If there is an implicit conversion, attempting to use it on a NaN value will throw an exception.

This approach will keep the user reasonably safe from accidentally ignoring a NaN condition for both the throwing and the nothrow versions. The throwing version will just be a little more syntactically convenient.

This behaviour should probably extend to explicit opCast!V() calls as well, where V is an integral type.

Unchecked unwrapping will always be available either way, by using CheckedInt.value.

To ease the writing of generic code which might accept a built-in integer or a CheckedInt, a template function like this can be included:

auto numValue(T)(in T t) pure
        if(isNumeric!T || isCheckedInt!T || isCIStore!T)
{
        static if(isCheckedInt!T || isCIStore!T)
                return t.value;
        else
                return t;
}

(Something like this actually already exists in both my version and Robert's version, for internal use.)

Reply via email to