1*da0073e9SAndroid Build Coastguard Worker #pragma once 2*da0073e9SAndroid Build Coastguard Worker 3*da0073e9SAndroid Build Coastguard Worker #include <type_traits> 4*da0073e9SAndroid Build Coastguard Worker #include <utility> 5*da0073e9SAndroid Build Coastguard Worker 6*da0073e9SAndroid Build Coastguard Worker namespace c10 { 7*da0073e9SAndroid Build Coastguard Worker 8*da0073e9SAndroid Build Coastguard Worker /** 9*da0073e9SAndroid Build Coastguard Worker * Mostly copied from https://llvm.org/doxygen/ScopeExit_8h_source.html 10*da0073e9SAndroid Build Coastguard Worker */ 11*da0073e9SAndroid Build Coastguard Worker template <typename Callable> 12*da0073e9SAndroid Build Coastguard Worker class scope_exit { 13*da0073e9SAndroid Build Coastguard Worker Callable ExitFunction; 14*da0073e9SAndroid Build Coastguard Worker bool Engaged = true; // False once moved-from or release()d. 15*da0073e9SAndroid Build Coastguard Worker 16*da0073e9SAndroid Build Coastguard Worker public: 17*da0073e9SAndroid Build Coastguard Worker template <typename Fp> 18*da0073e9SAndroid Build Coastguard Worker // NOLINTNEXTLINE(bugprone-forwarding-reference-overload) scope_exit(Fp && F)19*da0073e9SAndroid Build Coastguard Worker explicit scope_exit(Fp&& F) : ExitFunction(std::forward<Fp>(F)) {} 20*da0073e9SAndroid Build Coastguard Worker scope_exit(scope_exit && Rhs)21*da0073e9SAndroid Build Coastguard Worker scope_exit(scope_exit&& Rhs) noexcept 22*da0073e9SAndroid Build Coastguard Worker : ExitFunction(std::move(Rhs.ExitFunction)), Engaged(Rhs.Engaged) { 23*da0073e9SAndroid Build Coastguard Worker Rhs.release(); 24*da0073e9SAndroid Build Coastguard Worker } 25*da0073e9SAndroid Build Coastguard Worker scope_exit(const scope_exit&) = delete; 26*da0073e9SAndroid Build Coastguard Worker scope_exit& operator=(scope_exit&&) = delete; 27*da0073e9SAndroid Build Coastguard Worker scope_exit& operator=(const scope_exit&) = delete; 28*da0073e9SAndroid Build Coastguard Worker release()29*da0073e9SAndroid Build Coastguard Worker void release() { 30*da0073e9SAndroid Build Coastguard Worker Engaged = false; 31*da0073e9SAndroid Build Coastguard Worker } 32*da0073e9SAndroid Build Coastguard Worker ~scope_exit()33*da0073e9SAndroid Build Coastguard Worker ~scope_exit() { 34*da0073e9SAndroid Build Coastguard Worker if (Engaged) { 35*da0073e9SAndroid Build Coastguard Worker ExitFunction(); 36*da0073e9SAndroid Build Coastguard Worker } 37*da0073e9SAndroid Build Coastguard Worker } 38*da0073e9SAndroid Build Coastguard Worker }; 39*da0073e9SAndroid Build Coastguard Worker 40*da0073e9SAndroid Build Coastguard Worker // Keeps the callable object that is passed in, and execute it at the 41*da0073e9SAndroid Build Coastguard Worker // destruction of the returned object (usually at the scope exit where the 42*da0073e9SAndroid Build Coastguard Worker // returned object is kept). 43*da0073e9SAndroid Build Coastguard Worker // 44*da0073e9SAndroid Build Coastguard Worker // Interface is specified by p0052r2. 45*da0073e9SAndroid Build Coastguard Worker template <typename Callable> make_scope_exit(Callable && F)46*da0073e9SAndroid Build Coastguard Workerscope_exit<std::decay_t<Callable>> make_scope_exit(Callable&& F) { 47*da0073e9SAndroid Build Coastguard Worker return scope_exit<std::decay_t<Callable>>(std::forward<Callable>(F)); 48*da0073e9SAndroid Build Coastguard Worker } 49*da0073e9SAndroid Build Coastguard Worker 50*da0073e9SAndroid Build Coastguard Worker } // namespace c10 51