Chris@16
|
1 // Copyright Daniel Wallin, David Abrahams 2005. Use, modification and
|
Chris@16
|
2 // distribution is subject to the Boost Software License, Version 1.0. (See
|
Chris@16
|
3 // accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
4 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
5
|
Chris@16
|
6 #ifndef UNWRAP_CV_REFERENCE_050328_HPP
|
Chris@16
|
7 #define UNWRAP_CV_REFERENCE_050328_HPP
|
Chris@16
|
8
|
Chris@16
|
9 #include <boost/parameter/aux_/yesno.hpp>
|
Chris@16
|
10 #include <boost/mpl/bool.hpp>
|
Chris@16
|
11 #include <boost/mpl/identity.hpp>
|
Chris@16
|
12 #include <boost/mpl/eval_if.hpp>
|
Chris@16
|
13
|
Chris@16
|
14 namespace boost { template<class T> class reference_wrapper; }
|
Chris@16
|
15
|
Chris@16
|
16 namespace boost { namespace parameter { namespace aux {
|
Chris@16
|
17
|
Chris@16
|
18 //
|
Chris@16
|
19 // reference_wrapper support -- because of the forwarding problem,
|
Chris@16
|
20 // when passing arguments positionally by non-const reference, we
|
Chris@16
|
21 // ask users of named parameter interfaces to use ref(x) to wrap
|
Chris@16
|
22 // them.
|
Chris@16
|
23 //
|
Chris@16
|
24
|
Chris@16
|
25 // is_cv_reference_wrapper returns mpl::true_ if T is of type
|
Chris@16
|
26 // reference_wrapper<U> cv
|
Chris@16
|
27 template <class U>
|
Chris@16
|
28 yes_tag is_cv_reference_wrapper_check(reference_wrapper<U> const volatile*);
|
Chris@16
|
29 no_tag is_cv_reference_wrapper_check(...);
|
Chris@16
|
30
|
Chris@16
|
31 template <class T>
|
Chris@16
|
32 struct is_cv_reference_wrapper
|
Chris@16
|
33 {
|
Chris@16
|
34 BOOST_STATIC_CONSTANT(
|
Chris@16
|
35 bool, value = (
|
Chris@16
|
36 sizeof(is_cv_reference_wrapper_check((T*)0)) == sizeof(yes_tag)
|
Chris@16
|
37 )
|
Chris@16
|
38 );
|
Chris@16
|
39
|
Chris@16
|
40 typedef mpl::bool_<
|
Chris@16
|
41 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
Chris@16
|
42 is_cv_reference_wrapper::
|
Chris@16
|
43 #endif
|
Chris@16
|
44 value> type;
|
Chris@16
|
45 };
|
Chris@16
|
46
|
Chris@16
|
47 #if BOOST_WORKAROUND(MSVC, == 1200)
|
Chris@16
|
48 template <>
|
Chris@16
|
49 struct is_cv_reference_wrapper<int>
|
Chris@16
|
50 : mpl::false_ {};
|
Chris@16
|
51 #endif
|
Chris@16
|
52
|
Chris@16
|
53 // Needed for unwrap_cv_reference below. T might be const, so
|
Chris@16
|
54 // eval_if might fail because of deriving from T const on EDG.
|
Chris@16
|
55 template <class T>
|
Chris@16
|
56 struct get_type
|
Chris@16
|
57 {
|
Chris@16
|
58 typedef typename T::type type;
|
Chris@16
|
59 };
|
Chris@16
|
60
|
Chris@16
|
61 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
Chris@16
|
62 template <class T, class is_reference_wrapper = typename is_cv_reference_wrapper<T>::type>
|
Chris@16
|
63 struct unwrap_cv_reference
|
Chris@16
|
64 {
|
Chris@16
|
65 typedef T type;
|
Chris@16
|
66 };
|
Chris@16
|
67
|
Chris@16
|
68 template <class T>
|
Chris@16
|
69 struct unwrap_cv_reference<T const, mpl::false_>
|
Chris@16
|
70 {
|
Chris@16
|
71 typedef T const type;
|
Chris@16
|
72 };
|
Chris@16
|
73
|
Chris@16
|
74 template <class T>
|
Chris@16
|
75 struct unwrap_cv_reference<T, mpl::true_>
|
Chris@16
|
76 : T
|
Chris@16
|
77 {};
|
Chris@16
|
78
|
Chris@16
|
79 #else
|
Chris@16
|
80 // Produces the unwrapped type to hold a reference to in named<>
|
Chris@16
|
81 // Can't use boost::unwrap_reference<> here because it
|
Chris@16
|
82 // doesn't handle the case where T = reference_wrapper<U> cv
|
Chris@16
|
83 template <class T>
|
Chris@16
|
84 struct unwrap_cv_reference
|
Chris@16
|
85 {
|
Chris@16
|
86 typedef typename mpl::eval_if<
|
Chris@16
|
87 is_cv_reference_wrapper<T>
|
Chris@16
|
88 , get_type<T>
|
Chris@16
|
89 , mpl::identity<T>
|
Chris@16
|
90 >::type type;
|
Chris@16
|
91 };
|
Chris@16
|
92 #endif
|
Chris@16
|
93
|
Chris@16
|
94 }}} // namespace boost::parameter::aux
|
Chris@16
|
95
|
Chris@16
|
96 #endif // UNWRAP_CV_REFERENCE_050328_HPP
|
Chris@16
|
97
|