Boost logo

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