Boost logo

Boost :

From: Alexander Nasonov (alnsn_at_[hidden])
Date: 2006-08-02 19:39:27


Steven Watanabe wrote:
> [ skiped ]
> Finally, here is an example of how I am defining operations:
> [ skiped ]

I also use CRTP trick but I pass a signature of an operation as well:

struct add_int_constant
  : function<add_int_constant, anyT (anyT const&, int)>
{
    // ...
};

Here anyT is a placeholder for any<OperationList>.
It lets me distinguish between any<OperationList> and regular arguments.
Base class has operator() that deduces OperationList from a first anyT
argument. So a user can just call the add_int_constant functor:

    any< mpl::vector<add_int_constant> > a(9);
    a = add_int_constant()(a, 11);
    assert(extract<int>(a) == 20);

There is no stable interface for operation implementation yet. It should
be simple for very generic operation like to_ostream and for an opposite
case of different functions for every combination of types.

For the latter I'm thinking of the following approach:

    struct plus : function<plus, anyT (anyT const&, anyT const&)>
    {
        int entry(id<1>, int, int) const;
        double entry(id<2>, double, int) const;
        // ...
        std::string entry(id<100>, std::string const&, char) const;
        // ...
    };

Basically, it's multimethods where all entries belong to one class.
Using id<N> agruments, it's possible to view entries as MPL immutable
sequence of signatures (typeof is required). Obviously, such entries
can't be templates.

If OperationList is needed, a user could resort to a nested
"definition" template (pay attention to entry 200):

    struct plus : function<plus, anyT (anyT const&, anyT const&)>
    {
        template<class L> // L is OperationList
        struct definition
        {
            int entry(id<1>, int, int) const;
            double entry(id<2>, double, int) const;
            // ...

            any<L> entry(id<200>, any<L> const&, int) const;
        };
    };

I believe that SFINAE can detect a presence of "definition".

Operations with only one anyT agrument can be implemented without using
id<N> agruments:

    struct to_ostream : function<to_ostream, ostream& (ostream&, anyT const&)>
    {
        template<class T>
        ostream& entry(ostream& o , T const& t) const { return o << t; }

        ostream& entry(ostream& o, emptyT) const { return o; }
    };

Similarly, "definition" can be used if required.

-- 
Alexander Nasonov
Project Manager at Akmosoft ( http://www.akmosoft.com )
Blog: http://nasonov.blogspot.com
Email: $(FirstName) dot $(LastName) at gmail dot com

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