
Hi All. Some time ago Maxim Yegorushkin suggested use boost/bind to implement lazy ScopeGuard. I evolved this parasitic idea and reused a lot of code from boost/bind by preprocessing to implement make_guard binders. The ScopeGuard can be used as usual: scope_guard g = make_guard( func, args ); What do you think about it? Is it possible to "legalize" such approach? ========= #ifndef SCOPE_GUARD_HPP_INCLUDED #define SCOPE_GUARD_HPP_INCLUDED // scope_guard.hpp #include <boost/bind.hpp> //////////////////////////////////////////////////////////////////////////////////////////////// namespace boost { //////////////////////////////////////////////////////////////////////////////////////////////// namespace _bi { //////////////////////////////////////////////////////////////////////////////////////////////// class scope_guard_base { public: void dismiss() const { do_rollback_ = false; } protected: scope_guard_base(const scope_guard_base& other) : do_rollback_(other.do_rollback_) { other.dismiss(); } scope_guard_base() : do_rollback_(true) {} mutable bool do_rollback_; }; //////////////////////////////////////////////////////////////////////////////////////////////// template<class R, class F, class A> class scope_guard_impl : public scope_guard_base { public: scope_guard_impl(F f, A const& a) : rollback_(f, a) {} ~scope_guard_impl() { if(do_rollback_) rollback_(); } private: bind_t<R,F,A> rollback_; }; //////////////////////////////////////////////////////////////////////////////////////////////// } // namespace _bi //////////////////////////////////////////////////////////////////////////////////////////////// typedef _bi::scope_guard_base const& scope_guard; //////////////////////////////////////////////////////////////////////////////////////////////// // create make_guard() definitions by preprocessing boost::bind() sources #undef BOOST_BIND // it seems like authors forgot about it #define BOOST_BIND make_guard #define bind_t scope_guard_impl //////////////////////////////////////////////////////////////////////////////////////////////// // quotation from boost/bind.hpp // Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd. // Copyright (c) 2001 David Abrahams // function pointers #define BOOST_BIND_CC #define BOOST_BIND_ST #include <boost/bind/bind_cc.hpp> #undef BOOST_BIND_CC #undef BOOST_BIND_ST #ifdef BOOST_BIND_ENABLE_STDCALL #define BOOST_BIND_CC __stdcall #define BOOST_BIND_ST #include <boost/bind/bind_cc.hpp> #undef BOOST_BIND_CC #undef BOOST_BIND_ST #endif #ifdef BOOST_BIND_ENABLE_FASTCALL #define BOOST_BIND_CC __fastcall #define BOOST_BIND_ST #include <boost/bind/bind_cc.hpp> #undef BOOST_BIND_CC #undef BOOST_BIND_ST #endif #ifdef BOOST_BIND_ENABLE_PASCAL #define BOOST_BIND_ST pascal #define BOOST_BIND_CC #include <boost/bind/bind_cc.hpp> #undef BOOST_BIND_ST #undef BOOST_BIND_CC #endif // member function pointers #define BOOST_BIND_MF_NAME(X) X #define BOOST_BIND_MF_CC #include <boost/bind/bind_mf_cc.hpp> #undef BOOST_BIND_MF_NAME #undef BOOST_BIND_MF_CC #ifdef BOOST_MEM_FN_ENABLE_STDCALL #define BOOST_BIND_MF_NAME(X) X##_stdcall #define BOOST_BIND_MF_CC __stdcall #include <boost/bind/bind_mf_cc.hpp> #undef BOOST_BIND_MF_NAME #undef BOOST_BIND_MF_CC #endif #ifdef BOOST_MEM_FN_ENABLE_FASTCALL #define BOOST_BIND_MF_NAME(X) X##_fastcall #define BOOST_BIND_MF_CC __fastcall #include <boost/bind/bind_mf_cc.hpp> #undef BOOST_BIND_MF_NAME #undef BOOST_BIND_MF_CC #endif // end quotation boost/bind.hpp /////////////////////////////////////////////////////////////// #undef BOOST_BIND #undef bind_t //////////////////////////////////////////////////////////////////////////////////////////////// } // namespace boost //////////////////////////////////////////////////////////////////////////////////////////////// #endif // #ifndef SCOPE_GUARD_HPP_INCLUDED ============= Regards, Konstantin Echenko