| Home | Libraries | People | FAQ | More

##### `if_<>`, `and_<>`, and `not_<>`

We've already seen how to use expression generators like `proto::terminal<>` and `proto::shift_right<>` as grammars. We've also seen `proto::or_<>`, which we can use to express a set of alternate grammars. There are a few others of interest; in particular, `proto::if_<>`, `proto::and_<>` and `proto::not_<>`.

The `proto::not_<>` template is the simplest. It takes a grammar as a template parameter and logically negates it; `not_<Grammar>` will match any expression that `Grammar` does not match.

The `proto::if_<>` template is used together with a Proto transform that is evaluated against expression types to find matches. (Proto transforms will be described later.)

The `proto::and_<>` template is like `proto::or_<>`, except that each argument of the `proto::and_<>` must match in order for the `proto::and_<>` to match. As an example, consider the definition of `CharString` above that uses `proto::exact<>`. It could have been written without `proto::exact<>` as follows:

    struct CharString
      : proto::and_<
            proto::terminal< proto::_ >
          , proto::if_< boost::is_same< proto::_value, char const * >() >
        >
    {};

This says that a `CharString` must be a terminal, and its value type must be the same as `char const *`. Notice the template argument of `proto::if_<>`: `boost::is_same< proto::_value, char const * >()`. This is Proto transform that compares the value type of a terminal to `char const *`.

The `proto::if_<>` template has a couple of variants. In addition to `if_<Condition>` you can also say `if_<Condition, ThenGrammar>` and `if_<Condition, ThenGrammar, ElseGrammar>`. These let you select one sub-grammar or another based on the `Condition`.