Added ExceptionPolicy enum.
git-svn-id: svn://svn.code.sf.net/p/loki-lib/code/trunk@1082 7ec92016-0320-0410-acc4-a06ded1c099a
This commit is contained in:
parent
27f38492bd
commit
904bbee76d
1 changed files with 81 additions and 48 deletions
|
@ -4,12 +4,12 @@
|
||||||
// Copyright (c) 2000 Petru Marginean
|
// Copyright (c) 2000 Petru Marginean
|
||||||
// Copyright (c) 2005 Joshua Lehrer
|
// Copyright (c) 2005 Joshua Lehrer
|
||||||
//
|
//
|
||||||
// Permission to use, copy, modify, distribute and sell this software for any
|
// Permission to use, copy, modify, distribute and sell this software for any
|
||||||
// purpose is hereby granted without fee, provided that the above copyright
|
// purpose is hereby granted without fee, provided that the above copyright
|
||||||
// notice appear in all copies and that both that copyright notice and this
|
// notice appear in all copies and that both that copyright notice and this
|
||||||
// permission notice appear in supporting documentation.
|
// permission notice appear in supporting documentation.
|
||||||
// The author makes no representations about the
|
// The author makes no representations about the
|
||||||
// suitability of this software for any purpose. It is provided "as is"
|
// suitability of this software for any purpose. It is provided "as is"
|
||||||
// without express or implied warranty.
|
// without express or implied warranty.
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
#ifndef LOKI_SCOPEGUARD_INC_
|
#ifndef LOKI_SCOPEGUARD_INC_
|
||||||
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
// $Id$
|
// $Id$
|
||||||
|
|
||||||
|
#include <exception> // needed for calls to uncaught_exception.
|
||||||
|
|
||||||
#include <loki/RefToValue.h>
|
#include <loki/RefToValue.h>
|
||||||
|
|
||||||
|
@ -42,6 +43,30 @@ namespace Loki
|
||||||
|
|
||||||
class ScopeGuardImplBase
|
class ScopeGuardImplBase
|
||||||
{
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
enum ExceptionPolicy
|
||||||
|
{
|
||||||
|
AlwaysExecute = 0,
|
||||||
|
CallIfNoException = 1,
|
||||||
|
CallIfException = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
ScopeGuardImplBase() throw() : dismissed_(false), exceptionPolicy_( AlwaysExecute )
|
||||||
|
{}
|
||||||
|
|
||||||
|
void Dismiss() const throw()
|
||||||
|
{
|
||||||
|
dismissed_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetExceptionPolicy( ExceptionPolicy policy ) const throw()
|
||||||
|
{
|
||||||
|
exceptionPolicy_ = policy;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
/// Copy-assignment operator is not implemented and private.
|
/// Copy-assignment operator is not implemented and private.
|
||||||
ScopeGuardImplBase& operator =(const ScopeGuardImplBase&);
|
ScopeGuardImplBase& operator =(const ScopeGuardImplBase&);
|
||||||
|
|
||||||
|
@ -51,34 +76,42 @@ namespace Loki
|
||||||
{}
|
{}
|
||||||
|
|
||||||
/// Copy-constructor takes over responsibility from other ScopeGuard.
|
/// Copy-constructor takes over responsibility from other ScopeGuard.
|
||||||
ScopeGuardImplBase(const ScopeGuardImplBase& other) throw()
|
ScopeGuardImplBase(const ScopeGuardImplBase& other) throw()
|
||||||
: dismissed_(other.dismissed_)
|
: dismissed_(other.dismissed_)
|
||||||
|
, exceptionPolicy_( other.exceptionPolicy_ )
|
||||||
{
|
{
|
||||||
other.Dismiss();
|
other.Dismiss();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename J>
|
template <typename J>
|
||||||
static void SafeExecute(J& j) throw()
|
static void SafeExecute(J& j) throw()
|
||||||
{
|
{
|
||||||
|
if ( AlwaysExecute != j.exceptionPolicy_ )
|
||||||
|
{
|
||||||
|
const bool anyThrown = ::std::uncaught_exception();
|
||||||
|
if ( anyThrown )
|
||||||
|
{
|
||||||
|
if ( CallIfNoException == j.exceptionPolicy_ )
|
||||||
|
j.Dismiss();
|
||||||
|
}
|
||||||
|
else if ( CallIfException == j.exceptionPolicy_ )
|
||||||
|
{
|
||||||
|
j.Dismiss();
|
||||||
|
}
|
||||||
|
}
|
||||||
if (!j.dismissed_)
|
if (!j.dismissed_)
|
||||||
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
j.Execute();
|
j.Execute();
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{}
|
{}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mutable bool dismissed_;
|
mutable bool dismissed_;
|
||||||
|
mutable ExceptionPolicy exceptionPolicy_;
|
||||||
public:
|
|
||||||
ScopeGuardImplBase() throw() : dismissed_(false)
|
|
||||||
{}
|
|
||||||
|
|
||||||
void Dismiss() const throw()
|
|
||||||
{
|
|
||||||
dismissed_ = true;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
|
@ -113,24 +146,24 @@ namespace Loki
|
||||||
return ScopeGuardImpl0<F>(fun);
|
return ScopeGuardImpl0<F>(fun);
|
||||||
}
|
}
|
||||||
|
|
||||||
~ScopeGuardImpl0() throw()
|
~ScopeGuardImpl0() throw()
|
||||||
{
|
{
|
||||||
SafeExecute(*this);
|
SafeExecute(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Execute()
|
void Execute()
|
||||||
{
|
{
|
||||||
fun_();
|
fun_();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ScopeGuardImpl0(F fun) : fun_(fun)
|
ScopeGuardImpl0(F fun) : fun_(fun)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
F fun_;
|
F fun_;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename F>
|
template <typename F>
|
||||||
inline ScopeGuardImpl0<F> MakeGuard(F fun)
|
inline ScopeGuardImpl0<F> MakeGuard(F fun)
|
||||||
{
|
{
|
||||||
return ScopeGuardImpl0<F>::MakeGuard(fun);
|
return ScopeGuardImpl0<F>::MakeGuard(fun);
|
||||||
|
@ -160,7 +193,7 @@ namespace Loki
|
||||||
return ScopeGuardImpl1<F, P1>(fun, p1);
|
return ScopeGuardImpl1<F, P1>(fun, p1);
|
||||||
}
|
}
|
||||||
|
|
||||||
~ScopeGuardImpl1() throw()
|
~ScopeGuardImpl1() throw()
|
||||||
{
|
{
|
||||||
SafeExecute(*this);
|
SafeExecute(*this);
|
||||||
}
|
}
|
||||||
|
@ -171,14 +204,14 @@ namespace Loki
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ScopeGuardImpl1(F fun, P1 p1) : fun_(fun), p1_(p1)
|
ScopeGuardImpl1(F fun, P1 p1) : fun_(fun), p1_(p1)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
F fun_;
|
F fun_;
|
||||||
const P1 p1_;
|
const P1 p1_;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename F, typename P1>
|
template <typename F, typename P1>
|
||||||
inline ScopeGuardImpl1<F, P1> MakeGuard(F fun, P1 p1)
|
inline ScopeGuardImpl1<F, P1> MakeGuard(F fun, P1 p1)
|
||||||
{
|
{
|
||||||
return ScopeGuardImpl1<F, P1>::MakeGuard(fun, p1);
|
return ScopeGuardImpl1<F, P1>::MakeGuard(fun, p1);
|
||||||
|
@ -208,7 +241,7 @@ namespace Loki
|
||||||
return ScopeGuardImpl2<F, P1, P2>(fun, p1, p2);
|
return ScopeGuardImpl2<F, P1, P2>(fun, p1, p2);
|
||||||
}
|
}
|
||||||
|
|
||||||
~ScopeGuardImpl2() throw()
|
~ScopeGuardImpl2() throw()
|
||||||
{
|
{
|
||||||
SafeExecute(*this);
|
SafeExecute(*this);
|
||||||
}
|
}
|
||||||
|
@ -219,7 +252,7 @@ namespace Loki
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ScopeGuardImpl2(F fun, P1 p1, P2 p2) : fun_(fun), p1_(p1), p2_(p2)
|
ScopeGuardImpl2(F fun, P1 p1, P2 p2) : fun_(fun), p1_(p1), p2_(p2)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
F fun_;
|
F fun_;
|
||||||
|
@ -257,7 +290,7 @@ namespace Loki
|
||||||
return ScopeGuardImpl3<F, P1, P2, P3>(fun, p1, p2, p3);
|
return ScopeGuardImpl3<F, P1, P2, P3>(fun, p1, p2, p3);
|
||||||
}
|
}
|
||||||
|
|
||||||
~ScopeGuardImpl3() throw()
|
~ScopeGuardImpl3() throw()
|
||||||
{
|
{
|
||||||
SafeExecute(*this);
|
SafeExecute(*this);
|
||||||
}
|
}
|
||||||
|
@ -268,7 +301,7 @@ namespace Loki
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ScopeGuardImpl3(F fun, P1 p1, P2 p2, P3 p3) : fun_(fun), p1_(p1), p2_(p2), p3_(p3)
|
ScopeGuardImpl3(F fun, P1 p1, P2 p2, P3 p3) : fun_(fun), p1_(p1), p2_(p2), p3_(p3)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
F fun_;
|
F fun_;
|
||||||
|
@ -308,7 +341,7 @@ namespace Loki
|
||||||
return ScopeGuardImpl4< F, P1, P2, P3, P4 >( fun, p1, p2, p3, p4 );
|
return ScopeGuardImpl4< F, P1, P2, P3, P4 >( fun, p1, p2, p3, p4 );
|
||||||
}
|
}
|
||||||
|
|
||||||
~ScopeGuardImpl4() throw()
|
~ScopeGuardImpl4() throw()
|
||||||
{
|
{
|
||||||
SafeExecute( *this );
|
SafeExecute( *this );
|
||||||
}
|
}
|
||||||
|
@ -361,7 +394,7 @@ namespace Loki
|
||||||
return ScopeGuardImpl5< F, P1, P2, P3, P4, P5 >( fun, p1, p2, p3, p4, p5 );
|
return ScopeGuardImpl5< F, P1, P2, P3, P4, P5 >( fun, p1, p2, p3, p4, p5 );
|
||||||
}
|
}
|
||||||
|
|
||||||
~ScopeGuardImpl5() throw()
|
~ScopeGuardImpl5() throw()
|
||||||
{
|
{
|
||||||
SafeExecute( *this );
|
SafeExecute( *this );
|
||||||
}
|
}
|
||||||
|
@ -415,18 +448,18 @@ namespace Loki
|
||||||
return ObjScopeGuardImpl0<Obj, MemFun>(obj, memFun);
|
return ObjScopeGuardImpl0<Obj, MemFun>(obj, memFun);
|
||||||
}
|
}
|
||||||
|
|
||||||
~ObjScopeGuardImpl0() throw()
|
~ObjScopeGuardImpl0() throw()
|
||||||
{
|
{
|
||||||
SafeExecute(*this);
|
SafeExecute(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Execute()
|
void Execute()
|
||||||
{
|
{
|
||||||
(obj_.*memFun_)();
|
(obj_.*memFun_)();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ObjScopeGuardImpl0(Obj& obj, MemFun memFun) : obj_(obj), memFun_(memFun)
|
ObjScopeGuardImpl0(Obj& obj, MemFun memFun) : obj_(obj), memFun_(memFun)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
Obj& obj_;
|
Obj& obj_;
|
||||||
|
@ -440,13 +473,13 @@ namespace Loki
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Ret, class Obj1, class Obj2>
|
template <typename Ret, class Obj1, class Obj2>
|
||||||
inline ObjScopeGuardImpl0<Obj1,Ret(Obj2::*)()> MakeGuard(Ret(Obj2::*memFun)(), Obj1 &obj)
|
inline ObjScopeGuardImpl0<Obj1,Ret(Obj2::*)()> MakeGuard(Ret(Obj2::*memFun)(), Obj1 &obj)
|
||||||
{
|
{
|
||||||
return ObjScopeGuardImpl0<Obj1,Ret(Obj2::*)()>::MakeObjGuard(obj,memFun);
|
return ObjScopeGuardImpl0<Obj1,Ret(Obj2::*)()>::MakeObjGuard(obj,memFun);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Ret, class Obj1, class Obj2>
|
template <typename Ret, class Obj1, class Obj2>
|
||||||
inline ObjScopeGuardImpl0<Obj1,Ret(Obj2::*)()> MakeGuard(Ret(Obj2::*memFun)(), Obj1 *obj)
|
inline ObjScopeGuardImpl0<Obj1,Ret(Obj2::*)()> MakeGuard(Ret(Obj2::*memFun)(), Obj1 *obj)
|
||||||
{
|
{
|
||||||
return ObjScopeGuardImpl0<Obj1,Ret(Obj2::*)()>::MakeObjGuard(*obj,memFun);
|
return ObjScopeGuardImpl0<Obj1,Ret(Obj2::*)()>::MakeObjGuard(*obj,memFun);
|
||||||
}
|
}
|
||||||
|
@ -477,20 +510,20 @@ namespace Loki
|
||||||
return ObjScopeGuardImpl1<Obj, MemFun, P1>(obj, memFun, p1);
|
return ObjScopeGuardImpl1<Obj, MemFun, P1>(obj, memFun, p1);
|
||||||
}
|
}
|
||||||
|
|
||||||
~ObjScopeGuardImpl1() throw()
|
~ObjScopeGuardImpl1() throw()
|
||||||
{
|
{
|
||||||
SafeExecute(*this);
|
SafeExecute(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Execute()
|
void Execute()
|
||||||
{
|
{
|
||||||
(obj_.*memFun_)(p1_);
|
(obj_.*memFun_)(p1_);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ObjScopeGuardImpl1(Obj& obj, MemFun memFun, P1 p1) : obj_(obj), memFun_(memFun), p1_(p1)
|
ObjScopeGuardImpl1(Obj& obj, MemFun memFun, P1 p1) : obj_(obj), memFun_(memFun), p1_(p1)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
Obj& obj_;
|
Obj& obj_;
|
||||||
MemFun memFun_;
|
MemFun memFun_;
|
||||||
const P1 p1_;
|
const P1 p1_;
|
||||||
|
@ -503,13 +536,13 @@ namespace Loki
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Ret, class Obj1, class Obj2, typename P1a, typename P1b>
|
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)
|
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);
|
return ObjScopeGuardImpl1<Obj1,Ret(Obj2::*)(P1a),P1b>::MakeObjGuard(obj,memFun,p1);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Ret, class Obj1, class Obj2, typename P1a, typename P1b>
|
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)
|
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);
|
return ObjScopeGuardImpl1<Obj1,Ret(Obj2::*)(P1a),P1b>::MakeObjGuard(*obj,memFun,p1);
|
||||||
}
|
}
|
||||||
|
@ -540,18 +573,18 @@ namespace Loki
|
||||||
return ObjScopeGuardImpl2<Obj, MemFun, P1, P2>(obj, memFun, p1, p2);
|
return ObjScopeGuardImpl2<Obj, MemFun, P1, P2>(obj, memFun, p1, p2);
|
||||||
}
|
}
|
||||||
|
|
||||||
~ObjScopeGuardImpl2() throw()
|
~ObjScopeGuardImpl2() throw()
|
||||||
{
|
{
|
||||||
SafeExecute(*this);
|
SafeExecute(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Execute()
|
void Execute()
|
||||||
{
|
{
|
||||||
(obj_.*memFun_)(p1_, p2_);
|
(obj_.*memFun_)(p1_, p2_);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ObjScopeGuardImpl2(Obj& obj, MemFun memFun, P1 p1, P2 p2) : obj_(obj), memFun_(memFun), p1_(p1), p2_(p2)
|
ObjScopeGuardImpl2(Obj& obj, MemFun memFun, P1 p1, P2 p2) : obj_(obj), memFun_(memFun), p1_(p1), p2_(p2)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
Obj& obj_;
|
Obj& obj_;
|
||||||
|
@ -567,13 +600,13 @@ namespace Loki
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Ret, class Obj1, class Obj2, typename P1a, typename P1b, typename P2a, typename P2b>
|
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)
|
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);
|
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>
|
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)
|
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);
|
return ObjScopeGuardImpl2<Obj1,Ret(Obj2::*)(P1a,P2a),P1b,P2b>::MakeObjGuard(*obj,memFun,p1,p2);
|
||||||
}
|
}
|
||||||
|
@ -605,12 +638,12 @@ namespace Loki
|
||||||
return ObjScopeGuardImpl3< Obj, MemFun, P1, P2, P3 >( obj, memFun, p1, p2, p3 );
|
return ObjScopeGuardImpl3< Obj, MemFun, P1, P2, P3 >( obj, memFun, p1, p2, p3 );
|
||||||
}
|
}
|
||||||
|
|
||||||
~ObjScopeGuardImpl3() throw()
|
~ObjScopeGuardImpl3() throw()
|
||||||
{
|
{
|
||||||
SafeExecute( *this );
|
SafeExecute( *this );
|
||||||
}
|
}
|
||||||
|
|
||||||
void Execute()
|
void Execute()
|
||||||
{
|
{
|
||||||
( obj_.*memFun_ )( p1_, p2_, p3_ );
|
( obj_.*memFun_ )( p1_, p2_, p3_ );
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue