123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730 |
- // Copyright Daniel Wallin 2006.
- // Copyright Cromwell D. Enage 2017.
- // Distributed under the Boost Software License, Version 1.0.
- // (See accompanying file LICENSE_1_0.txt or copy at
- // http://www.boost.org/LICENSE_1_0.txt)
- #ifndef BOOST_PARAMETER_AUX_PREPROCESSOR_IMPL_FUNCTION_CAST_HPP
- #define BOOST_PARAMETER_AUX_PREPROCESSOR_IMPL_FUNCTION_CAST_HPP
- #include <boost/parameter/config.hpp>
- #if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING)
- namespace boost { namespace parameter { namespace aux {
- // Handles possible implicit casts. Used by preprocessor.hpp
- // to normalize user input.
- //
- // cast<void*>::execute() is identity
- // cast<void*(X)>::execute() is identity
- // cast<void(X)>::execute() casts to X
- //
- // preprocessor.hpp uses this like this:
- //
- // #define X(value, predicate)
- // cast<void predicate>::execute(value)
- //
- // X(something, *)
- // X(something, *(predicate))
- // X(something, (int))
- template <typename VoidExpr, typename Args>
- struct cast;
- }}} // namespace boost::parameter::aux
- #include <boost/parameter/aux_/use_default_tag.hpp>
- namespace boost { namespace parameter { namespace aux {
- template <typename T, typename B>
- inline ::boost::parameter::aux::use_default_tag
- forward(::boost::parameter::aux::use_default_tag)
- {
- return ::boost::parameter::aux::use_default_tag();
- }
- }}} // namespace boost::parameter::aux
- #include <boost/mpl/bool.hpp>
- #include <boost/mpl/if.hpp>
- #if defined(BOOST_PARAMETER_CAN_USE_MP11)
- #include <boost/mp11/integral.hpp>
- #include <boost/mp11/utility.hpp>
- #endif
- namespace boost { namespace parameter { namespace aux {
- template <typename Args>
- struct cast<void*,Args>
- {
- template <typename T, typename B>
- struct apply
- {
- typedef typename ::boost::mpl
- ::if_<B,T,::boost::mpl::true_>::type type;
- };
- #if defined(BOOST_PARAMETER_CAN_USE_MP11)
- template <typename T, typename B>
- using fn = ::boost::mp11::mp_if<B,T,::boost::mp11::mp_true>;
- #endif
- };
- }}} // namespace boost::parameter::aux
- #include <boost/parameter/aux_/void.hpp>
- namespace boost { namespace parameter { namespace aux {
- template <typename Predicate, typename Args>
- struct cast<void*(Predicate),Args>
- : ::boost::parameter::aux::cast<void*,Args>
- {
- };
- }}} // namespace boost::parameter::aux
- #include <boost/mpl/placeholders.hpp>
- namespace boost { namespace parameter { namespace aux {
- // This is a hack used in cast<> to turn the user supplied type,
- // which may or may not be a placeholder expression, into one,
- // so that it will be properly evaluated by mpl::apply.
- template <typename T, typename Dummy = ::boost::mpl::_1>
- struct as_placeholder_expr
- {
- typedef T type;
- };
- }}} // namespace boost::parameter::aux
- #if defined(BOOST_PARAMETER_CAN_USE_MP11)
- #include <boost/mp11/list.hpp>
- namespace boost { namespace parameter { namespace aux {
- template <typename Target, typename Source, typename Args>
- struct apply_target_fn
- {
- using type = ::boost::mp11
- ::mp_apply_q<Target,::boost::mp11::mp_list<Source,Args> >;
- };
- }}} // namespace boost::parameter::aux
- #endif
- #include <boost/mpl/apply.hpp>
- #if defined(BOOST_PARAMETER_CAN_USE_MP11)
- #include <boost/parameter/aux_/has_nested_template_fn.hpp>
- #include <type_traits>
- #else
- #include <boost/type_traits/is_same.hpp>
- #include <boost/type_traits/remove_const.hpp>
- #include <boost/type_traits/remove_reference.hpp>
- #endif
- namespace boost { namespace parameter { namespace aux {
- template <typename Target, typename Source, typename Args>
- #if defined(BOOST_PARAMETER_CAN_USE_MP11)
- using is_target_same_as_source = ::std::is_same<
- typename ::std::remove_const<
- typename ::std::remove_reference<
- typename ::boost::mp11::mp_if<
- ::boost::parameter::aux::has_nested_template_fn<Target>
- , ::boost::parameter::aux
- ::apply_target_fn<Target,Source,Args>
- , ::boost::mpl::apply2<
- ::boost::parameter::aux::as_placeholder_expr<Target>
- , Source
- , Args
- >
- >::type
- >::type
- >::type
- , typename ::std::remove_const<Source>::type
- >;
- #else // !defined(BOOST_PARAMETER_CAN_USE_MP11)
- struct is_target_same_as_source
- : ::boost::mpl::if_<
- ::boost::is_same<
- typename ::boost::remove_const<
- typename ::boost::remove_reference<
- typename ::boost::mpl::apply2<
- ::boost::parameter::aux
- ::as_placeholder_expr<Target>
- , Source
- , Args
- >::type
- >::type
- >::type
- , typename ::boost::remove_const<Source>::type
- >
- , ::boost::mpl::true_
- , ::boost::mpl::false_
- >::type
- {
- };
- #endif // BOOST_PARAMETER_CAN_USE_MP11
- }}} // namespace boost::parameter::aux
- #if !defined(BOOST_PARAMETER_CAN_USE_MP11)
- #include <boost/type_traits/add_const.hpp>
- #include <boost/type_traits/is_const.hpp>
- #endif
- namespace boost { namespace parameter { namespace aux {
- // Covers the case where is_convertible<Source,Target> but not
- // is_same<Source,Target>. Use cases are covered
- // by test/normalize_argument_types.cpp
- template <typename Source, typename Target>
- class cast_convert
- {
- typedef ::boost::parameter::aux::cast_convert<Source,Target> _self;
- public:
- #if defined(BOOST_PARAMETER_CAN_USE_MP11)
- using type = typename ::boost::mp11::mp_if<
- ::std::is_const<Source>
- , ::std::add_const<Target>
- , ::std::remove_const<Target>
- >::type;
- #else
- typedef typename boost::mpl::eval_if<
- ::boost::is_const<Source>
- , ::boost::add_const<Target>
- , ::boost::remove_const<Target>
- >::type type;
- #endif
- private:
- inline static typename _self::type
- #if defined(BOOST_PARAMETER_CAN_USE_MP11)
- _copy(typename ::std::remove_const<Target>::type value)
- #else
- _copy(typename ::boost::remove_const<Target>::type value)
- #endif
- {
- return value;
- }
- public:
- inline static typename _self::type evaluate(Source&& source)
- {
- return _self::_copy(source);
- }
- };
- template <typename Target, typename Source, typename Args>
- #if defined(BOOST_PARAMETER_CAN_USE_MP11)
- using cast_impl = ::std::remove_reference<
- typename ::boost::mp11::mp_if<
- ::boost::parameter::aux::has_nested_template_fn<Target>
- , ::boost::parameter::aux
- ::is_target_same_as_source<Target,Source,Args>
- , ::boost::mpl::apply2<
- ::boost::parameter::aux::as_placeholder_expr<Target>
- , Source
- , Args
- >
- >::type
- >;
- #else
- struct cast_impl
- : ::boost::remove_reference<
- typename ::boost::mpl::apply2<
- ::boost::parameter::aux::as_placeholder_expr<Target>
- , Source
- , Args
- >::type
- >
- {
- };
- #endif // BOOST_PARAMETER_CAN_USE_MP11
- }}} // namespace boost::parameter::aux
- #include <boost/mpl/eval_if.hpp>
- #include <boost/mpl/identity.hpp>
- namespace boost { namespace parameter { namespace aux {
- template <typename Target, typename Args>
- struct cast<void(Target),Args>
- {
- template <typename T, typename B>
- struct apply
- {
- typedef typename ::boost::mpl::eval_if<
- B
- , ::boost::mpl::eval_if<
- ::boost::parameter::aux
- ::is_target_same_as_source<Target,T,Args>
- , ::boost::mpl::identity<T>
- , ::boost::parameter::aux::cast_impl<Target,T,Args>
- >
- , ::boost::parameter::aux
- ::is_target_same_as_source<Target,T,Args>
- >::type type;
- };
- #if defined(BOOST_PARAMETER_CAN_USE_MP11)
- template <typename T, typename B>
- using fn = typename ::boost::mp11::mp_if<
- B
- , ::boost::mp11::mp_if<
- ::boost::parameter::aux
- ::is_target_same_as_source<Target,T,Args>
- , ::boost::mp11::mp_identity<T>
- , ::boost::parameter::aux::cast_impl<Target,T,Args>
- >
- , ::boost::parameter::aux
- ::is_target_same_as_source<Target,T,Args>
- >::type;
- #endif
- };
- }}} // namespace boost::parameter::aux
- #include <boost/parameter/value_type.hpp>
- #if !defined(BOOST_PARAMETER_CAN_USE_MP11)
- #include <boost/mpl/apply_wrap.hpp>
- #endif
- // Expands to the target type of the argument as indicated by the predicate.
- #if defined(BOOST_PARAMETER_CAN_USE_MP11)
- #define BOOST_PARAMETER_FUNCTION_CAST_T(tag, predicate, args) \
- ::boost::mp11::mp_apply_q< \
- ::boost::parameter::aux::cast<void predicate, args> \
- , ::boost::mp11::mp_list< \
- typename ::boost::parameter::value_type< \
- args \
- , tag \
- , ::boost::parameter::aux::use_default_tag \
- >::type \
- , ::boost::mp11::mp_true \
- > \
- >
- /**/
- #else // !defined(BOOST_PARAMETER_CAN_USE_MP11)
- #define BOOST_PARAMETER_FUNCTION_CAST_T(tag, predicate, args) \
- typename ::boost::mpl::apply_wrap2< \
- ::boost::parameter::aux::cast<void predicate, args> \
- , typename ::boost::parameter::value_type< \
- args \
- , tag \
- , ::boost::parameter::aux::use_default_tag \
- >::type \
- , ::boost::mpl::true_ \
- >::type
- /**/
- #endif // BOOST_PARAMETER_CAN_USE_MP11
- // Expands to boost::mpl::true_ if and only if the argument's source and
- // target types are the same.
- #if defined(BOOST_PARAMETER_CAN_USE_MP11)
- #define BOOST_PARAMETER_FUNCTION_CAST_B(tag, predicate, args) \
- ::boost::mp11::mp_apply_q< \
- ::boost::parameter::aux::cast<void predicate, args> \
- , ::boost::mp11::mp_list< \
- typename ::boost::parameter::value_type< \
- args \
- , tag \
- , ::boost::parameter::aux::use_default_tag \
- >::type \
- , ::boost::mp11::mp_false \
- > \
- >
- /**/
- #else // !defined(BOOST_PARAMETER_CAN_USE_MP11)
- #define BOOST_PARAMETER_FUNCTION_CAST_B(tag, predicate, args) \
- typename ::boost::mpl::apply_wrap2< \
- ::boost::parameter::aux::cast<void predicate, args> \
- , typename ::boost::parameter::value_type< \
- args \
- , tag \
- , ::boost::parameter::aux::use_default_tag \
- >::type \
- , ::boost::mpl::false_ \
- >::type
- /**/
- #endif // BOOST_PARAMETER_CAN_USE_MP11
- #include <boost/core/enable_if.hpp>
- #include <utility>
- namespace boost { namespace parameter { namespace aux {
- // If the source and target types are not the same,
- // then perform an implicit conversion.
- template <typename Target, typename B, typename Source>
- inline typename ::boost::lazy_disable_if<
- B
- , ::boost::parameter::aux::cast_convert<Source,Target>
- >::type
- forward(Source&& source)
- {
- return ::boost::parameter::aux::cast_convert<Source,Target>
- ::evaluate(::std::forward<Source>(source));
- }
- // If the source and target types are the same,
- // then simply forward the argument.
- // However, treat rvalue references to scalars as const lvalue references.
- template <typename T, typename B>
- inline typename ::boost::enable_if<B,T const&>::type forward(T const& t)
- {
- return t;
- }
- template <typename T, typename B>
- inline typename ::boost::enable_if<
- #if defined(BOOST_PARAMETER_CAN_USE_MP11)
- ::boost::mp11::mp_if<
- B
- , ::boost::mp11::mp_if<
- ::std::is_const<T>
- , ::boost::mp11::mp_false
- , ::boost::mp11::mp_true
- >
- , ::boost::mp11::mp_false
- >
- #else
- typename ::boost::mpl::eval_if<
- B
- , ::boost::mpl::if_<
- ::boost::is_const<T>
- , ::boost::mpl::false_
- , ::boost::mpl::true_
- >
- , ::boost::mpl::false_
- >::type
- #endif // BOOST_PARAMETER_CAN_USE_MP11
- , T&
- >::type
- forward(T& t)
- {
- return t;
- }
- }}} // namespace boost::parameter::aux
- #include <boost/type_traits/is_scalar.hpp>
- namespace boost { namespace parameter { namespace aux {
- template <typename T, typename B>
- inline typename ::boost::enable_if<
- #if defined(BOOST_PARAMETER_CAN_USE_MP11)
- ::boost::mp11::mp_if<
- B
- , ::boost::mp11::mp_if<
- ::std::is_scalar<T>
- , ::boost::mp11::mp_false
- , ::boost::mp11::mp_true
- >
- , ::boost::mp11::mp_false
- >
- #else
- typename ::boost::mpl::eval_if<
- B
- , ::boost::mpl::if_<
- ::boost::is_scalar<T>
- , ::boost::mpl::false_
- , ::boost::mpl::true_
- >
- , ::boost::mpl::false_
- >::type
- #endif // BOOST_PARAMETER_CAN_USE_MP11
- , T const&&
- >::type
- forward(T const&& t)
- {
- return static_cast<T const&&>(t);
- }
- template <typename T, typename B>
- inline typename ::boost::enable_if<
- #if defined(BOOST_PARAMETER_CAN_USE_MP11)
- ::boost::mp11::mp_if<
- B
- , ::boost::mp11::mp_if<
- ::std::is_scalar<T>
- , ::boost::mp11::mp_false
- , ::boost::mp11::mp_true
- >
- , ::boost::mp11::mp_false
- >
- #else
- typename ::boost::mpl::eval_if<
- B
- , ::boost::mpl::if_<
- ::boost::is_scalar<T>
- , ::boost::mpl::false_
- , ::boost::mpl::true_
- >
- , ::boost::mpl::false_
- >::type
- #endif // BOOST_PARAMETER_CAN_USE_MP11
- , T&&
- >::type
- forward(T&& t)
- {
- return ::std::forward<T>(t);
- }
- }}} // namespace boost::parameter::aux
- #elif BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
- #define BOOST_PARAMETER_FUNCTION_CAST_T(value_t, predicate, args) value_t
- #define BOOST_PARAMETER_FUNCTION_CAST_B(value, predicate, args) value
- #else // no perfect forwarding support and no Borland workarounds needed
- namespace boost { namespace parameter { namespace aux {
- // Handles possible implicit casts. Used by preprocessor.hpp
- // to normalize user input.
- //
- // cast<void*>::execute() is identity
- // cast<void*(X)>::execute() is identity
- // cast<void(X)>::execute() casts to X
- //
- // preprocessor.hpp uses this like this:
- //
- // #define X(value, predicate)
- // cast<void predicate>::execute(value)
- //
- // X(something, *)
- // X(something, *(predicate))
- // X(something, (int))
- template <typename VoidExpr, typename Args>
- struct cast;
- }}} // namespace boost::parameter::aux
- #include <boost/parameter/aux_/use_default_tag.hpp>
- #include <boost/mpl/bool.hpp>
- #include <boost/mpl/if.hpp>
- namespace boost { namespace parameter { namespace aux {
- template <typename Args>
- struct cast<void*,Args>
- {
- template <typename T>
- struct apply
- {
- typedef T& type;
- };
- inline static ::boost::parameter::aux::use_default_tag
- execute(::boost::parameter::aux::use_default_tag)
- {
- return ::boost::parameter::aux::use_default_tag();
- }
- template <typename U>
- inline static U& execute(U& value)
- {
- return value;
- }
- };
- }}} // namespace boost::parameter::aux
- #include <boost/parameter/aux_/void.hpp>
- namespace boost { namespace parameter { namespace aux {
- template <typename Predicate, typename Args>
- #if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x580))
- struct cast< ::boost::parameter::aux::voidstar(Predicate),Args>
- #else
- struct cast<void*(Predicate),Args>
- #endif
- : ::boost::parameter::aux::cast<void*,Args>
- {
- };
- }}} // namespace boost::parameter::aux
- #include <boost/mpl/placeholders.hpp>
- namespace boost { namespace parameter { namespace aux {
- // This is a hack used in cast<> to turn the user supplied type,
- // which may or may not be a placeholder expression, into one,
- // so that it will be properly evaluated by mpl::apply.
- template <typename T, typename Dummy = ::boost::mpl::_1>
- struct as_placeholder_expr
- {
- typedef T type;
- };
- }}} // namespace boost::parameter::aux
- #include <boost/mpl/apply.hpp>
- #include <boost/type_traits/is_same.hpp>
- #include <boost/type_traits/remove_const.hpp>
- #include <boost/type_traits/remove_reference.hpp>
- namespace boost { namespace parameter { namespace aux {
- template <typename Target, typename Source, typename Args>
- struct is_target_same_as_source
- : ::boost::mpl::if_<
- ::boost::is_same<
- typename ::boost::remove_const<
- typename ::boost::remove_reference<
- typename ::boost::mpl::apply2<
- ::boost::parameter::aux
- ::as_placeholder_expr<Target>
- , Source
- , Args
- >::type
- >::type
- >::type
- , typename ::boost::remove_const<Source>::type
- >
- , ::boost::mpl::true_
- , ::boost::mpl::false_
- >::type
- {
- };
- template <
- typename Target
- , typename Source
- , typename Args
- , typename Enable = ::boost::parameter::aux
- ::is_target_same_as_source<Target,Source,Args>
- >
- struct cast_impl
- {
- typedef Source& type;
- inline static Source& evaluate(Source& value)
- {
- return value;
- }
- };
- }}} // namespace boost::parameter::aux
- #include <boost/type_traits/add_const.hpp>
- #include <boost/type_traits/add_lvalue_reference.hpp>
- namespace boost { namespace parameter { namespace aux {
- // Covers the case where is_convertible<Source,Target> but not
- // is_same<Source,Target>. Use cases are covered
- // by test/normalize_argument_types.cpp
- template <typename Source, typename Target>
- class cast_convert
- {
- typedef ::boost::parameter::aux::cast_convert<Source,Target> _self;
- public:
- typedef typename ::boost::add_lvalue_reference<
- typename ::boost::add_const<Target>::type
- >::type type;
- private:
- template <typename U>
- inline static typename _self::type _mod_const(U const& u)
- {
- return u;
- }
- inline static Target _copy(Target value)
- {
- return value;
- }
- public:
- inline static typename _self::type evaluate(Source& source)
- {
- return _self::_mod_const(_self::_copy(source));
- }
- };
- template <typename Target, typename Source, typename Args>
- struct cast_impl<Target,Source,Args,::boost::mpl::false_>
- : ::boost::parameter::aux::cast_convert<
- Source,
- typename ::boost::mpl::apply2<
- ::boost::parameter::aux::as_placeholder_expr<Target>
- , Source
- , Args
- >::type
- >
- {
- };
- }}} // namespace boost::parameter::aux
- #include <boost/mpl/eval_if.hpp>
- namespace boost { namespace parameter { namespace aux {
- template <typename Target, typename Args>
- struct cast<void(Target),Args>
- {
- template <typename T>
- struct apply
- {
- typedef typename ::boost::mpl::eval_if<
- ::boost::parameter::aux
- ::is_target_same_as_source<Target,T,Args>
- , ::boost::add_lvalue_reference<T>
- , ::boost::parameter::aux::cast_impl<
- Target
- , T
- , Args
- , ::boost::mpl::false_
- >
- >::type type;
- };
- inline static ::boost::parameter::aux::use_default_tag
- execute(::boost::parameter::aux::use_default_tag)
- {
- return ::boost::parameter::aux::use_default_tag();
- }
- template <typename U>
- inline static typename ::boost::parameter::aux
- ::cast_impl<Target,U const,Args>::type
- execute(U const& value)
- {
- return ::boost::parameter::aux
- ::cast_impl<Target,U const,Args>::evaluate(value);
- }
- template <typename U>
- inline static typename ::boost::parameter::aux
- ::cast_impl<Target,U,Args>::type
- execute(U& value)
- {
- return ::boost::parameter::aux
- ::cast_impl<Target,U,Args>::evaluate(value);
- }
- };
- }}} // namespace boost::parameter::aux
- #include <boost/mpl/apply_wrap.hpp>
- #include <boost/parameter/value_type.hpp>
- // Expands to the reference-qualified target type of the argument
- // as indicated by the predicate.
- #define BOOST_PARAMETER_FUNCTION_CAST_T(tag, predicate, args) \
- typename ::boost::mpl::apply_wrap1< \
- ::boost::parameter::aux::cast<void predicate, args> \
- , typename ::boost::parameter::value_type< \
- args \
- , tag \
- , ::boost::parameter::aux::use_default_tag \
- >::type \
- >::type
- /**/
- // Expands to the converted or passed-through value
- // as indicated by the predicate.
- #define BOOST_PARAMETER_FUNCTION_CAST_B(value, predicate, args) \
- ::boost::parameter::aux::cast<void predicate, args>::execute(value)
- /**/
- #endif // perfect forwarding support, or Borland workarounds needed
- #endif // include guard
|