aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2014-11-12 00:16:19 +0000
committerJonathan Wakely <redi@gcc.gnu.org>2014-11-12 00:16:19 +0000
commit72e58f18aed02cadf0c19f11b8d524fab9613cac (patch)
tree764b1f5b152e4fdc07879325b77494767952403e /libstdc++-v3
parent847e9cf81e5101f327e4cd5ac629df93b0afb581 (diff)
downloadgcc-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/ChangeLog7
-rw-r--r--libstdc++-v3/include/experimental/optional24
-rw-r--r--libstdc++-v3/testsuite/experimental/optional/constexpr/observers/2.cc2
-rw-r--r--libstdc++-v3/testsuite/experimental/optional/observers/2.cc2
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 } };