]>
Commit | Line | Data |
---|---|---|
92f5a8d4 TL |
1 | // Copyright Daniel Wallin 2006. |
2 | // Copyright Cromwell D. Enage 2017. | |
3 | // Distributed under the Boost Software License, Version 1.0. | |
4 | // (See accompanying file LICENSE_1_0.txt or copy at | |
5 | // http://www.boost.org/LICENSE_1_0.txt) | |
6 | ||
7 | #ifndef BOOST_PARAMETER_AUX_PREPROCESSOR_IMPL_FUNCTION_CAST_HPP | |
8 | #define BOOST_PARAMETER_AUX_PREPROCESSOR_IMPL_FUNCTION_CAST_HPP | |
9 | ||
10 | #include <boost/parameter/config.hpp> | |
11 | ||
12 | #if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) | |
13 | ||
14 | namespace boost { namespace parameter { namespace aux { | |
15 | ||
16 | // Handles possible implicit casts. Used by preprocessor.hpp | |
17 | // to normalize user input. | |
18 | // | |
19 | // cast<void*>::execute() is identity | |
20 | // cast<void*(X)>::execute() is identity | |
21 | // cast<void(X)>::execute() casts to X | |
22 | // | |
23 | // preprocessor.hpp uses this like this: | |
24 | // | |
25 | // #define X(value, predicate) | |
26 | // cast<void predicate>::execute(value) | |
27 | // | |
28 | // X(something, *) | |
29 | // X(something, *(predicate)) | |
30 | // X(something, (int)) | |
31 | template <typename VoidExpr, typename Args> | |
32 | struct cast; | |
33 | }}} // namespace boost::parameter::aux | |
34 | ||
35 | #include <boost/parameter/aux_/use_default_tag.hpp> | |
36 | ||
37 | namespace boost { namespace parameter { namespace aux { | |
38 | ||
39 | template <typename T, typename B> | |
40 | inline ::boost::parameter::aux::use_default_tag | |
41 | forward(::boost::parameter::aux::use_default_tag) | |
42 | { | |
43 | return ::boost::parameter::aux::use_default_tag(); | |
44 | } | |
45 | }}} // namespace boost::parameter::aux | |
46 | ||
47 | #include <boost/mpl/bool.hpp> | |
48 | #include <boost/mpl/if.hpp> | |
49 | ||
50 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) | |
51 | #include <boost/mp11/integral.hpp> | |
52 | #include <boost/mp11/utility.hpp> | |
53 | #endif | |
54 | ||
55 | namespace boost { namespace parameter { namespace aux { | |
56 | ||
57 | template <typename Args> | |
58 | struct cast<void*,Args> | |
59 | { | |
60 | template <typename T, typename B> | |
61 | struct apply | |
62 | { | |
63 | typedef typename ::boost::mpl | |
64 | ::if_<B,T,::boost::mpl::true_>::type type; | |
65 | }; | |
66 | ||
67 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) | |
68 | template <typename T, typename B> | |
69 | using fn = ::boost::mp11::mp_if<B,T,::boost::mp11::mp_true>; | |
70 | #endif | |
71 | }; | |
72 | }}} // namespace boost::parameter::aux | |
73 | ||
74 | #include <boost/parameter/aux_/void.hpp> | |
75 | ||
76 | namespace boost { namespace parameter { namespace aux { | |
77 | ||
78 | template <typename Predicate, typename Args> | |
79 | struct cast<void*(Predicate),Args> | |
80 | : ::boost::parameter::aux::cast<void*,Args> | |
81 | { | |
82 | }; | |
83 | }}} // namespace boost::parameter::aux | |
84 | ||
85 | #include <boost/mpl/placeholders.hpp> | |
86 | ||
87 | namespace boost { namespace parameter { namespace aux { | |
88 | ||
89 | // This is a hack used in cast<> to turn the user supplied type, | |
90 | // which may or may not be a placeholder expression, into one, | |
91 | // so that it will be properly evaluated by mpl::apply. | |
92 | template <typename T, typename Dummy = ::boost::mpl::_1> | |
93 | struct as_placeholder_expr | |
94 | { | |
95 | typedef T type; | |
96 | }; | |
97 | }}} // namespace boost::parameter::aux | |
98 | ||
99 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) | |
100 | #include <boost/mp11/list.hpp> | |
101 | ||
102 | namespace boost { namespace parameter { namespace aux { | |
103 | ||
104 | template <typename Target, typename Source, typename Args> | |
105 | struct apply_target_fn | |
106 | { | |
107 | using type = ::boost::mp11 | |
108 | ::mp_apply_q<Target,::boost::mp11::mp_list<Source,Args> >; | |
109 | }; | |
110 | }}} // namespace boost::parameter::aux | |
111 | ||
112 | #endif | |
113 | ||
114 | #include <boost/mpl/apply.hpp> | |
115 | ||
116 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) | |
117 | #include <boost/parameter/aux_/has_nested_template_fn.hpp> | |
118 | #include <type_traits> | |
119 | #else | |
120 | #include <boost/type_traits/is_same.hpp> | |
121 | #include <boost/type_traits/remove_const.hpp> | |
122 | #include <boost/type_traits/remove_reference.hpp> | |
123 | #endif | |
124 | ||
125 | namespace boost { namespace parameter { namespace aux { | |
126 | ||
127 | template <typename Target, typename Source, typename Args> | |
128 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) | |
129 | using is_target_same_as_source = ::std::is_same< | |
130 | typename ::std::remove_const< | |
131 | typename ::std::remove_reference< | |
132 | typename ::boost::mp11::mp_if< | |
133 | ::boost::parameter::aux::has_nested_template_fn<Target> | |
134 | , ::boost::parameter::aux | |
135 | ::apply_target_fn<Target,Source,Args> | |
136 | , ::boost::mpl::apply2< | |
137 | ::boost::parameter::aux::as_placeholder_expr<Target> | |
138 | , Source | |
139 | , Args | |
140 | > | |
141 | >::type | |
142 | >::type | |
143 | >::type | |
144 | , typename ::std::remove_const<Source>::type | |
145 | >; | |
146 | #else // !defined(BOOST_PARAMETER_CAN_USE_MP11) | |
147 | struct is_target_same_as_source | |
148 | : ::boost::mpl::if_< | |
149 | ::boost::is_same< | |
150 | typename ::boost::remove_const< | |
151 | typename ::boost::remove_reference< | |
152 | typename ::boost::mpl::apply2< | |
153 | ::boost::parameter::aux | |
154 | ::as_placeholder_expr<Target> | |
155 | , Source | |
156 | , Args | |
157 | >::type | |
158 | >::type | |
159 | >::type | |
160 | , typename ::boost::remove_const<Source>::type | |
161 | > | |
162 | , ::boost::mpl::true_ | |
163 | , ::boost::mpl::false_ | |
164 | >::type | |
165 | { | |
166 | }; | |
167 | #endif // BOOST_PARAMETER_CAN_USE_MP11 | |
168 | }}} // namespace boost::parameter::aux | |
169 | ||
170 | #if !defined(BOOST_PARAMETER_CAN_USE_MP11) | |
171 | #include <boost/type_traits/add_const.hpp> | |
172 | #include <boost/type_traits/is_const.hpp> | |
173 | #endif | |
174 | ||
175 | namespace boost { namespace parameter { namespace aux { | |
176 | ||
177 | // Covers the case where is_convertible<Source,Target> but not | |
178 | // is_same<Source,Target>. Use cases are covered | |
179 | // by test/normalize_argument_types.cpp | |
180 | template <typename Source, typename Target> | |
181 | class cast_convert | |
182 | { | |
183 | typedef ::boost::parameter::aux::cast_convert<Source,Target> _self; | |
184 | ||
185 | public: | |
186 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) | |
187 | using type = typename ::boost::mp11::mp_if< | |
188 | ::std::is_const<Source> | |
189 | , ::std::add_const<Target> | |
190 | , ::std::remove_const<Target> | |
191 | >::type; | |
192 | #else | |
193 | typedef typename boost::mpl::eval_if< | |
194 | ::boost::is_const<Source> | |
195 | , ::boost::add_const<Target> | |
196 | , ::boost::remove_const<Target> | |
197 | >::type type; | |
198 | #endif | |
199 | ||
200 | private: | |
201 | inline static typename _self::type | |
202 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) | |
203 | _copy(typename ::std::remove_const<Target>::type value) | |
204 | #else | |
205 | _copy(typename ::boost::remove_const<Target>::type value) | |
206 | #endif | |
207 | { | |
208 | return value; | |
209 | } | |
210 | ||
211 | public: | |
212 | inline static typename _self::type evaluate(Source&& source) | |
213 | { | |
214 | return _self::_copy(source); | |
215 | } | |
216 | }; | |
217 | ||
218 | template <typename Target, typename Source, typename Args> | |
219 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) | |
220 | using cast_impl = ::std::remove_reference< | |
221 | typename ::boost::mp11::mp_if< | |
222 | ::boost::parameter::aux::has_nested_template_fn<Target> | |
223 | , ::boost::parameter::aux | |
224 | ::is_target_same_as_source<Target,Source,Args> | |
225 | , ::boost::mpl::apply2< | |
226 | ::boost::parameter::aux::as_placeholder_expr<Target> | |
227 | , Source | |
228 | , Args | |
229 | > | |
230 | >::type | |
231 | >; | |
232 | #else | |
233 | struct cast_impl | |
234 | : ::boost::remove_reference< | |
235 | typename ::boost::mpl::apply2< | |
236 | ::boost::parameter::aux::as_placeholder_expr<Target> | |
237 | , Source | |
238 | , Args | |
239 | >::type | |
240 | > | |
241 | { | |
242 | }; | |
243 | #endif // BOOST_PARAMETER_CAN_USE_MP11 | |
244 | }}} // namespace boost::parameter::aux | |
245 | ||
246 | #include <boost/mpl/eval_if.hpp> | |
247 | #include <boost/mpl/identity.hpp> | |
248 | ||
249 | namespace boost { namespace parameter { namespace aux { | |
250 | ||
251 | template <typename Target, typename Args> | |
252 | struct cast<void(Target),Args> | |
253 | { | |
254 | template <typename T, typename B> | |
255 | struct apply | |
256 | { | |
257 | typedef typename ::boost::mpl::eval_if< | |
258 | B | |
259 | , ::boost::mpl::eval_if< | |
260 | ::boost::parameter::aux | |
261 | ::is_target_same_as_source<Target,T,Args> | |
262 | , ::boost::mpl::identity<T> | |
263 | , ::boost::parameter::aux::cast_impl<Target,T,Args> | |
264 | > | |
265 | , ::boost::parameter::aux | |
266 | ::is_target_same_as_source<Target,T,Args> | |
267 | >::type type; | |
268 | }; | |
269 | ||
270 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) | |
271 | template <typename T, typename B> | |
272 | using fn = typename ::boost::mp11::mp_if< | |
273 | B | |
274 | , ::boost::mp11::mp_if< | |
275 | ::boost::parameter::aux | |
276 | ::is_target_same_as_source<Target,T,Args> | |
277 | , ::boost::mp11::mp_identity<T> | |
278 | , ::boost::parameter::aux::cast_impl<Target,T,Args> | |
279 | > | |
280 | , ::boost::parameter::aux | |
281 | ::is_target_same_as_source<Target,T,Args> | |
282 | >::type; | |
283 | #endif | |
284 | }; | |
285 | }}} // namespace boost::parameter::aux | |
286 | ||
287 | #include <boost/parameter/value_type.hpp> | |
288 | ||
289 | #if !defined(BOOST_PARAMETER_CAN_USE_MP11) | |
290 | #include <boost/mpl/apply_wrap.hpp> | |
291 | #endif | |
292 | ||
293 | // Expands to the target type of the argument as indicated by the predicate. | |
294 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) | |
295 | #define BOOST_PARAMETER_FUNCTION_CAST_T(tag, predicate, args) \ | |
296 | ::boost::mp11::mp_apply_q< \ | |
297 | ::boost::parameter::aux::cast<void predicate, args> \ | |
298 | , ::boost::mp11::mp_list< \ | |
299 | typename ::boost::parameter::value_type< \ | |
300 | args \ | |
301 | , tag \ | |
302 | , ::boost::parameter::aux::use_default_tag \ | |
303 | >::type \ | |
304 | , ::boost::mp11::mp_true \ | |
305 | > \ | |
306 | > | |
307 | /**/ | |
308 | #else // !defined(BOOST_PARAMETER_CAN_USE_MP11) | |
309 | #define BOOST_PARAMETER_FUNCTION_CAST_T(tag, predicate, args) \ | |
310 | typename ::boost::mpl::apply_wrap2< \ | |
311 | ::boost::parameter::aux::cast<void predicate, args> \ | |
312 | , typename ::boost::parameter::value_type< \ | |
313 | args \ | |
314 | , tag \ | |
315 | , ::boost::parameter::aux::use_default_tag \ | |
316 | >::type \ | |
317 | , ::boost::mpl::true_ \ | |
318 | >::type | |
319 | /**/ | |
320 | #endif // BOOST_PARAMETER_CAN_USE_MP11 | |
321 | ||
322 | // Expands to boost::mpl::true_ if and only if the argument's source and | |
323 | // target types are the same. | |
324 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) | |
325 | #define BOOST_PARAMETER_FUNCTION_CAST_B(tag, predicate, args) \ | |
326 | ::boost::mp11::mp_apply_q< \ | |
327 | ::boost::parameter::aux::cast<void predicate, args> \ | |
328 | , ::boost::mp11::mp_list< \ | |
329 | typename ::boost::parameter::value_type< \ | |
330 | args \ | |
331 | , tag \ | |
332 | , ::boost::parameter::aux::use_default_tag \ | |
333 | >::type \ | |
334 | , ::boost::mp11::mp_false \ | |
335 | > \ | |
336 | > | |
337 | /**/ | |
338 | #else // !defined(BOOST_PARAMETER_CAN_USE_MP11) | |
339 | #define BOOST_PARAMETER_FUNCTION_CAST_B(tag, predicate, args) \ | |
340 | typename ::boost::mpl::apply_wrap2< \ | |
341 | ::boost::parameter::aux::cast<void predicate, args> \ | |
342 | , typename ::boost::parameter::value_type< \ | |
343 | args \ | |
344 | , tag \ | |
345 | , ::boost::parameter::aux::use_default_tag \ | |
346 | >::type \ | |
347 | , ::boost::mpl::false_ \ | |
348 | >::type | |
349 | /**/ | |
350 | #endif // BOOST_PARAMETER_CAN_USE_MP11 | |
351 | ||
352 | #include <boost/core/enable_if.hpp> | |
353 | #include <utility> | |
354 | ||
355 | namespace boost { namespace parameter { namespace aux { | |
356 | ||
357 | // If the source and target types are not the same, | |
358 | // then perform an implicit conversion. | |
359 | template <typename Target, typename B, typename Source> | |
360 | inline typename ::boost::lazy_disable_if< | |
361 | B | |
362 | , ::boost::parameter::aux::cast_convert<Source,Target> | |
363 | >::type | |
364 | forward(Source&& source) | |
365 | { | |
366 | return ::boost::parameter::aux::cast_convert<Source,Target> | |
367 | ::evaluate(::std::forward<Source>(source)); | |
368 | } | |
369 | ||
370 | // If the source and target types are the same, | |
371 | // then simply forward the argument. | |
372 | // However, treat rvalue references to scalars as const lvalue references. | |
373 | template <typename T, typename B> | |
374 | inline typename ::boost::enable_if<B,T const&>::type forward(T const& t) | |
375 | { | |
376 | return t; | |
377 | } | |
378 | ||
379 | template <typename T, typename B> | |
380 | inline typename ::boost::enable_if< | |
381 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) | |
382 | ::boost::mp11::mp_if< | |
383 | B | |
384 | , ::boost::mp11::mp_if< | |
385 | ::std::is_const<T> | |
386 | , ::boost::mp11::mp_false | |
387 | , ::boost::mp11::mp_true | |
388 | > | |
389 | , ::boost::mp11::mp_false | |
390 | > | |
391 | #else | |
392 | typename ::boost::mpl::eval_if< | |
393 | B | |
394 | , ::boost::mpl::if_< | |
395 | ::boost::is_const<T> | |
396 | , ::boost::mpl::false_ | |
397 | , ::boost::mpl::true_ | |
398 | > | |
399 | , ::boost::mpl::false_ | |
400 | >::type | |
401 | #endif // BOOST_PARAMETER_CAN_USE_MP11 | |
402 | , T& | |
403 | >::type | |
404 | forward(T& t) | |
405 | { | |
406 | return t; | |
407 | } | |
408 | }}} // namespace boost::parameter::aux | |
409 | ||
410 | #include <boost/type_traits/is_scalar.hpp> | |
411 | ||
412 | namespace boost { namespace parameter { namespace aux { | |
413 | ||
414 | template <typename T, typename B> | |
415 | inline typename ::boost::enable_if< | |
416 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) | |
417 | ::boost::mp11::mp_if< | |
418 | B | |
419 | , ::boost::mp11::mp_if< | |
420 | ::std::is_scalar<T> | |
421 | , ::boost::mp11::mp_false | |
422 | , ::boost::mp11::mp_true | |
423 | > | |
424 | , ::boost::mp11::mp_false | |
425 | > | |
426 | #else | |
427 | typename ::boost::mpl::eval_if< | |
428 | B | |
429 | , ::boost::mpl::if_< | |
430 | ::boost::is_scalar<T> | |
431 | , ::boost::mpl::false_ | |
432 | , ::boost::mpl::true_ | |
433 | > | |
434 | , ::boost::mpl::false_ | |
435 | >::type | |
436 | #endif // BOOST_PARAMETER_CAN_USE_MP11 | |
437 | , T const&& | |
438 | >::type | |
439 | forward(T const&& t) | |
440 | { | |
441 | return static_cast<T const&&>(t); | |
442 | } | |
443 | ||
444 | template <typename T, typename B> | |
445 | inline typename ::boost::enable_if< | |
446 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) | |
447 | ::boost::mp11::mp_if< | |
448 | B | |
449 | , ::boost::mp11::mp_if< | |
450 | ::std::is_scalar<T> | |
451 | , ::boost::mp11::mp_false | |
452 | , ::boost::mp11::mp_true | |
453 | > | |
454 | , ::boost::mp11::mp_false | |
455 | > | |
456 | #else | |
457 | typename ::boost::mpl::eval_if< | |
458 | B | |
459 | , ::boost::mpl::if_< | |
460 | ::boost::is_scalar<T> | |
461 | , ::boost::mpl::false_ | |
462 | , ::boost::mpl::true_ | |
463 | > | |
464 | , ::boost::mpl::false_ | |
465 | >::type | |
466 | #endif // BOOST_PARAMETER_CAN_USE_MP11 | |
467 | , T&& | |
468 | >::type | |
469 | forward(T&& t) | |
470 | { | |
471 | return ::std::forward<T>(t); | |
472 | } | |
473 | }}} // namespace boost::parameter::aux | |
474 | ||
20effc67 | 475 | #elif BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564)) |
92f5a8d4 TL |
476 | #define BOOST_PARAMETER_FUNCTION_CAST_T(value_t, predicate, args) value_t |
477 | #define BOOST_PARAMETER_FUNCTION_CAST_B(value, predicate, args) value | |
478 | #else // no perfect forwarding support and no Borland workarounds needed | |
479 | ||
480 | namespace boost { namespace parameter { namespace aux { | |
481 | ||
482 | // Handles possible implicit casts. Used by preprocessor.hpp | |
483 | // to normalize user input. | |
484 | // | |
485 | // cast<void*>::execute() is identity | |
486 | // cast<void*(X)>::execute() is identity | |
487 | // cast<void(X)>::execute() casts to X | |
488 | // | |
489 | // preprocessor.hpp uses this like this: | |
490 | // | |
491 | // #define X(value, predicate) | |
492 | // cast<void predicate>::execute(value) | |
493 | // | |
494 | // X(something, *) | |
495 | // X(something, *(predicate)) | |
496 | // X(something, (int)) | |
497 | template <typename VoidExpr, typename Args> | |
498 | struct cast; | |
499 | }}} // namespace boost::parameter::aux | |
500 | ||
501 | #include <boost/parameter/aux_/use_default_tag.hpp> | |
502 | #include <boost/mpl/bool.hpp> | |
503 | #include <boost/mpl/if.hpp> | |
504 | ||
505 | namespace boost { namespace parameter { namespace aux { | |
506 | ||
507 | template <typename Args> | |
508 | struct cast<void*,Args> | |
509 | { | |
510 | template <typename T> | |
511 | struct apply | |
512 | { | |
513 | typedef T& type; | |
514 | }; | |
515 | ||
516 | inline static ::boost::parameter::aux::use_default_tag | |
517 | execute(::boost::parameter::aux::use_default_tag) | |
518 | { | |
519 | return ::boost::parameter::aux::use_default_tag(); | |
520 | } | |
521 | ||
522 | template <typename U> | |
523 | inline static U& execute(U& value) | |
524 | { | |
525 | return value; | |
526 | } | |
527 | }; | |
528 | }}} // namespace boost::parameter::aux | |
529 | ||
530 | #include <boost/parameter/aux_/void.hpp> | |
531 | ||
532 | namespace boost { namespace parameter { namespace aux { | |
533 | ||
534 | template <typename Predicate, typename Args> | |
535 | #if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x580)) | |
536 | struct cast< ::boost::parameter::aux::voidstar(Predicate),Args> | |
537 | #else | |
538 | struct cast<void*(Predicate),Args> | |
539 | #endif | |
540 | : ::boost::parameter::aux::cast<void*,Args> | |
541 | { | |
542 | }; | |
543 | }}} // namespace boost::parameter::aux | |
544 | ||
545 | #include <boost/mpl/placeholders.hpp> | |
546 | ||
547 | namespace boost { namespace parameter { namespace aux { | |
548 | ||
549 | // This is a hack used in cast<> to turn the user supplied type, | |
550 | // which may or may not be a placeholder expression, into one, | |
551 | // so that it will be properly evaluated by mpl::apply. | |
552 | template <typename T, typename Dummy = ::boost::mpl::_1> | |
553 | struct as_placeholder_expr | |
554 | { | |
555 | typedef T type; | |
556 | }; | |
557 | }}} // namespace boost::parameter::aux | |
558 | ||
559 | #include <boost/mpl/apply.hpp> | |
560 | #include <boost/type_traits/is_same.hpp> | |
561 | #include <boost/type_traits/remove_const.hpp> | |
562 | #include <boost/type_traits/remove_reference.hpp> | |
563 | ||
564 | namespace boost { namespace parameter { namespace aux { | |
565 | ||
566 | template <typename Target, typename Source, typename Args> | |
567 | struct is_target_same_as_source | |
568 | : ::boost::mpl::if_< | |
569 | ::boost::is_same< | |
570 | typename ::boost::remove_const< | |
571 | typename ::boost::remove_reference< | |
572 | typename ::boost::mpl::apply2< | |
573 | ::boost::parameter::aux | |
574 | ::as_placeholder_expr<Target> | |
575 | , Source | |
576 | , Args | |
577 | >::type | |
578 | >::type | |
579 | >::type | |
580 | , typename ::boost::remove_const<Source>::type | |
581 | > | |
582 | , ::boost::mpl::true_ | |
583 | , ::boost::mpl::false_ | |
584 | >::type | |
585 | { | |
586 | }; | |
587 | ||
588 | template < | |
589 | typename Target | |
590 | , typename Source | |
591 | , typename Args | |
592 | , typename Enable = ::boost::parameter::aux | |
593 | ::is_target_same_as_source<Target,Source,Args> | |
594 | > | |
595 | struct cast_impl | |
596 | { | |
597 | typedef Source& type; | |
598 | ||
599 | inline static Source& evaluate(Source& value) | |
600 | { | |
601 | return value; | |
602 | } | |
603 | }; | |
604 | }}} // namespace boost::parameter::aux | |
605 | ||
606 | #include <boost/type_traits/add_const.hpp> | |
607 | #include <boost/type_traits/add_lvalue_reference.hpp> | |
608 | ||
609 | namespace boost { namespace parameter { namespace aux { | |
610 | ||
611 | // Covers the case where is_convertible<Source,Target> but not | |
612 | // is_same<Source,Target>. Use cases are covered | |
613 | // by test/normalize_argument_types.cpp | |
614 | template <typename Source, typename Target> | |
615 | class cast_convert | |
616 | { | |
617 | typedef ::boost::parameter::aux::cast_convert<Source,Target> _self; | |
618 | ||
619 | public: | |
620 | typedef typename ::boost::add_lvalue_reference< | |
621 | typename ::boost::add_const<Target>::type | |
622 | >::type type; | |
623 | ||
624 | private: | |
625 | template <typename U> | |
626 | inline static typename _self::type _mod_const(U const& u) | |
627 | { | |
628 | return u; | |
629 | } | |
630 | ||
631 | inline static Target _copy(Target value) | |
632 | { | |
633 | return value; | |
634 | } | |
635 | ||
636 | public: | |
637 | inline static typename _self::type evaluate(Source& source) | |
638 | { | |
639 | return _self::_mod_const(_self::_copy(source)); | |
640 | } | |
641 | }; | |
642 | ||
643 | template <typename Target, typename Source, typename Args> | |
644 | struct cast_impl<Target,Source,Args,::boost::mpl::false_> | |
645 | : ::boost::parameter::aux::cast_convert< | |
646 | Source, | |
647 | typename ::boost::mpl::apply2< | |
648 | ::boost::parameter::aux::as_placeholder_expr<Target> | |
649 | , Source | |
650 | , Args | |
651 | >::type | |
652 | > | |
653 | { | |
654 | }; | |
655 | }}} // namespace boost::parameter::aux | |
656 | ||
657 | #include <boost/mpl/eval_if.hpp> | |
658 | ||
659 | namespace boost { namespace parameter { namespace aux { | |
660 | ||
661 | template <typename Target, typename Args> | |
662 | struct cast<void(Target),Args> | |
663 | { | |
664 | template <typename T> | |
665 | struct apply | |
666 | { | |
667 | typedef typename ::boost::mpl::eval_if< | |
668 | ::boost::parameter::aux | |
669 | ::is_target_same_as_source<Target,T,Args> | |
670 | , ::boost::add_lvalue_reference<T> | |
671 | , ::boost::parameter::aux::cast_impl< | |
672 | Target | |
673 | , T | |
674 | , Args | |
675 | , ::boost::mpl::false_ | |
676 | > | |
677 | >::type type; | |
678 | }; | |
679 | ||
680 | inline static ::boost::parameter::aux::use_default_tag | |
681 | execute(::boost::parameter::aux::use_default_tag) | |
682 | { | |
683 | return ::boost::parameter::aux::use_default_tag(); | |
684 | } | |
685 | ||
686 | template <typename U> | |
687 | inline static typename ::boost::parameter::aux | |
688 | ::cast_impl<Target,U const,Args>::type | |
689 | execute(U const& value) | |
690 | { | |
691 | return ::boost::parameter::aux | |
692 | ::cast_impl<Target,U const,Args>::evaluate(value); | |
693 | } | |
694 | ||
695 | template <typename U> | |
696 | inline static typename ::boost::parameter::aux | |
697 | ::cast_impl<Target,U,Args>::type | |
698 | execute(U& value) | |
699 | { | |
700 | return ::boost::parameter::aux | |
701 | ::cast_impl<Target,U,Args>::evaluate(value); | |
702 | } | |
703 | }; | |
704 | }}} // namespace boost::parameter::aux | |
705 | ||
706 | #include <boost/mpl/apply_wrap.hpp> | |
707 | #include <boost/parameter/value_type.hpp> | |
708 | ||
709 | // Expands to the reference-qualified target type of the argument | |
710 | // as indicated by the predicate. | |
711 | #define BOOST_PARAMETER_FUNCTION_CAST_T(tag, predicate, args) \ | |
712 | typename ::boost::mpl::apply_wrap1< \ | |
713 | ::boost::parameter::aux::cast<void predicate, args> \ | |
714 | , typename ::boost::parameter::value_type< \ | |
715 | args \ | |
716 | , tag \ | |
717 | , ::boost::parameter::aux::use_default_tag \ | |
718 | >::type \ | |
719 | >::type | |
720 | /**/ | |
721 | ||
722 | // Expands to the converted or passed-through value | |
723 | // as indicated by the predicate. | |
724 | #define BOOST_PARAMETER_FUNCTION_CAST_B(value, predicate, args) \ | |
725 | ::boost::parameter::aux::cast<void predicate, args>::execute(value) | |
726 | /**/ | |
727 | ||
728 | #endif // perfect forwarding support, or Borland workarounds needed | |
729 | #endif // include guard | |
730 |