...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
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.
// 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_grammar; // member classes/structs/unions 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; }; };
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_() > > {};