|
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