1 // Copyright (c) 2001-2011 Joel de Guzman 2 // Copyright (c) 2001-2011 Hartmut Kaiser 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_GENERATOR_BINDER_APR_17_2009_0952PM) 8 #define BOOST_SPIRIT_GENERATOR_BINDER_APR_17_2009_0952PM 9 10 #if defined(_MSC_VER) 11 #pragma once 12 #endif 13 14 #include <boost/fusion/include/at.hpp> 15 #include <boost/mpl/bool.hpp> 16 #include <boost/spirit/home/support/has_semantic_action.hpp> 17 18 namespace boost { namespace spirit { namespace karma { namespace detail 19 { 20 // generator_binder for plain rules 21 template <typename Generator, typename Auto> 22 struct generator_binder 23 { generator_binderboost::spirit::karma::detail::generator_binder24 generator_binder(Generator const& g) 25 : g(g) {} 26 27 template <typename OutputIterator, typename Delimiter, typename Context> callboost::spirit::karma::detail::generator_binder28 bool call(OutputIterator& sink, Context& context 29 , Delimiter const& delim, mpl::true_) const 30 { 31 // If DeducedAuto is false (semantic actions is present), the 32 // component's attribute is unused. 33 return g.generate(sink, context, delim, unused); 34 } 35 36 template <typename OutputIterator, typename Delimiter, typename Context> callboost::spirit::karma::detail::generator_binder37 bool call(OutputIterator& sink, Context& context 38 , Delimiter const& delim, mpl::false_) const 39 { 40 // If DeducedAuto is true (no semantic action), we pass the rule's 41 // attribute on to the component. 42 return g.generate(sink, context, delim 43 , fusion::at_c<0>(context.attributes)); 44 } 45 46 template <typename OutputIterator, typename Delimiter, typename Context> operator ()boost::spirit::karma::detail::generator_binder47 bool operator()(OutputIterator& sink, Context& context 48 , Delimiter const& delim) const 49 { 50 // If Auto is false, we need to deduce whether to apply auto rule 51 typedef typename traits::has_semantic_action<Generator>::type auto_rule; 52 return call(sink, context, delim, auto_rule()); 53 } 54 55 Generator g; 56 }; 57 58 // generator_binder for auto rules 59 template <typename Generator> 60 struct generator_binder<Generator, mpl::true_> 61 { generator_binderboost::spirit::karma::detail::generator_binder62 generator_binder(Generator const& g) 63 : g(g) {} 64 65 template <typename OutputIterator, typename Delimiter, typename Context> operator ()boost::spirit::karma::detail::generator_binder66 bool operator()(OutputIterator& sink, Context& context 67 , Delimiter const& delim) const 68 { 69 // If Auto is true, the component's attribute is unused. 70 return g.generate(sink, context, delim 71 , fusion::at_c<0>(context.attributes)); 72 } 73 74 Generator g; 75 }; 76 77 template <typename Auto, typename Generator> 78 inline generator_binder<Generator, Auto> bind_generator(Generator const & g)79 bind_generator(Generator const& g) 80 { 81 return generator_binder<Generator, Auto>(g); 82 } 83 84 }}}} 85 86 #endif 87