]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/spirit/include/boost/spirit/home/support/auto/meta_create.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / spirit / include / boost / spirit / home / support / auto / meta_create.hpp
1 // Copyright (c) 2001-2011 Hartmut Kaiser
2 //
3 // Distributed under the Boost Software License, Version 1.0. (See accompanying
4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5
6 #if !defined(BOOST_SPIRIT_SUPPORT_META_CREATE_NOV_21_2009_0327PM)
7 #define BOOST_SPIRIT_SUPPORT_META_CREATE_NOV_21_2009_0327PM
8
9 #if defined(_MSC_VER)
10 #pragma once
11 #endif
12
13 #include <boost/spirit/home/support/unused.hpp>
14
15 #include <boost/version.hpp>
16 #include <boost/spirit/include/phoenix_limits.hpp> // needs to be included before proto
17 #include <boost/proto/proto.hpp>
18 #include <boost/utility/result_of.hpp>
19 #include <boost/type_traits/add_const.hpp>
20 #include <boost/type_traits/add_reference.hpp>
21 #include <boost/type_traits/remove_const.hpp>
22 #include <boost/type_traits/remove_reference.hpp>
23 #include <boost/fusion/include/fold.hpp>
24 #include <boost/mpl/and.hpp>
25 #include <boost/mpl/not.hpp>
26
27 // needed for workaround below
28 #if defined(__GNUC__) && ((__GNUC__ < 4) || (__GNUC__ == 4) && (__GNUC_MINOR__ < 3))
29 #include <boost/type_traits/is_same.hpp>
30 #endif
31
32 namespace boost { namespace spirit { namespace traits
33 {
34 ///////////////////////////////////////////////////////////////////////////
35 // This is the main dispatch point for meta_create to the correct domain
36 template <typename Domain, typename T, typename Enable = void>
37 struct meta_create;
38
39 ///////////////////////////////////////////////////////////////////////////
40 // This allows to query whether a valid mapping exists for the given data
41 // type to a component in the given domain
42 template <typename Domain, typename T, typename Enable = void>
43 struct meta_create_exists : mpl::false_ {};
44 }}}
45
46 namespace boost { namespace spirit
47 {
48 ///////////////////////////////////////////////////////////////////////////
49 namespace detail
50 {
51 template <typename T>
52 struct add_const_ref
53 : add_reference<typename add_const<T>::type> {};
54
55 template <typename T>
56 struct remove_const_ref
57 : remove_const<typename remove_reference<T>::type> {};
58
59 // starting with Boost V1.42 fusion::fold has been changed to be compatible
60 // with mpl::fold (the sequence of template parameters for the meta-function
61 // object has been changed)
62 #if BOOST_VERSION < 104200
63 ///////////////////////////////////////////////////////////////////////
64 template <typename OpTag, typename Domain>
65 struct nary_proto_expr_function
66 {
67 template <typename T>
68 struct result;
69
70 // this is a workaround for older versions of g++ (< V4.3) which apparently have
71 // problems with the following template specialization
72 #if defined(__GNUC__) && ((__GNUC__ < 4) || (__GNUC__ == 4) && (__GNUC_MINOR__ < 3))
73 template <typename F, typename T1, typename T2>
74 struct result<F(T1, T2)>
75 {
76 BOOST_STATIC_ASSERT((is_same<F, nary_proto_expr_function>::value));
77 #else
78 template <typename T1, typename T2>
79 struct result<nary_proto_expr_function(T1, T2)>
80 {
81 #endif
82 typedef typename remove_const_ref<T2>::type left_type;
83 typedef typename
84 spirit::traits::meta_create<Domain, T1>::type
85 right_type;
86
87 typedef typename mpl::eval_if<
88 traits::not_is_unused<left_type>
89 , proto::result_of::make_expr<OpTag, left_type, right_type>
90 , mpl::identity<right_type>
91 >::type type;
92 };
93
94 template <typename T>
95 typename result<nary_proto_expr_function(T, unused_type const&)>::type
96 operator()(T, unused_type const&) const
97 {
98 typedef spirit::traits::meta_create<Domain, T> right_type;
99 return right_type::call();
100 }
101
102 template <typename T1, typename T2>
103 typename result<nary_proto_expr_function(T1, T2)>::type
104 operator()(T1, T2 const& t2) const
105 {
106 // we variants to the alternative operator
107 typedef spirit::traits::meta_create<Domain, T1> right_type;
108 return proto::make_expr<OpTag>(t2, right_type::call());
109 }
110 };
111 #else
112 ///////////////////////////////////////////////////////////////////////
113 template <typename OpTag, typename Domain>
114 struct nary_proto_expr_function
115 {
116 template <typename T>
117 struct result;
118
119 // this is a workaround for older versions of g++ (< V4.3) which apparently have
120 // problems with the following template specialization
121 #if defined(__GNUC__) && ((__GNUC__ < 4) || (__GNUC__ == 4) && (__GNUC_MINOR__ < 3))
122 template <typename F, typename T1, typename T2>
123 struct result<F(T1, T2)>
124 {
125 BOOST_STATIC_ASSERT((is_same<F, nary_proto_expr_function>::value));
126 #else
127 template <typename T1, typename T2>
128 struct result<nary_proto_expr_function(T1, T2)>
129 {
130 #endif
131 typedef typename remove_const_ref<T1>::type left_type;
132 typedef typename
133 spirit::traits::meta_create<Domain, T2>::type
134 right_type;
135
136 typedef typename mpl::eval_if<
137 traits::not_is_unused<left_type>
138 , proto::result_of::make_expr<OpTag, left_type, right_type>
139 , mpl::identity<right_type>
140 >::type type;
141 };
142
143 template <typename T>
144 typename result<nary_proto_expr_function(unused_type const&, T)>::type
145 operator()(unused_type const&, T) const
146 {
147 typedef spirit::traits::meta_create<Domain, T> right_type;
148 return right_type::call();
149 }
150
151 template <typename T1, typename T2>
152 typename result<nary_proto_expr_function(T1, T2)>::type
153 operator()(T1 const& t1, T2) const
154 {
155 // we variants to the alternative operator
156 typedef spirit::traits::meta_create<Domain, T2> right_type;
157 return proto::make_expr<OpTag>(t1, right_type::call());
158 }
159 };
160 #endif
161 }
162
163 ///////////////////////////////////////////////////////////////////////
164 template <typename T, typename OpTag, typename Domain>
165 struct make_unary_proto_expr
166 {
167 typedef spirit::traits::meta_create<Domain, T> subject_type;
168
169 typedef typename proto::result_of::make_expr<
170 OpTag, typename subject_type::type
171 >::type type;
172
173 static type call()
174 {
175 return proto::make_expr<OpTag>(subject_type::call());
176 }
177 };
178
179 ///////////////////////////////////////////////////////////////////////////
180 template <typename Sequence, typename OpTag, typename Domain>
181 struct make_nary_proto_expr
182 {
183 typedef detail::nary_proto_expr_function<OpTag, Domain>
184 make_proto_expr;
185
186 typedef typename fusion::result_of::fold<
187 Sequence, unused_type, make_proto_expr
188 >::type type;
189
190 static type call()
191 {
192 return fusion::fold(Sequence(), unused, make_proto_expr());
193 }
194 };
195
196 ///////////////////////////////////////////////////////////////////////////
197 namespace detail
198 {
199 // Starting with newer versions of Proto, all Proto expressions are at
200 // the same time Fusion sequences. This is the correct behavior, but
201 // we need to distinguish between Fusion sequences and Proto
202 // expressions. This meta-function does exactly that.
203 template <typename T>
204 struct is_fusion_sequence_but_not_proto_expr
205 : mpl::and_<
206 fusion::traits::is_sequence<T>
207 , mpl::not_<proto::is_expr<T> > >
208 {};
209 }
210 }}
211
212 #endif