Add SRB2_ASSERT, superceding I_Assert
This assertion macro always expands to a call of srb2::do_assert, which
is overloaded with two templates: one which applies if the provided
Level is less than or equal to the SRB2_ASSERTION_LEVEL, and one which
is a no-op. When optimizations are enabled, this will verifiably remove
the evaluation of the expression in all cases, instead of evaluating the
expression and doing nothing with it.
Add srb2::NotNull wrapper utility
This is meant to be used in places where pointers are used as
parameters. It can be used with any pointer-like type, not just raw
pointers. During construction of NotNull, the pointer will be asserted
not-null in debug and paranoia builds, and in release optimizations with
no assertions, the code decays gracefully to standard pointer-passing.
This mirrors the `finally` utility in Guidelines Support Library for
ensuring that a cleanup function is always called when the utility
object leaves scope, even when unwinding the stack from an exception.
This is to aid in transitioning malloc/free pairs in function bodies to
be more exception-safe.