Changeset 48308


Ignore:
Timestamp:
Aug 23, 2008, 7:54:14 AM (10 years ago)
Author:
Eric Niebler
Message:

adding new transforms users guide

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/libs/proto/doc/transforms.qbk

    r48307 r48308  
    88[import ../test/examples.cpp]
    99
    10 [/============================================================================]
    11 [section:expression_transformation Expression Transformation: Semantic Actions]
    12 [/============================================================================]
    13 
    14 Sometimes, rather than immediately executing an expression template, you'd like to
    15 transform it into some other object. Maybe the transformation is simple, like
    16 converting all references into values. Maybe it's complicated, like transforming an
    17 expression template into a finite-state automata for matching a regular expression.
    18 Proto provides a framework for applying tree transformations and several canned
    19 transformations that are generally useful.
    20 
    21 [/===============]
    22 [heading Overview]
    23 [/===============]
    24 
    25 Defining tree transformations involves defining the grammar for your DSEL
    26 and decorating it with transformations. Each rule in your grammar will
    27 have an associated transform describing how sub-expressions matching that rule
    28 are to be transformed. Just as the grammar is defined recursively, so too
    29 is the tree transformation.
    30 
    31 You associate transforms with your grammar rules using _when_. For instance,
    32 you might want to promote all `int` terminals to `long`. You would say the
    33 following:
    34 
    35     proto::when< proto::terminal<int>, proto::terminal<long>::type(proto::_value) >
    36 
    37 `proto::terminal<long>::type(proto::_value)` is an example of a Proto transform. It
    38 says to create an object of type `proto::terminal<long>::type` and initialize it
    39 with the result of the `proto::_value` transform. `proto::_value` is a transform
    40 defined by Proto which extracts the value from a terminal expression.
    41 
    42 [note The transform above might look a little strange at first. It appears
    43 to be constructing a temporary object in place. In fact, it is a
    44 /function type/. Since `proto::terminal<long>::type` and `proto::_value`
    45 are types, `proto::terminal<long>::type(proto::_value)` is actually the type
    46 of a function that takes `proto::_value` as a parameter and returns
    47 `proto::terminal<long>::type`. But no such function actually exists! Rather,
    48 Proto interprets this function type as a transform, the effect of which is
    49 described above. The resemblance to an in-place construction of a temporary
    50 object is intentional. It is a concise and natural notation for specifying
    51 transforms. Proto transforms use function types extensively, as we'll see.]
    52 
    53 A grammar decorated with transforms is a function object that takes three
    54 parameters:
    55 
    56 * `expr`    -- the Proto expression to transform
    57 * `state`   -- an optional initial state for the transformation
    58 * `data`    -- any optional mutable state information
    59 
    60 Many transforms do no use the state and data parameters, and you can pass
    61 dummy values for them or leave them off entirely. Later on we'll describe
    62 the difference between them and see where they are useful.
    63 
    64 In addition to being a function object, a grammar decorated with transforms
    65 is also a grammar. That is, it can be used as the second parameter to
    66 the _matches_ metafunction to see if an expression type matches the grammar.
    67 
    68 The first pararameter to the transform, `expr`, is a Proto expression. Its
    69 type /must/ match the grammar defined by the transform. It is an error to
    70 apply a transform to an expression that does not match the transform's
    71 grammar. If you try it, you're likely to get an ugly compiler error if you're
    72 lucky. If you're unlucky, it'll compile and do something weird at runtime.
    73 For instance, consider the following:
    74 
    75   // A grammar that matches an int terminal, and a
    76   // transform that promotes it to a long terminal.
    77   typedef
    78       proto::when<
    79           proto::terminal<int>
    80         , proto::terminal<long>::type(proto::_value)
    81       >
    82   Promote;
    83 
    84   // A character terminal
    85   proto::terminal<char>::type a = {'a'};
    86 
    87   // ERROR! The Promote transform expects an integer
    88   // terminal, not a character terminal.
    89   Promote promote;
    90   proto::terminal<long>::type i = promote(a);
    91 
    92 Grammars with transforms are proper function objects, so you can use
    93 `boost::result_of<>` to calculate their return types. So, applying a
    94 transform typically looks like this:
    95 
    96     // Assuming we have an expression to transform,
    97     // an initial state, and some auxiliary data ...
    98     Expr expr;
    99     State state;
    100     Data data;
    101 
    102     // ... calculate the result type of applying
    103     // Grammar's transform ...
    104     typedef typename
    105         boost::result_of<Grammar(Expr, State, Data)>::type
    106     result_type;
    107 
    108     // ... and apply Grammar's transform:
    109     result_type result = Grammar()(expr, state, data);
    110 
    111 [/====================================]
    112 [heading The State and Data Parameters]
    113 [/====================================]
    114 
    115 So in a transform, what are the `state` and `data` parameters used for?
    116 If you are familiar with the `std::accumulate()` standard algorithm,
    117 you know that it takes an input sequence, an initial state, and a
    118 binary function. The algorithm passes the initial state and the first
    119 element to the binary function to calculate a new state, which is
    120 then similarly combined with the second element, and so on. Users of
    121 functional programming languages know this operation as `fold`.
    122 
    123 Proto provides several variants of a `fold` transform that behaves
    124 analogously to `std::accumulate()`. The `fold` transform is described
    125 in detail later, but here we're just interested in the `state`
    126 parameter. Any transform that uses `fold` is going to require you
    127 to pass an initial state. That is what the second parameter of a
    128 transform is used for.
    129 
    130 The `data` parameter is a little different. It can be anything you
    131 want, and -- unlike the `state` parameter -- none of Proto's built-in
    132 transforms will touch it. Also unlike the `state` parameter, the
    133 `data` parameter will be passed around by non-const reference. You
    134 can use the `data` parameter to pass along data that your
    135 custom transforms might use or mutate.
    136 
    137 So the difference between `state` and `data` is that `state` is an
    138 accumulation variable that Proto will change, both in type and in
    139 value, during the transformation, whereas `data` is just a blob of
    140 bits that you would like available to your transforms. For instance,
    141 you might want to fold an expression tree to a Fusion list and do
    142 something locale-specific to each element before you put it in the
    143 list. In that case, your state parameter would be `fusion::nil`
    144 (i.e., an empty list), and the data parameter would be a
    145 `std::locale`.
    146 
    147 [/==========================================]
    148 [section Example: Calculator Arity Transform]
    149 [/==========================================]
    150 
    151 Let's have another look at our trusty calculator example. If you recall, the
    152 calculator allows the lazy evaluation of arithmetic expressions, with
    153 placeholders substituted with actual values provided at evaluation time. Valid
    154 expressions are of the form:
    155 
    156     (_1 + 3)
    157     (_2 - _1) / _2 * 100
    158 
    159 ... and so on. In the first expression, one argument must be provided before
    160 the expression can be evaluated. In the second, two arguments are needed. We
    161 could say the /arity/ of the first expression is one and of the second is two.
    162 The arity is determined by the highest placeholder in the expression. Our job
    163 will be to write a transform that calculates the arity of any calculator
    164 expression.
    165 
    166 [note *Why Bother Calculating Expression Arity?*
    167 
    168 This is more than just an intelectual exercise. Knowing the arity of a calculator
    169 expression is important if you want to give users a meaningful error message when
    170 they specify too few or too many arguments to an expression.]
    171 
    172 [/=========================]
    173 [heading Defining a Grammar]
    174 [/=========================]
    175 
    176 First, we must write the grammar for the calculator. It's really very simple.
    177 Calculator expression can be made up of any combination of 5 constituents:
    178 
    179 * Placeholder 1
    180 * Placeholder 2
    181 * A literal
    182 * Unary operations
    183 * Binary operations
    184 
    185 We can immediately write the calculator grammar as follows:
    186 
    187 [CalcGrammar]
    188 
    189 We can read this as follows: a calculator expression is either placeholder 1,
    190 placeholder 2, some other terminal, or some unary or binary operator whose operands
    191 are calculator expressions. Recall that `proto::_` is a wildcard that matches
    192 anything. So `proto::terminal< _ >` will match any terminal, and
    193 `proto::unary_expr< _, CalcArity >` will match any unary expression for which the
    194 operand matches `CalcArity` (the `_` matches any operator tag).
    195 
    196 [/============================]
    197 [heading Writing the Transform]
    198 [/============================]
     10[section Transforms]
     11
     12If you have ever built a parser with the help of a tool like Antlr, yacc or Boost.Spirit, you might be familiar with /semantic actions/. In addition to allowing you to define the grammar of the language recognized by the parser, these tools let you embed code within your grammar that executes when parts of the grammar participate in a parse. Proto has the equivalent of semantic actions. They are called /transforms/. This section describes how to embed transforms within your Proto grammars, turning your grammars into function objects that can manipulate or evaluate expressions in powerful ways.
     13
     14Proto transforms are an advanced topic. We'll take it slow, using examples to illustrate the key concepts, starting simple.
     15
     16[/==================================]
     17[section ["Activating] Your Grammars]
     18[/==================================]
     19
     20The Proto grammars we've seen so far are static. You can check at compile-time to see if an expression type matches a grammar, but that's it. Things get more interesting when you give them runtime behaviors. A grammar with embedded transforms is more than just a static grammar. It is a function object that accepts expressions that match the grammar and does /something/ with them.
     21
     22Below is a very simple grammar. It matches terminal expressions.
     23
     24    // A simple Proto grammar that matches all terminals
     25    proto::terminal< _ >
     26
     27Here is the same grammar with a transform that extracts the value from the terminal:
     28
     29    // A simple Proto grammar that matches all terminals
     30    // *and* a function object that extracts the value from
     31    // the terminal
     32    proto::when<
     33        proto::terminal< _ >
     34      , proto::_value          // <-- Look, a transform!
     35    >
     36
     37You can read this as follows: when you match a terminal expression, extract the value. The type `proto::_value` is a so-called transform. Later we'll see what makes it a transform, but for now just think of it as a kind of function object. Note the use of _when_: the first template parameter is the grammar to match and the second is the transform to execute. The result is both a grammar that matches terminal expressions and a function object that accepts terminal expressions and extracts their values.
     38
     39As with ordinary grammars, we can define an empty struct that inherits from a grammar+transform to give us an easy way to refer back to the thing we're defining, as follows:
     40
     41    // A grammar and a function object, as before
     42    struct Value
     43      : proto::when<
     44            proto::terminal< _ >
     45          , proto::_value
     46        >
     47    {};
     48
     49    // "Value" is a grammar that matches terminal expressions
     50    BOOST_MPL_ASSERT(( proto::matches< proto::terminal<int>::type, Value > ));
     51
     52    // "Value" also defines a function object that accepts terminals
     53    // and extracts their value.
     54    proto::terminal<int>::type answer = {42};
     55    Value get_value;
     56    int i = get_value( answer );
     57
     58[note A grammar with embedded transforms is both a grammar and a function object. Calling these things "grammars with transforms" would get tedious. We could call them something like "active grammars", but as we'll see /every/ grammar that you can define with Proto is "active"; that is, every grammar has some behavior when used as a function object. So we'll continue calling these things plain "grammars". The term "transform" is reserved for the thing that is used as the second parameter to the _when_ template.]
     59
     60[endsect]
     61
     62[/=========================================]
     63[section Handling Alternation and Recursion]
     64[/=========================================]
     65
     66Most grammars are a little more complicated than the one in the preceeding section. For the sake of illustration, let's define a rather nonsensical grammar that matches any expression and recurses to the leftmost terminal and returns its value. It will demonstrate how two key concepts of Proto grammars -- alternation and recursion -- interact with transforms. The grammar is described below.
     67
     68    // A grammar that matches any expression, and a function object
     69    // that returns the value of the leftmost terminal.
     70    struct LeftmostLeaf
     71      : proto::or_<
     72            // If the expression is a terminal, return its value
     73            proto::when<
     74                proto::terminal< _ >
     75              , proto::_value
     76            >
     77            // Otherwise, it is a non-terminal. Return the result
     78            // of invoking LeftmostLeaf on the 0th (leftmost) child.
     79          , proto::when<
     80                _
     81              , LeftmostLeaf( proto::_child0 )
     82            >
     83        >
     84    {};
     85
     86    // A Proto terminal wrapping std::cout
     87    proto::terminal< std::ostream & >::type cout_ = { std::cout };
     88   
     89    // Create an expression and use LeftmostLeaf to extract the
     90    // value of the leftmost terminal, which will be std::cout.
     91    std::ostream & sout = LeftmostLeaf()( cout_ << "the answer: " << 42 << '\n' );
     92
     93We've seen `proto::or_<>` before. Here it is serving two roles. First, it is a grammar that matches any of its alternate sub-grammars; in this case, either a terminal or a non-terminal. Second, it is also a function object that accepts an expression, finds the alternate sub-grammar that matches the expression, and applies its transform. And since `LeftmostLeaf` inherits from `proto::or_<>`, `LeftmostLeaf` is also both a grammar and a function object.
     94
     95[def _some_transform_ [~some-transform]]
     96
     97[note The second alternate uses `proto::_` as its grammar. Recall that `proto::_` is the wildcard grammar that matches any expression. Since alternates in `proto::or_<>` are tried in order, and since the first alternate handles all terminals, the second alternate handles all (and only) non-terminals. Often enough, `proto::when< _, _some_transform_ >` is the last alternate in a grammar, so for improved readability, you could use the equivalent `proto::otherwise< _some_transform_ >`.]
     98
     99The next section describes this grammar further.
     100
     101[endsect]
     102
     103[/==========================]
     104[section Callable Transforms]
     105[/==========================]
     106
     107[def __bold_transform__ [*LeftmostLeaf( proto::_child0 )]]
     108
     109In the grammar defined in the preceeding section, the transform associated with non-terminals is a little strange-looking:
     110
     111    proto::when<
     112        _
     113      , __bold_transform__   // <-- a "callable" transform
     114    >
     115
     116It has the effect of accepting non-terminal expressions, taking the 0th (leftmost) child and recursively invoking the `LeftmostLeaf` function on it. But `LeftmostLeaf( proto::_child0 )` is actually a /function type/. Literally, it is the type of a function that accepts an object of type `proto::_child0` and returns an object of type `LeftmostLeaf`. So how do we make sense of this transform? Clearly, there is no function that actually has this signature, nor would such a function be useful. The key is in understanding how `proto::when<>` /interprets/ its second template parameter.
     117
     118When the second template parameter to _when_ is a function type, _when_ interprets the function type as a transform. In this case, `LeftmostLeaf` is treated as the type of a function object to invoke, and `proto::_child0` is treated as a transform. First, `proto::_child0` is applied to the current expression (the non-terminal that matched this alternate sub-grammar), and the result (the 0th child) is passed as an argument to `LeftmostLeaf`.
     119
     120[note *Transforms are a Domain-Specific Language*
     121
     122`LeftmostLeaf( proto::_child0 )` /looks/ like an invocation of the `LeftmostLeaf` function object, but it's not, but then it actually is! Why this confusing subterfuge? Function types give us a natural and concise syntax for composing more complicated transforms from simpler ones. The fact that the syntax is suggestive of a function invocation is on purpose. It is a domain-specific embedded language for defining expression transformations. If the subterfuge worked, it may have fooled you into thinking the transform is doing exactly what it actually does! And that's the point.]
     123
     124The type `LeftmostLeaf( proto::_child0 )` is an example of a /callable transform/. It is a function type that represents a function object to call and its arguments. The types `proto::_child0` and `proto::_value` are /primitive transforms/. They are plain structs, not unlike function objects, from which callable transforms can be composed. There is one other type of transform, /object transforms/, that we'll encounter next.
     125
     126[endsect]
     127
     128[/========================]
     129[section Object Transforms]
     130[/========================]
     131
     132The very first transform we looked at simply extracted the value of terminals. Let's do the same thing, but this time we'll promote all ints to longs first. (Please forgive the contrived-ness of the examples so far; they get more interesting later.) Here's the grammar:
     133
     134    // A simple Proto grammar that matches all terminals,
     135    // and a function object that extracts the value from
     136    // the terminal, promoting ints to longs:
     137    struct ValueWithPomote
     138      : proto::or_<
     139            proto::when<
     140                proto::terminal< int >
     141              , long(proto::_value)     // <-- an "object" transform
     142            >
     143          , proto::when<
     144                proto::terminal< _ >
     145              , proto::_value
     146            >
     147        >
     148    {};
     149
     150You can read the above grammar as follows: when you match an int terminal, extract the value from the terminal and use it to initialize a long; otherwise, when you match another kind of terminal, just extract the value. The type `long(proto::_value)` is a so-called /object/ transform. It looks like the creation of a temporary long, but it's really a function type. Just as a callable transform is a function type that represents a function to call and its arguments, an object transforms is a function type that represents an object to construct and the arguments to its constructor.
     151
     152[/================================================]
     153[note *Object Transforms vs. Callable Transforms*
     154
     155When using function types as Proto transforms, they can either represent an object to construct or a function to call. It is similar to "normal" C++ where the syntax `foo("arg")` can either be interpreted as an object to construct or a function to call, depending on whether `foo` is a type or a function. But consider two of the transforms we've seen so far:
     156
     157``
     158    LeftmostLeaf(proto::_child0)  // <-- a callable transform
     159    long(proto::_value)           // <-- an object transform
     160``
     161
     162Proto can't know in general which is which, so it uses a trait, `proto::is_callable<>`, to differentiate. `is_callable< long >::value` is false so `long(proto::_value)` is an object to construct, but `is_callable< LeftmostLeaf >::value` is true so `LeftmostLeaf(proto::_child0)` is a function to call. Later on, we'll see how Proto recognizes a type as "callable".]
     163[/================================================]
     164
     165[endsect]
     166
     167[/================================]
     168[section Example: Calculator Arity]
     169[/================================]
     170
     171Now that we have the basics of Proto transforms down, let's consider a slightly more realistic example. We can use transforms to improve the type-safety of the [link boost_proto.users_guide.getting_started.hello_calculator calculator DSEL]. If you recall, it lets you write infix arithmetic expressions involving argument placeholders like `_1` and `_2` and pass them to STL algorithms as function objects, as follows:
     172
     173    double a1[4] = { 56, 84, 37, 69 };
     174    double a2[4] = { 65, 120, 60, 70 };
     175    double a3[4] = { 0 };
     176
     177    // Use std::transform() and a calculator expression
     178    // to calculate percentages given two input sequences:
     179    std::transform(a1, a1+4, a2, a3, (_2 - _1) / _2 * 100);
     180
     181This works because we gave calculator expressions an `operator()` that evaluates the expression, replacing the placeholders with the arguments to `operator()`. The overloaded `calculator<>::operator()` looked like this:
     182
     183    // Overload operator() to invoke proto::eval() with
     184    // our calculator_context.
     185    template<typename Expr>
     186    double
     187    calculator<Expr>::operator()(double a1 = 0, double a2 = 0, double a3 = 0) const
     188    {
     189        calculator_context ctx;
     190        ctx.args.push_back(a1);
     191        ctx.args.push_back(a2);
     192        ctx.args.push_back(a3);
     193       
     194        return proto::eval(*this, ctx);
     195    }
     196
     197Although this works, it's not ideal because it doesn't warn users if they supply too many or too few arguments to a calculator expression. Consider the following mistakes:
     198
     199    (_1 * _1)(4, 2);  // Oops, too many arguments!
     200    (_2 * _2)(42);    // Oops, too few arguments!
     201
     202The expression `_1 * _1` defines a unary calculator expression; it takes one argument and squares it. If we pass more than one argument, the extra arguments will be silently ignored, which might be surprising to users. The next expression, `_2 * _2` defines a binary calculator expression; it takes two arguments, ignores the first and squares the second. If we only pass one argument, the code silently fills in `0.0` for the second argument, which is also probably not what users expect. What can be done?
     203
     204We can say that the /arity/ of a calculator expression is the number of arguments it expects, and it is equal to the largest placeholder in the expression. So, the arity of `_1 * _1` is one, and the arity of `_2 * _2` is two. We can increase the type-safety of our calculator DSEL by making sure the artiy of an expression equals the actual number of arguments supplied. Computing the artiy of an expression is simple with the help of Proto transforms.
    199205
    200206It's straightforward to describe in words how the arity of an expression should
    201 be calculated. First, we describe the arity of each of the 5 constituents in
    202 the calculator grammar.
     207be calculated. Consider that calculator expressions can be made of `_1`, `_2`, literals, unary expressions and binary expressions. The following table shows the arities for each of these 5 constituents.
    203208
    204209[table Calculator Sub-Expression Arities
     
    211216]
    212217
    213 The total arity of a calculator expression is found by recursively evaluating
    214 the arity of all of the sub-expressions and taking the maximum.
    215 
    216 Let's look at the sub-expression for the placeholder `_1`. It is matched by this
    217 part of our grammar: `proto::terminal< placeholder<0> >`. We want to associate this
    218 part of our grammar with an arity of `1`. We do that by attaching a transform.
    219 Since the arity of an expression can be evaluated at compile time, let's use
    220 `mpl::int_<1>` to represent the arity of the first placeholder. The following
    221 attaches a transform that always evaluates to `mpl::int_<1>`:
    222 
    223     proto::when< proto::terminal< placeholder<0> >, mpl::int_<1>() >
    224 
    225 This grammar rule will match any `placeholder<0>` terminal, and will transform it
    226 to a (default-constructed) `mpl::int_<1>` object. As described previously,
    227 `mpl::int_<1>()` is a function type, but Proto interprets it as an object to
    228 construct. We will have a similar transform to convert `placeholder<1>` terminals
    229 into `mpl::int_<2>`, and other terminals into `mpl::int_<0>`.
    230 
    231 Next, let's write a transform for unary operators that returns the arity of the
    232 operand. It is simply:
    233 
    234     proto::when< proto::unary_expr< _, CalcArity >, CalcArity(proto::_child) >
    235 
    236 The transform `CalcArity(proto::_child)` recursively applies the `CalcArity`
    237 transform to the child node of the unary expression. As you might have noticed,
    238 `CalcArity(proto::_child)` is another function type, but Proto interprets this one
    239 differently. Rather than trying to construct a `CalcArity` object, Proto
    240 knows this is a function object and invokes it instead.
     218Using this information, we can write the grammar for calculator expressions and attach transforms for computing the arity of each constituent. The code below computes the expression arity as a compile-time integer, using integral wrappers and metafunctions from the Boost MPL Library. The grammar is described below.
     219
     220[CalcArity]
     221
     222When we find a placeholder terminal or a literal, we use an /object transform/ such as `mpl::int_<1>()` to create a (default-constructed) compile-time integer representing the arity of that terminal.
     223
     224For unary expressions, we use `CalcArity(proto::_child)` which is a /callable transform/ that computes the arity of the expression's child.
     225
     226The transform for binary expressions has a few new tricks. Let's look more closely:
     227
     228    // Compute the left and right arities and
     229    // take the larger of the two.
     230    mpl::max<CalcArity(proto::_left),
     231             CalcArity(proto::_right)>()
     232
     233This is an object transform; it default-constructs ... what exactly? The `mpl::max<>` template is an MPL metafunction that accepts two compile-time integers. It has a nested `::type` typedef (not shown) that is the maximum of the two. But here, we appear to be passing it two things that are /not/ compile-time integers; they're Proto callable transforms. Proto is smart enough to recognize that fact. It first evaluates the two nested callable transforms, computing the arities of the left and right child expressions. Then it puts the resulting integers into `mpl::max<>` and evaluates the metafunction by asking for the nested `::type`. That is the type of the object that gets default-constructed and returned.
     234
     235More generally, when evaluating object transforms, Proto looks as the object type and checks whether it is a template specialization, like `mpl::max<>`. If it is, Proto looks for nested transforms that it can evaluate. After any nested transforms have been evaluated and substituted back into the template, the new template specialization is the result type, unless that type has a nested `::type`, in which case that becomes the result.
     236
     237Now that we can calculate the arity of a calculator expression, let's redefine the `calculator<>` expression wrapper we wrote in the Getting Started guide to use the `CalcArity` grammar and some macros from Boost.MPL to issue compile-time errors when users specify too many or too few arguments.
     238
     239    // The calculator expression wrapper, as defined in the Hello
     240    // Calculator example in the Getting Started guide. It behaves
     241    // just like the expression it wraps, but with extra operator()
     242    // member functions that evaluate the expression.
     243    //   NEW: Use the CalcArity grammar to ensure that the correct
     244    //   number of arguments are supplied.
     245    template<typename Expr>
     246    struct calculator
     247      : proto::extends<Expr, calculator<Expr>, calculator_domain>
     248    {
     249        typedef
     250            proto::extends<Expr, calculator<Expr>, calculator_domain>
     251        base_type;
     252
     253        calculator(Expr const &expr = Expr())
     254          : base_type(expr)
     255        {}
     256
     257        typedef double result_type;
     258
     259        // Use CalcArity to compute the arity of Expr:
     260        static int const arity = boost::result_of<CalcArity(Expr)>::type::value;
     261
     262        double operator()() const
     263        {
     264            BOOST_MPL_ASSERT_RELATION(0, ==, arity);
     265            calculator_context ctx;
     266            return proto::eval(*this, ctx);
     267        }
     268
     269        double operator()(double a1) const
     270        {
     271            BOOST_MPL_ASSERT_RELATION(1, ==, arity);
     272            calculator_context ctx;
     273            ctx.args.push_back(a1);
     274            return proto::eval(*this, ctx);
     275        }
     276
     277        // ... and additional operator() overloads to handle more arguments ...
     278    };
     279
     280Note the use of `boost::result_of<>` to access the return type of the `CalcArity` function object. Since we used compile-time integers in our transforms, the arity of the expression is encoded in the return type of the `CalcArity` function object. Proto grammars are valid TR1-style function objects, so you can use `boost::result_of<>` to figure out their return types.
     281
     282With our compile-time assertions in place, when users provide too many or too few arguments to a calculator expression, as in:
     283
     284    (_2 * _2)(42); // Oops, too few arguments!
     285
     286... they will get a compile-time error message on the line with the assertion that reads something like this[footnote This error message was generated with Microsoft Visual C++ 9.0. Different compilers will emit different messages with varying degrees of readability.]:
     287
     288[pre
     289c:\boost\org\trunk\libs\proto\scratch\main.cpp(97) : error C2664: 'boost::mpl::asse
     290rtion\_failed' : cannot convert parameter 1 from 'boost::mpl::failed \*\*\*\*\*\*\*\*\*\*\*\*boo
     291st::mpl::assert\_relation<x,y,\_\_formal>::\*\*\*\*\*\*\*\*\*\*\*\*' to 'boost::mpl::assert<false>
     292::type'
     293   with
     294   \[
     295       x\=1,
     296       y\=2,
     297       \_\_formal\=bool boost::mpl::operator\=\=(boost::mpl::failed,boost::mpl::failed)
     298   \]
     299]
     300
     301The point of this exercise was to show that we can write a fairly simple Proto grammar with embedded transforms that is declarative and readable and can compute interesting properties of arbitrarily complicated expressions. But transforms can do more than that. Boost.Xpressive uses transforms to turn expressions into finite state automata for matching regular expressions, and Boost.Spirit uses transforms to build recursive descent parser generators. Proto comes with a collection of built-in transforms that you can use to perform very sophisticated expression manipulations like these. In the next few sections we'll see some of them in action.
     302
     303[endsect]
     304
     305[/===============================================]
     306[section:state Transforms With State Accumulation]
     307[/===============================================]
     308
     309TODO
     310
     311[endsect]
    241312
    242313[/================================================]
    243 [note *Object Transforms vs. Callable Transforms*
    244 
    245 When using function types as Proto transforms, they can either represent an object
    246 to construct or a function to call. It is similar to C++ where the syntax `foo(x)`
    247 can either be interpreted as an object to construct or a function to call,
    248 depending on whether `foo` is a type or a function. Proto can't know in general
    249 which is the case, so it uses a trait, `proto::is_callable<>`, to differentiate.
    250 `is_callable< mpl::int_<1> >::value` is false so `mpl::int_<1>()` is an object to
    251 construct, but `is_callable< CalcArity >::value` is true so
    252 `CalcArity(proto::_child)` is a function to call.
    253 (`is_callable< CalcArity >::value` is true because `CalcArity` inherits from
    254 `proto::or_<>`, which is callable.)]
     314[section:data Passing Auxiliary Data To Transforms]
    255315[/================================================]
    256316
    257 [/
    258     That begs the question, what does `unary_expr<>`'s transform do? Well,
    259     `unary_expr< _, CalcArity >` has a default transform
    260     associated with it. It is a /pass-through/ transform. When an expression
    261     of the form `expr< T, list1< X > >` is passed to the transform, its `apply<>`
    262     member template will invoke the `CalcArity` transform (which we haven't
    263     completely defined yet -- patience) on `X` resulting in `Y`, and then
    264     reassemble the expression as `expr< T, list1< Y > >`.
    265 
    266     [note You may have noticed that Proto types like `unary_expr<>` serve several
    267     different but related roles. In particular, `unary_expr<>` is ...
    268 
    269     ... [*a metafunction]: `unary_expr<T, X>::type` is a typedef for
    270     `expr<T, list1<X> >`.
    271 
    272     ... [*a grammar]: `unary_expr<U, Y>` is a simle grammar that matches
    273     `expr<T, list1<X> >` if an only if `U` is `T` or `proto::_`, and `Y` is a
    274     grammar that matches `X`.
    275 
    276     ... [*a transform]: `unary_expr<U, Y>::apply<expr<T, list1<X> >, S, V>::type`
    277     applies `unary_expr<>`'s pass-through transform to `expr<T, list1<X> >` with
    278     state `S` and data `V`. The result is
    279     `expr<T, list1< Y::apply<X, S, V>::type > >`.
    280     ]
    281 
    282     So, putting a few things together, consider the calculator expression `+_1`,
    283     which would have the following type:
    284 
    285         expr< tag::unary_plus, list1<
    286             expr< tag::terminal, term< placeholder<0> > >
    287         > >
    288 
    289     If we executed the `unary_expr< _, CalcArity >` transform on this
    290     expression, we would expect to get:
    291 
    292         expr< tag::unary_plus, list1<
    293             mpl::int_<1>
    294         > >
    295 
    296     And if we added the `_child<>` transform also, as in
    297     `child< unary_expr< _, CalcArity > >`, we expect the result
    298     to be:
    299 
    300         mpl::int_<1>
    301 
    302     Which is exactly what we want.
    303 
    304     [note *Default Transforms*
    305 
    306     All the tools Proto provides for defining grammar rules have default transforms
    307     associated with them. Just as `unary_expr<>` has a pass-through transform,
    308     so too does `binary_expr<>`, `shift_right<>`, and all the others.
    309     `proto::or_<>` has a default transform which evaluates the transform of the
    310     branch that matched. `proto::and_<>`'s default transform evaluates the
    311     transform of the last branch. Even `proto::expr<>`, `proto::if_<>`,
    312     `proto::not_<>`, and `proto::_` have no-op default transforms that simply return
    313     unmodified the expressions passed to them.
    314     ]
    315 ]
    316 
    317 The arity of a binary operator is the maximum of the arity of the left and
    318 right operands. We can specify this with the help of `mpl::max<>`, which is a
    319 so-called metafunction that computes the maximum of two compile-time integers.
    320 The transform is described below:
    321 
    322     proto::when< proto::binary_expr< _, CalcArity, CalcArity >,
    323        mpl::max< CalcArity(proto::_left), CalcArity(proto::_right) >()
    324     >
    325 
    326 The above says to match binary calculator expressions and compute their
    327 arity by first computing the arity of the left and right children and then
    328 taking their maximum.
    329 
    330 [def _X_ [~X]]
    331 [def _Y_ [~Y]]
    332 [def _Z_ [~Z]]
    333 
    334 There's a lot going on in the above transform, so let's take it one piece
    335 at a time, starting with the parts we know. `CalcArity(proto::_left)`
    336 will calculate the arity of the left child, returning a compile-time integer.
    337 Likewise for `CalcArity(proto::_right)`. What is new is that these two
    338 transforms are nested within another: `mpl::max<...>()`. Proto notices that
    339 `mpl::max<...>` is not callable, so this transform is interpreted as an
    340 object to construct rather than a function to invoke. Using meta-programming
    341 tricks, Proto disassembles the `mpl::max<...>` template looking for nested
    342 Proto transforms to apply. It finds two and applies them, resulting in
    343 `mpl::max< mpl::int_<_X_>, mpl::int_<_Y_> >`.
    344 
    345 Having first applied any nested transforms, Proto then looks to see if
    346 `mpl::max< mpl::int_<_X_>, mpl::int_<_Y_> >` has a nested `::type` typedef.
    347 This is a common convention used by metafunctions. In this case,
    348 `mpl::max<...>::type` is a typedef for `mpl::int_< _Z_ >` where `_Z_` is the
    349 maximum of `_X_` and `_Y_`. The trailing `()` on the transform indicates that
    350 the result should be default-constructed, so this transform returns
    351 `mpl::int_<_Z_>()`. And we're done.
    352 
    353 [note Had `mpl::max<>` not had a nested `::type` typedef, the transform
    354 would have created and returned a default-constructed `mpl::max<>` object
    355 instead. That is, the result of substituting nested transforms need not
    356 of necessity have a nested `::type` typedef, but it is used if it is there.]
    357 
    358 Piecing it all together, the complete `CalcArity` looks like this:
    359 
    360 [CalcArity]
    361 
    362 We can use our `CalcArity` transform to calculate the arity of any
    363 calculator expression:
    364 
    365     CalcArity arity_of;
    366     std::cout << arity_of( proto::lit(100) * 20 ) << '\n';
    367     std::cout << arity_of( (_1 - _1) / _1 * 100 ) << '\n';
    368     std::cout << arity_of( (_2 - _1) / _2 * 100 ) << '\n';
    369 
    370 This displays the following:
    371 
    372 [pre
    373 0
    374 1
    375 2
    376 ]
    377 
    378 (Aside: the output statements use the fact that `mpl::int_<_X_>`
    379 has a conversion to `int(_X_)`.)
    380 
    381 [endsect]
    382 
    383 [/========================]
    384 [section Canned Transforms]
    385 [/========================]
    386 
    387 So far, we've seen how to write custom transforms using function types.
    388 These were implemented in terms of more primitive transforms provided by
    389 Proto, such as `_child`, `_left`, and `_right`. This section describes those
    390 transforms and others in detail.
    391 
    392 [/
    393 
    394 Why is this here??
    395 
    396 All the transforms defined in this section are of the following form:
    397 
    398 [def _some_transform_ [~some_transform]]
    399 
    400     struct _some_transform_ : proto::transform< _some_transform_ >
    401     {
    402         template<typename Expr, typename State, typename Date>
    403         struct impl : proto::transform_impl< Expr, State, Data >
    404         {
    405             typedef ... result_type;
    406 
    407             result_type operator()(
    408                 typename impl::expr_param expr
    409               , typename impl::state_param state
    410               , typename impl::data_param data
    411             ) const
    412             {
    413                 return ...;
    414             }
    415         };
    416     };
    417 
    418 So defined, `_some_transform_` is a transform "in the raw", just like
    419 `proto::_value` or `proto::_child`. These transforms are the building
    420 blocks from which you can compose larger transforms using function types.
    421 
    422 ]
    423 
    424 [section:child_c_and_friends [^_value], [^_child], [^_left], and [^_right]]
    425 
    426     namespace boost { namespace proto
    427     {
    428         struct _value;
    429 
    430         template<long N>
    431         struct _child_c;
    432 
    433         typedef _child_c<0> _child0;
    434         typedef _child_c<1> _child1;
    435         // ... up to BOOST_PROTO_MAX_ARITY-1
    436 
    437         typedef _child_c<0> _child;
    438         typedef _child_c<0> _left;
    439         typedef _child_c<1> _right;
    440     }}
    441 
    442 These transforms are useful for extracting the ['[^N]]th argument from an
    443 expression. The `_left` transform is equivalent to the `_child_c<0>` transform,
    444 and the `_right` transform is equivalent to the `_child_c<1>` transform. The
    445 `_value` transform extracts the value from a terminal expression.
    446 
    447 [table
    448     [   [Expression]
    449         [Returns]
    450     ]
    451     [   [`boost::result_of<proto::_value(Expr, State, Data)>::type`]
    452         [`proto::result_of::value<Expr>::type`]
    453     ]
    454     [   [`proto::_value()(expr, state, data)`]
    455         [`proto::value(expr)`]
    456     ]
    457     [   [`boost::result_of<proto::_child_c<N>(Expr, State, Data)>::type`]
    458         [`proto::result_of::child_c<Expr, N>::type`]
    459     ]
    460     [   [`proto::_child_c<N>()(expr, state, data)`]
    461         [`proto::child_c<N>(expr)`]
    462     ]
    463     [   [`boost::result_of<proto::_left(Expr, State, Data)>::type`]
    464         [`proto::result_of::left<Expr>::type`]
    465     ]
    466     [   [`proto::_left()(expr, state, data)`]
    467         [`proto::left(expr)`]
    468     ]
    469     [   [`boost::result_of<proto::_right(Expr, State, Data)>::type`]
    470         [`proto::result_of::right<Expr>::type`]
    471     ]
    472     [   [`proto::_right()(expr, state, data)`]
    473         [`proto::right(expr)`]
    474     ]
    475 ]
    476 
    477 Example:
    478 
    479     // Matches an integer terminal and extracts the int.
    480     struct Int
    481       : when< terminal<int>, _value >
    482     {};
    483 
    484 [endsect]
    485 
    486 [section:identity_and_friends [^_expr], [^_state] and [^_data]]
    487 
    488     namespace boost { namespace proto
    489     {
    490         struct _expr;
    491         struct _state;
    492         struct _data;
    493     }}
    494 
    495 The `_expr`, `_state` and `_data` transforms merely return the
    496 `expr`, `state` and `data` arguments, respectively. Proto's
    497 wildcard pattern, `_`, behaves like `_expr` when used
    498 as a transform.
    499 
    500 [table
    501     [   [Expression]
    502         [Returns]
    503     ]
    504     [   [`boost::result_of<proto::_(Expr, State, Data)>::type`]
    505         [`Expr`]
    506     ]
    507     [   [`proto::_()(expr, state, data)`]
    508         [`expr`]
    509     ]
    510     [   [`boost::result_of<proto::_expr(Expr, State, Data)>::type`]
    511         [`Expr`]
    512     ]
    513     [   [`proto::_expr()(expr, state, data)`]
    514         [`expr`]
    515     ]
    516     [   [`boost::result_of<proto::_state(Expr, State, Data)>::type`]
    517         [`State`]
    518     ]
    519     [   [`proto::_state()(expr, state, data)`]
    520         [`state`]
    521     ]
    522     [   [`boost::result_of<proto::_data(Expr, State, Data)>::type`]
    523         [`Data`]
    524     ]
    525     [   [`proto::_data()(expr, state, data)`]
    526         [`data`]
    527     ]
    528 ]
    529 
    530 Example:
    531 
    532     // Matches a subscript expression where the left- and right-hand operands
    533     // match MyGrammar, returns the expression unmodified
    534     struct Subscript
    535       : proto::when< proto::subscript<MyGrammar, MyGrammar>, proto::_expr >
    536     {};
    537 
    538 [endsect]
    539 
    540 [section:if [^if_<>]]
    541 
    542     namespace boost { namespace proto
    543     {
    544         namespace control
    545         {
    546             template<
    547                 typename If
    548               , typename Then = _
    549               , typename Else = not_<_>
    550             >
    551             struct if_;
    552         }
    553 
    554         using control::if_;
    555     }}
    556 
    557 We've already seen the _if_ template in the context of grammars, but
    558 _if_ can also be used as a transform. It can be used to conditionally
    559 apply one transform or another based on some condition. The three
    560 template parameters are Proto transforms. The result of applying the
    561 first transform should be a compile-time Boolean. If it is true, then
    562 the first transform is applied. The second is applied otherwise.
    563 
    564 [table
    565     [   [Expression]
    566         [Returns]
    567     ]
    568     [   [``boost::result_of<
    569     proto::if_<If, Then, Else>(Expr, State, Data)
    570 >::type``]
    571         [``typedef
    572     mpl::if_<
    573         boost::result_of<proto::when<_, If>(Expr, State, Data)>::type
    574       , proto::when<_, Then>
    575       , proto::when<_, Else>
    576     >::type
    577 branch;
    578 
    579 typedef boost::result_of<branch(Expr, State, Data)>::type type;``]
    580     ]
    581     [   [`proto::if_<If, Then, Else>()(expr, state, data)`]
    582         [``typedef ... branch; // Same as above
    583 branch()(expr, state, data);``]
    584     ]
    585 ]
    586 
    587 Example:
    588 
    589     // Match a terminal. If size of the terminal
    590     // argument is less than or equal to 4, make
    591     // a new terminal that stores the argument by
    592     // value. Otherwise, store the argument by
    593     // reference.
    594     struct ByValOrRef
    595       : proto::when<
    596             proto::terminal<_>
    597           , proto::if_<
    598                 mpl::less_equal<
    599                     mpl::sizeof_<proto::_value>
    600                   , mpl::size_t<4>
    601                 >()
    602               , proto::_make_terminal(proto::_value)
    603               , proto::_make_terminal(proto::_ref(proto::_value))
    604             >
    605         >
    606     {};
    607 
    608 [endsect]
    609 
    610 [section:and_or_not [^and_<>], [^or_<>], and [^not_<>]]
    611 
    612     namespace boost { namespace proto
    613     {
    614         namespace control
    615         {
    616             template<typename... T>
    617             struct and_;
    618 
    619             template<typename... T>
    620             struct or_;
    621 
    622             template<typename T>
    623             struct not_;
    624         }
    625 
    626         using control::and_;
    627         using control::or_;
    628         using control::not_;
    629     }}
    630 
    631 As with _if_, the grammar elements _and_, _or_, and _not_ can
    632 also be used as transforms. At a high level, here is what the
    633 transforms do:
    634 
    635 [variablelist
    636 [ [`and_<T0,T1,...,Tn>`]
    637   [Apply the transform `Tn`.] ]
    638 [ [`or_<T0,T1,...,Tn>`]
    639   [Apply the transform `Tx` where `x` is the lowest number
    640    such that `matches<Expr,Tx>::value` is `true`.] ]
    641 [ [`not_<T>`] [Return the current expression unchanged.] ]
    642 ]
    643 
    644 The following table specifies the behaviors described above more
    645 precisely.
    646 
    647 [table
    648     [   [Expression]
    649         [Returns]
    650     ]
    651     [   [``boost::result_of<
    652     proto::and_<A,B,C>(Expr, State, Data)
    653 >::type``]
    654         [`boost::result_of<C(Expr, State, Data)>::type`]
    655     ]
    656     [   [`proto::and_<A,B,C>()(expr, state, data)`]
    657         [`C()(expr, state, data)`]
    658     ]
    659     [   [``boost::result_of<
    660     proto::or_<A,B,C>(Expr, State, Data)
    661 >::type``]
    662         [``typedef mpl::if_<
    663     proto::matches<Expr, A>
    664   , A
    665   , mpl::if_<
    666         proto::matches<Expr, B>
    667       , B
    668       , C
    669     >::type
    670 >::type which;
    671 
    672 typedef boost::result_of<which(Expr, State, Data)>::type type;``]
    673     ]
    674     [   [`proto::or_<A,B,C>()(expr, state, data)`]
    675         [``typedef ... which; // Same as above
    676 which()(expr, state, data);``]
    677     ]
    678     [   [``boost::result_of<
    679     proto::not_<A>(Expr, State, Data)
    680 >::type``]
    681         [`Expr`]
    682     ]
    683     [   [`proto::not_<A>()(expr, state, data)`]
    684         [`expr`]
    685     ]
    686 ]
    687 
    688 Example:
    689 
    690     // A transform that matches any expression and
    691     // unwraps any reference_wrapped terminals it
    692     // finds.
    693     struct UnwrapReference
    694       : proto::or_<
    695             // Pass through terminals that are not
    696             // reference_wrappers unchanged:
    697             proto::and_<
    698                 proto::terminal<_>
    699               , proto::not_<proto::if_<boost::is_reference_wrapper<proto::_value>()> >
    700             >
    701             // For other terminals (i.e., reference_wrapper
    702             // terminals), unwrap the reference:
    703           , proto::when<
    704                 proto::terminal<_>
    705               , proto::terminal<boost::unwrap_reference<proto::_value> >(proto::_value)
    706             >
    707             // Otherwise, match non-terminals and
    708             // recurse.
    709           , proto::when<
    710                 proto::nary_expr<_, proto::vararg<UnwrapReference> >
    711             >
    712         >
    713     {};
    714 
    715 The above transform serves to illustrate the behaviors of the _and_,
    716 _or_, and _not_ transforms, but it is admittedly contrived. The
    717 transform is more easily written as follows:
    718 
    719     // Functionally identical to the UnwrapReference
    720     // transform above:
    721     struct UnwrapReference
    722       : proto::or_<
    723             proto::when<
    724                 proto::terminal<boost::reference_wrapper<_> >
    725               , proto::terminal<boost::unwrap_reference<proto::_value> >(proto::_value)
    726             >
    727           , proto::terminal<_>
    728           , proto::nary_expr<_, proto::vararg<UnwrapReference> >
    729         >
    730     {};
    731 
    732 [endsect]
    733 
    734 [section:call [^call<>]]
    735 
    736 [def __CALLABLE__ [~[^Callable]]]
    737 
    738     namespace boost { namespace proto
    739     {
    740         template<typename Fun>
    741         struct call;
    742     }}
    743 
    744 The `call<>` transform is used to invoke callable transforms and evaluate
    745 their arguments. When you use a callable transform as in
    746 `when< unary_plus<_>, __CALLABLE__(_child) >`, the `call<>` transform is used behind
    747 the scenes to evaluate `__CALLABLE__(_child)`. In fact, for any callable
    748 transform, the following short- and long-forms are equivalent:
    749 
    750 [table
    751     [ [Short From]
    752       [Long Form] ]
    753     [ [ `proto::when< Grammar, __CALLABLE__(Tran1, Tran2...) >` ]
    754       [ `proto::when< Grammar, proto::call< __CALLABLE__(Tran1, Tran2...) > >` ] ]
    755 ]
    756 
    757 You might decide to use `call<>` explicitly in cases when Proto can't figure out
    758 that a given transform is callable. (See the discussion on the `is_callable<>` trait
    759 [link boost_proto.users_guide.expression_transformation.is_callable here].)
    760 Rather than specialize `proto::is_callable<>` for your transform, you can simply
    761 wrap its use in `call<>`, instead.
    762 
    763 [tip For users of legacy compilers like MSVC 7.1, `call<>` is useful to work
    764 around compiler bugs. Doubly-nested transforms such as `__CALLABLE__(_child1(_child2))`
    765 cause older compilers problems, but the equivalent `__CALLABLE__(call<_child1(_child2)>)`
    766 solves the problem.]
    767 
    768 The semantics of `call<>` are described in the table below:
    769 
    770 [table
    771     [   [Expression]
    772         [Returns]
    773     ]
    774     [   [`boost::result_of<proto::call<Fun(A0, A1, ... AN)>(Expr, State, Data)>::type`]
    775         [``boost::result_of<Fun(
    776     boost::result_of<proto::when<_, A0>(Expr, State, Data)>::type
    777   , boost::result_of<proto::when<_, A1>(Expr, State, Data)>::type
    778     ...
    779   , boost::result_of<proto::when<_, AN>(Expr, State, Data)>::type
    780 )>::type``]
    781     ]
    782     [   [`proto::call<Fun(A0, A1, ... AN)>()(expr, state, data)`]
    783         [``Fun()(
    784     proto::when<_, A0>()(expr, state, data)
    785   , proto::when<_, A1>()(expr, state, data)
    786     ...
    787   , proto::when<_, AN>()(expr, state, data)
    788 )``]
    789     ]
    790 ]
    791 
    792 The target of a callable transform can be any function object that implements
    793 the Boost.ResultOf protocol. Function objects that take up to
    794 `BOOST_PROTO_MAX_ARITY` are handled.
    795 
    796 For callable transforms that take 0, 1, or 2 arguments, special handling is done
    797 to see if the transform actually expects 3 arguments, as Proto's primitive
    798 transforms do. (This can be detected with meta-programming tricks.) So, even
    799 though a transform like `_child1` requires three parameters: expression,
    800 state and data; it can be "called" with just one, like `_child1(_child2)`. Proto
    801 treats this as if were `call<_child1(_child2, _state, _data)>`.
    802 
    803 If no transform arguments are specified at all, as in `call<_child1>`, this is
    804 the same as `_child1`. For this reason, `call<_child1>(_child2)` is the same as
    805 `call<_child1(_child2)>`.
    806 
    807 Example:
    808 
    809 [LazyMakePair2]
    810 
    811 [endsect]
    812 
    813 [section:make [^make<>]]
    814 
    815 [def __OBJECT__ [~[^Object]]]
    816 
    817     namespace boost { namespace proto
    818     {
    819         template<typename Fun>
    820         struct make;
    821     }}
    822 
    823 The `make<>` transform is used to construct objects and evaluate
    824 their constructor arguments. When you use an object transform as in
    825 `when< unary_plus<_>, __OBJECT__(_child) >`, the `make<>` transform is used behind
    826 the scenes to evaluate `__OBJECT__(_child)`. In fact, for any object
    827 transform, the following short- and long-forms are equivalent:
    828 
    829 [table
    830     [ [Short From]
    831       [Long Form] ]
    832     [ [ `proto::when< Grammar, __OBJECT__(Tran1, Tran2...) >` ]
    833       [ `proto::when< Grammar, proto::make< __OBJECT__(Tran1, Tran2...) > >` ] ]
    834 ]
    835 
    836 You might decide to use `make<>` to explicitly differentiate object
    837 transforms from callable transforms. (See `call<>`.)
    838 
    839 [tip For users of legacy compilers like MSVC 7.1, `make<>` is useful to work
    840 around compiler bugs. Doubly-nested transforms such as `Object1(Object2(_child))`
    841 cause older compilers problems, but the equivalent `Object1(make<Object2(_child)>)`
    842 solves the problem.]
    843 
    844 The `make<>` transform checks to see if the resulting object type is a template.
    845 If it is, the template type is disassembled to find nested transforms. Proto
    846 considers the following types to represent transforms:
    847 
    848 [def __type__ [~type]]
    849 [def __X__  X\']
    850 [def __X0__ X0\']
    851 [def __X1__ X1\']
    852 [def __MakeImpl__ [~[^MakeImpl]]]
    853 
    854 * Function types
    855 * Function pointer types
    856 * Types for which `proto::is_callable<__type__>::value` is `true`
    857 
    858 When an object transform with a template type such as
    859 `Object<X0,X1,...>(Args...)` is evaluated with a given
    860 `Expr`, `State`, and `Data`, the result type is
    861 `__MakeImpl__<Object<X0,X1,...>, Expr, State, Data>::type` which is
    862 defined as follows. For each `X` in `X0,X1,...`, do:
    863 
    864 * If `X` is a transform, then let `__X__` be
    865   `boost::result_of<proto::when<_, X>(Expr, State, Data)>::type`.
    866   Note that a substitution took place.
    867 * Otherwise, if `X` is a template like `Object2<Y0,Y1,...>`, then
    868   let `__X__` be `__MakeImpl__<Object2<Y0,Y1,...>, Expr, State, Data>::type`
    869   (which evaluates this procedure recursively). Note whether any
    870   substitutions took place during this operation.
    871 * Otherwise, let `__X__` be `X`, and note that no substitution
    872   took place.
    873 * If any substitutions took place in any of the above steps and
    874   `Object<__X0__,__X1__,...>` has a nested `::type` typedef, the
    875   result type is `Object<__X0__,__X1__,...>::type`.
    876 * Otherwise, the result type is `Object<__X0__,__X1__,...>`.
    877 
    878 Note that `when<>` is implemented in terms of `call<>` and `make<>`,
    879 so the above procedure is evaluated recursively.
    880 
    881 Given the above description of the `__MakeImpl__<>` helper, the semantics
    882 of the `make<>` transform is described as follows:
    883 
    884 [def __AN__ A[~N]]
    885 
    886 [table
    887     [   [Expression]
    888         [Returns]
    889     ]
    890     [   [`boost::result_of<proto::make<Object(A0, A1, ... __AN__)>(Expr, State, Data)>::type`]
    891         [`__MakeImpl__<Object, Expr, State, Data>::type`]
    892     ]
    893     [   [`proto::make<Object(A0, A1, ... __AN__)>()(expr, state, data)`]
    894         [``__MakeImpl__<Object, Expr, State, Data>::type(
    895     proto::when<_, A0>()(expr, state, data)
    896   , proto::when<_, A1>()(expr, state, data)
    897     ...
    898   , proto::when<_, __AN__>()(expr, state, data)
    899 )``]
    900     ]
    901 ]
    902 
    903 Objects with constructors that take up to `BOOST_PROTO_MAX_ARITY` are handled.
    904 Some types are so-called /aggregates/ that do not have constructors; rather,
    905 they use /aggregate initialization/. For these types, you can specialize
    906 `proto::is_aggregate<>` and Proto will use a brace initializer list to
    907 initialize the object rather than a constructor. Proto knows that `proto::expr<>`
    908 is such an aggregate, so if you use object transforms to "construct" a
    909 new node in an expression tree, the right thing happens.
    910 
    911 If no transform arguments are specified at all, as in `make<Object>`, this is
    912 the same as `make<Object()>`.
    913 
    914 Example:
    915 
    916 [LazyMakePair]
    917 
    918 [endsect]
    919 
    920 [section:lazy [^lazy<>]]
    921 
    922     namespace boost { namespace proto
    923     {
    924         template<typename Fun>
    925         struct lazy;
    926     }}
    927 
    928 Sometimes you would like a higher-order transform that returns another
    929 transform to be evaluated. This can happen when you have a transform
    930 whose behavior needs to be parameterized on the current state of the
    931 transformation. For these situations, you can use the `lazy<>` transform,
    932 which is essentially an invocation of the `make<>` transform (to evaluate
    933 any nested transforms and create the higher-order transform) followed
    934 by an invocation of `call<>` (to actually execute the higher-order
    935 transform).
    936 
    937 The behavior of `lazy<>` is easily specified in terms of `make<>` and
    938 `call<>`.
    939 
    940 [table
    941     [   [Expression]
    942         [Returns]
    943     ]
    944     [   [`boost::result_of<proto::lazy<Object(A0, A1, ... __AN__)>(Expr, State, Data)>::type`]
    945         [``boost::result_of<proto::call<
    946     boost::result_of<proto::make<Object>(Expr, State, Data)>::type(A0, A1, ... __AN__)
    947 >(Expr, State, Data)>::type``]
    948     ]
    949     [   [`proto::lazy<Object(A0, A1, ... __AN__)>()(expr, state, data)`]
    950         [``proto::call<
    951     boost::result_of<proto::make<Object>(Expr, State, Data)>::type(A0, A1, ... __AN__)
    952 >()(expr, state, data)``]
    953     ]
    954 ]
    955 
    956 If no transform arguments are specified at all, as in `lazy<Object>`, this is
    957 the same as `lazy<Object(_expr, _state, _data)>`.
    958 
    959 [endsect]
    960 
    961 [section:when [^when<>]]
    962 
    963     namespace boost { namespace proto
    964     {
    965         template<typename Grammar, typename Transform = Grammar>
    966         struct when;
    967     }}
    968 
    969 `when<>` associates a grammar rule with a transform. It can be used
    970 in a grammar in place of the rule; that is, it behaves as a grammar
    971 rule. Expression tree nodes that match the grammar rule are processed
    972 with the associated transform; that is, `when<>` also behaves like
    973 a transform.
    974 
    975 When no transform is specified, as with `when< unary_plus<Calculator> >`,
    976 the grammar is treated as the transform. Every grammar element has
    977 a default transform. For most, such as `unary_plus<>`, the default transform
    978 is `pass_through<>`.
    979 
    980 The `when<>` transform is easily specified in terms of `call<>`,
    981 `make<>`, and the `is_callable<>` trait.
    982 
    983 [table
    984     [   [Expression]
    985         [Returns]
    986     ]
    987     [   [`boost::result_of<proto::when<Grammar, R(A0, A1, ... __AN__)>(Expr, State, Data)>::type`]
    988         [``boost::result_of<boost::mpl::if_<
    989     proto::is_callable<R>
    990   , proto::call<R(A0, A1, ... __AN__)>
    991   , proto::make<R(A0, A1, ... __AN__)>
    992 >::type(Expr, State, Data)>::type``]
    993     ]
    994     [   [`proto::when<Grammar, R(A0, A1, ... __AN__)>()(expr, state, data)`]
    995         [``boost::mpl::if_<
    996     proto::is_callable<R>
    997   , proto::call<R(A0, A1, ... __AN__)>
    998   , proto::make<R(A0, A1, ... __AN__)>
    999 >::type()(expr, state, data)``]
    1000     ]
    1001 ]
    1002 
    1003 If no transform arguments are specified, as in `when<Grammar, _child>`, the
    1004 transform is assumed to be callable; that is, it is equivalent to
    1005 `when<Grammar, call<_child> >`.[footnote It is done this way to improve compile
    1006 times.]
    1007 
    1008 [endsect]
    1009 
    1010 [section:fold [^fold<>] and [^reverse_fold<>]]
    1011 
    1012     namespace boost { namespace proto
    1013     {
    1014         template<typename Sequence, typename State0, typename Fun>
    1015         struct fold;
    1016 
    1017         template<typename Sequence, typename State0, typename Fun>
    1018         struct reverse_fold;
    1019     }}
    1020 
    1021 The transforms `fold<>` and `reverse_fold<>` are akin to the
    1022 `std::accumulate()` algorithm in the STL, or the `fold()` algorithm in
    1023 Boost.Fusion. They iterate over some sequence and
    1024 accumulate some state at each element. The `fold<>`
    1025 transform iterates over the children in order, starting with the 0th child.
    1026 The `reverse_fold<>` transform does it in reverse order, starting with the Nth
    1027 child. (Note that for building things like cons lists, you'll often want to
    1028 built it back-to-front with `reverse_fold<>`.)
    1029 
    1030 Both `fold<>` and `reverse_fold<>` are implemented in terms of `fusion::fold<>`.
    1031 The three template parameters must each be Proto transforms. The have the following
    1032 meaning:
    1033 
    1034 * `Sequence`: A Proto transform that returns a Fusion sequence.
    1035 * `State`: A Proto transform that returns the initial state of the fold.
    1036 * `Fun`: A Proto transform representing the operation to perform at each
    1037   iteration of the fold algorithm.
    1038 
    1039 Often, the `Sequence` parameter is `proto::_`, which returns the current node
    1040 in the Proto expression tree. Tree nodes are valid Fusion sequences, where
    1041 the children are the elements of the sequence.
    1042 
    1043 [def __AS_CALLABLE__ [~[^AsCallable]]]
    1044 
    1045 The semantics of the `fold<>` and `reverse_fold<>` transforms can both be
    1046 understood in terms of a helper struct, `__AS_CALLABLE__<>`, which binds the
    1047 data and the `Fun` transform into a binary function object for use by
    1048 `fusion::fold()`. `__AS_CALLABLE__<>` has the following behavior:
    1049 
    1050 [table
    1051     [   [Expression]
    1052         [Returns]
    1053     ]
    1054     [   [`boost::result_of<__AS_CALLABLE__<Fun, Data>(Expr, State)>::type`]
    1055         [`boost::result_of<proto::when<_, Fun>(Expr, State, Data)>::type`]
    1056     ]
    1057     [   [`__AS_CALLABLE__<Fun, Data>(data)(expr, state)`]
    1058         [`proto::when<_, Fun>()(expr, state, data)`]
    1059     ]
    1060 ]
    1061 
    1062 With the above `__AS_CALLABLE__<>` adaptor, `fold<>` and `reverse_fold<>`
    1063 can be easily implemented in terms of `fusion::fold<>`:
    1064 
    1065 [table
    1066     [   [Expression]
    1067         [Returns]
    1068     ]
    1069     [   [`boost::result_of<proto::fold<Sequence, State0, Fun>(Expr, State, Data)>::type`]
    1070         [``fusion::result_of::fold<
    1071     boost::result_of<proto::when<_, Sequence>(Expr, State, Data)>::type
    1072   , boost::result_of<proto::when<_, State0>(Expr, State, Data)>::type
    1073   , __AS_CALLABLE__<Fun, Data>
    1074 >::type``]
    1075     ]
    1076     [   [`proto::fold<Sequence, State0, Fun>()(expr, state, data)`]
    1077         [``fusion::fold(
    1078     proto::when<_, Sequence>()(expr, state, data)
    1079   , proto::when<_, State0>()(expr, state, data)
    1080   , __AS_CALLABLE__<Fun, Data>(data)
    1081 )``]
    1082     ]
    1083     [   [`boost::result_of<proto::reverse_fold<Sequence, State0, Fun>(Expr, State, Data)>::type`]
    1084         [``fusion::result_of::fold<
    1085     fusion::result_of::reverse<
    1086         boost::result_of<proto::when<_, Sequence>(Expr, State, Data)>::type
    1087     >::type
    1088   , boost::result_of<proto::when<_, State0>(Expr, State, Data)>::type
    1089   , __AS_CALLABLE__<Fun, Data>
    1090 >::type``]
    1091     ]
    1092     [   [`proto::reverse_fold<Sequence, State0, Fun>()(expr, state, data)`]
    1093         [``fusion::fold(
    1094     fusion::reverse(
    1095         proto::when<_, Sequence>()(expr, state, data)
    1096     )
    1097   , proto::when<_, State0>()(expr, state, data)
    1098   , __AS_CALLABLE__<Fun, Data>(data)
    1099 )``]
    1100     ]
    1101 ]
    1102 
    1103 [#reverse_fold_example]Example:
    1104 
    1105 [AsArgList]
    1106 
    1107 [endsect]
    1108 
    1109 [section:fold_tree [^fold_tree<>] and [^reverse_fold_tree<>]]
    1110 
    1111     namespace boost { namespace proto
    1112     {
    1113         template<typename Sequence, typename State0, typename Fun>
    1114         struct fold_tree;
    1115 
    1116         template<typename Sequence, typename State0, typename Fun>
    1117         struct reverse_fold_tree;
    1118     }}
    1119 
    1120 The `fold_tree<>` and `reverse_fold_tree<>` transforms recursively apply the
    1121 `fold<>` and `reverse_fold<>` transforms to sub-trees that all share a common
    1122 tag type. This is useful for flattening trees into lists; for example, you
    1123 might use `reverse_fold_tree<>` to flatten an expression tree like `a | b | c`
    1124 into a Fusion list like `cons(a, cons(b, cons(c)))`.
    1125 
    1126 The `fold_tree<>` and `reverse_fold_tree<>` transforms are unlike the other
    1127 transforms that Proto provides in that they operate on entire sub-trees rather
    1128 than just single nodes within the tree.
    1129 
    1130 [def __FOLD_TREE_IMPL__ [~[^FoldTreeImpl]]]
    1131 [def __REVERSE_FOLD_TREE_IMPL__ [~[^ReverseFoldTreeImpl]]]
    1132 
    1133 These are higher-level transforms, implemented in terms of the `fold<>`
    1134 and `reverse_fold<>` transforms and helper structs `__FOLD_TREE_IMPL__<>` and
    1135 `__REVERSE_FOLD_TREE_IMPL__<>`, one of which is shown below:
    1136 
    1137     // FoldTreeImpl either recurses into the expression, if its Grammar
    1138     // matches, or else ends the recursion by matching Grammar and
    1139     // applying its transform.
    1140     template<typename Grammar, typename Fun>
    1141     struct __FOLD_TREE_IMPL__
    1142       : proto::or_<
    1143             proto::when<Grammar, proto::fold<_, proto::_state, __FOLD_TREE_IMPL__<Grammar, Fun> > >
    1144           , proto::when<_, Fun>
    1145         >
    1146     {};
    1147 
    1148 The `__REVERSE_FOLD_TREE_IMPL__<>` helper is specified similarly, only with
    1149 `reverse_fold<>` instead of `fold<>`. With these two helpers, we can
    1150 specify the behavior of `fold_tree<>` and `reverse_fold_tree<>` as
    1151 follows:
    1152 
    1153 [table
    1154     [   [Expression]
    1155         [Returns]
    1156     ]
    1157     [   [``boost::result_of<
    1158     proto::fold_tree<Sequence, State0, Fun>(Expr, State, Data)
    1159 >::type``]
    1160         [``boost::result_of<
    1161     proto::fold<
    1162         Sequence
    1163       , State0
    1164       , __FOLD_TREE_IMPL__<
    1165             proto::nary_expr<Expr::proto_tag, proto::vararg<_> >
    1166           , Fun
    1167         >
    1168     >(Expr, State, Data)
    1169 >::type``]
    1170     ]
    1171     [   [`proto::fold_tree<Sequence, State0, Fun>()(expr, state, data)`]
    1172         [``proto::fold<
    1173     Sequence
    1174   , State0
    1175   , __FOLD_TREE_IMPL__<
    1176         proto::nary_expr<Expr::proto_tag, proto::vararg<_> >
    1177       , Fun
    1178     >
    1179 >()(expr, state, data)``]
    1180     ]
    1181     [   [``boost::result_of<
    1182     proto::reverse_fold_tree<Sequence, State0, Fun>(Expr, State, Data)
    1183 >::type``]
    1184         [``boost::result_of<
    1185     proto::reverse_fold<
    1186         Sequence
    1187       , State0
    1188       , __REVERSE_FOLD_TREE_IMPL__<
    1189             proto::nary_expr<Expr::proto_tag, proto::vararg<_> >
    1190           , Fun
    1191         >
    1192     >(Expr, State, Data)
    1193 >::type``]
    1194     ]
    1195     [   [`proto::reverse_fold_tree<Sequence, State0, Fun>()(expr, state, data)`]
    1196         [``proto::reverse_fold<
    1197     Sequence
    1198   , State0
    1199   , __REVERSE_FOLD_TREE_IMPL__<
    1200         proto::nary_expr<Expr::proto_tag, proto::vararg<_> >
    1201       , Fun
    1202     >
    1203 >()(expr, state, data)``]
    1204     ]
    1205 ]
    1206 
    1207 Example:
    1208 
    1209 [FoldTreeToList]
    1210 
    1211 [endsect]
    1212 
    1213 [section:pass_through [^pass_through<>]]
    1214 
    1215     namespace boost { namespace proto
    1216     {
    1217         template<typename Grammar>
    1218         struct pass_through;
    1219     }}
    1220 
    1221 The `pass_through<>` transform iterates over the pairs of
    1222 children in the grammar and the expression, applying the child grammar's
    1223 transform to the corresponding child expression. The resulting transformed
    1224 children expressions are reassembled back into an expression of the same
    1225 type as the parent expression.
    1226 
    1227 As a side-effect, `pass_through<>` transforms all sub-expressions held by
    1228 reference into ones held by value.
    1229 
    1230 Note that all expression generator metafunctions (Eg., `unary_plus<>`,
    1231 `shift_right<>`, `function<>`, `nary_expr<>`, etc.) have a pass-through
    1232 transform by default, so there is rarely any need to use the `pass_through<>`
    1233 transform explicitly.
    1234 
    1235 [table
    1236     [   [Expression]
    1237         [Returns]
    1238     ]
    1239     [   [``boost::result_of<
    1240     proto::pass_through<Grammar>(Expr, State, Data)
    1241 >::type``]
    1242         [``proto::nary_expr<
    1243     Expr::proto_tag
    1244   , boost::result_of<Grammar::proto_child0(Expr::proto_child0, State, Data)>::type
    1245   , boost::result_of<Grammar::proto_child1(Expr::proto_child1, State, Data)>::type
    1246     // ...
    1247   , boost::result_of<Grammar::proto_childN(Expr::proto_childN, State, Data)>::type
    1248 >::type``]
    1249     ]
    1250     [   [`proto::pass_through<Grammar>()(expr, state, data)`]
    1251         [``proto::make_expr<Expr::proto_tag>(
    1252     Grammar::proto_child0()(proto::child_c<0>(expr), state, data)
    1253     Grammar::proto_child1()(proto::child_c<1>(expr), state, data)
    1254     // ...
    1255     Grammar::proto_childN()(proto::child_c<N>(expr), state, data)
    1256 )``]
    1257     ]
    1258 ]
    1259 
    1260 Example:
    1261 
    1262 [Promote]
    1263 
    1264 [endsect]
     317TODO
     318
     319[endsect]
     320
     321[/===========================================]
     322[section:built_in Proto's Built-In Transforms]
     323[/===========================================]
     324
     325TODO
    1265326
    1266327[endsect]
    1267328
    1268329[/======================================================]
    1269 [section:user_defined_transforms User-Defined Transforms]
     330[section:primitives Building Custom Primitive Transforms]
    1270331[/======================================================]
    1271332
    1272 In previous sections, we've seen how to compose larger transforms
    1273 out of smaller transforms using function types. The smaller transforms
    1274 from which larger transforms are composed are /primitive transforms/,
    1275 and Proto provides a bunch of common ones such as `_child0` and `_value`.
    1276 In this section we'll see how to author your own primitive transforms.
    1277 
    1278 [note There are a few reasons why you might want to write your own
    1279 primitive transforms. For instance, your transform may be complicated,
    1280 and composing it out of primitives becomes unwieldy. You might also need
    1281 to work around compiler bugs on legacy compilers that makes
    1282 composing transforms using function types problematic. Finally,
    1283 you might also decide to define your own primitive transforms
    1284 to improve compile times. Since Proto can simply invoke a
    1285 primitive transform directly without having to process arguments
    1286 or differentiate callable transforms from object transforms,
    1287 primitive transforms are more efficient.]
     333In previous sections, we've seen how to compose larger transforms out of smaller transforms using function types. The smaller transforms from which larger transforms are composed are /primitive transforms/, and Proto provides a bunch of common ones such as `_child0` and `_value`. In this section we'll see how to author your own primitive transforms.
     334
     335[note There are a few reasons why you might want to write your own primitive transforms. For instance, your transform may be complicated, and composing it out of primitives becomes unwieldy. You might also need to work around compiler bugs on legacy compilers that makes composing transforms using function types problematic. Finally, you might also decide to define your own primitive transforms to improve compile times. Since Proto can simply invoke a primitive transform directly without having to process arguments or differentiate callable transforms from object transforms, primitive transforms are more efficient.]
    1288336
    1289337[def _N_ [~N]]
    1290338
    1291 Primitive transforms inherit from `proto::transform<>`
    1292 and have a nested `impl<>` template that inherits from
    1293 `proto::transform_impl<>`. For example, this is how Proto
    1294 defines the `_child_c<_N_>` transform, which returns the
    1295 _N_-th child of the current expression:
     339Primitive transforms inherit from `proto::transform<>` and have a nested `impl<>` template that inherits from `proto::transform_impl<>`. For example, this is how Proto defines the `_child_c<_N_>` transform, which returns the _N_-th child of the current expression:
    1296340
    1297341    namespace boost { namespace proto
     
    1329373    }}
    1330374
    1331 The `proto::transform<>` base class provides the `operator()` overloads
    1332 and the nested `result<>` template that make your transform a valid
    1333 function object. These are implemented in terms of the nested `impl<>`
    1334 template you define.
    1335 
    1336 The `proto::transform_impl<>` base class is a convenience. It
    1337 provides some nested typedefs that are generally useful. The are
    1338 specified in the table below:
     375The `proto::transform<>` base class provides the `operator()` overloads and the nested `result<>` template that make your transform a valid function object. These are implemented in terms of the nested `impl<>` template you define.
     376
     377The `proto::transform_impl<>` base class is a convenience. It provides some nested typedefs that are generally useful. The are specified in the table below:
    1339378
    1340379[table proto::transform_impl<Expr, State, Data> typedefs
     
    1348387]
    1349388
    1350 You'll notice that `_child_c::impl::operator()` takes arguments of types
    1351 `expr_param`, `state_param`, and `data_param`. The typedefs make it easy to
    1352 accept arguments by reference or const reference accordingly.
    1353 
    1354 The only other interesting bit is the `is_callable<>` specialization, which
    1355 will be described in the
    1356 [link boost_proto.users_guide.expression_transformation.is_callable
    1357 next section].
     389You'll notice that `_child_c::impl::operator()` takes arguments of types `expr_param`, `state_param`, and `data_param`. The typedefs make it easy to accept arguments by reference or const reference accordingly.
     390
     391The only other interesting bit is the `is_callable<>` specialization, which will be described in the [link boost_proto.users_guide.expression_transformation.is_callable next section].
    1358392
    1359393[endsect]
     
    1363397[/=================================================]
    1364398
    1365 Transforms are typically of the form `proto::when< Something, R(A0,A1,...) >`. The
    1366 question is whether `R` represents a function to call or an object to
    1367 construct, and the answer determines how _when_ evaluates the transform.
    1368 _when_ uses the `proto::is_callable<>` trait to disambiguate between the two.
    1369 Proto does its best to guess whether a transform is callable or not, but
    1370 it doesn't always get it right. It's best to know the rules Proto uses,
    1371 so that you know when you need to be more explicit.
    1372 
    1373 For most types `T`, `proto::is_callable<T>` checks for inheritence from
    1374 `proto::callable`. However, if the type `T` is a template specialization,
    1375 Proto assumes that it is /not/ callable ['even if the template inherits from
    1376 `proto::callable`]. We'll see why in a minute. Consider the following erroneous
    1377 callable transform:
    1378 
    1379     // Proto can't tell this defines a
    1380     // callable transform!
     399Transforms are typically of the form `proto::when< Something, R(A0,A1,...) >`. The question is whether `R` represents a function to call or an object to construct, and the answer determines how _when_ evaluates the transform. _when_ uses the `proto::is_callable<>` trait to disambiguate between the two. Proto does its best to guess whether a type is callable or not, but it doesn't always get it right. It's best to know the rules Proto uses, so that you know when you need to be more explicit.
     400
     401For most types `T`, `proto::is_callable<T>` checks for inheritence from `proto::callable`. However, if the type `T` is a template specialization, Proto assumes that it is /not/ callable ['even if the template inherits from `proto::callable`]. We'll see why in a minute. Consider the following erroneous callable object:
     402
     403    // Proto can't tell this defines
     404    // something callable!
    1381405    template<typename T>
    1382406    struct times2 : proto::callable
     
    1399423    {};
    1400424
    1401 The problem is that Proto doesn't know that `times2<int>` is a callable
    1402 transform. Instead, it assumes it is an object transform and will try to
    1403 construct a `times2<int>` object and initialize it will an `int`. That
    1404 will not compile.
    1405 
    1406 [note Why can't Proto tell that `times2<int>` is callable? After all,
    1407 it inherits from `proto::callable`, and that is detectable, right?
    1408 The problem is that merely asking whether some type `X<Y>` inherits from
    1409 `callable` will cause the template `X<Y>` to be instantiated. That's a
    1410 problem for a type like `std::vector<_value(_child1)>`. `std::vector<>`
    1411 will not suffer to be instantiated with `_value(_child1)` as a template
    1412 parameter. As a result, Proto has to assume that a type `X<Y>` represents
    1413 an object transform and not a callable transform.]
    1414 
    1415 There are a couple of solutions to the `times2<int>` problem. One
    1416 solution is to wrap the transform in `proto::call<>`. This forces Proto
    1417 to treat `times2<int>` as callable:
     425The problem is that Proto doesn't know that `times2<int>` is callable, so rather that invoking the `times2<int>` function object, Proto will try to construct a `times2<int>` object and initialize it will an `int`. That will not compile.
     426
     427[note Why can't Proto tell that `times2<int>` is callable? After all, it inherits from `proto::callable`, and that is detectable, right? The problem is that merely asking whether some type `X<Y>` inherits from `callable` will cause the template `X<Y>` to be instantiated. That's a problem for a type like `std::vector<_value(_child1)>`. `std::vector<>` will not suffer to be instantiated with `_value(_child1)` as a template parameter. Since merely asking the question will sometimes result in a hard error, Proto can't ask; it has to assume that `X<Y>` represents an object to construct and not a function to call.]
     428
     429There are a couple of solutions to the `times2<int>` problem. One solution is to wrap the transform in `proto::call<>`. This forces Proto to treat `times2<int>` as callable:
    1418430
    1419431    // OK, calls times2<int>
     
    1425437    {};
    1426438
    1427 This can be a bit of a pain, because we need to wrap every use of
    1428 `times2<int>`, which can be tedious and error prone, and makes our
    1429 grammar cluttered and harder to read.
    1430 
    1431 Another solution is to specialize `proto::is_callable<>` on our
    1432 `times2<>` template:
     439This can be a bit of a pain, because we need to wrap every use of `times2<int>`, which can be tedious and error prone, and makes our grammar cluttered and harder to read.
     440
     441Another solution is to specialize `proto::is_callable<>` on our `times2<>` template:
    1433442
    1434443    namespace boost { namespace proto
    1435444    {
     445        // Tell Proto that times2<> is callable
    1436446        template<typename T>
    1437447        struct is_callable<times2<T> >
     
    1448458    {};
    1449459
    1450 This is better, but still a pain because of the need to open
    1451 Proto's namespace.
    1452 
    1453 You could simply make sure that the transform is not
    1454 a template specialization. Consider the following:
     460This is better, but still a pain because of the need to open Proto's namespace.
     461
     462You could simply make sure that the callable type is not a template specialization. Consider the following:
    1455463
    1456464    // No longer a template specialization!
     
    1465473    {};
    1466474
    1467 This works because now Proto can tell that `times2int` inherits
    1468 (indirectly) from `proto::callable`. Any non-template types can
    1469 be safely checked for inheritance because, as they are not
    1470 templates, there is no worry about instantiation errors.
    1471 
    1472 There is one last way to tell Proto that `times2<>` is callable.
    1473 You could add an extra dummy template parameter that defaults
    1474 to `proto::callable`:
     475This works because now Proto can tell that `times2int` inherits (indirectly) from `proto::callable`. Any non-template types can be safely checked for inheritance because, as they are not templates, there is no worry about instantiation errors.
     476
     477There is one last way to tell Proto that `times2<>` is callable. You could add an extra dummy template parameter that defaults to `proto::callable`:
    1475478
    1476479    // Proto will recognize this as callable
     
    1494497    {};
    1495498
    1496 Note that in addition to the extra template parameter, `times2<>`
    1497 still inherits from `proto::callable`. That's not necessary in this
    1498 example but it's good style because any types derived from `times2<>`
    1499 (as `times2int` defined above) will still be considered callable.
    1500 
    1501 [endsect]
    1502 
    1503 [endsect]
     499Note that in addition to the extra template parameter, `times2<>` still inherits from `proto::callable`. That's not necessary in this example but it's good style because any types derived from `times2<>` (as `times2int` defined above) will still be considered callable.
     500
     501[endsect]
     502
     503[endsect]
Note: See TracChangeset for help on using the changeset viewer.