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