Boost logo

Boost :

Subject: Re: [boost] Review of Local Exits
From: Lorenzo Caminiti (lorcaminiti_at_[hidden])
Date: 2011-11-20 05:53:09

On Sun, Nov 20, 2011 at 4:36 AM, Alexander Nasonov <alnsn_at_[hidden]> wrote:
> Vicente J. Botet Escriba wrote:
>> Le 19/11/11 23:08, Lorenzo Caminiti a écrit :
>> >...
>> >FYI, I can write pp code that transforms void, this_, etc into lambda
>> >captures. For example:
>> >
>> >TO_CAPTURE(void) // expand to []
>> >TO_CAPTURE(this_,&x) // expand to [this,&x]
>> >TO_CAPTURE( (this_) (&x) ) // expand to [this,&x]
>> >
>> >This way SCOPE_EXIT(void) and SCOPE_EXIT( (this_) (&x) ) or even
>> >SCOPE_EXIT(this_,&x) could support void and this_ while still working
>> >on both C++03 and C++11...
>> >
>> >>  - For the same reason, const bind&  and bind&  should be removed from
>> >>    the interface.
>> >Well, if local exits are not merged with scope exits, local exits can
>> >keep const bind&, bind&, this_, void, etc.
>> ...
>> Alex, could you explain why (a part form following the lambda
>> capture), you don't want to accept these new bindings in ScopedExit?
> Because binding syntax in Local is not compatible with ScopeExit
> captures. If Lorenzo can add support for this_ and void extensions
> (with emphasis on extensions), I'd be fine with this.

1. One challenge (from a pp implementation prospective) is that
reference bindings start with the non-alphanumeric symbol & which
limits that pp manipulations I can do on such a token (i.e., I cannot
CAT in from of it). Because of that, I'd need to try to implement the
macros before I can be sure 100% but I think the following should be
possible (because the parenthesis wrapping (&x) helps):

SCOPE_EXIT( (&x) (y) ) // current
SCOPE_EXIT( (&x) (this_) (y) ) // extension to support this_
SCOPE_EXIT( void ) // extension to support no bindings

It should be possible to also transform all of the above to lambda
bindings (respectively [&x, y], [&x, this, y], and []) for a C++11
implementation of ScopeExit. In C++03 implementation of scope exits
you will have to use this_ (not this) within the scope exit to access
the object, in C++11 it could be implemented so you can use both or
either this_ and this.

2. I do not think I can support const binding instead:

SCOPE_EXIT( (const &x) (const this_) (const y) ) // no, I can't do this

Because &x starts with & so I cannot CAT it in front to see if it
starts with const as in "const &x", plus C++11 lambdas do not support
const bindings anyway.

3. Also I do not think I can also support the variadic syntax:

SCOPE_EXIT(&x, y) // no, I can't do this

Because I'd need to CAT in front &x to distinguish SCOPE_EXIT(&x) from
SCOPE_EXIT(void) given that &x is no longer wrapped within extra
parenthesis as in SCOPE_EXIT( (&x) ).

If I make 1) the improvements for void and this_ to ScopeExit (which I
am very happy to try to make) then the only advantage of local exits
are 2) const bindings and 3) variadics syntax. I think that both 2)
and 3) are not necessary for the scope exit construct so I'd think
that local exits can be removed from Boost.Local and replaced by
ScopeExit with the improvements above.

P.S. If someone really neededs 2) const bindings and 3) variadics for
their scope exits, they could trivially program the following using

struct scope_exit {
    scope_exit(function<void ()> f) : f_(f) {}
    ~scope_exit() { f_(); }
    function<void ()> f_;

// some local scope
void BOOST_LOCAL_FUNCTION(const capture& x, capture this_, const
capture y) { // const and variadics
    ... // clean up code
scope_exit exit1(on_exit1);


Boost list run by bdawes at, gregod at, cpdaniel at, john at