175 lines
5.7 KiB
C++
175 lines
5.7 KiB
C++
|
// Copyright Daniel Wallin, David Abrahams 2005.
|
||
|
// Copyright Cromwell D. Enage 2017.
|
||
|
// Distributed under 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 BOOST_PARAMETER_AUX_UNWRAP_CV_REFERENCE_HPP
|
||
|
#define BOOST_PARAMETER_AUX_UNWRAP_CV_REFERENCE_HPP
|
||
|
|
||
|
namespace boost {
|
||
|
|
||
|
template <typename T>
|
||
|
class reference_wrapper;
|
||
|
} // namespace boost
|
||
|
|
||
|
#include <boost/parameter/aux_/yesno.hpp>
|
||
|
|
||
|
namespace boost { namespace parameter { namespace aux {
|
||
|
|
||
|
//
|
||
|
// reference_wrapper support -- if perfect forwarding is unsupported,
|
||
|
// then when passing arguments positionally by non-const reference,
|
||
|
// we ask users of named parameter interfaces to use ref(x) to wrap them.
|
||
|
//
|
||
|
|
||
|
template <typename U>
|
||
|
::boost::parameter::aux::yes_tag
|
||
|
is_cv_reference_wrapper_check(
|
||
|
::boost::reference_wrapper<U> const volatile*
|
||
|
);
|
||
|
|
||
|
::boost::parameter::aux::no_tag is_cv_reference_wrapper_check(...);
|
||
|
}}} // namespace boost::parameter::aux
|
||
|
|
||
|
#include <boost/parameter/config.hpp>
|
||
|
|
||
|
#if !defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)
|
||
|
#include <functional>
|
||
|
|
||
|
namespace boost { namespace parameter { namespace aux {
|
||
|
|
||
|
// Support for std::ref(x) -- Cromwell D. Enage
|
||
|
template <typename U>
|
||
|
::boost::parameter::aux::yes_tag
|
||
|
is_cv_reference_wrapper_check(
|
||
|
::std::reference_wrapper<U> const volatile*
|
||
|
);
|
||
|
}}} // namespace boost::parameter::aux
|
||
|
#endif
|
||
|
|
||
|
#include <boost/parameter/aux_/preprocessor/nullptr.hpp>
|
||
|
|
||
|
#if defined(BOOST_PARAMETER_CAN_USE_MP11) && !( \
|
||
|
BOOST_WORKAROUND(BOOST_MSVC, >= 1900) && \
|
||
|
BOOST_WORKAROUND(BOOST_MSVC, < 1910) \
|
||
|
)
|
||
|
#include <boost/mp11/integral.hpp>
|
||
|
#include <boost/mp11/utility.hpp>
|
||
|
#include <type_traits>
|
||
|
#else // !defined(BOOST_PARAMETER_CAN_USE_MP11) || MSVC-14.0
|
||
|
#include <boost/mpl/bool.hpp>
|
||
|
#include <boost/type_traits/remove_reference.hpp>
|
||
|
#if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564)) && \
|
||
|
!BOOST_WORKAROUND(BOOST_GCC, < 40000)
|
||
|
#include <boost/mpl/eval_if.hpp>
|
||
|
#endif
|
||
|
#endif // BOOST_PARAMETER_CAN_USE_MP11 && not MSVC-14.0
|
||
|
|
||
|
namespace boost { namespace parameter { namespace aux {
|
||
|
|
||
|
#if defined(BOOST_PARAMETER_CAN_USE_MP11) && !( \
|
||
|
BOOST_WORKAROUND(BOOST_MSVC, >= 1900) && \
|
||
|
BOOST_WORKAROUND(BOOST_MSVC, < 1910) \
|
||
|
)
|
||
|
// This metafunction returns mp11::mp_true if T is of type
|
||
|
// reference_wrapper<U> cv.
|
||
|
template <typename T>
|
||
|
using is_cv_reference_wrapper = ::boost::mp11::mp_bool<
|
||
|
sizeof(
|
||
|
::boost::parameter::aux::is_cv_reference_wrapper_check(
|
||
|
static_cast<
|
||
|
typename ::std::remove_reference<T>::type*
|
||
|
>(BOOST_PARAMETER_AUX_PP_NULLPTR)
|
||
|
)
|
||
|
) == sizeof(::boost::parameter::aux::yes_tag)
|
||
|
>;
|
||
|
|
||
|
// Needed for unwrap_cv_reference below. T might be const, so
|
||
|
// mp_eval_if<> might fail because of deriving from T const on EDG.
|
||
|
template <typename T>
|
||
|
using unwrap_cv_reference_impl = typename ::std::remove_reference<T>::type;
|
||
|
|
||
|
// Produces the unwrapped type to hold a reference to in
|
||
|
// tagged_argument<>. Can't use boost::unwrap_reference<> here
|
||
|
// because it doesn't handle the case where T = reference_wrapper<U> cv.
|
||
|
template <typename T>
|
||
|
using unwrap_cv_reference = ::boost::mp11::mp_eval_if<
|
||
|
::boost::parameter::aux::is_cv_reference_wrapper<T>
|
||
|
, ::boost::parameter::aux::unwrap_cv_reference_impl<T>
|
||
|
, ::std::remove_reference
|
||
|
, T
|
||
|
>;
|
||
|
#else // !defined(BOOST_PARAMETER_CAN_USE_MP11) || MSVC-14.0
|
||
|
// This metafunction returns mpl::true_ if T is of type
|
||
|
// reference_wrapper<U> cv.
|
||
|
template <typename T>
|
||
|
struct is_cv_reference_wrapper
|
||
|
{
|
||
|
BOOST_STATIC_CONSTANT(
|
||
|
bool, value = (
|
||
|
sizeof(
|
||
|
::boost::parameter::aux::is_cv_reference_wrapper_check(
|
||
|
static_cast<
|
||
|
typename ::boost::remove_reference<T>::type*
|
||
|
>(BOOST_PARAMETER_AUX_PP_NULLPTR)
|
||
|
)
|
||
|
) == sizeof(::boost::parameter::aux::yes_tag)
|
||
|
)
|
||
|
);
|
||
|
|
||
|
typedef boost::mpl::bool_<
|
||
|
#if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
|
||
|
is_cv_reference_wrapper::
|
||
|
#endif
|
||
|
value> type;
|
||
|
};
|
||
|
|
||
|
#if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564)) || \
|
||
|
BOOST_WORKAROUND(BOOST_GCC, < 40000)
|
||
|
template <
|
||
|
typename T
|
||
|
, typename = typename ::boost::parameter::aux
|
||
|
::is_cv_reference_wrapper<T>::type
|
||
|
>
|
||
|
struct unwrap_cv_reference : ::boost::remove_reference<T>
|
||
|
{
|
||
|
};
|
||
|
|
||
|
template <typename T>
|
||
|
struct unwrap_cv_reference<T const,::boost::mpl::false_>
|
||
|
{
|
||
|
typedef T const type;
|
||
|
};
|
||
|
|
||
|
template <typename T>
|
||
|
struct unwrap_cv_reference<T,::boost::mpl::true_> : T
|
||
|
{
|
||
|
};
|
||
|
#else // no Borland or GCC 3- workarounds needed
|
||
|
// Needed for unwrap_cv_reference below. T might be const, so
|
||
|
// eval_if<> might fail because of deriving from T const on EDG.
|
||
|
template <typename T>
|
||
|
struct unwrap_cv_reference_impl : ::boost::remove_reference<T>::type
|
||
|
{
|
||
|
};
|
||
|
|
||
|
// Produces the unwrapped type to hold a reference to in
|
||
|
// tagged_argument<>. Can't use boost::unwrap_reference<> here
|
||
|
// because it doesn't handle the case where T = reference_wrapper<U> cv.
|
||
|
template <typename T>
|
||
|
struct unwrap_cv_reference
|
||
|
: ::boost::mpl::eval_if<
|
||
|
::boost::parameter::aux::is_cv_reference_wrapper<T>
|
||
|
, ::boost::parameter::aux::unwrap_cv_reference_impl<T>
|
||
|
, ::boost::remove_reference<T>
|
||
|
>
|
||
|
{
|
||
|
};
|
||
|
#endif // Borland or GCC 3- workarounds needed
|
||
|
#endif // BOOST_PARAMETER_CAN_USE_MP11 && not MSVC-14.0
|
||
|
}}} // namespace boost::parameter::aux
|
||
|
|
||
|
#endif // include guard
|
||
|
|