|
Boost : |
From: Konstantin Echenko (clean_at_[hidden])
Date: 2004-10-03 08:38:13
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
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk