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
22namespace 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
78namespace 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
122namespace boost { namespace parameter { namespace aux {
123
124 template <
125 typename Keyword
126 , typename Arg
127#if BOOST_WORKAROUND(__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(__BORLANDC__, BOOST_TESTED_AT(0x564))
142#include <boost/mpl/bool.hpp>
143#include <boost/type_traits/remove_reference.hpp>
144
145namespace 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

source code of include/boost/parameter/aux_/tag.hpp