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_LEX_META_COMPILER_APR_20_2009_0756PM)
8 #define BOOST_SPIRIT_LEX_META_COMPILER_APR_20_2009_0756PM
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/lex/domain.hpp>
16 #include <boost/spirit/home/lex/lexer_type.hpp>
17 #include <boost/proto/tags.hpp>
18 #include <boost/type_traits/remove_reference.hpp>
19 #include <boost/utility/enable_if.hpp>
20 
21 namespace boost { namespace spirit
22 {
23     template <typename T>
24     struct use_terminal<lex::domain, T
25       , typename enable_if<traits::is_lexer<T> >::type> // enables lexers
26       : mpl::true_ {};
27 
28     namespace lex
29     {
30         template <typename T, typename Modifiers, typename Enable = void>
31         struct make_primitive // by default, return it as-is
32         {
33             typedef T result_type;
34 
35             template <typename T_>
36             T_& operator()(T_& val, unused_type) const
37             {
38                 return val;
39             }
40 
41             template <typename T_>
42             T_ const& operator()(T_ const& val, unused_type) const
43             {
44                 return val;
45             }
46         };
47 
48         template <typename Tag, typename Elements
49           , typename Modifiers, typename Enable = void>
50         struct make_composite;
51     }
52 
53     // Lex primitive meta-compiler
54     template <>
55     struct make_component<lex::domain, proto::tag::terminal>
56     {
57         template <typename Sig>
58         struct result;
59 
60         template <typename This, typename Elements, typename Modifiers>
61         struct result<This(Elements, Modifiers)>
62         {
63             typedef typename lex::make_primitive<
64                 typename remove_const<typename Elements::car_type>::type,
65                 typename remove_reference<Modifiers>::type>::result_type
66             type;
67         };
68 
69         template <typename Elements, typename Modifiers>
70         typename result<make_component(Elements, Modifiers)>::type
71         operator()(Elements const& elements, Modifiers const& modifiers) const
72         {
73             typedef typename remove_const<typename Elements::car_type>::type term;
74             return lex::make_primitive<term, Modifiers>()(elements.car, modifiers);
75         }
76     };
77 
78     // Lex composite meta-compiler
79     template <typename Tag>
80     struct make_component<lex::domain, Tag>
81     {
82         template <typename Sig>
83         struct result;
84 
85         template <typename This, typename Elements, typename Modifiers>
86         struct result<This(Elements, Modifiers)>
87         {
88             typedef typename
89                 lex::make_composite<Tag, Elements
90                   , typename remove_reference<Modifiers>::type>::result_type
91             type;
92         };
93 
94         template <typename Elements, typename Modifiers>
95         typename result<make_component(Elements, Modifiers)>::type
96         operator()(Elements const& elements, Modifiers const& modifiers) const
97         {
98             return lex::make_composite<Tag, Elements, Modifiers>()(
99                 elements, modifiers);
100         }
101     };
102 
103 }}
104 
105 #endif
106