/////////////////////////////////////////////////////////////////////////////// // as_quantifier.hpp // // Copyright 2007 Eric Niebler. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #ifndef BOOST_XPRESSIVE_DETAIL_STATIC_TRANSFORMS_AS_QUANTIFIER_HPP_EAN_04_01_2007 #define BOOST_XPRESSIVE_DETAIL_STATIC_TRANSFORMS_AS_QUANTIFIER_HPP_EAN_04_01_2007 // MS compatible compilers support #pragma once #if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif #include #include #include #include #include #include namespace boost { namespace xpressive { namespace detail { /////////////////////////////////////////////////////////////////////////////// // generic_quant_tag template struct generic_quant_tag { typedef mpl::integral_c min_type; typedef mpl::integral_c max_type; }; /////////////////////////////////////////////////////////////////////////////// // min_type / max_type template struct min_type : Tag::min_type {}; template<> struct min_type : mpl::integral_c {}; template<> struct min_type : mpl::integral_c {}; template<> struct min_type : mpl::integral_c {}; template struct max_type : Tag::max_type {}; template<> struct max_type : mpl::integral_c {}; template<> struct max_type : mpl::integral_c {}; template<> struct max_type : mpl::integral_c {}; /////////////////////////////////////////////////////////////////////////////// // as_simple_quantifier template struct as_simple_quantifier : Grammar { typedef proto::transform::arg grammar_type; as_simple_quantifier(); template struct apply { typedef typename grammar_type::template apply::type xpr_type; typedef simple_repeat_matcher matcher_type; typedef typename proto::terminal::type type; }; template static typename apply::type call(Expr const &expr, State const &, Visitor &visitor) { typename apply::xpr_type const &xpr = grammar_type::call(expr, true_xpression(), visitor); return apply::type::make( typename apply::matcher_type( xpr , min_type::value , max_type::value , xpr.get_width().value() ) ); } }; /////////////////////////////////////////////////////////////////////////////// // add_hidden_mark template struct add_hidden_mark : Grammar { add_hidden_mark(); template struct apply : proto::shift_right< proto::terminal::type , typename proto::shift_right< Expr , proto::terminal::type >::type > {}; template static typename apply::type call(Expr const &expr, State const &, Visitor &visitor) { // we're inserting a hidden mark ... so grab the next hidden mark number. int mark_nbr = visitor.get_hidden_mark(); mark_begin_matcher begin(mark_nbr); mark_end_matcher end(mark_nbr); typename apply::type that = {{begin}, {expr, {end}}}; return that; } }; /////////////////////////////////////////////////////////////////////////////// // InsertMark struct InsertMark : proto::or_< proto::assign , add_hidden_mark > {}; /////////////////////////////////////////////////////////////////////////////// // as_default_quantifier_impl template struct as_default_quantifier_impl { template struct apply : proto::shift_right< proto::terminal::type , typename proto::shift_right< typename InsertMark::apply::type, State, Visitor>::type , typename proto::terminal >::type >::type > {}; template static typename apply::type call(Expr const &expr, State const &state, Visitor &visitor) { // Ensure this sub-expression is book-ended with mark matchers typedef typename proto::result_of::arg::type arg_type; typename InsertMark::apply::type const & marked_sub = InsertMark::call(proto::arg(expr), state, visitor); // Get the mark_number from the begin_mark_matcher int mark_number = proto::arg(proto::left(marked_sub)).mark_number_; BOOST_ASSERT(0 != mark_number); unsigned min_ = min_type::value; unsigned max_ = max_type::value; repeat_begin_matcher begin(mark_number); repeat_end_matcher end(mark_number, min_, max_); typename apply::type that = {{begin}, {marked_sub, {end}}}; return that; } }; /////////////////////////////////////////////////////////////////////////////// // optional_tag template struct optional_tag {}; /////////////////////////////////////////////////////////////////////////////// // as_default_optional template struct as_default_optional : Grammar { as_default_optional(); template struct apply { typedef optional_matcher< typename Grammar::template apply::type , Greedy > type; }; template static typename apply::type call(Expr const &expr, State const &, Visitor &visitor) { return typename apply::type( Grammar::call(expr, alternate_end_xpression(), visitor) ); } }; /////////////////////////////////////////////////////////////////////////////// // as_mark_optional template struct as_mark_optional : Grammar { as_mark_optional(); template struct apply { typedef optional_mark_matcher< typename Grammar::template apply::type , Greedy > type; }; template static typename apply::type call(Expr const &expr, State const &, Visitor &visitor) { int mark_number = proto::arg(proto::left(expr)).mark_number_; return typename apply::type( Grammar::call(expr, alternate_end_xpression(), visitor) , mark_number ); } }; /////////////////////////////////////////////////////////////////////////////// // IsMarkerOrRepeater struct IsMarkerOrRepeater : proto::or_< proto::shift_right, proto::_> , proto::assign, proto::_> > {}; /////////////////////////////////////////////////////////////////////////////// // as_optional template struct as_optional : proto::if_< proto::matches , as_mark_optional , as_default_optional > { as_optional(); }; /////////////////////////////////////////////////////////////////////////////// // make_optional_ template struct make_optional_ { template struct apply : proto::unary_expr, Expr> {}; template static typename apply::type call(Expr const &expr, State const &, Visitor &) { typename apply::type that = {expr}; return that; } }; /////////////////////////////////////////////////////////////////////////////// // as_default_quantifier_impl template struct as_default_quantifier_impl : proto::transform::compose< as_default_quantifier_impl , make_optional_ > {}; /////////////////////////////////////////////////////////////////////////////// // as_default_quantifier_impl template struct as_default_quantifier_impl : proto::transform::compose< proto::transform::arg , make_optional_ > {}; /////////////////////////////////////////////////////////////////////////////// // as_default_quantifier template struct as_default_quantifier : Grammar { as_default_quantifier(); template struct apply : as_default_quantifier_impl< Greedy , min_type::value , max_type::value >::template apply {}; template static typename apply::type call(Expr const &expr, State const &state, Visitor &visitor) { return as_default_quantifier_impl< Greedy , min_type::value , max_type::value >::call(expr, state, visitor); } }; }}} #endif