Fix operator & detection trait to check for free function overloads as well

llvm-svn: 221395
This commit is contained in:
Eric Fiselier 2014-11-05 20:59:18 +00:00
parent 16371acdc4
commit c7e48bec0e
2 changed files with 20 additions and 2 deletions

View File

@ -3642,7 +3642,7 @@ struct underlying_type
#ifndef _LIBCPP_HAS_NO_ADVANCED_SFINAE
template <class _Tp>
struct __has_operator_addressof_imp
struct __has_operator_addressof_member_imp
{
template <class>
static auto __test(__any) -> false_type;
@ -3653,9 +3653,22 @@ struct __has_operator_addressof_imp
static const bool value = decltype(__test<_Tp>(nullptr))::value;
};
template <class _Tp>
struct __has_operator_addressof_free_imp
{
template <class>
static auto __test(__any) -> false_type;
template <class _Up>
static auto __test(_Up* __u)
-> typename __select_2nd<decltype(operator&(*__u)), true_type>::type;
static const bool value = decltype(__test<_Tp>(nullptr))::value;
};
template <class _Tp>
struct __has_operator_addressof
: public integral_constant<bool, __has_operator_addressof_imp<_Tp>::value>
: public integral_constant<bool, __has_operator_addressof_member_imp<_Tp>::value
|| __has_operator_addressof_free_imp<_Tp>::value>
{};
#endif // _LIBCPP_HAS_NO_ADVANCED_SFINAE

View File

@ -40,6 +40,10 @@ struct E
constexpr C operator&() const;
};
struct F {};
constexpr F* operator&(F const &) { return nullptr; }
#endif // _LIBCPP_HAS_NO_CONSTEXPR
int main()
@ -49,5 +53,6 @@ int main()
static_assert(std::__has_operator_addressof<A>::value == false, "");
static_assert(std::__has_operator_addressof<B>::value == true, "");
static_assert(std::__has_operator_addressof<E>::value == true, "");
static_assert(std::__has_operator_addressof<F>::value == true, "");
#endif // _LIBCPP_HAS_NO_CONSTEXPR
}