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:
rich_sposato 2011-06-21 01:07:22 +00:00
parent 27f38492bd
commit 904bbee76d

View file

@ -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_ );
} }