• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*=============================================================================
2     Copyright (c) 2001-2011 Joel de Guzman
3     Copyright (c) 2001-2011 Hartmut Kaiser
4     Copyright (c) 2009 Francois Barel
5 
6     Distributed under the Boost Software License, Version 1.0. (See accompanying
7     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8 ==============================================================================*/
9 #if !defined(BOOST_SPIRIT_EXTRACT_PARAM_AUGUST_08_2009_0848AM)
10 #define BOOST_SPIRIT_EXTRACT_PARAM_AUGUST_08_2009_0848AM
11 
12 #if defined(_MSC_VER)
13 #pragma once
14 #endif
15 
16 #include <boost/spirit/home/support/meta_compiler.hpp>
17 #include <boost/spirit/home/support/nonterminal/locals.hpp>
18 #include <boost/spirit/home/support/unused.hpp>
19 #include <boost/spirit/home/support/common_terminals.hpp>
20 
21 #include <boost/function_types/is_function.hpp>
22 #include <boost/function_types/parameter_types.hpp>
23 #include <boost/function_types/result_type.hpp>
24 #include <boost/fusion/include/as_list.hpp>
25 #include <boost/fusion/include/as_vector.hpp>
26 #include <boost/mpl/deref.hpp>
27 #include <boost/mpl/end.hpp>
28 #include <boost/mpl/eval_if.hpp>
29 #include <boost/mpl/find_if.hpp>
30 #include <boost/mpl/identity.hpp>
31 #include <boost/mpl/if.hpp>
32 #include <boost/mpl/or.hpp>
33 #include <boost/mpl/and.hpp>
34 #include <boost/mpl/placeholders.hpp>
35 #include <boost/type_traits/is_same.hpp>
36 
37 namespace boost { namespace spirit { namespace detail
38 {
39     ///////////////////////////////////////////////////////////////////////////
40     // Helpers to extract params (locals, attributes, ...) from nonterminal
41     // template arguments
42     ///////////////////////////////////////////////////////////////////////////
43     template <typename Types, typename Pred, typename Default>
44     struct extract_param
45     {
46         typedef typename mpl::find_if<Types, Pred>::type pos;
47 
48         typedef typename
49             mpl::eval_if<
50                 is_same<pos, typename mpl::end<Types>::type>
51               , mpl::identity<Default>
52               , mpl::deref<pos>
53             >::type
54         type;
55     };
56 
57     ///////////////////////////////////////////////////////////////////////////
58     template <typename Types>
59     struct extract_locals
60       : fusion::result_of::as_vector<
61             typename extract_param<
62                 Types
63               , is_locals<mpl::_>
64               , locals<>
65             >::type
66         >
67     {};
68 
69     ///////////////////////////////////////////////////////////////////////////
70     template <typename Domain, typename Types>
71     struct extract_component
72       : spirit::result_of::compile<
73             Domain
74           , typename extract_param<
75                 Types
76               , traits::matches<Domain, mpl::_>
77               , unused_type
78             >::type
79         >
80     {};
81 
82     ///////////////////////////////////////////////////////////////////////////
83     template <typename T>
84     struct make_function_type : mpl::identity<T()> {};
85 
86     ///////////////////////////////////////////////////////////////////////////
87     template <typename Types, typename Encoding, typename Domain>
88     struct extract_sig
89     {
90         typedef typename
91             extract_param<
92                 Types
93               , mpl::or_<
94                     function_types::is_function<mpl::_>
95                   , mpl::and_<
96                         mpl::not_<is_locals<mpl::_> >
97                       , mpl::not_<is_same<mpl::_, Encoding> >
98                       , mpl::not_<traits::matches<Domain, mpl::_> >
99                       , mpl::not_<is_same<mpl::_, unused_type> >
100                     >
101                 >
102               , void()
103             >::type
104         attr_of_ftype;
105 
106         typedef typename
107             mpl::eval_if<
108                 function_types::is_function<attr_of_ftype>
109               , mpl::identity<attr_of_ftype>
110               , make_function_type<attr_of_ftype>
111             >::type
112         type;
113     };
114 
115     template <typename Sig>
116     struct attr_from_sig
117     {
118         typedef typename function_types::result_type<Sig>::type attr;
119 
120         typedef typename
121             mpl::if_<
122                 is_same<attr, void>
123               , unused_type
124               , attr
125             >::type
126         type;
127     };
128 
129     template <typename Sig>
130     struct params_from_sig
131     {
132         typedef typename function_types::parameter_types<Sig>::type params;
133 
134         typedef typename fusion::result_of::as_list<params>::type type;
135     };
136 
137     ///////////////////////////////////////////////////////////////////////////
138     template <typename Types>
139     struct extract_encoding
140       : extract_param<
141             Types
142           , is_char_encoding<mpl::_>
143           , unused_type
144         >
145     {};
146 }}}
147 
148 #endif
149