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)
7 #ifndef BOOST_PARAMETER_AUX_TAG_DWA2005610_HPP
8 #define BOOST_PARAMETER_AUX_TAG_DWA2005610_HPP
10 #include <boost/parameter/aux_/unwrap_cv_reference.hpp>
11 #include <boost/parameter/aux_/tagged_argument.hpp>
12 #include <boost/parameter/config.hpp>
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>
22 namespace boost { namespace parameter { namespace aux {
24 template <typename Keyword, typename Arg>
25 struct tag_if_lvalue_reference
27 using type = ::boost::parameter::aux::tagged_argument_list_of_1<
28 ::boost::parameter::aux::tagged_argument<
30 , typename ::boost::parameter::aux
31 ::unwrap_cv_reference<Arg>::type
36 template <typename Keyword, typename Arg>
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>
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>
56 template <typename Keyword, typename Arg>
57 using tag = ::boost::mp11::mp_if<
59 ::std::is_lvalue_reference<Arg>
60 , ::boost::mp11::mp_true
61 , ::boost::parameter::aux::is_cv_reference_wrapper<Arg>
63 , ::boost::parameter::aux::tag_if_lvalue_reference<Keyword,Arg>
64 , ::boost::parameter::aux::tag_if_otherwise<Keyword,Arg>
66 }}} // namespace boost::parameter::aux_
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>
78 namespace boost { namespace parameter { namespace aux {
80 template <typename Keyword, typename ActualArg>
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>
91 , ::boost::parameter::aux::is_cv_reference_wrapper<ActualArg>
93 , ::boost::mpl::identity<
94 #if defined(BOOST_PARAMETER_CAN_USE_MP11)
95 ::boost::parameter::aux::tagged_argument_list_of_1<
97 ::boost::parameter::aux::tagged_argument<Keyword,Arg>
98 #if defined(BOOST_PARAMETER_CAN_USE_MP11)
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>
108 , ::boost::parameter::aux::tagged_argument_list_of_1<
109 ::boost::parameter::aux::tagged_argument_rref<Keyword,Arg>
112 , ::boost::parameter::aux::tagged_argument<Keyword,ConstArg>
113 , ::boost::parameter::aux::tagged_argument_rref<Keyword,Arg>
118 }}} // namespace boost::parameter::aux_
120 #else // !defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING)
122 namespace boost { namespace parameter { namespace aux {
127 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
128 , typename = typename ::boost::parameter::aux
129 ::is_cv_reference_wrapper<Arg>::type
134 typedef ::boost::parameter::aux::tagged_argument<
136 , typename ::boost::parameter::aux::unwrap_cv_reference<Arg>::type
139 }}} // namespace boost::parameter::aux_
141 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
142 #include <boost/mpl/bool.hpp>
143 #include <boost/type_traits/remove_reference.hpp>
145 namespace boost { namespace parameter { namespace aux {
147 template <typename Keyword, typename Arg>
148 struct tag<Keyword,Arg,::boost::mpl::false_>
150 typedef ::boost::parameter::aux::tagged_argument<
152 , typename ::boost::remove_reference<Arg>::type
155 }}} // namespace boost::parameter::aux_
157 #endif // Borland workarounds needed.
158 #endif // MP11 or perfect forwarding support
159 #endif // include guard