/* * Copyright(C) 1999-2022 National Technology & Engineering Solutions * of Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with * NTESS, the U.S. Government retains certain rights in this software. * * See packages/seacas/LICENSE for details */ #pragma once /* Scopeguard, by Andrei Alexandrescu and Petru Marginean, December 2000. Modified by Joshua Lehrer, FactSet Research Systems, November 2005. */ template class RefHolder { T &ref_; public: explicit RefHolder(T &ref) : ref_(ref) {} operator T &() const { return ref_; } RefHolder &operator=(const RefHolder &) = delete; }; template inline RefHolder ByRef(T &t) { return RefHolder(t); } class ScopeGuardImplBase { ScopeGuardImplBase &operator=(const ScopeGuardImplBase &) = delete; protected: ~ScopeGuardImplBase() = default; ScopeGuardImplBase(const ScopeGuardImplBase &other) : dismissed_(other.dismissed_) { other.Dismiss(); } template static void SafeExecute(J &j) { if (!j.dismissed_) { try { j.Execute(); } catch (...) { } } } mutable bool dismissed_{false}; public: ScopeGuardImplBase() = default; void Dismiss() const { dismissed_ = true; } }; // typedef const ScopeGuardImplBase& ScopeGuard; #ifndef _MSC_VER __attribute__((unused)) #endif typedef const ScopeGuardImplBase &ScopeGuard; template class ScopeGuardImpl0 : public ScopeGuardImplBase { public: static ScopeGuardImpl0 MakeGuard(F fun) { return ScopeGuardImpl0(fun); } ~ScopeGuardImpl0() { SafeExecute(*this); } void Execute() { fun_(); } protected: explicit ScopeGuardImpl0(F fun) : fun_(fun) {} F fun_; }; template inline ScopeGuardImpl0 MakeGuard(F fun) { return ScopeGuardImpl0::MakeGuard(fun); } template class ScopeGuardImpl1 : public ScopeGuardImplBase { public: static ScopeGuardImpl1 MakeGuard(F fun, P1 p1) { return ScopeGuardImpl1(fun, p1); } ~ScopeGuardImpl1() { SafeExecute(*this); } void Execute() { fun_(p1_); } protected: ScopeGuardImpl1(F fun, P1 p1) : fun_(fun), p1_(p1) {} F fun_; const P1 p1_; }; template inline ScopeGuardImpl1 MakeGuard(F fun, P1 p1) { return ScopeGuardImpl1::MakeGuard(fun, p1); } template class ScopeGuardImpl2 : public ScopeGuardImplBase { public: static ScopeGuardImpl2 MakeGuard(F fun, P1 p1, P2 p2) { return ScopeGuardImpl2(fun, p1, p2); } ~ScopeGuardImpl2() { SafeExecute(*this); } void Execute() { fun_(p1_, p2_); } protected: ScopeGuardImpl2(F fun, P1 p1, P2 p2) : fun_(fun), p1_(p1), p2_(p2) {} F fun_; const P1 p1_; const P2 p2_; }; template inline ScopeGuardImpl2 MakeGuard(F fun, P1 p1, P2 p2) { return ScopeGuardImpl2::MakeGuard(fun, p1, p2); } template class ScopeGuardImpl3 : public ScopeGuardImplBase { public: static ScopeGuardImpl3 MakeGuard(F fun, P1 p1, P2 p2, P3 p3) { return ScopeGuardImpl3(fun, p1, p2, p3); } ~ScopeGuardImpl3() { SafeExecute(*this); } void Execute() { fun_(p1_, p2_, p3_); } protected: ScopeGuardImpl3(F fun, P1 p1, P2 p2, P3 p3) : fun_(fun), p1_(p1), p2_(p2), p3_(p3) {} F fun_; const P1 p1_; const P2 p2_; const P3 p3_; }; template inline ScopeGuardImpl3 MakeGuard(F fun, P1 p1, P2 p2, P3 p3) { return ScopeGuardImpl3::MakeGuard(fun, p1, p2, p3); } //************************************************************ template class ObjScopeGuardImpl0 : public ScopeGuardImplBase { public: static ObjScopeGuardImpl0 MakeObjGuard(Obj &obj, MemFun memFun) { return ObjScopeGuardImpl0(obj, memFun); } ~ObjScopeGuardImpl0() { SafeExecute(*this); } void Execute() { (obj_.*memFun_)(); } protected: ObjScopeGuardImpl0(Obj &obj, MemFun memFun) : obj_(obj), memFun_(memFun) {} Obj &obj_; MemFun memFun_; }; template inline ObjScopeGuardImpl0 MakeObjGuard(Obj &obj, MemFun memFun) { return ObjScopeGuardImpl0::MakeObjGuard(obj, memFun); } template inline ObjScopeGuardImpl0 MakeGuard(Ret (Obj2::*memFun)(), Obj1 &obj) { return ObjScopeGuardImpl0::MakeObjGuard(obj, memFun); } template inline ObjScopeGuardImpl0 MakeGuard(Ret (Obj2::*memFun)(), Obj1 *obj) { return ObjScopeGuardImpl0::MakeObjGuard(*obj, memFun); } template class ObjScopeGuardImpl1 : public ScopeGuardImplBase { public: static ObjScopeGuardImpl1 MakeObjGuard(Obj &obj, MemFun memFun, P1 p1) { return ObjScopeGuardImpl1(obj, memFun, p1); } ~ObjScopeGuardImpl1() { SafeExecute(*this); } void Execute() { (obj_.*memFun_)(p1_); } protected: ObjScopeGuardImpl1(Obj &obj, MemFun memFun, P1 p1) : obj_(obj), memFun_(memFun), p1_(p1) {} Obj &obj_; MemFun memFun_; const P1 p1_; }; template inline ObjScopeGuardImpl1 MakeObjGuard(Obj &obj, MemFun memFun, P1 p1) { return ObjScopeGuardImpl1::MakeObjGuard(obj, memFun, p1); } template inline ObjScopeGuardImpl1 MakeGuard(Ret (Obj2::*memFun)(P1a), Obj1 &obj, P1b p1) { return ObjScopeGuardImpl1::MakeObjGuard(obj, memFun, p1); } template inline ObjScopeGuardImpl1 MakeGuard(Ret (Obj2::*memFun)(P1a), Obj1 *obj, P1b p1) { return ObjScopeGuardImpl1::MakeObjGuard(*obj, memFun, p1); } template class ObjScopeGuardImpl2 : public ScopeGuardImplBase { public: static ObjScopeGuardImpl2 MakeObjGuard(Obj &obj, MemFun memFun, P1 p1, P2 p2) { return ObjScopeGuardImpl2(obj, memFun, p1, p2); } ~ObjScopeGuardImpl2() { SafeExecute(*this); } void Execute() { (obj_.*memFun_)(p1_, p2_); } protected: ObjScopeGuardImpl2(Obj &obj, MemFun memFun, P1 p1, P2 p2) : obj_(obj), memFun_(memFun), p1_(p1), p2_(p2) { } Obj &obj_; MemFun memFun_; const P1 p1_; const P2 p2_; }; template inline ObjScopeGuardImpl2 MakeObjGuard(Obj &obj, MemFun memFun, P1 p1, P2 p2) { return ObjScopeGuardImpl2::MakeObjGuard(obj, memFun, p1, p2); } template inline ObjScopeGuardImpl2 MakeGuard(Ret (Obj2::*memFun)(P1a, P2a), Obj1 &obj, P1b p1, P2b p2) { return ObjScopeGuardImpl2::MakeObjGuard(obj, memFun, p1, p2); } template inline ObjScopeGuardImpl2 MakeGuard(Ret (Obj2::*memFun)(P1a, P2a), Obj1 *obj, P1b p1, P2b p2) { return ObjScopeGuardImpl2::MakeObjGuard(*obj, memFun, p1, p2); } #define CONCATENATE_DIRECT(s1, s2) s1##s2 #define CONCATENATE(s1, s2) CONCATENATE_DIRECT(s1, s2) #define ANONYMOUS_VARIABLE(str) CONCATENATE(str, __LINE__) #define ON_BLOCK_EXIT ScopeGuard ANONYMOUS_VARIABLE(scopeGuard) = MakeGuard #define ON_BLOCK_EXIT_OBJ ScopeGuard ANONYMOUS_VARIABLE(scopeGuard) = MakeObjGuard