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 // Needed for unwrap_cv_reference below. T might be const, so 48 // eval_if might fail because of deriving from T const on EDG. 49 template <class T> 50 struct get_type 51 { 52 typedef typename T::type type; 53 }; 54 55 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) 56 template <class T, class is_reference_wrapper = typename is_cv_reference_wrapper<T>::type> 57 struct unwrap_cv_reference 58 { 59 typedef T type; 60 }; 61 62 template <class T> 63 struct unwrap_cv_reference<T const, mpl::false_> 64 { 65 typedef T const type; 66 }; 67 68 template <class T> 69 struct unwrap_cv_reference<T, mpl::true_> entryboost::multi_index::detail::index_matcher::entry70 : T 71 {}; 72 73 #else 74 // Produces the unwrapped type to hold a reference to in named<> 75 // Can't use boost::unwrap_reference<> here because it 76 // doesn't handle the case where T = reference_wrapper<U> cv 77 template <class T> 78 struct unwrap_cv_reference 79 { 80 typedef typename mpl::eval_if< operator ()boost::multi_index::detail::index_matcher::entry::less_by_node81 is_cv_reference_wrapper<T> 82 , get_type<T> 83 , mpl::identity<T> 84 >::type type; 85 }; 86 #endif 87 88 }}} // namespace boost::parameter::aux 89 90 #endif // UNWRAP_CV_REFERENCE_050328_HPP 91 92