https://gcc.gnu.org/g:4b55cd211f33200b3c25afe138853351ce4ac4d3
commit r15-2305-g4b55cd211f33200b3c25afe138853351ce4ac4d3 Author: Jonathan Wakely <jwak...@redhat.com> Date: Tue Jul 23 11:46:05 2024 +0100 libstdc++: Use _M_get() in std::optional internals Now that _base::_M_get() doesn't check the precondition, we can use _M_get() instead of operator*() for the internal uses where we've already checked the precondition holds. Add a using-declaration so that we don't need to lookup _M_get in the dependent base class, and make optional<U> a friend so that the converting constructors and assignment operators can use the parameter's _M_get member. libstdc++-v3/ChangeLog: * include/std/optional (optional): Add using-declaraction for _Base::_M_get and declare optional<U> as friend. (optional(const optional<U>&)): Use _M_get instead of operator*. (optional(optional<U>&&)): Likewise. (operator=(const optional<U>&)): Likewise. (operator=(optional<U>&&)): Likewise. (and_then, tansform): Likewise. Diff: --- libstdc++-v3/include/std/optional | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/libstdc++-v3/include/std/optional b/libstdc++-v3/include/std/optional index af72004645e2..9ed7ab501402 100644 --- a/libstdc++-v3/include/std/optional +++ b/libstdc++-v3/include/std/optional @@ -760,7 +760,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION noexcept(is_nothrow_constructible_v<_Tp, const _Up&>) { if (__t) - emplace(*__t); + emplace(__t._M_get()); } template<typename _Up, @@ -773,7 +773,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION noexcept(is_nothrow_constructible_v<_Tp, const _Up&>) { if (__t) - emplace(*__t); + emplace(__t._M_get()); } template<typename _Up, @@ -786,7 +786,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION noexcept(is_nothrow_constructible_v<_Tp, _Up>) { if (__t) - emplace(std::move(*__t)); + emplace(std::move(__t._M_get())); } template<typename _Up, @@ -799,7 +799,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION noexcept(is_nothrow_constructible_v<_Tp, _Up>) { if (__t) - emplace(std::move(*__t)); + emplace(std::move(__t._M_get())); } template<typename... _Args, @@ -863,9 +863,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION if (__u) { if (this->_M_is_engaged()) - this->_M_get() = *__u; + this->_M_get() = __u._M_get(); else - this->_M_construct(*__u); + this->_M_construct(__u._M_get()); } else { @@ -889,9 +889,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION if (__u) { if (this->_M_is_engaged()) - this->_M_get() = std::move(*__u); + this->_M_get() = std::move(__u._M_get()); else - this->_M_construct(std::move(*__u)); + this->_M_construct(std::move(__u._M_get())); } else { @@ -1056,7 +1056,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return static_cast<_Tp>(std::forward<_Up>(__u)); } -#if __cpp_lib_optional >= 202110L +#if __cpp_lib_optional >= 202110L // C++23 // [optional.monadic] template<typename _Fn> @@ -1068,7 +1068,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION "the function passed to std::optional<T>::and_then " "must return a std::optional"); if (has_value()) - return std::__invoke(std::forward<_Fn>(__f), **this); + return std::__invoke(std::forward<_Fn>(__f), _M_get()); else return _Up(); } @@ -1082,7 +1082,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION "the function passed to std::optional<T>::and_then " "must return a std::optional"); if (has_value()) - return std::__invoke(std::forward<_Fn>(__f), **this); + return std::__invoke(std::forward<_Fn>(__f), _M_get()); else return _Up(); } @@ -1096,7 +1096,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION "the function passed to std::optional<T>::and_then " "must return a std::optional"); if (has_value()) - return std::__invoke(std::forward<_Fn>(__f), std::move(**this)); + return std::__invoke(std::forward<_Fn>(__f), std::move(_M_get())); else return _Up(); } @@ -1110,7 +1110,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION "the function passed to std::optional<T>::and_then " "must return a std::optional"); if (has_value()) - return std::__invoke(std::forward<_Fn>(__f), std::move(**this)); + return std::__invoke(std::forward<_Fn>(__f), std::move(_M_get())); else return _Up(); } @@ -1121,7 +1121,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { using _Up = remove_cv_t<invoke_result_t<_Fn, _Tp&>>; if (has_value()) - return optional<_Up>(_Optional_func<_Fn>{__f}, **this); + return optional<_Up>(_Optional_func<_Fn>{__f}, _M_get()); else return optional<_Up>(); } @@ -1132,7 +1132,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { using _Up = remove_cv_t<invoke_result_t<_Fn, const _Tp&>>; if (has_value()) - return optional<_Up>(_Optional_func<_Fn>{__f}, **this); + return optional<_Up>(_Optional_func<_Fn>{__f}, _M_get()); else return optional<_Up>(); } @@ -1143,7 +1143,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { using _Up = remove_cv_t<invoke_result_t<_Fn, _Tp>>; if (has_value()) - return optional<_Up>(_Optional_func<_Fn>{__f}, std::move(**this)); + return optional<_Up>(_Optional_func<_Fn>{__f}, std::move(_M_get())); else return optional<_Up>(); } @@ -1154,7 +1154,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { using _Up = remove_cv_t<invoke_result_t<_Fn, const _Tp>>; if (has_value()) - return optional<_Up>(_Optional_func<_Fn>{__f}, std::move(**this)); + return optional<_Up>(_Optional_func<_Fn>{__f}, std::move(_M_get())); else return optional<_Up>(); } @@ -1193,9 +1193,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX20_CONSTEXPR void reset() noexcept { this->_M_reset(); } private: -#if __cplusplus >= 202002L + using _Base::_M_get; + template<typename _Up> friend class optional; +#if __cpp_lib_optional >= 202110L // C++23 template<typename _Fn, typename _Value> explicit constexpr optional(_Optional_func<_Fn> __f, _Value&& __v)