1 /*============================================================================= 2 Copyright (c) 2001-2011 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_META_COMPILER_OCTOBER_16_2008_0347PM) 8 #define BOOST_SPIRIT_META_COMPILER_OCTOBER_16_2008_0347PM 9 10 #if defined(_MSC_VER) 11 #pragma once 12 #endif 13 14 #include <boost/spirit/home/support/meta_compiler.hpp> 15 #include <boost/spirit/home/qi/domain.hpp> 16 #include <boost/spirit/home/qi/parser.hpp> 17 #include <boost/spirit/home/support/string_traits.hpp> 18 #include <boost/type_traits/remove_reference.hpp> 19 #include <boost/utility/enable_if.hpp> 20 #include <boost/fusion/include/at.hpp> 21 22 namespace boost { namespace spirit 23 { 24 template <typename T> 25 struct use_terminal<qi::domain, T 26 , typename enable_if<traits::is_parser<T> >::type> // enables parsers 27 : mpl::true_ {}; 28 29 namespace qi 30 { 31 template <typename T, typename Modifiers, typename Enable = void> 32 struct make_primitive // by default, return it as-is 33 { 34 typedef T result_type; 35 36 template <typename T_> operator ()boost::spirit::qi::make_primitive37 T_& operator()(T_& val, unused_type) const 38 { 39 return val; 40 } 41 42 template <typename T_> operator ()boost::spirit::qi::make_primitive43 T_ const& operator()(T_ const& val, unused_type) const 44 { 45 return val; 46 } 47 }; 48 49 template <typename Tag, typename Elements 50 , typename Modifiers, typename Enable = void> 51 struct make_composite; 52 53 template <typename Directive, typename Body 54 , typename Modifiers, typename Enable = void> 55 struct make_directive 56 { 57 typedef Body result_type; operator ()boost::spirit::qi::make_directive58 result_type operator()(unused_type, Body const& body, unused_type) const 59 { 60 return body; // By default, a directive simply returns its subject 61 } 62 }; 63 } 64 65 // Qi primitive meta-compiler 66 template <> 67 struct make_component<qi::domain, proto::tag::terminal> 68 { 69 template <typename Sig> 70 struct result; 71 72 template <typename This, typename Elements, typename Modifiers> 73 struct result<This(Elements, Modifiers)> 74 { 75 typedef typename qi::make_primitive< 76 typename remove_const<typename Elements::car_type>::type, 77 typename remove_reference<Modifiers>::type>::result_type 78 type; 79 }; 80 81 template <typename Elements, typename Modifiers> 82 typename result<make_component(Elements, Modifiers)>::type operator ()boost::spirit::make_component83 operator()(Elements const& elements, Modifiers const& modifiers) const 84 { 85 typedef typename remove_const<typename Elements::car_type>::type term; 86 return qi::make_primitive<term, Modifiers>()(elements.car, modifiers); 87 } 88 }; 89 90 // Qi composite meta-compiler 91 template <typename Tag> 92 struct make_component<qi::domain, Tag> 93 { 94 template <typename Sig> 95 struct result; 96 97 template <typename This, typename Elements, typename Modifiers> 98 struct result<This(Elements, Modifiers)> 99 { 100 typedef typename 101 qi::make_composite<Tag, Elements, 102 typename remove_reference<Modifiers>::type>::result_type 103 type; 104 }; 105 106 template <typename Elements, typename Modifiers> 107 typename result<make_component(Elements, Modifiers)>::type operator ()boost::spirit::make_component108 operator()(Elements const& elements, Modifiers const& modifiers) const 109 { 110 return qi::make_composite<Tag, Elements, Modifiers>()( 111 elements, modifiers); 112 } 113 }; 114 115 // Qi function meta-compiler 116 template <> 117 struct make_component<qi::domain, proto::tag::function> 118 { 119 template <typename Sig> 120 struct result; 121 122 template <typename This, typename Elements, typename Modifiers> 123 struct result<This(Elements, Modifiers)> 124 { 125 typedef typename 126 qi::make_composite< 127 typename remove_const<typename Elements::car_type>::type, 128 typename Elements::cdr_type, 129 typename remove_reference<Modifiers>::type 130 >::result_type 131 type; 132 }; 133 134 template <typename Elements, typename Modifiers> 135 typename result<make_component(Elements, Modifiers)>::type operator ()boost::spirit::make_component136 operator()(Elements const& elements, Modifiers const& modifiers) const 137 { 138 return qi::make_composite< 139 typename remove_const<typename Elements::car_type>::type, 140 typename Elements::cdr_type, 141 Modifiers>()(elements.cdr, modifiers); 142 } 143 }; 144 145 // Qi directive meta-compiler 146 template <> 147 struct make_component<qi::domain, tag::directive> 148 { 149 template <typename Sig> 150 struct result; 151 152 template <typename This, typename Elements, typename Modifiers> 153 struct result<This(Elements, Modifiers)> 154 { 155 typedef typename 156 qi::make_directive< 157 typename remove_const<typename Elements::car_type>::type, 158 typename remove_const<typename Elements::cdr_type::car_type>::type, 159 typename remove_reference<Modifiers>::type 160 >::result_type 161 type; 162 }; 163 164 template <typename Elements, typename Modifiers> 165 typename result<make_component(Elements, Modifiers)>::type operator ()boost::spirit::make_component166 operator()(Elements const& elements, Modifiers const& modifiers) const 167 { 168 return qi::make_directive< 169 typename remove_const<typename Elements::car_type>::type, 170 typename remove_const<typename Elements::cdr_type::car_type>::type, 171 Modifiers>()(elements.car, elements.cdr.car, modifiers); 172 } 173 }; 174 175 }} 176 177 #endif 178