|
Boost Users : |
Subject: Re: [Boost-users] [Proto] lambda functions with named variables
From: Eric Niebler (eric_at_[hidden])
Date: 2010-11-02 00:16:25
On 11/1/2010 12:59 PM, Manjunath Kudlur wrote:
>>
>> 2) To provide a map-like container in which I can store things like boost::any objects. OK, maybe this is not for Proto to address but though it might still have something to offer...
>>
>
> Have you checked out Boost.Fusion map or vector for this purpose?
Second this. You do *not* want to use boost::any for this as you will
lose all type safety and optimization opportunities. Here's the basic
strategy:
Define tags like this:
template<typename T>
struct arg_ { typedef T type; };
template<typename T>
struct arg
: proto::terminal<arg_<T> >
{};
struct x_ {};
struct y_ {};
arg<x_>::type const x = {{}};
arg<y_>::type const y = {{}};
Now you have placeholders named x and y to play with. Now this:
lam(x, y)
should return some object that:
1) Has a member typedef for mpl::vector<x_, y_>
2) Has an operator() member that accepts a Proto expression
The operator() in (2) above should return an object that:
1) Holds the Proto expression (by reference)
2) Has the mpl::vector of tags as a member typedef
3) Has an operator() member that accepts arguments for the lambda
The operator() in (3) above should have the same arity as the
mpl::vector of tags. It should take the arguments and put them in a
fusion::vector. Then it takes the mpl::vector of tags and the
fusion::vector of arguments and turn it into a fusion::map. This map
will be used as the state parameter when evaluating the Proto expression
(along with the map) with the following Proto algorithm:
struct at_key : proto::callable
{
template<typename Sig>
struct result;
template<typename This, typename Map, typename Key>
struct result<This(Map, Key)>
: fusion::result_of::at_key<
typename boost::remove_reference<Map>::type
, typename boost::remove_const<
typename boost::remove_reference<Key>::type
>::type
>
{};
template<typename Map, typename Key>
typename fusion::result_of::at_key<Map, Key>::type
operator()(Map & map, Key const &) const
{
return fusion::at_key<Key>(map);
}
};
struct LambdaEval
: proto::or_<
proto::when<
proto::terminal<arg_<_> >
, at_key(proto::_state, mpl::deref<proto::_value>())
>
, proto::_default<LambdaEval>
>
{};
Have fun!
-- Eric Niebler BoostPro Computing http://www.boostpro.com
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net