| Home | Libraries | People | FAQ | More

## Struct template if_

boost::proto::if_ — Used to select one grammar or another based on the result of a compile-time Boolean. When used as a transform, `proto::if_<>` selects between two transforms based on a compile-time Boolean.

## Synopsis

    // In header: <boost/proto/matches.hpp>

    template<typename If, typename Then = proto::_,
             typename Else = proto::not_<proto::_> >
    struct if_ :  proto::transform<if_<If, Then, Else> > {
      // types
      typedef if_ proto_base_expr;
      template<typename Expr, typename State, typename Data>
      struct impl :  proto::transform_impl< Expr, State, Data > {
        // types
        typedef typename mpl::if_<
          typename boost::result_of<proto::when<proto::_, If>(Expr, State, Data)>::type,
          typename boost::result_of<proto::when<proto::_, Then>(Expr, State, Data)>::type,
          typename boost::result_of<proto::when<proto::_, Else>(Expr, State, Data)>::type
        >::type result_type;

        // public member functions
        result_type operator()(typename impl::expr_param,
                               typename impl::state_param,
                               typename impl::data_param) const;
      };
    };

## Description

When `proto::if_<If, Then, Else>` is used as a grammar, `If` must be a Proto transform and `Then` and `Else` must be grammars. An expression type `E` matches `proto::if_<If, Then, Else>` if `boost::result_of<proto::when<proto::_, If>(E)>::type::value` is `true` and `E` matches `Then`; or, if `boost::result_of<proto::when<proto::_, If>(E)>::type::value` is `false` and `E` matches `Else`.

The template parameter `Then` defaults to `proto::_` and `Else` defaults to `proto::not_<proto::_>`, so an expression type `E` will match `proto::if_<If>` if and only if `boost::result_of<proto::when<proto::_, If>(E)>::type::value` is `true`.

    // A grammar that only matches integral terminals,
    // using is_integral<> from Boost.Type_traits.
    struct IsIntegral :
      proto::and_<
        proto::terminal<proto::_>,
        proto::if_< boost::is_integral<proto::_value>()>
      >
    {};

When `proto::if_<If, Then, Else>` is used as a transform, `If`, `Then` and `Else` must be Proto transforms. When applying the transform to an expression `E`, state `S` and data `V`, if `boost::result_of<proto::when<proto::_, If>(E,S,V)>::type::value` is `true` then the `Then` transform is applied; otherwise the `Else` transform is applied.

    // Match a terminal. If the terminal is integral, return
    // mpl::true_; otherwise, return mpl::false_.
    struct IsIntegral2 :
      proto::when<
        proto::terminal<_>,
        proto::if_<
          boost::is_integral<proto::_value>(),
          mpl::true_(),
          mpl::false_()
        >
      >
    {};