diff --git a/include/ircd/util/unwind.h b/include/ircd/util/unwind.h index 499a0f350..c2f7d8f0d 100644 --- a/include/ircd/util/unwind.h +++ b/include/ircd/util/unwind.h @@ -49,6 +49,8 @@ struct ircd::util::unwind /// struct ircd::util::unwind::nominal { + struct assertion; + const std::function func; template @@ -74,6 +76,8 @@ struct ircd::util::unwind::nominal /// struct ircd::util::unwind::exceptional { + struct assertion; + const std::function func; template @@ -89,3 +93,28 @@ struct ircd::util::unwind::exceptional exceptional(const exceptional &) = delete; }; + +/// Asserts that unwind is occurring without any exception. This allows some +/// section of code, for example, the latter half of a function, to assert that +/// it is not throwing and disrupting the other half. This is useful when no +/// exception is expected thus placing other guarantees should not be required +/// if this guarantee is met. +/// +struct ircd::util::unwind::nominal::assertion +{ + ~assertion() noexcept + { + assert(likely(!std::uncaught_exception())); + } +}; + +/// Complements exceptional::assertion. This triggers an assertion when +/// unwinding WITHOUT an exception. +/// +struct ircd::util::unwind::exceptional::assertion +{ + ~assertion() noexcept + { + assert(likely(std::uncaught_exception())); + } +};