• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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