Sophie

Sophie

distrib > Mandriva > 9.1 > ppc > by-pkgid > b9ba69a436161613d8fb030c8c726a8e > files > 372

spirit-1.5.1-2mdk.noarch.rpm


Hi again,

Gee, I am in a trap :-) I always get this itch to
face challenges. This time access to outer scopes'
local variables. Here you are:

First a sample:

    context<nil_t>(1)
    [
        cout << loc1 << '\n',
        context<nil_t>(2)
        [
            cout << loc1.parent<1>() << ' ' << loc1 << '\n',
            context<nil_t>(3)
            [
                cout << loc1.parent<2>() << ' ' << loc1.parent<1>() << ' ' << loc1 << '\n'
            ]
        ]
    ]

    (); // guess what this is ???

Will print out:

1
1 2
1 2 3

Cool eh?.. There are only slight changes to my previous posted code.

------------------------------------------

local_var_result

This is a return type computer. Given a constant integer N, a parent
index and a tuple, get the Nth local variable type. The parent index
is an integer specifying which parent scope to access; 0==current
scope, 1==parent scope, 2==parent's parent scope.

This is a metaprogram with partial specializations. There is a general
case, a special case for local_tuples and a terminating special case
for local_tuples.

    General case: If TupleT is not really a local_tuple, we just
    return nil_t.

    local_tuples case:
        Parent index is 0: We get the Nth local variable.
        Otherwise: We subclass from local_tuples<N, Parent-1, TupleArgsT>

//////////////////////////////////
template <int N, int Parent, typename TupleT>
struct local_var_result {

    typedef nil_t type;
};

//////////////////////////////////
template <int N, int Parent, typename TupleArgsT, typename TupleLocsT>
struct local_var_result<N, Parent, local_tuple<TupleArgsT, TupleLocsT> >
:   public local_var_result<N, Parent-1, TupleArgsT> {};

//////////////////////////////////
template <int N, typename TupleArgsT, typename TupleLocsT>
struct local_var_result<N, 0, local_tuple<TupleArgsT, TupleLocsT> > {

    typedef typename tuple_element<
        N, TupleLocsT
    >::type& type;

    static type get(local_tuple<TupleArgsT, TupleLocsT> const& tuple)
    { return tuple.locs[tuple_index<N>()]; }
};

------------------------------------------

local_var

This class looks so curiously like the argument class. local_var
provides access to the Nth local variable packed in the tuple duo
local_tuple above. Parent specifies the Nth parent scope. 0==current
scope, 1==parent scope, 2==parent's parent scope. The member function
parent<N>() may be called to provide access to outer scopes.

Note that the member function eval expects a local_tuple argument.
Otherwise there will be acompile-time error. local_var primitives only
work within the context of a context_composite.

Provided are some predefined local_var actors for 0..N local variable
access: loc1..locN.

template <int N, int Parent = 0>
struct local_var {

    template <typename TupleT>
    struct result {

        typedef typename local_var_result<N, Parent, TupleT>::type type;
    };

    template <typename TupleT>
    typename local_var_result<N, Parent, TupleT>::type
    eval(TupleT const& tuple) const
    {
        return local_var_result<N, Parent, TupleT>::get(tuple);
    }

    template <int PIndex>
    actor<local_var<N, Parent+PIndex> >
    parent() const
    {
        return local_var<N, Parent+PIndex>();
    }
};

------------------------------------------

That's it. Nice 'n easy...

--Joel