/** @file @brief Header declaring a C++11 `finally` or "scope-guard" construct. Inspirations are many - Alexandrescu's original and C++11 ScopeGuard, and the Guideline Support Library's (GSL) `final_act`/`finally` https://github.com/Microsoft/GSL/blob/0cf947db7760bf5756e4cb0d47c72a257ed527c5/include/gsl_util.h come to mind, but this has been written and re-written numerous times since its introduction into the C++ global consciousness, and this implementation was written independently after I couldn't find a previous independent implementation I had written a few weeks earlier in an implementation file. -- Rylie Pavlik See UniqueDestructionActionWrapper for a "generalized" (in some sense) version of this. Originally written for use in OSVR for Sensics , relicensed to BSL 1.0 with permission. This header is maintained as a part of 'util-headers' - you can always find the latest version online at https://github.com/rpavlik/util-headers This GUID can help identify the project: d1dbc94e-e863-49cf-bc08-ab4d9f486613 This copy of the header is from the revision that Git calls 1a8444782d15cb9458052e3d8251c4f5b8e808d5 Commit date: "2022-03-11 12:11:32 -0600" @date 2016 @author Rylie Pavlik */ // Copyright 2016, Sensics, Inc. // // SPDX-License-Identifier: BSL-1.0 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #ifndef INCLUDED_Finally_h_GUID_D925FE58_9C57_448B_C0BB_19A42B3243BA #define INCLUDED_Finally_h_GUID_D925FE58_9C57_448B_C0BB_19A42B3243BA // Internal Includes // - none // Library/third-party includes // - none // Standard includes #include namespace util { namespace detail { /// Allows you to run a callable something at the end of a scope. /// /// The class that provides the scope-guard behavior. Often not referred to /// by name because auto is useful here, and often not created by a direct /// constructor call because of the finally() convenience functions combined /// with lambdas. template class FinalTask { public: /// Explicit constructor from something callable. explicit FinalTask(F f) : f_(std::move(f)) {} /// Move constructor - cancels the moved-from task. FinalTask(FinalTask &&other) : f_(std::move(other.f_)), do_(other.do_) { other.cancel(); } /// non-copyable FinalTask(FinalTask const &) = delete; /// non-assignable FinalTask &operator=(FinalTask const &) = delete; /// Destructor - if we haven't been cancelled, do our callable thing. ~FinalTask() { if (do_) { f_(); } } /// Cancel causes us to not do our final task on destruction. void cancel() { do_ = false; } private: /// Our callable task to do at destruction. F f_; /// Whether we should actually do it. bool do_ = true; }; } // namespace detail /// Creation free function for final tasks to run on scope exit. Works great /// when paired with lambdas (particularly with `[&]` reference capture). /// Use like: /// `auto f = finally([&]{ dothis(); });` to have `dothis()` called when `f` /// goes out of scope, no matter how. template inline detail::FinalTask finally(F &&f) { /// Perfect forwarding version. return detail::FinalTask(std::forward(f)); } /// @overload template inline detail::FinalTask finally(F const &f) { // Added this overload because GSL had it and GSL is supposed to be best // practices guidelines... return detail::FinalTask(f); } } // namespace util #endif // INCLUDED_Finally_h_GUID_D925FE58_9C57_448B_C0BB_19A42B3243BA