// Copyright Daniel Wallin, David Abrahams 2005. Use, modification and | |
// distribution is subject to the Boost Software License, Version 1.0. (See | |
// accompanying file LICENSE_1_0.txt or copy at | |
// http://www.boost.org/LICENSE_1_0.txt) | |
#ifndef UNWRAP_CV_REFERENCE_050328_HPP | |
#define UNWRAP_CV_REFERENCE_050328_HPP | |
#include <boost/parameter/aux_/yesno.hpp> | |
#include <boost/mpl/bool.hpp> | |
#include <boost/mpl/identity.hpp> | |
#include <boost/mpl/eval_if.hpp> | |
namespace boost { template<class T> class reference_wrapper; } | |
namespace boost { namespace parameter { namespace aux { | |
// | |
// reference_wrapper support -- because of the forwarding problem, | |
// when passing arguments positionally by non-const reference, we | |
// ask users of named parameter interfaces to use ref(x) to wrap | |
// them. | |
// | |
// is_cv_reference_wrapper returns mpl::true_ if T is of type | |
// reference_wrapper<U> cv | |
template <class U> | |
yes_tag is_cv_reference_wrapper_check(reference_wrapper<U> const volatile*); | |
no_tag is_cv_reference_wrapper_check(...); | |
template <class T> | |
struct is_cv_reference_wrapper | |
{ | |
BOOST_STATIC_CONSTANT( | |
bool, value = ( | |
sizeof(is_cv_reference_wrapper_check((T*)0)) == sizeof(yes_tag) | |
) | |
); | |
typedef mpl::bool_< | |
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) | |
is_cv_reference_wrapper:: | |
#endif | |
value> type; | |
}; | |
#if BOOST_WORKAROUND(MSVC, == 1200) | |
template <> | |
struct is_cv_reference_wrapper<int> | |
: mpl::false_ {}; | |
#endif | |
// Needed for unwrap_cv_reference below. T might be const, so | |
// eval_if might fail because of deriving from T const on EDG. | |
template <class T> | |
struct get_type | |
{ | |
typedef typename T::type type; | |
}; | |
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) | |
template <class T, class is_reference_wrapper = typename is_cv_reference_wrapper<T>::type> | |
struct unwrap_cv_reference | |
{ | |
typedef T type; | |
}; | |
template <class T> | |
struct unwrap_cv_reference<T const, mpl::false_> | |
{ | |
typedef T const type; | |
}; | |
template <class T> | |
struct unwrap_cv_reference<T, mpl::true_> | |
: T | |
{}; | |
#else | |
// Produces the unwrapped type to hold a reference to in named<> | |
// Can't use boost::unwrap_reference<> here because it | |
// doesn't handle the case where T = reference_wrapper<U> cv | |
template <class T> | |
struct unwrap_cv_reference | |
{ | |
typedef typename mpl::eval_if< | |
is_cv_reference_wrapper<T> | |
, get_type<T> | |
, mpl::identity<T> | |
>::type type; | |
}; | |
#endif | |
}}} // namespace boost::parameter::aux | |
#endif // UNWRAP_CV_REFERENCE_050328_HPP | |