On Thu, 02 Jul 2026 at 14:22 +0200, Tomasz Kamiński wrote:
This patch extracts optional<_Tp&> specialization to the new
bits/optional_ref.h file. This allows it to be used as return
type of exception_ptr_cast (as required by P3981R2) from <exception>,
without introducing cyclic dependency.

In addition to reference specialization, the definitions of
nullopt_t, nullopt, __is_valid_contained_type..., and _Optional_func
required for it are moved to this new file. We also forward declare
__gnu_cxx::__normal_iterator required for iterator type defintion.

To minimize set of dependencies, the following methods remain
defined (now out of line) in <optional> header:
* value - requires __throw_bad_optional_access
* begin/end - requires __normal_iterator
* then, or_else, transform, constructor from _Optional_func
  - depends on invoke
* value_or - moved for consistency
Furthemore, to avoid introduction of dependency of <concepts>,
the requires clause for or_else is changed from invocable<_Fn>
to is_invocable_v<_Fn>. The is conforming, as standard specifies
the former in Constraints, and user cannot really on subsumption.

Finally, the in_place_t (and other tags) are extracted into separate
bits/inplace_tags.h header, removing the dependency on bist/utility.h.

bist -> bits


libstdc++-v3/ChangeLog:

        * include/Makefile.am (bits/optional_ref.h): Add.
        * include/Makefile.in: Regenerate.
        * include/bits/inplace_tags.h: New file.
        * include/bits/utility.h (std::in_place_t, std::in_place)
        (std::in_place_type_t, std::in_place_type)
        (std::in_place_index_t, in_place_index): Move to
        bits/inplace_tags.h.
        * include/bits/optional_ref.h: New file.
        * include/std/optional (std::nullopt_t, std::nullopt)
        (std::__is_valid_contained_type_for_optional)
        (std::_Optional_func, std::optional<_Tp&>)
        (std::__is_optional_ref_v, std::__optional_ref_base):
        Moved to bits/optional_ref.h.
        (optional<_Tp&>::begin, optional<_Tp&>::end)
        (optional<_Tp&>::value, optional<_Tp&>::value_or)
        (optional<_Tp&>::and_then, optional<_Tp&>::transform)
        (optional<_Tp&>::optional(_Optional_func<_Fn>, _Value):
        Define out of line.
        (optional<_Tp&>::or_else): Define out of line, and
        change requires from invocable<_Fn> to is_invocable_v<_Fn>.
---
Testing on x86_64-linux. All test passed locally.
OK for trunk when exteded suite happens?

libstdc++-v3/include/Makefile.am         |   2 +
libstdc++-v3/include/Makefile.in         |   2 +
libstdc++-v3/include/bits/inplace_tags.h |  84 +++++
libstdc++-v3/include/bits/optional_ref.h | 389 ++++++++++++++++++++++
libstdc++-v3/include/bits/utility.h      |  39 +--
libstdc++-v3/include/std/optional        | 405 ++++-------------------
6 files changed, 545 insertions(+), 376 deletions(-)
create mode 100644 libstdc++-v3/include/bits/inplace_tags.h
create mode 100644 libstdc++-v3/include/bits/optional_ref.h

diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index f91a93ae4aa..262ba42950b 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -138,6 +138,7 @@ bits_freestanding = \
        ${bits_srcdir}/enable_special_members.h \
        ${bits_srcdir}/functexcept.h \
        ${bits_srcdir}/functional_hash.h \
+       ${bits_srcdir}/inplace_tags.h \
        ${bits_srcdir}/intcmp.h \
        ${bits_srcdir}/invoke.h \
        ${bits_srcdir}/iosfwd.h \
@@ -152,6 +153,7 @@ bits_freestanding = \
        ${bits_srcdir}/memoryfwd.h \
        ${bits_srcdir}/monostate.h \
        ${bits_srcdir}/move.h \
+       ${bits_srcdir}/optional_ref.h \
        ${bits_srcdir}/ostream.h \
        ${bits_srcdir}/out_ptr.h \
        ${bits_srcdir}/predefined_ops.h \
diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in
index 611ef30c6cd..0d97a5acdb2 100644
--- a/libstdc++-v3/include/Makefile.in
+++ b/libstdc++-v3/include/Makefile.in
@@ -496,6 +496,7 @@ bits_freestanding = \
        ${bits_srcdir}/enable_special_members.h \
        ${bits_srcdir}/functexcept.h \
        ${bits_srcdir}/functional_hash.h \
+       ${bits_srcdir}/inplace_tags.h \
        ${bits_srcdir}/intcmp.h \
        ${bits_srcdir}/invoke.h \
        ${bits_srcdir}/iosfwd.h \
@@ -510,6 +511,7 @@ bits_freestanding = \
        ${bits_srcdir}/memoryfwd.h \
        ${bits_srcdir}/monostate.h \
        ${bits_srcdir}/move.h \
+       ${bits_srcdir}/optional_ref.h \
        ${bits_srcdir}/ostream.h \
        ${bits_srcdir}/out_ptr.h \
        ${bits_srcdir}/predefined_ops.h \
diff --git a/libstdc++-v3/include/bits/inplace_tags.h 
b/libstdc++-v3/include/bits/inplace_tags.h
new file mode 100644
index 00000000000..c6c1f762c61
--- /dev/null
+++ b/libstdc++-v3/include/bits/inplace_tags.h
@@ -0,0 +1,84 @@
+// Tag types for inplace construction. -*- C++ -*-
+
+// Copyright (C) 2004-2026 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file include/bits/inplace_tags.h
+ *  This is an internal header file, included by other library headers.
+ *  Do not attempt to use it directly. @headername{utility}
+ *
+ *  This file contains the parts of `<utility>` needed by other headers,
+ *  so they don't need to include the whole of `<utility>`.
+ */
+
+#ifndef _GLIBCXX_INPLACE_TAGS_H
+#define _GLIBCXX_INPLACE_TAGS_H 1
+
+#ifdef _GLIBCXX_SYSHDR
+#pragma GCC system_header
+#endif
+
+#if __cplusplus >= 201703L
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  struct in_place_t {
+    explicit in_place_t() = default;
+  };
+
+  inline constexpr in_place_t in_place{};
+
+  template<typename _Tp> struct in_place_type_t
+  {
+    explicit in_place_type_t() = default;
+  };
+
+  template<typename _Tp>
+    inline constexpr in_place_type_t<_Tp> in_place_type{};
+
+  template<size_t _Idx> struct in_place_index_t
+  {
+    explicit in_place_index_t() = default;
+  };
+
+  template<size_t _Idx>
+    inline constexpr in_place_index_t<_Idx> in_place_index{};
+
+  template<typename>
+    inline constexpr bool __is_in_place_type_v = false;
+
+  template<typename _Tp>
+    inline constexpr bool __is_in_place_type_v<in_place_type_t<_Tp>> = true;
+
+  template<typename>
+    inline constexpr bool __is_in_place_index_v = false;
+
+  template<size_t _Nm>
+    inline constexpr bool __is_in_place_index_v<in_place_index_t<_Nm>> = true;
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace
+
+#endif // C++17
+#endif /* _GLIBCXX_INPLACE_TAGS_H */
diff --git a/libstdc++-v3/include/bits/optional_ref.h 
b/libstdc++-v3/include/bits/optional_ref.h
new file mode 100644
index 00000000000..e018a4199e9
--- /dev/null
+++ b/libstdc++-v3/include/bits/optional_ref.h
@@ -0,0 +1,389 @@
+// optional<T&> -*- C++ -*-
+
+// Copyright (C) 2013-2026 Free Software Foundation, Inc.
+// Copyright The GNU Toolchain Authors.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file include/optional
+ *  This is a tandard C++ Library header.

No it isn't :-)
This comment block should be removed, the @file block below is
correct.


OK with that change

+ */
+
+/** @file bits/optional_ref.h
+ *  This is an internal header file, included by other library headers.
+ *  Do not attempt to use it directly. @headername{optional}
+ */
+
+#ifndef _GLIBCXX_OPTIONAL_REF
+#define _GLIBCXX_OPTIONAL_REF 1
+
+#ifdef _GLIBCXX_SYSHDR
+#pragma GCC system_header
+#endif
+
+#ifdef __glibcxx_optional // C++ >= 17
+
+#include <type_traits>
+#include <bits/move.h>
+#include <bits/inplace_tags.h>
+
+namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  template<typename _Iterator, typename _Container>
+    class __normal_iterator;
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace __gnu_cxx
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+   /**
+   *  @addtogroup utilities
+   *  @{
+   */
+
+  template<typename _Tp>
+    class optional;
+
+  /// Tag type to disengage optional objects.
+  struct nullopt_t
+  {
+    // Do not user-declare default constructor at all for
+    // optional_value = {} syntax to work.
+    // nullopt_t() = delete;
+
+    // Used for constructing nullopt.
+    enum class _Construct { _Token };
+
+    // Must be constexpr for nullopt_t to be literal.
+    explicit constexpr nullopt_t(_Construct) noexcept { }
+  };
+
+  /// Tag to disengage optional objects.
+  inline constexpr nullopt_t nullopt { nullopt_t::_Construct::_Token };
+
+  template<typename _Fn> struct _Optional_func { _Fn& _M_f; };
+
+  template<typename _Tp>
+    inline constexpr bool __is_valid_contained_type_for_optional =
+      (
+#if __glibcxx_optional >= 202506L
+       is_lvalue_reference_v<_Tp> ||
+#endif
+       (is_object_v<_Tp> && is_destructible_v<_Tp> && !is_array_v<_Tp>)
+      )
+      && !is_same_v<remove_cv_t<remove_reference_t<_Tp>>, nullopt_t>
+      && !is_same_v<remove_cv_t<remove_reference_t<_Tp>>, in_place_t>;
+
+#if __glibcxx_optional >= 202506L // C++26
+  template<typename _Tp>
+    class optional<_Tp&>;
+
+  template<typename _Tp>
+    constexpr bool __is_optional_ref_v = false;
+
+  template<typename _Tp>
+    constexpr bool __is_optional_ref_v<optional<_Tp&>> = true;
+
+  template<typename _Tp>
+    struct __optional_ref_base
+    {};
+
+#ifdef __glibcxx_optional_range_support // >= C++26
+  template<typename _Tp>
+    struct __optional_ref_base<_Tp[]>
+    {};
+
+  template<typename _Tp>
+    requires is_object_v<_Tp>
+    struct __optional_ref_base<_Tp>
+    {
+      using iterator = __gnu_cxx::__normal_iterator<_Tp*, optional<_Tp&>>;
+    };
+#endif // __glibcxx_optional_range_support
+
+  template<typename _Tp>
+    class optional<_Tp&> : public __optional_ref_base<_Tp>
+    {
+      static_assert(__is_valid_contained_type_for_optional<_Tp&>);
+
+    public:
+      using value_type = _Tp;
+
+      // Constructors.
+      constexpr optional() noexcept = default;
+      constexpr optional(nullopt_t) noexcept : optional() {}
+      constexpr optional(const optional&) noexcept = default;
+
+      template<typename _Arg>
+       requires is_constructible_v<_Tp&, _Arg>
+         && (!reference_constructs_from_temporary_v<_Tp&, _Arg>)
+       explicit constexpr
+       optional(in_place_t, _Arg&& __arg)
+       {
+         __convert_ref_init_val(std::forward<_Arg>(__arg));
+       }
+
+      template<typename _Up>
+       requires (!is_same_v<remove_cvref_t<_Up>, optional>)
+         && (!is_same_v<remove_cvref_t<_Up>, in_place_t>)
+         && is_constructible_v<_Tp&, _Up>
+         && (!reference_constructs_from_temporary_v<_Tp&, _Up>)
+       explicit(!is_convertible_v<_Up, _Tp&>)
+       constexpr
+       optional(_Up&& __u)
+       noexcept(is_nothrow_constructible_v<_Tp&, _Up>)
+       {
+         __convert_ref_init_val(std::forward<_Up>(__u));
+       }
+
+      template<typename _Up>
+       requires (!is_same_v<remove_cvref_t<_Up>, optional>)
+         && (!is_same_v<remove_cvref_t<_Up>, in_place_t>)
+         && is_constructible_v<_Tp&, _Up>
+         && reference_constructs_from_temporary_v<_Tp&, _Up>
+       explicit(!is_convertible_v<_Up, _Tp&>)
+       constexpr
+       optional(_Up&& __u) = delete;
+
+      // optional<U> &
+      template<typename _Up>
+       requires (!is_same_v<remove_cv_t<_Tp>, optional<_Up>>)
+         && (!is_same_v<_Tp&, _Up>)
+         && is_constructible_v<_Tp&, _Up&>
+         && (!reference_constructs_from_temporary_v<_Tp&, _Up&>)
+       explicit(!is_convertible_v<_Up&, _Tp&>)
+       constexpr
+       optional(optional<_Up>& __rhs)
+       noexcept(is_nothrow_constructible_v<_Tp&, _Up&>)
+       {
+         if (__rhs)
+           __convert_ref_init_val(__rhs._M_fwd());
+       }
+
+      template<typename _Up>
+       requires (!is_same_v<remove_cv_t<_Tp>, optional<_Up>>)
+         && (!is_same_v<_Tp&, _Up>)
+         && is_constructible_v<_Tp&, _Up&>
+         && reference_constructs_from_temporary_v<_Tp&, _Up&>
+       explicit(!is_convertible_v<_Up&, _Tp&>)
+       constexpr
+       optional(optional<_Up>& __rhs) = delete;
+
+      // const optional<U>&
+      template<typename _Up>
+       requires (!is_same_v<remove_cv_t<_Tp>, optional<_Up>>)
+         && (!is_same_v<_Tp&, _Up>)
+         && is_constructible_v<_Tp&, const _Up&>
+         && (!reference_constructs_from_temporary_v<_Tp&, const _Up&>)
+       explicit(!is_convertible_v<const _Up&, _Tp&>)
+       constexpr
+       optional(const optional<_Up>& __rhs)
+       noexcept(is_nothrow_constructible_v<_Tp&, _Up&>)
+       {
+         if (__rhs)
+           __convert_ref_init_val(__rhs._M_fwd());
+       }
+
+      template<typename _Up>
+       requires (!is_same_v<remove_cv_t<_Tp>, optional<_Up>>)
+         && (!is_same_v<_Tp&, _Up>)
+         && is_constructible_v<_Tp&, const _Up&>
+         && reference_constructs_from_temporary_v<_Tp&, const _Up&>
+       explicit(!is_convertible_v<const _Up&, _Tp&>)
+       constexpr
+       optional(const optional<_Up>& __rhs) = delete;
+
+      // optional<U>&&
+      template<typename _Up>
+       requires (!is_same_v<remove_cv_t<_Tp>, optional<_Up>>)
+         && (!is_same_v<_Tp&, _Up>)
+         && is_constructible_v<_Tp&, _Up>
+         && (!reference_constructs_from_temporary_v<_Tp&, _Up>)
+       explicit(!is_convertible_v<_Up, _Tp&>)
+       constexpr
+       optional(optional<_Up>&& __rhs)
+       noexcept(is_nothrow_constructible_v<_Tp&, _Up>)
+       {
+         if (__rhs)
+           __convert_ref_init_val(std::move(__rhs)._M_fwd());
+       }
+
+      template<typename _Up>
+       requires (!is_same_v<remove_cv_t<_Tp>, optional<_Up>>)
+         && (!is_same_v<_Tp&, _Up>)
+         && is_constructible_v<_Tp&, _Up>
+         && reference_constructs_from_temporary_v<_Tp&, _Up>
+       explicit(!is_convertible_v<_Up, _Tp&>)
+       constexpr
+       optional(optional<_Up>&& __rhs) = delete;
+
+      // const optional<U>&&
+      template<typename _Up>
+       requires (!is_same_v<remove_cv_t<_Tp>, optional<_Up>>)
+         && (!is_same_v<_Tp&, _Up>)
+         && is_constructible_v<_Tp&, const _Up>
+         && (!reference_constructs_from_temporary_v<_Tp&, _Up>)
+       explicit(!is_convertible_v<const _Up, _Tp&>)
+       constexpr
+       optional(const optional<_Up>&& __rhs)
+       noexcept(is_nothrow_constructible_v<_Tp&, const _Up>)
+       {
+         if (__rhs)
+           __convert_ref_init_val(std::move(__rhs)._M_fwd());
+       }
+
+      template<typename _Up>
+       requires (!is_same_v<remove_cv_t<_Tp>, optional<_Up>>)
+         && (!is_same_v<_Tp&, _Up>)
+         && is_constructible_v<_Tp&, const _Up>
+         && reference_constructs_from_temporary_v<_Tp&, const _Up>
+       explicit(!is_convertible_v<const _Up, _Tp&>)
+       constexpr
+       optional(const optional<_Up>&& __rhs) = delete;
+
+      constexpr ~optional() = default;
+
+      // Assignment.
+      constexpr optional& operator=(nullopt_t) noexcept
+      {
+       _M_val = nullptr;
+       return *this;
+      }
+
+      constexpr optional& operator=(const optional&) noexcept = default;
+
+      template<typename _Up>
+       requires is_constructible_v<_Tp&, _Up>
+         && (!reference_constructs_from_temporary_v<_Tp&, _Up>)
+       constexpr _Tp&
+       emplace(_Up&& __u)
+       noexcept(is_nothrow_constructible_v<_Tp&, _Up>)
+       {
+         __convert_ref_init_val(std::forward<_Up>(__u));
+         // _GLIBCXX_RESOLVE_LIB_DEFECTS
+         // 4300. Missing Returns: element in optional<T&>::emplace
+         return *_M_val;
+       }
+
+      // Swap.
+      constexpr void swap(optional& __rhs) noexcept
+      { std::swap(_M_val, __rhs._M_val); }
+
+#ifdef __glibcxx_optional_range_support // >= C++26
+      // Iterator support.
+      constexpr auto begin() const noexcept
+       requires is_object_v<_Tp> && (!is_unbounded_array_v<_Tp>);
+
+      constexpr auto end() const noexcept
+       requires is_object_v<_Tp> && (!is_unbounded_array_v<_Tp>);
+#endif // __glibcxx_optional_range_support
+
+      // Observers.
+      constexpr _Tp* operator->() const noexcept
+      {
+       __glibcxx_assert(_M_val); // hardened precondition
+       return _M_val;
+      }
+
+      constexpr _Tp& operator*() const noexcept
+      {
+       __glibcxx_assert(_M_val); // hardened precondition
+       return *_M_val;
+      }
+
+      constexpr explicit operator bool() const noexcept
+      {
+       return _M_val;
+      }
+
+      constexpr bool has_value() const noexcept
+      {
+       return _M_val;
+      }
+
+      constexpr _Tp& value() const;
+
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // 4304. std::optional<NonReturnable&> is ill-formed due to value_or
+      template<typename _Up = remove_cv_t<_Tp>>
+       requires is_object_v<_Tp> && (!is_array_v<_Tp>)
+       constexpr decay_t<_Tp>
+       value_or(_Up&& __u) const;
+
+      // Monadic operations.
+      template<typename _Fn>
+       constexpr auto
+       and_then(_Fn&& __f) const;
+
+      template<typename _Fn>
+       constexpr
+       optional<remove_cv_t<invoke_result_t<_Fn, _Tp&>>>
+       transform(_Fn&& __f) const;
+
+      template<typename _Fn>
+       requires is_invocable_v<_Fn>
+       constexpr
+       optional
+       or_else(_Fn&& __f) const;
+
+      // Modifiers.
+      constexpr void reset() noexcept
+      {
+       _M_val = nullptr;
+      }
+
+    private:
+      _Tp *_M_val = nullptr;
+
+      [[__gnu__::__always_inline__]]
+      constexpr _Tp&
+      _M_fwd() const noexcept
+      { return *_M_val; }
+
+      template<typename _Up> friend class optional;
+
+      template<typename _Up>
+       constexpr
+       void
+       __convert_ref_init_val(_Up&& __u)
+       noexcept
+       {
+         _Tp& __r(std::forward<_Up>(__u));
+         _M_val = std::addressof(__r);
+       }
+
+      template<typename _Fn, typename _Value>
+       explicit constexpr
+       optional(_Optional_func<_Fn> __f, _Value&& __v);
+    };
+#endif // __glibcxx_optional >= 202506L
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace std
+
+#endif // __glibcxx_optional
+
+#endif // _GLIBCXX_OPTIONAL_REF
diff --git a/libstdc++-v3/include/bits/utility.h 
b/libstdc++-v3/include/bits/utility.h
index 320dd507b43..f3e956f33f9 100644
--- a/libstdc++-v3/include/bits/utility.h
+++ b/libstdc++-v3/include/bits/utility.h
@@ -41,6 +41,7 @@

#include <type_traits>
#include <bits/move.h>
+#include <bits/inplace_tags.h>
#ifdef __glibcxx_constant_wrapper // C++ >= 26
#  include <bits/invoke.h>
#endif
@@ -549,44 +550,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#endif // __integer_pack
#endif // __cpp_structured_bindings >= 202411L

-#if __cplusplus >= 201703L
-
-  struct in_place_t {
-    explicit in_place_t() = default;
-  };
-
-  inline constexpr in_place_t in_place{};
-
-  template<typename _Tp> struct in_place_type_t
-  {
-    explicit in_place_type_t() = default;
-  };
-
-  template<typename _Tp>
-    inline constexpr in_place_type_t<_Tp> in_place_type{};
-
-  template<size_t _Idx> struct in_place_index_t
-  {
-    explicit in_place_index_t() = default;
-  };
-
-  template<size_t _Idx>
-    inline constexpr in_place_index_t<_Idx> in_place_index{};
-
-  template<typename>
-    inline constexpr bool __is_in_place_type_v = false;
-
-  template<typename _Tp>
-    inline constexpr bool __is_in_place_type_v<in_place_type_t<_Tp>> = true;
-
-  template<typename>
-    inline constexpr bool __is_in_place_index_v = false;
-
-  template<size_t _Nm>
-    inline constexpr bool __is_in_place_index_v<in_place_index_t<_Nm>> = true;
-
-#endif // C++17
-
#if _GLIBCXX_USE_BUILTIN_TRAIT(__type_pack_element)
  template<size_t _Np, typename... _Types>
    struct _Nth_type
diff --git a/libstdc++-v3/include/std/optional 
b/libstdc++-v3/include/std/optional
index 221beb2446d..d6fd33e8c2e 100644
--- a/libstdc++-v3/include/std/optional
+++ b/libstdc++-v3/include/std/optional
@@ -51,6 +51,7 @@
#include <bits/enable_special_members.h>
#include <bits/exception_defines.h>
#include <bits/functional_hash.h>
+#include <bits/optional_ref.h>  // nullopt_t, optional<_Tp&>
#include <bits/stl_construct.h> // _Construct
#include <bits/utility.h> // in_place_t
#if __cplusplus > 201703L
@@ -77,28 +78,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   *  @{
   */

-  template<typename _Tp>
-    class optional;
-
-  /// Tag type to disengage optional objects.
-  struct nullopt_t
-  {
-    // Do not user-declare default constructor at all for
-    // optional_value = {} syntax to work.
-    // nullopt_t() = delete;
-
-    // Used for constructing nullopt.
-    enum class _Construct { _Token };
-
-    // Must be constexpr for nullopt_t to be literal.
-    explicit constexpr nullopt_t(_Construct) noexcept { }
-  };
-
-  /// Tag to disengage optional objects.
-  inline constexpr nullopt_t nullopt { nullopt_t::_Construct::_Token };
-
-  template<typename _Fn> struct _Optional_func { _Fn& _M_f; };
-
  /**
   *  @brief Exception class thrown when a disengaged optional object is
   *  dereferenced.
@@ -795,17 +774,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
# define _GLIBCXX_USE_CONSTRAINTS_FOR_OPTIONAL 1
#endif

-  template<typename _Tp>
-    inline constexpr bool __is_valid_contained_type_for_optional =
-      (
-#if __cpp_lib_optional >= 202506L
-       is_lvalue_reference_v<_Tp> ||
-#endif
-       (is_object_v<_Tp> && is_destructible_v<_Tp> && !is_array_v<_Tp>)
-      )
-      && !is_same_v<remove_cv_t<remove_reference_t<_Tp>>, nullopt_t>
-      && !is_same_v<remove_cv_t<remove_reference_t<_Tp>>, in_place_t>;
-
  /**
    * @brief Class template for optional values.
    */
@@ -1505,334 +1473,95 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
    };

#if __cpp_lib_optional >= 202506L // C++26
+#ifdef __cpp_lib_optional_range_support
  template<typename _Tp>
-    class optional<_Tp&>;
-
-  template<typename _Tp>
-    constexpr bool __is_optional_ref_v = false;
-
-  template<typename _Tp>
-    constexpr bool __is_optional_ref_v<optional<_Tp&>> = true;
-
-  template<typename _Tp>
-    struct __optional_ref_base
-    {};
-
-#ifdef __cpp_lib_optional_range_support // >= C++26
-  template<typename _Tp>
-    struct __optional_ref_base<_Tp[]>
-    {};
+    constexpr auto
+    optional<_Tp&>::begin() const noexcept
+      requires is_object_v<_Tp> && (!is_unbounded_array_v<_Tp>)
+    { return __gnu_cxx::__normal_iterator<_Tp*, optional>(_M_val); }

  template<typename _Tp>
-    requires is_object_v<_Tp>
-    struct __optional_ref_base<_Tp>
-    {
-      using iterator = __gnu_cxx::__normal_iterator<_Tp*, optional<_Tp&>>;
-    };
+    constexpr auto
+    optional<_Tp&>::end() const noexcept
+      requires is_object_v<_Tp> && (!is_unbounded_array_v<_Tp>)
+    { return begin() + has_value(); }
#endif // __cpp_lib_optional_range_support

  template<typename _Tp>
-    class optional<_Tp&> : public __optional_ref_base<_Tp>
+    constexpr _Tp&
+    optional<_Tp&>::value() const
    {
-      static_assert(__is_valid_contained_type_for_optional<_Tp&>);
-
-    public:
-      using value_type = _Tp;
-
-      // Constructors.
-      constexpr optional() noexcept = default;
-      constexpr optional(nullopt_t) noexcept : optional() {}
-      constexpr optional(const optional&) noexcept = default;
-
-      template<typename _Arg>
-       requires is_constructible_v<_Tp&, _Arg>
-         && (!reference_constructs_from_temporary_v<_Tp&, _Arg>)
-       explicit constexpr
-       optional(in_place_t, _Arg&& __arg)
-       {
-         __convert_ref_init_val(std::forward<_Arg>(__arg));
-       }
-
-      template<typename _Up>
-       requires (!is_same_v<remove_cvref_t<_Up>, optional>)
-         && (!is_same_v<remove_cvref_t<_Up>, in_place_t>)
-         && is_constructible_v<_Tp&, _Up>
-         && (!reference_constructs_from_temporary_v<_Tp&, _Up>)
-       explicit(!is_convertible_v<_Up, _Tp&>)
-       constexpr
-       optional(_Up&& __u)
-       noexcept(is_nothrow_constructible_v<_Tp&, _Up>)
-       {
-         __convert_ref_init_val(std::forward<_Up>(__u));
-       }
-
-      template<typename _Up>
-       requires (!is_same_v<remove_cvref_t<_Up>, optional>)
-         && (!is_same_v<remove_cvref_t<_Up>, in_place_t>)
-         && is_constructible_v<_Tp&, _Up>
-         && reference_constructs_from_temporary_v<_Tp&, _Up>
-       explicit(!is_convertible_v<_Up, _Tp&>)
-       constexpr
-       optional(_Up&& __u) = delete;
-
-      // optional<U> &
-      template<typename _Up>
-       requires (!is_same_v<remove_cv_t<_Tp>, optional<_Up>>)
-         && (!is_same_v<_Tp&, _Up>)
-         && is_constructible_v<_Tp&, _Up&>
-         && (!reference_constructs_from_temporary_v<_Tp&, _Up&>)
-       explicit(!is_convertible_v<_Up&, _Tp&>)
-       constexpr
-       optional(optional<_Up>& __rhs)
-       noexcept(is_nothrow_constructible_v<_Tp&, _Up&>)
-       {
-         if (__rhs)
-           __convert_ref_init_val(__rhs._M_fwd());
-       }
-
-      template<typename _Up>
-       requires (!is_same_v<remove_cv_t<_Tp>, optional<_Up>>)
-         && (!is_same_v<_Tp&, _Up>)
-         && is_constructible_v<_Tp&, _Up&>
-         && reference_constructs_from_temporary_v<_Tp&, _Up&>
-       explicit(!is_convertible_v<_Up&, _Tp&>)
-       constexpr
-       optional(optional<_Up>& __rhs) = delete;
-
-      // const optional<U>&
-      template<typename _Up>
-       requires (!is_same_v<remove_cv_t<_Tp>, optional<_Up>>)
-         && (!is_same_v<_Tp&, _Up>)
-         && is_constructible_v<_Tp&, const _Up&>
-         && (!reference_constructs_from_temporary_v<_Tp&, const _Up&>)
-       explicit(!is_convertible_v<const _Up&, _Tp&>)
-       constexpr
-       optional(const optional<_Up>& __rhs)
-       noexcept(is_nothrow_constructible_v<_Tp&, _Up&>)
-       {
-         if (__rhs)
-           __convert_ref_init_val(__rhs._M_fwd());
-       }
-
-      template<typename _Up>
-       requires (!is_same_v<remove_cv_t<_Tp>, optional<_Up>>)
-         && (!is_same_v<_Tp&, _Up>)
-         && is_constructible_v<_Tp&, const _Up&>
-         && reference_constructs_from_temporary_v<_Tp&, const _Up&>
-       explicit(!is_convertible_v<const _Up&, _Tp&>)
-       constexpr
-       optional(const optional<_Up>& __rhs) = delete;
-
-      // optional<U>&&
-      template<typename _Up>
-       requires (!is_same_v<remove_cv_t<_Tp>, optional<_Up>>)
-         && (!is_same_v<_Tp&, _Up>)
-         && is_constructible_v<_Tp&, _Up>
-         && (!reference_constructs_from_temporary_v<_Tp&, _Up>)
-       explicit(!is_convertible_v<_Up, _Tp&>)
-       constexpr
-       optional(optional<_Up>&& __rhs)
-       noexcept(is_nothrow_constructible_v<_Tp&, _Up>)
-       {
-         if (__rhs)
-           __convert_ref_init_val(std::move(__rhs)._M_fwd());
-       }
-
-      template<typename _Up>
-       requires (!is_same_v<remove_cv_t<_Tp>, optional<_Up>>)
-         && (!is_same_v<_Tp&, _Up>)
-         && is_constructible_v<_Tp&, _Up>
-         && reference_constructs_from_temporary_v<_Tp&, _Up>
-       explicit(!is_convertible_v<_Up, _Tp&>)
-       constexpr
-       optional(optional<_Up>&& __rhs) = delete;
-
-      // const optional<U>&&
-      template<typename _Up>
-       requires (!is_same_v<remove_cv_t<_Tp>, optional<_Up>>)
-         && (!is_same_v<_Tp&, _Up>)
-         && is_constructible_v<_Tp&, const _Up>
-         && (!reference_constructs_from_temporary_v<_Tp&, _Up>)
-       explicit(!is_convertible_v<const _Up, _Tp&>)
-       constexpr
-       optional(const optional<_Up>&& __rhs)
-       noexcept(is_nothrow_constructible_v<_Tp&, const _Up>)
-       {
-         if (__rhs)
-           __convert_ref_init_val(std::move(__rhs)._M_fwd());
-       }
-
-      template<typename _Up>
-       requires (!is_same_v<remove_cv_t<_Tp>, optional<_Up>>)
-         && (!is_same_v<_Tp&, _Up>)
-         && is_constructible_v<_Tp&, const _Up>
-         && reference_constructs_from_temporary_v<_Tp&, const _Up>
-       explicit(!is_convertible_v<const _Up, _Tp&>)
-       constexpr
-       optional(const optional<_Up>&& __rhs) = delete;
-
-      constexpr ~optional() = default;
+      if (_M_val)
+       return *_M_val;
+      __throw_bad_optional_access();
+    }

-      // Assignment.
-      constexpr optional& operator=(nullopt_t) noexcept
+  template<typename _Tp>
+    template<typename _Up>
+      requires is_object_v<_Tp> && (!is_array_v<_Tp>)
+      constexpr decay_t<_Tp>
+      optional<_Tp&>::value_or(_Up&& __u) const
      {
-       _M_val = nullptr;
-       return *this;
-      }
-
-      constexpr optional& operator=(const optional&) noexcept = default;
-
-      template<typename _Up>
-       requires is_constructible_v<_Tp&, _Up>
-         && (!reference_constructs_from_temporary_v<_Tp&, _Up>)
-       constexpr _Tp&
-       emplace(_Up&& __u)
-       noexcept(is_nothrow_constructible_v<_Tp&, _Up>)
-       {
-         __convert_ref_init_val(std::forward<_Up>(__u));
-         // _GLIBCXX_RESOLVE_LIB_DEFECTS
-         // 4300. Missing Returns: element in optional<T&>::emplace
+       using _Xp = remove_cv_t<_Tp>;
+       static_assert(is_convertible_v<_Tp&, _Xp>);
+       static_assert(is_convertible_v<_Up, _Xp>);
+       if (_M_val)
          return *_M_val;
-       }
-
-      // Swap.
-      constexpr void swap(optional& __rhs) noexcept
-      { std::swap(_M_val, __rhs._M_val); }
-
-#ifdef __cpp_lib_optional_range_support // >= C++26
-      // Iterator support.
-      constexpr auto begin() const noexcept
-       requires is_object_v<_Tp> && (!is_unbounded_array_v<_Tp>)
-      { return __gnu_cxx::__normal_iterator<_Tp*, optional>(_M_val); }
-
-      constexpr auto end() const noexcept
-       requires is_object_v<_Tp> && (!is_unbounded_array_v<_Tp>)
-      { return begin() + has_value(); }
-#endif // __cpp_lib_optional_range_support
-
-      // Observers.
-      constexpr _Tp* operator->() const noexcept
-      {
-       __glibcxx_assert(_M_val); // hardened precondition
-       return _M_val;
-      }
-
-      constexpr _Tp& operator*() const noexcept
-      {
-       __glibcxx_assert(_M_val); // hardened precondition
-       return *_M_val;
+       return std::forward<_Up>(__u);
      }

-      constexpr explicit operator bool() const noexcept
+  template<typename _Tp>
+    template<typename _Fn>
+      constexpr auto
+      optional<_Tp&>::and_then(_Fn&& __f) const
      {
-       return _M_val;
+        using _Up = remove_cvref_t<invoke_result_t<_Fn, _Tp&>>;
+        static_assert(__is_optional_v<_Up>,
+                      "the function passed to std::optional<T&>::and_then "
+                      "must return a std::optional");
+        if (has_value())
+          return std::__invoke(std::forward<_Fn>(__f), *_M_val);
+        else
+          return _Up();
      }

-      constexpr bool has_value() const noexcept
+  template<typename _Tp>
+    template<typename _Fn>
+      constexpr optional<remove_cv_t<invoke_result_t<_Fn, _Tp&>>>
+      optional<_Tp&>::transform(_Fn&& __f) const
      {
-       return _M_val;
+        using _Up = remove_cv_t<invoke_result_t<_Fn, _Tp&>>;
+        if (has_value())
+          return optional<_Up>(_Optional_func<_Fn>{__f}, *_M_val);
+        else
+          return optional<_Up>();
      }

-      constexpr _Tp& value() const
+  template<typename _Tp>
+    template<typename _Fn>
+      requires is_invocable_v<_Fn>
+      constexpr optional<_Tp&>
+      optional<_Tp&>::or_else(_Fn&& __f) const
      {
-       if (_M_val)
-         return *_M_val;
-       __throw_bad_optional_access();
+        static_assert(is_same_v<remove_cvref_t<invoke_result_t<_Fn>>, 
optional>,
+                      "the function passed to std::optional<T&>::or_else "
+                      "must return a std::optional<T&>");
+        // _GLIBCXX_RESOLVE_LIB_DEFECTS
+        // 4367. Improve optional<T&>::or_else
+        if (has_value())
+          return *this;
+        else
+          return std::forward<_Fn>(__f)();
      }

-      // _GLIBCXX_RESOLVE_LIB_DEFECTS
-      // 4304. std::optional<NonReturnable&> is ill-formed due to value_or
-      template<typename _Up = remove_cv_t<_Tp>>
-       requires is_object_v<_Tp> && (!is_array_v<_Tp>)
-       constexpr decay_t<_Tp>
-       value_or(_Up&& __u) const
-       {
-         using _Xp = remove_cv_t<_Tp>;
-         static_assert(is_convertible_v<_Tp&, _Xp>);
-         static_assert(is_convertible_v<_Up, _Xp>);
-         if (_M_val)
-           return *_M_val;
-         return std::forward<_Up>(__u);
-       }
-
-      // Monadic operations.
-      template<typename _Fn>
-       constexpr auto
-       and_then(_Fn&& __f) const
-       {
-         using _Up = remove_cvref_t<invoke_result_t<_Fn, _Tp&>>;
-         static_assert(__is_optional_v<_Up>,
-                       "the function passed to std::optional<T&>::and_then "
-                       "must return a std::optional");
-         if (has_value())
-           return std::__invoke(std::forward<_Fn>(__f), *_M_val);
-         else
-           return _Up();
-       }
-
-      template<typename _Fn>
-       constexpr
-       optional<remove_cv_t<invoke_result_t<_Fn, _Tp&>>>
-       transform(_Fn&& __f) const
-       {
-         using _Up = remove_cv_t<invoke_result_t<_Fn, _Tp&>>;
-         if (has_value())
-           return optional<_Up>(_Optional_func<_Fn>{__f}, *_M_val);
-         else
-           return optional<_Up>();
-       }
-
-      template<typename _Fn>
-       requires invocable<_Fn>
-       constexpr
-       optional
-       or_else(_Fn&& __f) const
-       {
-         static_assert(is_same_v<remove_cvref_t<invoke_result_t<_Fn>>, 
optional>,
-                       "the function passed to std::optional<T&>::or_else "
-                       "must return a std::optional<T&>");
-         // _GLIBCXX_RESOLVE_LIB_DEFECTS
-         // 4367. Improve optional<T&>::or_else
-         if (has_value())
-           return *this;
-         else
-           return std::forward<_Fn>(__f)();
-       }
-
-      // Modifiers.
-      constexpr void reset() noexcept
+  template<typename _Tp>
+    template<typename _Fn, typename _Value>
+      constexpr
+      optional<_Tp&>::optional(_Optional_func<_Fn> __f, _Value&& __v)
      {
-       _M_val = nullptr;
+        _Tp& __r = std::__invoke(std::forward<_Fn>(__f._M_f), 
std::forward<_Value>(__v));
+        _M_val = std::addressof(__r);
      }
-
-    private:
-      _Tp *_M_val = nullptr;
-
-      [[__gnu__::__always_inline__]]
-      constexpr _Tp&
-      _M_fwd() const noexcept
-      { return *_M_val; }
-
-      template<typename _Up> friend class optional;
-
-      template<typename _Up>
-       constexpr
-       void
-       __convert_ref_init_val(_Up&& __u)
-       noexcept
-       {
-         _Tp& __r(std::forward<_Up>(__u));
-         _M_val = std::addressof(__r);
-       }
-
-      template<typename _Fn, typename _Value>
-       explicit constexpr
-       optional(_Optional_func<_Fn> __f, _Value&& __v)
-       {
-         _Tp& __r = std::__invoke(std::forward<_Fn>(__f._M_f), 
std::forward<_Value>(__v));
-         _M_val = std::addressof(__r);
-       }
-    };
#endif // __cpp_lib_optional >= 202506L

  template<typename _Tp>
--
2.54.0



Reply via email to