Boost logo

Proto :

Subject: Re: [proto] pod_generator Question
From: Nate Knight (Nate.Knight_at_[hidden])
Date: 2011-02-13 12:46:15

> The second argument to BOOST_PROTO_DEFINE_OPERATORS is a domain. When
> defining a domain you (usually) specify a generator with an expression
> wrapper. What are you using for a domain, and how do you define it?
> When I want an end-user-friendly terminal type, I derive it from the
> expression wrapper class, like this:
> template<class Expr> struct my_wrapper;
> struct my_domain : domain< generator<my_wrapper> > {};
> template<class Expr> struct my_wrapper
> : extends< Expr, my_wrapper<Expr>, my_domain > {
> ...
> };
> class my_int : my_wrapper< terminal<int>::type > {
> ...
> };
> Sounds like pod-ness is important to you, so this scheme won't work. Is
> that the problem you're having?

I am trying to allow user defined types to be treated as terminals. I provide a trait class

template<typename T, typename Enable = void>
struct IsMap
  : mpl::false_

template<typename T>
struct IsMap<T, typename T::is_map>
  : mpl::true_

So that only types with a typedef is_map or those that specialize IsMap are considered valid terminals.
I then use this with BOOST_PROTO_DEFINE_OPERATORS like

namespace MapOps
    struct map {};

where map_domain is

struct map_domain
  : domain< pod_generator<map_expr>, Map >

template<typename ProtoExpression>
struct map_expr
    BOOST_PROTO_BASIC_EXTENDS(ProtoExpression, map_expr, map_domain)

and Map is the grammar for valid expressions.

I am trying to figure out the most convenient way to have the operator overloads found properly in user code. So far I see several options,

1) "using namespace MapOps;" where expressions are needed.
2) Have users derive their maps from MapOps::map (I lose pod-ness (in C++03) here, right?).
3) Have all maps defined in the same namespace as the operations.
4) Define the operators in the global namespace.

Any suggestions on best practice here?


Proto list run by eric at