+2014-11-12 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/experimental/optional (_Has_addressof): Check for non-member
+ operator&.
+ * testsuite/experimental/optional/observers/2.cc: Add operator&.
+ * testsuite/experimental/optional/constexpr/observers/2.cc: Likewise.
+
2014-11-11 Jonathan Wakely <jwakely@redhat.com>
* include/std/type_traits (__void_t): Define new alias template.
__throw_bad_optional_access(const char* __s)
{ _GLIBCXX_THROW_OR_ABORT(bad_optional_access(__s)); }
- template<typename _Tp, typename _Sfinae = void>
- struct _Has_addressof_impl : std::false_type { };
+ template<typename _Tp, typename = void>
+ struct _Has_addressof_mem : std::false_type { };
template<typename _Tp>
- struct _Has_addressof_impl<_Tp,
- decltype( std::declval<const _Tp&>().operator&(), void() )>
- : std::true_type { };
+ struct _Has_addressof_mem<_Tp,
+ __void_t<decltype( std::declval<const _Tp&>().operator&() )>
+ >
+ : std::true_type { };
+
+ template<typename _Tp, typename = void>
+ struct _Has_addressof_free : std::false_type { };
+
+ template<typename _Tp>
+ struct _Has_addressof_free<_Tp,
+ __void_t<decltype( operator&(std::declval<const _Tp&>()) )>
+ >
+ : std::true_type { };
/**
* @brief Trait that detects the presence of an overloaded unary operator&.
* declval<_Tp * const&>().operator&()).
*/
template<typename _Tp>
- struct _Has_addressof : _Has_addressof_impl<_Tp>::type { };
+ struct _Has_addressof
+ : std::__or_<_Has_addressof_mem<_Tp>, _Has_addressof_free<_Tp>>::type
+ { };
/**
* @brief An overload that attempts to take the address of an lvalue as a