Cloned SEACAS for EXODUS library with extra build files for internal package management.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

271 lines
8.2 KiB

2 years ago
/*
* 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 T> class RefHolder
{
T &ref_;
public:
explicit RefHolder(T &ref) : ref_(ref) {}
operator T &() const { return ref_; }
RefHolder &operator=(const RefHolder &) = delete;
};
template <class T> inline RefHolder<T> ByRef(T &t) { return RefHolder<T>(t); }
class ScopeGuardImplBase
{
ScopeGuardImplBase &operator=(const ScopeGuardImplBase &) = delete;
protected:
~ScopeGuardImplBase() = default;
ScopeGuardImplBase(const ScopeGuardImplBase &other) : dismissed_(other.dismissed_)
{
other.Dismiss();
}
template <typename J> 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 <typename F> class ScopeGuardImpl0 : public ScopeGuardImplBase
{
public:
static ScopeGuardImpl0<F> MakeGuard(F fun) { return ScopeGuardImpl0<F>(fun); }
~ScopeGuardImpl0() { SafeExecute(*this); }
void Execute() { fun_(); }
protected:
explicit ScopeGuardImpl0(F fun) : fun_(fun) {}
F fun_;
};
template <typename F> inline ScopeGuardImpl0<F> MakeGuard(F fun)
{
return ScopeGuardImpl0<F>::MakeGuard(fun);
}
template <typename F, typename P1> class ScopeGuardImpl1 : public ScopeGuardImplBase
{
public:
static ScopeGuardImpl1<F, P1> MakeGuard(F fun, P1 p1) { return ScopeGuardImpl1<F, P1>(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 <typename F, typename P1> inline ScopeGuardImpl1<F, P1> MakeGuard(F fun, P1 p1)
{
return ScopeGuardImpl1<F, P1>::MakeGuard(fun, p1);
}
template <typename F, typename P1, typename P2> class ScopeGuardImpl2 : public ScopeGuardImplBase
{
public:
static ScopeGuardImpl2<F, P1, P2> MakeGuard(F fun, P1 p1, P2 p2)
{
return ScopeGuardImpl2<F, P1, P2>(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 <typename F, typename P1, typename P2>
inline ScopeGuardImpl2<F, P1, P2> MakeGuard(F fun, P1 p1, P2 p2)
{
return ScopeGuardImpl2<F, P1, P2>::MakeGuard(fun, p1, p2);
}
template <typename F, typename P1, typename P2, typename P3>
class ScopeGuardImpl3 : public ScopeGuardImplBase
{
public:
static ScopeGuardImpl3<F, P1, P2, P3> MakeGuard(F fun, P1 p1, P2 p2, P3 p3)
{
return ScopeGuardImpl3<F, P1, P2, P3>(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 <typename F, typename P1, typename P2, typename P3>
inline ScopeGuardImpl3<F, P1, P2, P3> MakeGuard(F fun, P1 p1, P2 p2, P3 p3)
{
return ScopeGuardImpl3<F, P1, P2, P3>::MakeGuard(fun, p1, p2, p3);
}
//************************************************************
template <class Obj, typename MemFun> class ObjScopeGuardImpl0 : public ScopeGuardImplBase
{
public:
static ObjScopeGuardImpl0<Obj, MemFun> MakeObjGuard(Obj &obj, MemFun memFun)
{
return ObjScopeGuardImpl0<Obj, MemFun>(obj, memFun);
}
~ObjScopeGuardImpl0() { SafeExecute(*this); }
void Execute() { (obj_.*memFun_)(); }
protected:
ObjScopeGuardImpl0(Obj &obj, MemFun memFun) : obj_(obj), memFun_(memFun) {}
Obj &obj_;
MemFun memFun_;
};
template <class Obj, typename MemFun>
inline ObjScopeGuardImpl0<Obj, MemFun> MakeObjGuard(Obj &obj, MemFun memFun)
{
return ObjScopeGuardImpl0<Obj, MemFun>::MakeObjGuard(obj, memFun);
}
template <typename Ret, class Obj1, class Obj2>
inline ObjScopeGuardImpl0<Obj1, Ret (Obj2::*)()> MakeGuard(Ret (Obj2::*memFun)(), Obj1 &obj)
{
return ObjScopeGuardImpl0<Obj1, Ret (Obj2::*)()>::MakeObjGuard(obj, memFun);
}
template <typename Ret, class Obj1, class Obj2>
inline ObjScopeGuardImpl0<Obj1, Ret (Obj2::*)()> MakeGuard(Ret (Obj2::*memFun)(), Obj1 *obj)
{
return ObjScopeGuardImpl0<Obj1, Ret (Obj2::*)()>::MakeObjGuard(*obj, memFun);
}
template <class Obj, typename MemFun, typename P1>
class ObjScopeGuardImpl1 : public ScopeGuardImplBase
{
public:
static ObjScopeGuardImpl1<Obj, MemFun, P1> MakeObjGuard(Obj &obj, MemFun memFun, P1 p1)
{
return ObjScopeGuardImpl1<Obj, MemFun, P1>(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 <class Obj, typename MemFun, typename P1>
inline ObjScopeGuardImpl1<Obj, MemFun, P1> MakeObjGuard(Obj &obj, MemFun memFun, P1 p1)
{
return ObjScopeGuardImpl1<Obj, MemFun, P1>::MakeObjGuard(obj, memFun, p1);
}
template <typename Ret, class Obj1, class Obj2, typename P1a, typename P1b>
inline ObjScopeGuardImpl1<Obj1, Ret (Obj2::*)(P1a), P1b> MakeGuard(Ret (Obj2::*memFun)(P1a),
Obj1 &obj, P1b p1)
{
return ObjScopeGuardImpl1<Obj1, Ret (Obj2::*)(P1a), P1b>::MakeObjGuard(obj, memFun, p1);
}
template <typename Ret, class Obj1, class Obj2, typename P1a, typename P1b>
inline ObjScopeGuardImpl1<Obj1, Ret (Obj2::*)(P1a), P1b> MakeGuard(Ret (Obj2::*memFun)(P1a),
Obj1 *obj, P1b p1)
{
return ObjScopeGuardImpl1<Obj1, Ret (Obj2::*)(P1a), P1b>::MakeObjGuard(*obj, memFun, p1);
}
template <class Obj, typename MemFun, typename P1, typename P2>
class ObjScopeGuardImpl2 : public ScopeGuardImplBase
{
public:
static ObjScopeGuardImpl2<Obj, MemFun, P1, P2> MakeObjGuard(Obj &obj, MemFun memFun, P1 p1, P2 p2)
{
return ObjScopeGuardImpl2<Obj, MemFun, P1, P2>(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 <class Obj, typename MemFun, typename P1, typename P2>
inline ObjScopeGuardImpl2<Obj, MemFun, P1, P2> MakeObjGuard(Obj &obj, MemFun memFun, P1 p1, P2 p2)
{
return ObjScopeGuardImpl2<Obj, MemFun, P1, P2>::MakeObjGuard(obj, memFun, p1, p2);
}
template <typename Ret, class Obj1, class Obj2, typename P1a, typename P1b, typename P2a,
typename P2b>
inline ObjScopeGuardImpl2<Obj1, Ret (Obj2::*)(P1a, P2a), P1b, P2b>
MakeGuard(Ret (Obj2::*memFun)(P1a, P2a), Obj1 &obj, P1b p1, P2b p2)
{
return ObjScopeGuardImpl2<Obj1, Ret (Obj2::*)(P1a, P2a), P1b, P2b>::MakeObjGuard(obj, memFun, p1,
p2);
}
template <typename Ret, class Obj1, class Obj2, typename P1a, typename P1b, typename P2a,
typename P2b>
inline ObjScopeGuardImpl2<Obj1, Ret (Obj2::*)(P1a, P2a), P1b, P2b>
MakeGuard(Ret (Obj2::*memFun)(P1a, P2a), Obj1 *obj, P1b p1, P2b p2)
{
return ObjScopeGuardImpl2<Obj1, Ret (Obj2::*)(P1a, P2a), P1b, P2b>::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