diff --git a/include/type_traits b/include/type_traits index b359710e..7a7b4c1a 100644 --- a/include/type_traits +++ b/include/type_traits @@ -3642,7 +3642,7 @@ struct underlying_type #ifndef _LIBCPP_HAS_NO_ADVANCED_SFINAE template -struct __has_operator_addressof_imp +struct __has_operator_addressof_member_imp { template 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 +struct __has_operator_addressof_free_imp +{ + template + static auto __test(__any) -> false_type; + template + static auto __test(_Up* __u) + -> typename __select_2nd::type; + + static const bool value = decltype(__test<_Tp>(nullptr))::value; +}; + template struct __has_operator_addressof - : public integral_constant::value> + : public integral_constant::value + || __has_operator_addressof_free_imp<_Tp>::value> {}; #endif // _LIBCPP_HAS_NO_ADVANCED_SFINAE diff --git a/test/utilities/meta/meta.unary/meta.unary.prop/__has_operator_addressof.pass.cpp b/test/utilities/meta/meta.unary/meta.unary.prop/__has_operator_addressof.pass.cpp index de27b982..81368939 100644 --- a/test/utilities/meta/meta.unary/meta.unary.prop/__has_operator_addressof.pass.cpp +++ b/test/utilities/meta/meta.unary/meta.unary.prop/__has_operator_addressof.pass.cpp @@ -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::value == false, ""); static_assert(std::__has_operator_addressof::value == true, ""); static_assert(std::__has_operator_addressof::value == true, ""); + static_assert(std::__has_operator_addressof::value == true, ""); #endif // _LIBCPP_HAS_NO_CONSTEXPR }