From 1637d42545cced0c58204ecb36499e512eeb3841 Mon Sep 17 00:00:00 2001 From: Ville Voutilainen Date: Tue, 6 Dec 2016 14:47:54 +0200 Subject: [PATCH] Constrain optional's __constexpr_addressof in its return type and use a constexpr addressof for optional, if available. Constrain optional's __constexpr_addressof in its return type and use a constexpr addressof for optional, if available. * include/experimental/optional (__constexpr_addressof): Constrain in the return type instead of in a template parameter. (_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. From-SVN: r243298 --- libstdc++-v3/ChangeLog | 11 +++++++++++ libstdc++-v3/include/experimental/optional | 22 +++++++++++++++++----- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 1d47e38..47e9abf 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,14 @@ +2016-12-06 Ville Voutilainen + + Constrain optional's __constexpr_addressof in its return type + and use a constexpr addressof for optional, if available. + * include/experimental/optional (__constexpr_addressof): + Constrain in the return type instead of in a template parameter. + (_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. + 2016-11-27 Tim Shen * include/std/variant (visit): Make visit constexpr. Also cleanup diff --git a/libstdc++-v3/include/experimental/optional b/libstdc++-v3/include/experimental/optional index a631158..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 struct _Has_addressof_mem : std::false_type { }; @@ -170,16 +171,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * overloaded addressof operator (unary operator&), in which case the call * will not be a constant expression. */ - template::value, int>...> - constexpr _Tp* __constexpr_addressof(_Tp& __t) + template + constexpr + enable_if_t::value, _Tp*> + __constexpr_addressof(_Tp& __t) { return &__t; } /** * @brief Fallback overload that defers to __addressof. */ - template::value, int>...> - inline _Tp* __constexpr_addressof(_Tp& __t) + template + inline + 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 @@ -705,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->() -- 2.7.4