]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/proto/include/boost/proto/transform/make.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / proto / include / boost / proto / transform / make.hpp
CommitLineData
7c673cae
FG
1///////////////////////////////////////////////////////////////////////////////
2/// \file make.hpp
3/// Contains definition of the make<> transform.
4//
5// Copyright 2008 Eric Niebler. Distributed under the Boost
6// Software License, Version 1.0. (See accompanying file
7// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8
9#ifndef BOOST_PROTO_TRANSFORM_MAKE_HPP_EAN_12_02_2007
10#define BOOST_PROTO_TRANSFORM_MAKE_HPP_EAN_12_02_2007
11
12#include <boost/detail/workaround.hpp>
13#include <boost/preprocessor/repetition/enum.hpp>
14#include <boost/preprocessor/repetition/enum_params.hpp>
15#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
16#include <boost/preprocessor/repetition/enum_binary_params.hpp>
17#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
18#include <boost/preprocessor/repetition/repeat_from_to.hpp>
19#include <boost/preprocessor/facilities/intercept.hpp>
20#include <boost/preprocessor/cat.hpp>
21#include <boost/preprocessor/iteration/iterate.hpp>
22#include <boost/preprocessor/selection/max.hpp>
23#include <boost/preprocessor/arithmetic/inc.hpp>
24#include <boost/mpl/and.hpp>
25#include <boost/mpl/aux_/has_type.hpp>
26#include <boost/proto/detail/template_arity.hpp>
27#include <boost/utility/result_of.hpp>
28#include <boost/proto/proto_fwd.hpp>
29#include <boost/proto/traits.hpp>
30#include <boost/proto/args.hpp>
31#include <boost/proto/transform/impl.hpp>
32#include <boost/proto/transform/detail/pack.hpp>
33#include <boost/proto/detail/as_lvalue.hpp>
34#include <boost/proto/detail/ignore_unused.hpp>
35
36#if defined(_MSC_VER)
37# pragma warning(push)
38# pragma warning(disable : 4714) // function 'xxx' marked as __forceinline not inlined
39#endif
40
41namespace boost { namespace proto
42{
43 namespace detail
44 {
45 template<typename T>
46 struct is_applyable
47 : mpl::and_<is_callable<T>, is_transform<T> >
48 {};
49
50 template<typename T, bool HasType = mpl::aux::has_type<T>::value>
51 struct nested_type
52 {
53 typedef typename T::type type;
54 };
55
56 template<typename T>
57 struct nested_type<T, false>
58 {
59 typedef T type;
60 };
61
62 template<typename T, bool Applied>
63 struct nested_type_if
64 {
65 typedef T type;
66 static bool const applied = false;
67 };
68
69 template<typename T>
70 struct nested_type_if<T, true>
71 : nested_type<T>
72 {
73 static bool const applied = true;
74 };
75
76 template<
77 typename R
78 , typename Expr, typename State, typename Data
79 BOOST_PROTO_TEMPLATE_ARITY_PARAM(long Arity = detail::template_arity<R>::value)
80 >
81 struct make_
82 {
83 typedef R type;
84 static bool const applied = false;
85 };
86
87 template<
88 typename R
89 , typename Expr, typename State, typename Data
90 , bool IsApplyable = is_applyable<R>::value
91 >
92 struct make_if_
93 : make_<R, Expr, State, Data>
94 {};
95
96 template<typename R, typename Expr, typename State, typename Data>
97 struct make_if_<R, Expr, State, Data, true>
98 : uncvref<typename when<_, R>::template impl<Expr, State, Data>::result_type>
99 {
100 static bool const applied = true;
101 };
102
103 #if BOOST_WORKAROUND(__GNUC__, == 3) || (BOOST_WORKAROUND(__GNUC__, == 4) && __GNUC_MINOR__ == 0)
104 // work around GCC bug
105 template<typename Tag, typename Args, long N, typename Expr, typename State, typename Data>
106 struct make_if_<proto::expr<Tag, Args, N>, Expr, State, Data, false>
107 {
108 typedef proto::expr<Tag, Args, N> type;
109 static bool const applied = false;
110 };
111
112 // work around GCC bug
113 template<typename Tag, typename Args, long N, typename Expr, typename State, typename Data>
114 struct make_if_<proto::basic_expr<Tag, Args, N>, Expr, State, Data, false>
115 {
116 typedef proto::basic_expr<Tag, Args, N> type;
117 static bool const applied = false;
118 };
119 #endif
120
121 template<typename Type, bool IsAggregate = detail::is_aggregate_<Type>::value>
122 struct construct_
123 {
124 typedef Type result_type;
125
126 BOOST_FORCEINLINE
127 Type operator ()() const
128 {
129 return Type();
130 }
131
132 // Other overloads generated by the preprocessor
133 #include <boost/proto/transform/detail/construct_funop.hpp>
134 };
135
136 template<typename Type>
137 struct construct_<Type, true>
138 {
139 typedef Type result_type;
140
141 BOOST_FORCEINLINE
142 Type operator ()() const
143 {
144 return Type();
145 }
146
147 // Other overloads generated by the preprocessor
148 #include <boost/proto/transform/detail/construct_pod_funop.hpp>
149 };
150
151 }
152
153 /// \brief A PrimitiveTransform which prevents another PrimitiveTransform
154 /// from being applied in an \c ObjectTransform.
155 ///
156 /// When building higher order transforms with <tt>make\<\></tt> or
157 /// <tt>lazy\<\></tt>, you sometimes would like to build types that
158 /// are parameterized with Proto transforms. In such lambda-style
159 /// transforms, Proto will unhelpfully find all nested transforms
160 /// and apply them, even if you don't want them to be applied. Consider
161 /// the following transform, which will replace the \c _ in
162 /// <tt>Bar<_>()</tt> with <tt>proto::terminal\<int\>::type</tt>:
163 ///
164 /// \code
165 /// template<typename T>
166 /// struct Bar
167 /// {};
168 ///
169 /// struct Foo
170 /// : proto::when<_, Bar<_>() >
171 /// {};
172 ///
173 /// proto::terminal<int>::type i = {0};
174 ///
175 /// int main()
176 /// {
177 /// Foo()(i);
178 /// std::cout << typeid(Foo()(i)).name() << std::endl;
179 /// }
180 /// \endcode
181 ///
182 /// If you actually wanted to default-construct an object of type
183 /// <tt>Bar\<_\></tt>, you would have to protect the \c _ to prevent
184 /// it from being applied. You can use <tt>proto::protect\<\></tt>
185 /// as follows:
186 ///
187 /// \code
188 /// // OK: replace anything with Bar<_>()
189 /// struct Foo
190 /// : proto::when<_, Bar<protect<_> >() >
191 /// {};
192 /// \endcode
193 template<typename PrimitiveTransform>
194 struct protect : transform<protect<PrimitiveTransform> >
195 {
196 template<typename, typename, typename>
197 struct impl
198 {
199 typedef PrimitiveTransform result_type;
200 };
201 };
202
203 /// \brief A PrimitiveTransform which computes a type by evaluating any
204 /// nested transforms and then constructs an object of that type.
205 ///
206 /// The <tt>make\<\></tt> transform checks to see if \c Object is a template.
207 /// If it is, the template type is disassembled to find nested transforms.
208 /// Proto considers the following types to represent transforms:
209 ///
210 /// \li Function types
211 /// \li Function pointer types
212 /// \li Types for which <tt>proto::is_callable\< type \>::value</tt> is \c true
213 ///
214 /// <tt>boost::result_of\<make\<T\<X0,X1,...\> \>(Expr, State, Data)\>::type</tt>
215 /// is evaluated as follows. For each \c X in <tt>X0,X1,...</tt>, do:
216 ///
217 /// \li If \c X is a template like <tt>U\<Y0,Y1,...\></tt>, then let <tt>X'</tt>
218 /// be <tt>boost::result_of\<make\<U\<Y0,Y1,...\> \>(Expr, State, Data)\>::type</tt>
219 /// (which evaluates this procedure recursively). Note whether any
220 /// substitutions took place during this operation.
221 /// \li Otherwise, if \c X is a transform, then let <tt>X'</tt> be
222 /// <tt>boost::result_of\<when\<_, X\>(Expr, State, Data)\>::type</tt>.
223 /// Note that a substitution took place.
224 /// \li Otherwise, let <tt>X'</tt> be \c X, and note that no substitution
225 /// took place.
226 /// \li If any substitutions took place in any of the above steps and
227 /// <tt>T\<X0',X1',...\></tt> has a nested <tt>::type</tt> typedef,
228 /// the result type is <tt>T\<X0',X1',...\>::type</tt>.
229 /// \li Otherwise, the result type is <tt>T\<X0',X1',...\></tt>.
230 ///
231 /// Note that <tt>when\<\></tt> is implemented in terms of <tt>call\<\></tt>
232 /// and <tt>make\<\></tt>, so the above procedure is evaluated recursively.
233 template<typename Object>
234 struct make : transform<make<Object> >
235 {
236 template<typename Expr, typename State, typename Data>
237 struct impl : transform_impl<Expr, State, Data>
238 {
239 typedef typename detail::make_if_<Object, Expr, State, Data>::type result_type;
240
241 /// \return <tt>result_type()</tt>
242 BOOST_FORCEINLINE
243 result_type operator ()(
244 typename impl::expr_param
245 , typename impl::state_param
246 , typename impl::data_param
247 ) const
248 {
249 return result_type();
250 }
251 };
252 };
253
254 /// INTERNAL ONLY
255 template<typename Fun>
256 struct make<detail::msvc_fun_workaround<Fun> >
257 : make<Fun>
258 {};
259
260 // Other specializations generated by the preprocessor.
261 #include <boost/proto/transform/detail/make.hpp>
262 #include <boost/proto/transform/detail/make_gcc_workaround.hpp>
263
264 /// INTERNAL ONLY
265 ///
266 template<typename Object>
267 struct is_callable<make<Object> >
268 : mpl::true_
269 {};
270
271 /// INTERNAL ONLY
272 ///
273 template<typename PrimitiveTransform>
274 struct is_callable<protect<PrimitiveTransform> >
275 : mpl::true_
276 {};
277
278}}
279
280#if defined(_MSC_VER)
281# pragma warning(pop)
282#endif
283
284#endif