[v3 PATCH] Constrain optional's __constexpr_addressof in its return type, Use a constexpr addressof for optional, if available.
Ville Voutilainen
ville.voutilainen@gmail.com
Tue Dec 6 08:52:00 GMT 2016
The background for these is at
https://stackoverflow.com/questions/40983822/cannot-use-a-constant-reference-of-experimentaloptional-when-using-clang-lib
We use excessive trickery to constrain __constexpr_addressof in
experimental::optional.
That trickery is not agreed on by compilers, and we can cope with a much simpler
approach.
The first patch just simplifies that trickery by moving the
constraints from a template
parameter to the return type.
The second patch uses a constexpr std::__addressof if it's available.
I split these
out in case we want just the first patch but not the second. The second patch
allows C++17 users to benefit from a completely constexpr addressof even
for experimental::optional (std::optional already gives that).
Tested on Linux-x64. Ok for trunk, the gcc-6 branch and the gcc-5 branch?
2016-12-06 Ville Voutilainen <ville.voutilainen@gmail.com>
Constrain optional's __constexpr_addressof in its return type.
* include/experimental/optional (__constexpr_addressof):
Constrain in the return type instead of in a template parameter.
2016-12-06 Ville Voutilainen <ville.voutilainen@gmail.com>
Use a constexpr addressof for optional, if available.
* include/experimental/optional (_Has_addressof_mem)
(_Has_addressof_free, _Has_addressof, __constexpr_addressof):
Guard with #ifndef __cpp_lib_addressof_constexpr.
(operator->()): Use std::__addressof if it's constexpr.
-------------- next part --------------
diff --git a/libstdc++-v3/include/experimental/optional b/libstdc++-v3/include/experimental/optional
index a631158..8263639 100644
--- a/libstdc++-v3/include/experimental/optional
+++ b/libstdc++-v3/include/experimental/optional
@@ -170,15 +170,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* overloaded addressof operator (unary operator&), in which case the call
* will not be a constant expression.
*/
- template<typename _Tp, enable_if_t<!_Has_addressof<_Tp>::value, int>...>
- constexpr _Tp* __constexpr_addressof(_Tp& __t)
+ template<typename _Tp>
+ constexpr
+ enable_if_t<!_Has_addressof<_Tp>::value, _Tp*>
+ __constexpr_addressof(_Tp& __t)
{ return &__t; }
/**
* @brief Fallback overload that defers to __addressof.
*/
- template<typename _Tp, enable_if_t<_Has_addressof<_Tp>::value, int>...>
- inline _Tp* __constexpr_addressof(_Tp& __t)
+ template<typename _Tp>
+ inline
+ enable_if_t<_Has_addressof<_Tp>::value, _Tp*>
+ __constexpr_addressof(_Tp& __t)
{ return std::__addressof(__t); }
/**
-------------- next part --------------
diff --git a/libstdc++-v3/include/experimental/optional b/libstdc++-v3/include/experimental/optional
index 8263639..6994e77 100644
--- a/libstdc++-v3/include/experimental/optional
+++ b/libstdc++-v3/include/experimental/optional
@@ -134,6 +134,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__throw_bad_optional_access(const char* __s)
{ _GLIBCXX_THROW_OR_ABORT(bad_optional_access(__s)); }
+#ifndef __cpp_lib_addressof_constexpr
template<typename _Tp, typename = void>
struct _Has_addressof_mem : std::false_type { };
@@ -184,6 +185,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
enable_if_t<_Has_addressof<_Tp>::value, _Tp*>
__constexpr_addressof(_Tp& __t)
{ return std::__addressof(__t); }
+#endif // __cpp_lib_addressof_constexpr
/**
* @brief Class template that holds the necessary state for @ref optional
@@ -709,7 +711,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// [X.Y.4.5] Observers.
constexpr const _Tp*
operator->() const
- { return __constexpr_addressof(this->_M_get()); }
+ {
+#ifndef __cpp_lib_addressof_constexpr
+ return __constexpr_addressof(this->_M_get());
+#else
+ return std::__addressof(this->_M_get());
+#endif
+ }
_Tp*
operator->()
More information about the Libstdc++
mailing list