/* ---------------------------------------------------------------------- *\ File: ScopeGuard.h Title: ScopeGuard Description: Implementation of ScopeGuard(TM), a class that allows actions to be queued up and performed when a particular scope is exited, unless it is dismissed. This is taken from an article in the December 2000 Experts Forum of the C/C++ Users Journal, Online Edition, which was written by Andrei Alexandrescu and Petru Marginean. Since the actual source was not available, I have re-implemented the ideas in the article based on code snippets. I have also changed the implementation so it does not require a separate class to be defined for each combination of # of parameters and member/non-member function. \* ---------------------------------------------------------------------- */ #include #include /* ---------------------------------------------------------------------- *\ ScopeGuard Implementation \* ---------------------------------------------------------------------- */ class ScopeGuardImpl { public: typedef void (VoidFun)(void); void Dismiss() const throw() { dismissed_ = true; } ScopeGuardImpl(boost::function fun) : dismissed_(false),fun_(fun) {} ScopeGuardImpl(const ScopeGuardImpl& other) : dismissed_(other.dismissed_),fun_(other.fun_) { other.Dismiss(); std::cout << "Copying!!!\n";} ~ScopeGuardImpl(){ if(!dismissed_){ try{fun_();}catch(...){} } } private: boost::function fun_; mutable bool dismissed_; // Disable assignment ScopeGuardImpl& operator=( const ScopeGuardImpl&); }; // typedef used for defining ScopeGuard typedef const ScopeGuardImpl& ScopeGuard; /* ---------------------------------------------------------------------- *\ ScopeGuard Helper Function Type: Non-member function # Params: 0 \* ---------------------------------------------------------------------- */ template ScopeGuardImpl MakeScopeGuard(const Fun& fun){ return ScopeGuardImpl(fun); } /* ---------------------------------------------------------------------- *\ ScopeGuard Helper Function Type: Non-member function # Params: 1 \* ---------------------------------------------------------------------- */ template ScopeGuardImpl MakeScopeGuard(const Fun& fun, const Param1& param1){ return ScopeGuardImpl(boost::bind(fun,param1)); } /* ---------------------------------------------------------------------- *\ ScopeGuard Helper Function Type: Non-member function # Params: 2 \* ---------------------------------------------------------------------- */ template ScopeGuardImpl MakeScopeGuard(const Fun& fun, const Param1& param1, const Param2& param2){ return ScopeGuardImpl(boost::bind(fun,param1,param2)); } /* ---------------------------------------------------------------------- *\ ScopeGuard Helper Function Type: Non-member function # Params: 3 \* ---------------------------------------------------------------------- */ template ScopeGuardImpl MakeScopeGuard(const Fun& fun, const Param1& param1, const Param2& param2, const Param3& param3){ return ScopeGuardImpl(boost::bind(fun,param1,param2,param3)); } /* ---------------------------------------------------------------------- *\ ScopeGuard Helper Function Type: Non-member function # Params: 4 \* ---------------------------------------------------------------------- */ template ScopeGuardImpl MakeScopeGuard(const Fun& fun, const Param1& param1, const Param2& param2, const Param3& param3, const Param4& param4){ return ScopeGuardImpl(boost::bind(fun,param1,param2,param3,param4)); } /* ---------------------------------------------------------------------- *\ ScopeGuard Helper Function Type: Non-member function # Params: 5 \* ---------------------------------------------------------------------- */ template ScopeGuardImpl MakeScopeGuard(const Fun& fun, const Param1& param1, const Param2& param2, const Param3& param3, const Param4& param4, const Param5& param5){ return ScopeGuardImpl(boost::bind(fun,param1,param2,param3,param4,param5)); } /* ---------------------------------------------------------------------- *\ ScopeGuard Helper Function Type: Non-member function # Params: 6 \* ---------------------------------------------------------------------- */ template ScopeGuardImpl MakeScopeGuard(const Fun& fun, const Param1& param1, const Param2& param2, const Param3& param3, const Param4& param4, const Param5& param5, const Param6& param6){ return ScopeGuardImpl(boost::bind(fun,param1,param2,param3,param4,param5,param6)); } /* ---------------------------------------------------------------------- *\ ScopeGuard Helper Function Type: Non-member function # Params: 7 \* ---------------------------------------------------------------------- */ template ScopeGuardImpl MakeScopeGuard(const Fun& fun, const Param1& param1, const Param2& param2, const Param3& param3, const Param4& param4, const Param5& param5, const Param6& param6, const Param7& param7){ return ScopeGuardImpl(boost::bind(fun,param1,param2,param3,param4,param5,param6,param7)); } /* ---------------------------------------------------------------------- *\ ScopeGuard Helper Function Type: Non-member function # Params: 8 \* ---------------------------------------------------------------------- */ template ScopeGuardImpl MakeScopeGuard(const Fun& fun, const Param1& param1, const Param2& param2, const Param3& param3, const Param4& param4, const Param5& param5, const Param6& param6, const Param7& param7, const Param8& param8){ return ScopeGuardImpl(boost::bind(fun,param1,param2,param3,param4,param5,param6,param7, param8)); } /* ---------------------------------------------------------------------- *\ ScopeGuard Helper Function Type: Non-member function # Params: 9 \* ---------------------------------------------------------------------- */ template ScopeGuardImpl MakeScopeGuard(const Fun& fun, const Param1& param1, const Param2& param2, const Param3& param3, const Param4& param4, const Param5& param5, const Param6& param6, const Param7& param7, const Param8& param8, const Param9& param9){ return ScopeGuardImpl(boost::bind(fun,param1,param2,param3,param4,param5,param6,param7, param8,param9)); } /* ---------------------------------------------------------------------- *\ ScopeGuard Helper Function Type: Member function # Params: 0 \* ---------------------------------------------------------------------- */ template ScopeGuardImpl MakeScopeGuard(Obj& obj,const MemFun& fun){ return ScopeGuardImpl(boost::bind(fun,boost::ref(obj))); } /* ---------------------------------------------------------------------- *\ ScopeGuard Helper Function Type: Member function # Params: 1 \* ---------------------------------------------------------------------- */ template ScopeGuardImpl MakeScopeGuard(Obj& obj,const MemFun& fun, const Param1& param1){ return ScopeGuardImpl(boost::bind(fun,boost::ref(obj),param1)); } /* ---------------------------------------------------------------------- *\ ScopeGuard Helper Function Type: Member function # Params: 2 \* ---------------------------------------------------------------------- */ template ScopeGuardImpl MakeScopeGuard(Obj& obj,const MemFun& fun, const Param1& param1, const Param2& param2){ return ScopeGuardImpl(boost::bind(fun,boost::ref(obj),param1,param2)); } /* ---------------------------------------------------------------------- *\ ScopeGuard Helper Function Type: Member function # Params: 3 \* ---------------------------------------------------------------------- */ template ScopeGuardImpl MakeScopeGuard(Obj& obj,const MemFun& fun, const Param1& param1, const Param2& param2, const Param3& param3){ return ScopeGuardImpl(boost::bind(fun,boost::ref(obj),param1,param2,param3)); } /* ---------------------------------------------------------------------- *\ ScopeGuard Helper Function Type: Member function # Params: 4 \* ---------------------------------------------------------------------- */ template ScopeGuardImpl MakeScopeGuard(Obj& obj,const MemFun& fun, const Param1& param1, const Param2& param2, const Param3& param3, const Param4& param4){ return ScopeGuardImpl(boost::bind(fun,boost::ref(obj),param1,param2,param3,param4)); } /* ---------------------------------------------------------------------- *\ ScopeGuard Helper Function Type: Member function # Params: 5 \* ---------------------------------------------------------------------- */ template ScopeGuardImpl MakeScopeGuard(Obj& obj,const MemFun& fun, const Param1& param1, const Param2& param2, const Param3& param3, const Param4& param4, const Param5& param5){ return ScopeGuardImpl(boost::bind(fun,boost::ref(obj),param1,param2,param3,param4, param5)); } /* ---------------------------------------------------------------------- *\ ScopeGuard Helper Function Type: Member function # Params: 6 \* ---------------------------------------------------------------------- */ template ScopeGuardImpl MakeScopeGuard(Obj& obj,const MemFun& fun, const Param1& param1, const Param2& param2, const Param3& param3, const Param4& param4, const Param5& param5, const Param6& param6){ return ScopeGuardImpl(boost::bind(fun,boost::ref(obj),param1,param2,param3,param4, param5,param6)); } /* ---------------------------------------------------------------------- *\ ScopeGuard Helper Function Type: Member function # Params: 7 \* ---------------------------------------------------------------------- */ template ScopeGuardImpl MakeScopeGuard(Obj& obj,const MemFun& fun, const Param1& param1, const Param2& param2, const Param3& param3, const Param4& param4, const Param5& param5, const Param6& param6, const Param7& param7){ return ScopeGuardImpl(boost::bind(fun,boost::ref(obj),param1,param2,param3,param4, param5,param6,param7)); } /* ---------------------------------------------------------------------- *\ ScopeGuard Helper Function Type: Member function # Params: 8 \* ---------------------------------------------------------------------- */ template ScopeGuardImpl MakeScopeGuard(Obj& obj,const MemFun& fun, const Param1& param1, const Param2& param2, const Param3& param3, const Param4& param4, const Param5& param5, const Param6& param6, const Param7& param7, const Param8& param8){ return ScopeGuardImpl(boost::bind(fun,boost::ref(obj),param1,param2,param3,param4, param5,param6,param7,param8)); }