Imath: Options for Exceptions


Owen T.
 

I received a request to introduce an exception free alternative to any Imath function which throws an exception currently. There are a few ways of doing this. If any of them seem superior let me know. Now I am inclined towards option 1 as it has already been used by other parts of Imath.

OPTION 1: Bool parameter (currently used by Matrix inversion functions in Imath, false by default)
template<class T>
T Frustum<T>::aspect(bool singExc) const
{
    T rightMinusLeft = _right-_left;
    T topMinusBottom = _top-_bottom;

    if (abs(topMinusBottom) < 1 &&
        abs(rightMinusLeft) > limits<T>::max() * abs(topMinusBottom) &&
        singExc)
    {
        throw std::domain_error ("Bad viewing frustum: "
                               "aspect ratio cannot be computed.");
    }

    return rightMinusLeft / topMinusBottom;
}

OPTION 2: Two differently named functions
template<class T>
T Frustum<T>::aspectExc() const
{
    T rightMinusLeft = _right-_left;
    T topMinusBottom = _top-_bottom;

    if (abs(topMinusBottom) < 1 &&
        abs(rightMinusLeft) > limits<T>::max() * abs(topMinusBottom))
    {
        throw std::domain_error ("Bad viewing frustum: "
                               "aspect ratio cannot be computed.");
    }

    return rightMinusLeft / topMinusBottom;
}

template<class T>
T Frustum<T>::aspect() const
{
    T rightMinusLeft = _right-_left;
    T topMinusBottom = _top-_bottom;

    return rightMinusLeft / topMinusBottom;
}

OPTION 3: Implementation of new 'exc_code'
template<class T>
T Frustum<T>::aspect(exc_code& ec) const
{
    T rightMinusLeft = _right-_left;
    T topMinusBottom = _top-_bottom;

    if (abs(topMinusBottom) < 1 &&
        abs(rightMinusLeft) > limits<T>::max() * abs(topMinusBottom))
    {
        ec = ("Bad viewing frustum: "
                  "aspect ratio cannot be computed.");
    //this can be changed to contain other information depending on exc_code,
    }

    return rightMinusLeft / topMinusBottom;
}

template<class T>
T Frustum<T>::aspect() const
{
    T rightMinusLeft = _right-_left;
    T topMinusBottom = _top-_bottom;

    return rightMinusLeft / topMinusBottom;
}

Option 3 is similar to the exception handling of std::filesystem::rename since C++17

Join openexr-dev@lists.aswf.io to automatically receive all group messages.