// This source code is released into the public domain. export module nihil.guard; import nihil.std; namespace nihil { // guard: invoke a callable when this object is destroyed; this is similar to // scope_exit from the library fundamentals TS, which LLVM doesn't implement. export template struct guard final { // Initialise the guard with a callable we will invoke later. explicit guard(F func) : m_func(std::move(func)) {} // We are being destroyed, so call the callable. // If the callable throws, std::terminate() will be called. ~guard() { if (m_func) std::invoke(*m_func); } // Release the guard. This turns the destructor into a no-op. auto release(this guard &self) noexcept -> void { self.m_func.reset(); } // Not default-constructible, movable or copyable. guard() = delete; guard(guard const &) = delete; guard(guard &&) noexcept = delete; auto operator=(this guard &, guard const &) -> guard & = delete; auto operator=(this guard &, guard &&) noexcept -> guard & = delete; private: // The callable to be invoked when we are destroyed. std::optional m_func; }; } // namespace nihil