SPROUT_CONSTEXPR result_type operator()( Expr const& expr, context_type const& ctx ) const { return sprout::weed::eval(sprout::tuples::get<0>(expr.args()), ctx).success() ? result_type(true, ctx.begin(), attribute_type(), ctx) : result_type(false, ctx.begin(), attribute_type(), ctx) ; }
SPROUT_CONSTEXPR typename std::enable_if< (sizeof...(Attrs) + 2 < limit::value), result_type >::type call( expr_type const& expr, context_type const& ctx, sprout::weed::limited::category limited_category, Result const& res, Head const& head, Attrs const&... attrs ) const { return res.success() ? call( expr, res.ctx(), limited_category, sprout::weed::eval(expr, res.ctx()), head, attrs..., res.attr() ) : result_type( true, ctx.begin(), sprout::weed::attr_cnv::times<limit::value, attr_type>(head, attrs...), ctx ) ; }
SPROUT_CONSTEXPR result_type call_1( expr1_type const& expr1, expr2_type const& expr2, context_type const& ctx, sprout::weed::limited::category limited_category, Result const& res, Attrs const&... attrs ) const { return res.success() ? call( expr1, expr2, res.ctx(), limited_category, sprout::weed::eval(expr1, res.ctx()), attrs... ) : result_type( true, ctx.begin(), sprout::weed::attr_cnv::modulus<limit::value, attr_type>(attrs...), ctx ) ; }
SPROUT_CONSTEXPR result_type call( Arg const& arg, context_type const& ctx ) const { return sprout::distance(ctx.begin(), ctx.end()) >= sprout::size(arg) && sprout::equal(sprout::begin(arg), sprout::end(arg), ctx.begin()) ? result_type( true, sprout::next(ctx.begin(), sprout::size(arg)), attribute_type(), context_type(ctx, sprout::next(ctx.begin(), sprout::size(arg))) ) : result_type(false, ctx.begin(), attribute_type(), ctx) ; }
SPROUT_CONSTEXPR result_type operator()( Expr const& expr, context_type const& ctx ) const { typedef typename std::iterator_traits<Iterator>::value_type elem_type; return ctx.begin() != ctx.end() && *ctx.begin() == elem_type(sprout::tuples::get<0>(expr.args())) ? result_type( true, sprout::next(ctx.begin()), attribute_type(), context_type(ctx, sprout::next(ctx.begin())) ) : result_type(false, ctx.begin(), attribute_type(), ctx) ; }
SPROUT_CONSTEXPR result_type call_1( typename Expr::args_type const& args, context_type const& ctx, Result1 const& res ) const { return res.success() && !sprout::weed::eval(sprout::tuples::get<1>(args), ctx).success() ? res : result_type(false, ctx.begin(), attribute_type(), ctx) ; }
SPROUT_CONSTEXPR result_type call_inf( expr_type const& expr, context_type const& ctx, Result const& res ) const { return res.success() ? call_inf(expr, res.ctx(), sprout::weed::eval(expr, res.ctx())) : result_type(true, ctx.begin(), attribute_type(), ctx) ; }
SPROUT_CONSTEXPR result_type operator()( Expr const& expr, context_type const& ctx ) const { return call( sprout::tuples::get<0>(expr.args()) .template operator()(ctx.begin(), ctx.end(), ctx), ctx ); }
SPROUT_CONSTEXPR typename std::enable_if< Infinity, result_type >::type call( expr1_type const& expr1, expr2_type const& expr2, context_type const& ctx, Result const& res ) const { return res.success() ? call_inf_1(expr1, expr2, res.ctx(), sprout::weed::eval(expr2, res.ctx())) : result_type(false, ctx.begin(), attribute_type(), ctx) ; }
SPROUT_CONSTEXPR result_type call_2( typename Expr::args_type const&, context_type const& ctx, Result2 const& res ) const { return res.success() ? result_type( true, res.current(), sprout::weed::attr_cnv::bitwise_or<attr1_type, attr2_type>(res.attr()), context_type(ctx, res.current()) ) : result_type(false, ctx.begin(), attribute_type(), ctx) ; }
SPROUT_CONSTEXPR result_type call_2( typename Expr::args_type const&, context_type const& ctx, Attr1 const& attr, Result2 const& res ) const { return res.success() ? result_type( true, res.current(), sprout::weed::attr_cnv::shift_left(attr, res.attr()), context_type(ctx, res.current()) ) : result_type(false, ctx.begin(), attribute_type(), ctx) ; }
SPROUT_CONSTEXPR result_type call_1( typename Expr::args_type const& args, context_type const& ctx, Result1 const& res ) const { return res.success() ? result_type( true, res.current(), sprout::weed::attr_cnv::mem_ptr( res.attr(), sprout::tuples::get<0>(sprout::tuples::get<1>(args).args()) ), context_type(ctx, res.current()) ) : result_type(false, ctx.begin(), attribute_type(), ctx) ; }
SPROUT_CONSTEXPR typename std::enable_if< !Infinity, result_type >::type call( expr_type const& expr, context_type const& ctx, Result const& res ) const { return res.success() ? call( expr, res.ctx(), sprout::tuples::get<0>(expr.args()).limited_category(), sprout::weed::eval(expr, res.ctx()), res.attr() ) : result_type(true, ctx.begin(), attribute_type(), ctx) ; }
SPROUT_CONSTEXPR typename std::enable_if< sizeof...(Attrs) + 1 == limit::value, result_type >::type call( expr1_type const& expr1, expr2_type const& expr2, context_type const& ctx, sprout::weed::limited::category limited_category, Result const& res, Head const& head, Attrs const&... attrs ) const { return res.success() ? limited_category == sprout::weed::limited::discard ? call_1( expr1, expr2, res.ctx(), limited_category, sprout::weed::eval(expr2, res.ctx()), head, attrs... ) : call_1( expr1, expr2, res.ctx(), limited_category, sprout::weed::eval(expr2, res.ctx()), attrs..., res.attr() ) : result_type( true, ctx.begin(), sprout::weed::attr_cnv::modulus<limit::value, attr_type>(head, attrs...), ctx ) ; }