1 // Copyright David Abrahams 2005. 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_TAG_DWA2005610_HPP 8 #define BOOST_PARAMETER_AUX_TAG_DWA2005610_HPP 9 10 #include <boost/parameter/aux_/unwrap_cv_reference.hpp> 11 #include <boost/parameter/aux_/tagged_argument.hpp> 12 #include <boost/parameter/config.hpp> 13 14 #if defined(BOOST_PARAMETER_CAN_USE_MP11) && \ 15 !BOOST_WORKAROUND(BOOST_MSVC, >= 1910) 16 // MSVC-14.1+ assigns rvalue references to tagged_argument instances 17 // instead of tagged_argument_rref instances with this code. 18 #include <boost/mp11/integral.hpp> 19 #include <boost/mp11/utility.hpp> 20 #include <type_traits> 21 22 namespace boost { namespace parameter { namespace aux { 23 24 template <typename Keyword, typename Arg> 25 struct tag_if_lvalue_reference 26 { 27 using type = ::boost::parameter::aux::tagged_argument_list_of_1< 28 ::boost::parameter::aux::tagged_argument< 29 Keyword 30 , typename ::boost::parameter::aux 31 ::unwrap_cv_reference<Arg>::type 32 > 33 >; 34 }; 35 36 template <typename Keyword, typename Arg> 37 struct tag_if_scalar 38 { 39 using type = ::boost::parameter::aux::tagged_argument_list_of_1< 40 ::boost::parameter::aux 41 ::tagged_argument<Keyword,typename ::std::add_const<Arg>::type> 42 >; 43 }; 44 45 template <typename Keyword, typename Arg> 46 using tag_if_otherwise = ::boost::mp11::mp_if< 47 ::std::is_scalar<typename ::std::remove_const<Arg>::type> 48 , ::boost::parameter::aux::tag_if_scalar<Keyword,Arg> 49 , ::boost::mp11::mp_identity< 50 ::boost::parameter::aux::tagged_argument_list_of_1< 51 ::boost::parameter::aux::tagged_argument_rref<Keyword,Arg> 52 > 53 > 54 >; 55 56 template <typename Keyword, typename Arg> 57 using tag = ::boost::mp11::mp_if< 58 ::boost::mp11::mp_if< 59 ::std::is_lvalue_reference<Arg> 60 , ::boost::mp11::mp_true 61 , ::boost::parameter::aux::is_cv_reference_wrapper<Arg> 62 > 63 , ::boost::parameter::aux::tag_if_lvalue_reference<Keyword,Arg> 64 , ::boost::parameter::aux::tag_if_otherwise<Keyword,Arg> 65 >; 66 }}} // namespace boost::parameter::aux_ 67 68 #elif defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) 69 #include <boost/mpl/bool.hpp> 70 #include <boost/mpl/if.hpp> 71 #include <boost/mpl/eval_if.hpp> 72 #include <boost/mpl/identity.hpp> 73 #include <boost/type_traits/add_const.hpp> 74 #include <boost/type_traits/is_scalar.hpp> 75 #include <boost/type_traits/is_lvalue_reference.hpp> 76 #include <boost/type_traits/remove_const.hpp> 77 78 namespace boost { namespace parameter { namespace aux { 79 80 template <typename Keyword, typename ActualArg> 81 struct tag 82 { 83 typedef typename ::boost::parameter::aux 84 ::unwrap_cv_reference<ActualArg>::type Arg; 85 typedef typename ::boost::add_const<Arg>::type ConstArg; 86 typedef typename ::boost::remove_const<Arg>::type MutArg; 87 typedef typename ::boost::mpl::eval_if< 88 typename ::boost::mpl::if_< 89 ::boost::is_lvalue_reference<ActualArg> 90 , ::boost::mpl::true_ 91 , ::boost::parameter::aux::is_cv_reference_wrapper<ActualArg> 92 >::type 93 , ::boost::mpl::identity< 94 #if defined(BOOST_PARAMETER_CAN_USE_MP11) 95 ::boost::parameter::aux::tagged_argument_list_of_1< 96 #endif 97 ::boost::parameter::aux::tagged_argument<Keyword,Arg> 98 #if defined(BOOST_PARAMETER_CAN_USE_MP11) 99 > 100 #endif 101 > 102 , ::boost::mpl::if_< 103 ::boost::is_scalar<MutArg> 104 #if defined(BOOST_PARAMETER_CAN_USE_MP11) 105 , ::boost::parameter::aux::tagged_argument_list_of_1< 106 ::boost::parameter::aux::tagged_argument<Keyword,ConstArg> 107 > 108 , ::boost::parameter::aux::tagged_argument_list_of_1< 109 ::boost::parameter::aux::tagged_argument_rref<Keyword,Arg> 110 > 111 #else 112 , ::boost::parameter::aux::tagged_argument<Keyword,ConstArg> 113 , ::boost::parameter::aux::tagged_argument_rref<Keyword,Arg> 114 #endif 115 > 116 >::type type; 117 }; 118 }}} // namespace boost::parameter::aux_ 119 120 #else // !defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) 121 122 namespace boost { namespace parameter { namespace aux { 123 124 template < 125 typename Keyword 126 , typename Arg 127 #if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564)) 128 , typename = typename ::boost::parameter::aux 129 ::is_cv_reference_wrapper<Arg>::type 130 #endif 131 > 132 struct tag 133 { 134 typedef ::boost::parameter::aux::tagged_argument< 135 Keyword 136 , typename ::boost::parameter::aux::unwrap_cv_reference<Arg>::type 137 > type; 138 }; 139 }}} // namespace boost::parameter::aux_ 140 141 #if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564)) 142 #include <boost/mpl/bool.hpp> 143 #include <boost/type_traits/remove_reference.hpp> 144 145 namespace boost { namespace parameter { namespace aux { 146 147 template <typename Keyword, typename Arg> 148 struct tag<Keyword,Arg,::boost::mpl::false_> 149 { 150 typedef ::boost::parameter::aux::tagged_argument< 151 Keyword 152 , typename ::boost::remove_reference<Arg>::type 153 > type; 154 }; 155 }}} // namespace boost::parameter::aux_ 156 157 #endif // Borland workarounds needed. 158 #endif // MP11 or perfect forwarding support 159 #endif // include guard 160 161