]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/parameter/aux_/preprocessor/impl/function_cast.hpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / boost / parameter / aux_ / preprocessor / impl / function_cast.hpp
CommitLineData
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
14namespace 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
37namespace 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
55namespace 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
76namespace 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
87namespace 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
102namespace 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
125namespace 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
175namespace 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
249namespace 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
355namespace 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
412namespace 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
480namespace 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
505namespace 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
532namespace 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
547namespace 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
564namespace 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
609namespace 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
659namespace 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