|
Boost : |
Subject: Re: [boost] [scope_exit] Boost.ScopeExit capturing 'this'
From: adam.butcher_at_[hidden]
Date: 2009-03-10 04:35:52
Hi All,
Alex is very busy at the moment so has asked me to forward my latest
ScopeExit 'this capture' diff to the mailing list. This is the first
chance I've had myself to do this so here it is. Hopefully we don't
overlap with each other.
The enhancement allows capturing of 'this' in the BOOST_SCOPE_EXIT
capture sequence allowing access to any class members within the body.
The current diff allows for the following opening syntaxes and has
been trialled on gcc4.2, gcc4.3, vc7.1 and vc9.0.
1. BOOST_SCOPE_EXIT( (this) (&a) (&b) )
2. BOOST_SCOPE_EXIT( (this) )
3. BOOST_SCOPE_EXIT( (&a) (&b) )
4. BOOST_SCOPE_EXIT()
This avoids the current necessity of creating a temporary copy of
'this' just so that a reference may be passed as a scope exit
argument; thus removing the convenience of scope exit since you must
spell out the full type of 'pointer-to-enclosing-class' and name an
instance of it prior to using BOOST_SCOPE_EXIT.
The 'this' element is dealt with specifically by the preprocessor code
in BOOST_SCOPE_EXIT and as such must appear as the first element
in the sequence if it is to be captured.
Member access for the enclosing class can be performed with the
syntax:
(*this) -- convertible to enclosing 'this'
(**this) -- enclosing 'this'
(*this)->member -- accesses member 'member' of enclosing 'this'
This syntax is perhaps controversial though I think both Alex and
myself are reasonably happy with it. Alternatives suggested were
'this_', 'this_()', 'enclosing_this', 'enclosing_this()', 'enclosing',
'enclosing()', 'self' and 'self()'.
The versions of opening syntax where local capture sequences are empty
(2. and 4. above) generate pre-processor warnings about insufficient
arguments to macros on vc7.1 and vc9.0 which I have ignored by
suppressing the warnings. I am sure that by extending or optimizing
the use of Boost.PP it may be possible to remove them in all but the
final case (4.) -- I am no Boost.PP expert so I'm sure there is a more
efficient way of implementing 'this-capture' anyway.
We would welcome any feedback from Boost.ScopeExit users.
Regards,
Adam
The diff is attached and fragments of off-list mails are included below:
Adam Butcher/UKMAIN/MM1 wrote on 02/03/2009 13:37:50:
> Re: Boost.ScopeExit capturing 'this'
>
> Hi Alex,
>
> Adam Butcher/UKMAIN/MM1 wrote on 02/03/2009 08:33:42:
> > Re: Boost.ScopeExit capturing 'this'
> >
> > Alexander Nasonov <alnsn_at_[hidden]> wrote on 28/02/2009 19:31:52:
> > > Re: Boost.ScopeExit capturing 'this'
> > >
> > > Hi Adam,
> > > Thanks for the interest in improving ScopeExit. I agree that 'this'
> > > is imporant but I have no perfect solution for this so far.
> > >
> > > _THIS suffix doesn't look nice to me.
> > >
> > Agreed, I don't like it either -- it was a fallback when I was
> > beaten by the PP library (or my ability to program the pre-processor
> > in general :-).
> >
> > > I would prefer some magic
> > > in BOOST_SCOPE_EXIT argruments to introducing a new macro.
> > > Off the top of my head:
> > >
> > > BOOST_SCOPE_EXIT( (this)(&a)(b) ) // (this) must be first
> > >
> > I tried something like that and played with BOOST_SCOPE_EXIT( this
> > (&a) (&b) ) and BOOST_SCOPE_EXIT( this ( (&a) (&b) ) ) also but
> > couldn't figure out a way in the PP library to treat 'this'
> > specially whilst ignoring it if the first sequence-item happened to
> > be something other than this.
> > I hope it is possible -- but I gave up after a number of close but
> > ultimately insufficient attempts -- I will have another go.
> >
> Just had a play over lunch and have come up with something to allow
> a uniform interface for
> BOOST_SCOPE_EXIT( (this)(&a)(&b) )
> and
> BOOST_SCOPE_EXIT( (&a)(&b) )
>
> Here is my proof-of-concept for the mechanics:
>
---------------------------------------------------------------------------
> #include <boost/preprocessor/library.hpp>
>
> // should be innocuous as C++ standard doesn't permit this(...); make
> // it equivalent anyway so as to generate appropriate error if used.
> #define this(x) (this(x))
>
> #define X0 zero(
> #define X1 one(
>
> #define zero(_) 0
> #define one(_) 1
>
> // Expand to 1 if the first sequence element is 'this'
> // or 0 otherwise.
> //
> // head = front(seq) --> 'this' or 'a'
> // funcexp = head(_) --> '(this(_))' or 'a(_)'
> // number_and_possible_tokens = seq_size(funcexp)
> // yields either
> // 0 a(_)
> // or 1
> // expansion of 'cat(X,number_and_possible_tokens _) )'
> // yields either
> // X0 _ ) --> zero( _ ) --> 0
> // or X1 tokens _ ) --> one( tokens _ ) --> 1
> //
> #define TEST_FOR_ARG0_THIS(seq) \
> BOOST_PP_CAT(X,BOOST_PP_SEQ_SIZE(BOOST_PP_SEQ_HEAD(seq)(_)) _) \
> ) \
> -- just for info: seq
>
> TEST_FOR_ARG0_THIS( (this)(a)(b)(c) )
> TEST_FOR_ARG0_THIS( (a)(b)(c) )
>
> -- checks for 'this' behaviour --
>
> this
> this(x)
> this()
>
---------------------------------------------------------------------------
>
> This outputs (tested on gcc4.2, gcc4.3, msvc7.1 and msvc9.0)
>
> 1 -- just for info: (this)(a)(b)(c)
> 0 -- just for info: (a)(b)(c)
>
> -- checks for 'this' behaviour --
>
> this
> (this(x))
> (this())
>
> The result of TEST_FOR_ARG0_THIS(seq) can be used as a conditional,
> if 1 we pass in 'BOOST_PP_SEQ_TAIL(seq)' and 'this' into
> BOOST_SCOPE_EXIT_AUX_IMPL and if 0 we pass 'seq' and 'nothis' into it.
>
> It should pan out okay -- it is pretty rude to make 'this(...)' a
> macro, though since C++ doesn't allow that syntax (that I'm aware
> of) it should be innocuous and will still generate an appropriate
> error if the user did, in error, use this(...).
>
> What do you think? I'll have a go at integrating it into
> scope_exit.hpp (with the required identifier name changes) if I get
> time later -- if not I'll send a diff tonight.
>
> Regards,
> Adam
> Re: [boost] [scope_exit] Boost.ScopeExit capturing 'this'
>
> I have replied to Adam but I have forgotten to add boost-devel to CC.
> Unfortunately, I don't access to my yandex account from work to forward
> the message now.
>
> Alex
------------------------------------------------------------
This email and any attached files contains company confidential information which may be legally privileged. It is intended only for the person(s) or entity to which it is addressed and solely for the purposes set forth therein. If you are not the intended recipient or have received this email in error please notify the sender by return, delete it from your system and destroy any local copies. It is strictly forbidden to use the information in this email including any attachment or part thereof including copying, disclosing, distributing, amending or using for any other purpose.
In addition the sender excludes all liabilities (whether tortious or common law) for damage or breach arising or related to this email including but not limited to viruses and libel.
SELEX Communications Limited is a Private Limited Company registered in England and Wales under Company Number 964533 and whose Registered Office is Lambda House, Christopher Martin Rd, Basildon, SS14 3EL. England.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk