diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2014-11-12 00:16:19 +0000 |
---|---|---|
committer | Jonathan Wakely <redi@gcc.gnu.org> | 2014-11-12 00:16:19 +0000 |
commit | 72e58f18aed02cadf0c19f11b8d524fab9613cac (patch) | |
tree | 764b1f5b152e4fdc07879325b77494767952403e /libstdc++-v3 | |
parent | 847e9cf81e5101f327e4cd5ac629df93b0afb581 (diff) | |
download | gcc-72e58f18aed02cadf0c19f11b8d524fab9613cac.zip gcc-72e58f18aed02cadf0c19f11b8d524fab9613cac.tar.gz gcc-72e58f18aed02cadf0c19f11b8d524fab9613cac.tar.bz2 |
optional (_Has_addressof): Check for non-member operator&.
* 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.
From-SVN: r217397
Diffstat (limited to 'libstdc++-v3')
-rw-r--r-- | libstdc++-v3/ChangeLog | 7 | ||||
-rw-r--r-- | libstdc++-v3/include/experimental/optional | 24 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/experimental/optional/constexpr/observers/2.cc | 2 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/experimental/optional/observers/2.cc | 2 |
4 files changed, 29 insertions, 6 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 4a17fd0..0c9d430 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,10 @@ +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. diff --git a/libstdc++-v3/include/experimental/optional b/libstdc++-v3/include/experimental/optional index 7e01abe..2d3127a 100644 --- a/libstdc++-v3/include/experimental/optional +++ b/libstdc++-v3/include/experimental/optional @@ -127,13 +127,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __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&. @@ -143,7 +153,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * 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 diff --git a/libstdc++-v3/testsuite/experimental/optional/constexpr/observers/2.cc b/libstdc++-v3/testsuite/experimental/optional/constexpr/observers/2.cc index 14b5e3b..2c9215c 100644 --- a/libstdc++-v3/testsuite/experimental/optional/constexpr/observers/2.cc +++ b/libstdc++-v3/testsuite/experimental/optional/constexpr/observers/2.cc @@ -26,6 +26,8 @@ struct value_type { int i; + + void* operator&() { return nullptr; } // N.B. non-const }; int main() diff --git a/libstdc++-v3/testsuite/experimental/optional/observers/2.cc b/libstdc++-v3/testsuite/experimental/optional/observers/2.cc index 8499b47..9fb2edb 100644 --- a/libstdc++-v3/testsuite/experimental/optional/observers/2.cc +++ b/libstdc++-v3/testsuite/experimental/optional/observers/2.cc @@ -26,6 +26,8 @@ struct value_type int i; }; +void* operator&(const value_type&) = delete; + int main() { std::experimental::optional<value_type> o { value_type { 51 } }; |