1 /*============================================================================= 2 Copyright (c) 2001-2014 Joel de Guzman 3 4 Distributed under the Boost Software License, Version 1.0. (See accompanying 5 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 =============================================================================*/ 7 #if !defined(BOOST_SPIRIT_X3_CALL_CONTEXT_MAY_26_2014_0234PM) 8 #define BOOST_SPIRIT_X3_CALL_CONTEXT_MAY_26_2014_0234PM 9 10 #include <type_traits> 11 12 #include <boost/spirit/home/x3/support/context.hpp> 13 #include <boost/spirit/home/x3/support/utility/is_callable.hpp> 14 #include <boost/range/iterator_range_core.hpp> 15 16 namespace boost { namespace spirit { namespace x3 17 { 18 //////////////////////////////////////////////////////////////////////////// 19 struct rule_val_context_tag; 20 21 template <typename Context> _val(Context const & context)22 inline decltype(auto) _val(Context const& context) 23 { 24 return x3::get<rule_val_context_tag>(context); 25 } 26 27 //////////////////////////////////////////////////////////////////////////// 28 struct where_context_tag; 29 30 template <typename Context> _where(Context const & context)31 inline decltype(auto) _where(Context const& context) 32 { 33 return x3::get<where_context_tag>(context); 34 } 35 36 //////////////////////////////////////////////////////////////////////////// 37 struct attr_context_tag; 38 39 template <typename Context> _attr(Context const & context)40 inline decltype(auto) _attr(Context const& context) 41 { 42 return x3::get<attr_context_tag>(context); 43 } 44 45 //////////////////////////////////////////////////////////////////////////// 46 namespace detail 47 { 48 template <typename F, typename Context> call(F f,Context const & context,mpl::true_)49 auto call(F f, Context const& context, mpl::true_) 50 { 51 return f(context); 52 } 53 54 template <typename F, typename Context> call(F f,Context const &,mpl::false_)55 auto call(F f, Context const& /* context */, mpl::false_) 56 { 57 return f(); 58 } 59 } 60 61 template < 62 typename F, typename Iterator 63 , typename Context, typename RuleContext, typename Attribute> call(F f,Iterator & first,Iterator const & last,Context const & context,RuleContext & rcontext,Attribute & attr)64 auto call( 65 F f, Iterator& first, Iterator const& last 66 , Context const& context, RuleContext& rcontext, Attribute& attr) 67 { 68 boost::iterator_range<Iterator> rng(first, last); 69 auto val_context = make_context<rule_val_context_tag>(rcontext, context); 70 auto where_context = make_context<where_context_tag>(rng, val_context); 71 auto attr_context = make_context<attr_context_tag>(attr, where_context); 72 return detail::call(f, attr_context, is_callable<F(decltype(attr_context) const&)>()); 73 } 74 }}} 75 76 #endif 77