louis-langholtz / PlayRho

An interactive physics engine & library.
zlib License
133 stars 24 forks source link

Checked class template support for non-throwing for known valid values #466

Closed louis-langholtz closed 1 year ago

louis-langholtz commented 1 year ago

Expected/Desired Behavior or Experience:

Using code has a noexcept interface to using Checked class template that uses an alternative to throwing for invalid values. For example the checker function might provide a std::optional returning interface whereby using code on knowing validity could use the noexcept std::optional<T>::operator* interface and itself then not have that causing it to be flagged as possibly escaping an exception.

Actual Behavior:

The Checked class template type doesn't have a non-throwing mechanism for checking types so using code sometimes is flagged as throwing even when that wouldn't happen. For example, the integer 3 is clearly non-negative but there's currently no function to create a NonNegative of it that's marked noexcept. So clang-tidy right now is flagging some code erroneously like an exception may be thrown in function X which should not throw exceptions [bugprone-exception-escape].

Steps to Reproduce the Actual Behavior:

Use clang-tidy on the code base and see "exception may be thrown" warnings from [bugprone-exception-escape].

louis-langholtz commented 1 year ago

This issue has been overcome by events (OBE). Specifically, this desired performance is now supported by the NoExcept template parameter argument with the value of true. For example, the NonNegativeFF interface for non-negative asserted values can be used for constants and then specific variables can be set by it in a non-throwing and non-rechecking way:

#include <playrho/NonNegative.hpp>

void foo() {
    constexpr auto Zero = NonNegativeFF<Real>(0.0);
    NonNegative<Real> variable = Zero;
}

Here, in the assignment of Zero to variable, Zero is implicitly converted, without rechecking, to a NonNegative<Real> via Checked's copy-like constructor template, and then variable is assigned via default assignment.