Boost logo

Boost :

Subject: Re: [boost] [local_function] any interest in a LocalFunction library?
From: Lorenzo Caminiti (lorcaminiti_at_[hidden])
Date: 2010-08-24 09:59:31


On Mon, Aug 23, 2010 at 3:42 PM, Pierre Morcello
<pmorcell-cppfrance_at_[hidden]> wrote:
>> I can implement Boost.LocalFunction macros, which are
>> similar to your 'V3' macros, in pure C++ ISO standard (no __VA_ARGS__). I
>> will study your code more.
>
> __VA_ARGS__ is iso C99 (but ok not c++). The point is only that boost prefers iso C90, since it is much more widely supported.

Yes, I know. My goal is to write Boost.LocalFunction without using C99
features -- just C++.

> I have some implementation question on your proposition : how will you detect that 'this' exist, that you are not inside a static function ? If you can do such a thing I am interested to know how you do it (because I did not find out myself) ?

Well, I am still implementing Boost.LocalFunction :) However,
Boost.LocalFunction does not detect `this` automatically but the user
specifies it as one of the bound parameters:

    struct c {
        void f(int x) {
            double y = x;
            BOOST_LOCAL_FUNCTION( (int)(l)( (const char*)(a) (bound)(
(this)(&x)(y) ) ) ) { // `this` is bound here.
                if (y > 0) this_->x_ = x; // Access `this` via `this_`.
                return this_->x_;
            } BOOST_LOCAL_FUNCTION_END
            int r = BOOST_LOCAL_FUNCTION_CALL("hello");
        }
    private:
        int x_;
    };

The macro inspects all tokens within the bound sequence, if one of
these tokens matches the word `this` then the macro expands to code
that binds the object `this` and passes it to the local function
(static function of a local class) as a parameter named `this_`
(unfortunately, `this` is a reserved keyword so it cannot be used as a
parameter name and I have to use `this_`...). `this` can also be bound
as `const` (for "constant local member functions") but it cannot be
bound as reference (i.e., you have accesses to the object alway by
pointer as usual in C++).

Ideally, when `this` is one of the bound parameters, it would be
available within the local function either implicitly or via `this`
and not via a special name like `this_`. That would be the usual C++
syntax:

    struct c {
        void f(int x) {
            double y = x;
            BOOST_LOCAL_FUNCTION( (int)(l)( (const char*)(a) (bound)(
(this)(&x)(y) ) ) ) { // `this` is bound here.
                if (y > 0) x_ = x; // Implicitly access `this` (and
not `this_`).
                return this->x_; // Access as `this` (and not `this`_).
            } BOOST_LOCAL_FUNCTION_END
            int r = BOOST_LOCAL_FUNCTION_CALL("hello");
        }
    private:
        int x_;
    };

However, the only way I know to implement this relies on an undefined
behavior of `static_cast<>` (see
http://groups.google.com/group/comp.lang.c++.moderated/browse_thread/thread/d3a86f27277f713b
) so I cannot use such method. That said, I _might_ provide a
configuration macro
`BOOST_LOCAL_FUNCTION_CONFIG_IMPLICIT_THIS_VIA_UNDEFINED_BEHAVIOR`
(#undefined by default) which, if #defined by the user, will generate
code that supports both `this_` (1st example above) as well as
implicit `this` access (2nd example above) within the local function.

> My example is trickier than it looks, since it uses the defect 45 of the iso to allow private access for nested classes. This quite unfortunate since the defect 45 is only of statut DR instead of TC1 (which is required for being part of the standard).

I understand. As I said, I will study your code more closely (I just
looked at real quickly) as part of my Boost.LocalFunction development.

-- 
Lorenzo

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk