1 // Copyright (c) 2001-2011 Hartmut Kaiser 2 // 3 // Distributed under the Boost Software License, Version 1.0. (See accompanying 4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 5 6 #if !defined(BOOST_SPIRIT_REPOSITORY_KARMA_CONFIX_AUG_19_2008_1041AM) 7 #define BOOST_SPIRIT_REPOSITORY_KARMA_CONFIX_AUG_19_2008_1041AM 8 9 #if defined(_MSC_VER) 10 #pragma once 11 #endif 12 13 #include <boost/spirit/home/support/common_terminals.hpp> 14 #include <boost/spirit/home/support/info.hpp> 15 #include <boost/spirit/home/support/unused.hpp> 16 #include <boost/spirit/home/karma/detail/attributes.hpp> 17 #include <boost/spirit/home/karma/domain.hpp> 18 #include <boost/spirit/home/karma/meta_compiler.hpp> 19 20 #include <boost/spirit/repository/home/support/confix.hpp> 21 22 #include <boost/fusion/include/vector.hpp> 23 #include <boost/mpl/or.hpp> 24 25 /////////////////////////////////////////////////////////////////////////////// 26 namespace boost { namespace spirit 27 { 28 /////////////////////////////////////////////////////////////////////////// 29 // Enablers 30 /////////////////////////////////////////////////////////////////////////// 31 32 // enables confix(..., ...)[] 33 template <typename Prefix, typename Suffix> 34 struct use_directive<karma::domain 35 , terminal_ex<repository::tag::confix, fusion::vector2<Prefix, Suffix> > > 36 : mpl::true_ {}; 37 38 // enables *lazy* confix(..., ...)[g] 39 template <> 40 struct use_lazy_directive<karma::domain, repository::tag::confix, 2> 41 : mpl::true_ {}; 42 43 }} 44 45 /////////////////////////////////////////////////////////////////////////////// 46 namespace boost { namespace spirit { namespace repository { namespace karma 47 { 48 #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS 49 using repository::confix; 50 #endif 51 using repository::confix_type; 52 53 /////////////////////////////////////////////////////////////////////////// 54 template <typename Subject, typename Prefix, typename Suffix> 55 struct confix_generator 56 : spirit::karma::primitive_generator<confix_generator<Subject, Prefix, Suffix> > 57 { 58 typedef Subject subject_type; 59 60 template <typename Context, typename Iterator> 61 struct attribute 62 : traits::attribute_of<subject_type, Context, Iterator> 63 {}; 64 confix_generatorboost::spirit::repository::karma::confix_generator65 confix_generator(Subject const& subject, Prefix const& prefix 66 , Suffix const& suffix) 67 : subject(subject), prefix(prefix), suffix(suffix) {} 68 69 /////////////////////////////////////////////////////////////////////// 70 template <typename OutputIterator, typename Context, typename Delimiter 71 , typename Attribute> generateboost::spirit::repository::karma::confix_generator72 bool generate(OutputIterator& sink, Context& ctx, Delimiter const& d 73 , Attribute const& attr) const 74 { 75 // generate the prefix, the embedded item and the suffix 76 return prefix.generate(sink, ctx, d, unused) && 77 subject.generate(sink, ctx, d, attr) && 78 suffix.generate(sink, ctx, d, unused); 79 } 80 81 template <typename Context> whatboost::spirit::repository::karma::confix_generator82 info what(Context const& ctx) const 83 { 84 return info("confix", subject.what(ctx)); 85 } 86 87 Subject subject; 88 Prefix prefix; 89 Suffix suffix; 90 }; 91 92 }}}} 93 94 /////////////////////////////////////////////////////////////////////////////// 95 namespace boost { namespace spirit { namespace karma 96 { 97 /////////////////////////////////////////////////////////////////////////// 98 // Generator generators: make_xxx function (objects) 99 /////////////////////////////////////////////////////////////////////////// 100 101 // creates confix(..., ...)[] directive generator 102 template <typename Prefix, typename Suffix, typename Subject 103 , typename Modifiers> 104 struct make_directive< 105 terminal_ex<repository::tag::confix, fusion::vector2<Prefix, Suffix> > 106 , Subject, Modifiers> 107 { 108 typedef typename 109 result_of::compile<karma::domain, Prefix, Modifiers>::type 110 prefix_type; 111 typedef typename 112 result_of::compile<karma::domain, Suffix, Modifiers>::type 113 suffix_type; 114 115 typedef repository::karma::confix_generator< 116 Subject, prefix_type, suffix_type> result_type; 117 118 template <typename Terminal> operator ()boost::spirit::karma::make_directive119 result_type operator()(Terminal const& term, Subject const& subject 120 , Modifiers const& modifiers) const 121 { 122 return result_type(subject 123 , compile<karma::domain>(fusion::at_c<0>(term.args), modifiers) 124 , compile<karma::domain>(fusion::at_c<1>(term.args), modifiers)); 125 } 126 }; 127 128 }}} 129 130 namespace boost { namespace spirit { namespace traits 131 { 132 template <typename Subject, typename Prefix, typename Suffix> 133 struct has_semantic_action< 134 repository::karma::confix_generator<Subject, Prefix, Suffix> > 135 : mpl::or_< 136 has_semantic_action<Subject> 137 , has_semantic_action<Prefix> 138 , has_semantic_action<Suffix> 139 > {}; 140 }}} 141 142 #endif 143