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