get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/2226850/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 2226850,
    "url": "http://patchwork.ozlabs.org/api/patches/2226850/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/gcc/patch/bmm.hhupath8dc.gcc.gcc-TEST.tkaminsk.107.1.1@forge-stage.sourceware.org/",
    "project": {
        "id": 17,
        "url": "http://patchwork.ozlabs.org/api/projects/17/?format=api",
        "name": "GNU Compiler Collection",
        "link_name": "gcc",
        "list_id": "gcc-patches.gcc.gnu.org",
        "list_email": "gcc-patches@gcc.gnu.org",
        "web_url": null,
        "scm_url": null,
        "webscm_url": null,
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<bmm.hhupath8dc.gcc.gcc-TEST.tkaminsk.107.1.1@forge-stage.sourceware.org>",
    "list_archive_url": null,
    "date": "2026-04-22T18:55:17",
    "name": "[v1,01/13] libstdc++: WIP: optional<T&> (P2988R12)",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "a47ed86cd02525ef0ccab6152568a5a26029472a",
    "submitter": {
        "id": 93223,
        "url": "http://patchwork.ozlabs.org/api/people/93223/?format=api",
        "name": "tkaminsk via Sourceware Forge",
        "email": "forge-bot+tkaminsk@forge-stage.sourceware.org"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/gcc/patch/bmm.hhupath8dc.gcc.gcc-TEST.tkaminsk.107.1.1@forge-stage.sourceware.org/mbox/",
    "series": [
        {
            "id": 501097,
            "url": "http://patchwork.ozlabs.org/api/series/501097/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/gcc/list/?series=501097",
            "date": "2026-04-22T18:55:20",
            "name": "libstdc++: optional<T&> (P2988R12)",
            "version": 1,
            "mbox": "http://patchwork.ozlabs.org/series/501097/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/2226850/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/2226850/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org>",
        "X-Original-To": [
            "incoming@patchwork.ozlabs.org",
            "gcc-patches@gcc.gnu.org"
        ],
        "Delivered-To": [
            "patchwork-incoming@legolas.ozlabs.org",
            "gcc-patches@gcc.gnu.org"
        ],
        "Authentication-Results": [
            "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org\n (client-ip=38.145.34.32; helo=vm01.sourceware.org;\n envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org;\n receiver=patchwork.ozlabs.org)",
            "sourceware.org; dmarc=none (p=none dis=none)\n header.from=forge-stage.sourceware.org",
            "sourceware.org;\n spf=pass smtp.mailfrom=forge-stage.sourceware.org",
            "server2.sourceware.org;\n arc=none smtp.remote-ip=38.145.34.39"
        ],
        "Received": [
            "from vm01.sourceware.org (vm01.sourceware.org [38.145.34.32])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4g19P96C4Wz1yD5\n\tfor <incoming@patchwork.ozlabs.org>; Thu, 23 Apr 2026 06:12:13 +1000 (AEST)",
            "from vm01.sourceware.org (localhost [127.0.0.1])\n\tby sourceware.org (Postfix) with ESMTP id C021943EFF9D\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 22 Apr 2026 20:12:10 +0000 (GMT)",
            "from forge-stage.sourceware.org (vm08.sourceware.org [38.145.34.39])\n by sourceware.org (Postfix) with ESMTPS id 194D640A086B\n for <gcc-patches@gcc.gnu.org>; Wed, 22 Apr 2026 18:56:23 +0000 (GMT)",
            "from forge-stage.sourceware.org (localhost [IPv6:::1])\n (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n key-exchange x25519 server-signature ECDSA (prime256v1) server-digest SHA256)\n (No client certificate requested)\n by forge-stage.sourceware.org (Postfix) with ESMTPS id E9FA9435B2\n for <gcc-patches@gcc.gnu.org>; Wed, 22 Apr 2026 18:56:22 +0000 (UTC)"
        ],
        "DKIM-Filter": [
            "OpenDKIM Filter v2.11.0 sourceware.org C021943EFF9D",
            "OpenDKIM Filter v2.11.0 sourceware.org 194D640A086B"
        ],
        "DMARC-Filter": "OpenDMARC Filter v1.4.2 sourceware.org 194D640A086B",
        "ARC-Filter": "OpenARC Filter v1.0.0 sourceware.org 194D640A086B",
        "ARC-Seal": "i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1776884183; cv=none;\n b=lYQ0GWOPG8mrMwG53YeCOabR8Gfdcj9K06ZK5EhxEn1APkZPdcgnXEhx9wr2hMNy6Djto5G0yc67nDD/xBuaS96y1sfGiZbgcKdtSiK+ViitdgYZ2ftH+JQBmWbk48ebekrfLb9uYnj6audr+UwQTms5B2AkydY/0mo2gPxNZjY=",
        "ARC-Message-Signature": "i=1; a=rsa-sha256; d=sourceware.org; s=key;\n t=1776884183; c=relaxed/simple;\n bh=prHMFglfjhe9GelOYmV6vnmOgDXmaytlo0x8HYS/qLM=;\n h=From:Date:Subject:To:Message-ID;\n b=pl7eNZFNv6X57Nw85M9+WnkL3GQhEptCV+gG6JoIjBMT2hHm6YKKocFEd0x73ejB6mlJ+3DNpUAtLKCSNf7bLx+hZypvhMIzsxMJWCcMT5qVZEjgFelbRnwPe1E2y0Zmks8sayaZtHmpeVFJ10/Jul/v10oQtp6l4PTP56e0XIY=",
        "ARC-Authentication-Results": "i=1; server2.sourceware.org",
        "From": "tkaminsk via Sourceware Forge\n <forge-bot+tkaminsk@forge-stage.sourceware.org>",
        "Date": "Wed, 22 Apr 2026 18:55:17 +0000",
        "Subject": "[PATCH v1 01/13] libstdc++: WIP: optional<T&> (P2988R12)",
        "To": "gcc-patches mailing list <gcc-patches@gcc.gnu.org>",
        "Message-ID": "\n <bmm.hhupath8dc.gcc.gcc-TEST.tkaminsk.107.1.1@forge-stage.sourceware.org>",
        "X-Mailer": "batrachomyomachia",
        "X-Pull-Request-Organization": "gcc",
        "X-Pull-Request-Repository": "gcc-TEST",
        "X-Pull-Request": "https://forge.sourceware.org/gcc/gcc-TEST/pulls/107",
        "References": "\n <bmm.hhupath8dc.gcc.gcc-TEST.tkaminsk.107.1.0@forge-stage.sourceware.org>",
        "In-Reply-To": "\n <bmm.hhupath8dc.gcc.gcc-TEST.tkaminsk.107.1.0@forge-stage.sourceware.org>",
        "X-Patch-URL": "\n https://forge.sourceware.org/tkaminsk/gcc/commit/4b371936f3a9dfe94de9c3bba919bba0d84456b5",
        "X-BeenThere": "gcc-patches@gcc.gnu.org",
        "X-Mailman-Version": "2.1.30",
        "Precedence": "list",
        "List-Id": "Gcc-patches mailing list <gcc-patches.gcc.gnu.org>",
        "List-Unsubscribe": "<https://gcc.gnu.org/mailman/options/gcc-patches>,\n <mailto:gcc-patches-request@gcc.gnu.org?subject=unsubscribe>",
        "List-Archive": "<https://gcc.gnu.org/pipermail/gcc-patches/>",
        "List-Post": "<mailto:gcc-patches@gcc.gnu.org>",
        "List-Help": "<mailto:gcc-patches-request@gcc.gnu.org?subject=help>",
        "List-Subscribe": "<https://gcc.gnu.org/mailman/listinfo/gcc-patches>,\n <mailto:gcc-patches-request@gcc.gnu.org?subject=subscribe>",
        "Reply-To": "gcc-patches mailing list <gcc-patches@gcc.gnu.org>,\n tkaminsk@gcc.gnu.org",
        "Errors-To": "gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org"
    },
    "content": "From: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>\n\nINCOMPLETE (needs lots of tests!). The value of the FTM is made-up.\n\nThe converting constructors from optional<U> are tedious to type.\nMaybe deduce the argument and centralize the implementation?\n\nNoted a few things to address in P2988R12, editorially / easy LWG issues.\n\nmake_optional: the proposed change breaks\n  make_optional<T>({braced-init-list}), wanted? Disabled for now.\n\nlibstdc++-v3/ChangeLog:\n\n\t* include/bits/version.def (__cpp_lib_optional): Bump the\n\tfeature-testing macro.\n\t* include/bits/version.h: Regenerate.\n\t* include/std/optional (optional): Add specialization for\n\treferences. Do minor amendments to the primary template as\n\tper P2988R12.\n\t* testsuite/20_util/optional/requirements.cc: Amend the\n\tfeature-testing macro test.\n\t* testsuite/20_util/optional/requirements_neg.cc: Amend the\n\ttesting of optional<T&>.\n\t* testsuite/20_util/optional/version.cc: Amend the\n\tfeature-testing macro test.\n---\n libstdc++-v3/include/bits/version.def         |   4 +\n libstdc++-v3/include/bits/version.h           |   7 +-\n libstdc++-v3/include/std/optional             | 347 +++++++++++++++++-\n .../20_util/optional/requirements.cc          |   4 +-\n .../20_util/optional/requirements_neg.cc      |  17 +-\n .../testsuite/20_util/optional/version.cc     |   4 +-\n 6 files changed, 374 insertions(+), 9 deletions(-)",
    "diff": "diff --git a/libstdc++-v3/include/bits/version.def b/libstdc++-v3/include/bits/version.def\nindex 1118da4b541e..111aa19a3aac 100644\n--- a/libstdc++-v3/include/bits/version.def\n+++ b/libstdc++-v3/include/bits/version.def\n@@ -878,6 +878,10 @@ ftms = {\n // Moved down here (after concepts) by topological sort.\n ftms = {\n   name = optional;\n+  values = {\n+    v = 202506;\n+    cxxmin = 26;\n+  };\n   values = {\n     v = 202110;\n     cxxmin = 23;\ndiff --git a/libstdc++-v3/include/bits/version.h b/libstdc++-v3/include/bits/version.h\nindex c452bbeec8e0..e98ecdf94e7c 100644\n--- a/libstdc++-v3/include/bits/version.h\n+++ b/libstdc++-v3/include/bits/version.h\n@@ -985,7 +985,12 @@\n #undef __glibcxx_want_concepts\n \n #if !defined(__cpp_lib_optional)\n-# if (__cplusplus >= 202100L) && (__glibcxx_concepts)\n+# if (__cplusplus >  202302L)\n+#  define __glibcxx_optional 202506L\n+#  if defined(__glibcxx_want_all) || defined(__glibcxx_want_optional)\n+#   define __cpp_lib_optional 202506L\n+#  endif\n+# elif (__cplusplus >= 202100L) && (__glibcxx_concepts)\n #  define __glibcxx_optional 202110L\n #  if defined(__glibcxx_want_all) || defined(__glibcxx_want_optional)\n #   define __cpp_lib_optional 202110L\ndiff --git a/libstdc++-v3/include/std/optional b/libstdc++-v3/include/std/optional\nindex e5051d72c828..2f61b2e0ae99 100644\n--- a/libstdc++-v3/include/std/optional\n+++ b/libstdc++-v3/include/std/optional\n@@ -777,6 +777,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n # define _GLIBCXX_USE_CONSTRAINTS_FOR_OPTIONAL 1\n #endif\n \n+  template<typename _Tp>\n+    inline constexpr bool __is_valid_contained_type_for_optional =\n+      (\n+#if __cpp_lib_optional >= 202506L\n+\tis_lvalue_reference_v<_Tp> ||\n+#endif\n+\t(is_object_v<_Tp> && !is_array_v<_Tp>)\n+      )\n+      && !is_same_v<remove_cv_t<remove_reference_t<_Tp>>, nullopt_t>\n+      && !is_same_v<remove_cv_t<remove_reference_t<_Tp>>, in_place_t>\n+      && (!is_object_v<_Tp> || is_destructible_v<_Tp>);\n+\n   /**\n     * @brief Class template for optional values.\n     */\n@@ -795,9 +807,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n \t// Unique tag type.\n \toptional<_Tp>>\n     {\n-      static_assert(!is_same_v<remove_cv_t<_Tp>, nullopt_t>);\n-      static_assert(!is_same_v<remove_cv_t<_Tp>, in_place_t>);\n-      static_assert(is_object_v<_Tp> && !is_array_v<_Tp>);\n+      static_assert(__is_valid_contained_type_for_optional<_Tp>);\n \n     private:\n       using _Base = _Optional_base<_Tp>;\n@@ -1366,6 +1376,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n \ttransform(_Fn&& __f) &\n \t{\n \t  using _Up = remove_cv_t<invoke_result_t<_Fn, _Tp&>>;\n+\t  static_assert(__is_valid_contained_type_for_optional<_Up>,\n+\t\t\t\"the function passed to std::optional<T>::transform \"\n+\t\t\t\"must return a type \"\n+\t\t\t\"that can be stored inside std::optional\");\n \t  if (has_value())\n \t    return optional<_Up>(_Optional_func<_Fn>{__f}, _M_get());\n \t  else\n@@ -1377,6 +1391,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n \ttransform(_Fn&& __f) const &\n \t{\n \t  using _Up = remove_cv_t<invoke_result_t<_Fn, const _Tp&>>;\n+\t  static_assert(__is_valid_contained_type_for_optional<_Up>,\n+\t\t\t\"the function passed to std::optional<T>::transform \"\n+\t\t\t\"must return a type \"\n+\t\t\t\"that can be stored inside std::optional\");\n \t  if (has_value())\n \t    return optional<_Up>(_Optional_func<_Fn>{__f}, _M_get());\n \t  else\n@@ -1388,6 +1406,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n \ttransform(_Fn&& __f) &&\n \t{\n \t  using _Up = remove_cv_t<invoke_result_t<_Fn, _Tp>>;\n+\t  static_assert(__is_valid_contained_type_for_optional<_Up>,\n+\t\t\t\"the function passed to std::optional<T>::transform \"\n+\t\t\t\"must return a type \"\n+\t\t\t\"that can be stored inside std::optional\");\n \t  if (has_value())\n \t    return optional<_Up>(_Optional_func<_Fn>{__f}, std::move(_M_get()));\n \t  else\n@@ -1399,6 +1421,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n \ttransform(_Fn&& __f) const &&\n \t{\n \t  using _Up = remove_cv_t<invoke_result_t<_Fn, const _Tp>>;\n+\t  static_assert(__is_valid_contained_type_for_optional<_Up>,\n+\t\t\t\"the function passed to std::optional<T>::transform \"\n+\t\t\t\"must return a type \"\n+\t\t\t\"that can be stored inside std::optional\");\n \t  if (has_value())\n \t    return optional<_Up>(_Optional_func<_Fn>{__f}, std::move(_M_get()));\n \t  else\n@@ -1453,6 +1479,306 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n #endif\n     };\n \n+#if __cpp_lib_optional >= 202506L // C++26\n+  template<typename _Tp>\n+    class optional<_Tp&>\n+    {\n+      static_assert(__is_valid_contained_type_for_optional<_Tp&>);\n+\n+    public:\n+      using value_type = _Tp;\n+      using iterator = __gnu_cxx::__normal_iterator<_Tp*, optional>;\n+\n+      // Constructors.\n+      constexpr optional() noexcept = default;\n+      constexpr optional(nullopt_t) noexcept : optional() {}\n+      constexpr optional(const optional&) noexcept = default;\n+\n+      template<typename _Arg>\n+\trequires is_constructible_v<_Tp&, _Arg>\n+\t  && (!reference_constructs_from_temporary_v<_Tp&, _Arg>)\n+\texplicit constexpr\n+\toptional(in_place_t, _Arg&& __arg)\n+\t{\n+\t  __convert_ref_init_val(std::forward<_Arg>(__arg));\n+\t}\n+\n+      template<typename _Up>\n+\trequires (!is_same_v<remove_cvref_t<_Up>, optional>)\n+\t  && (!is_same_v<remove_cvref_t<_Up>, in_place_t>)\n+\t  && is_constructible_v<_Tp&, _Up>\n+\t  && (!reference_constructs_from_temporary_v<_Tp&, _Up>)\n+\texplicit(!is_convertible_v<_Up, _Tp&>)\n+\tconstexpr\n+\toptional(_Up&& __u)\n+\tnoexcept(is_nothrow_constructible_v<_Tp&, _Up>)\n+\t{\n+\t  __convert_ref_init_val(std::forward<_Up>(__u));\n+\t}\n+\n+      template<typename _Up>\n+\trequires (!is_same_v<remove_cvref_t<_Up>, optional>)\n+\t  && (!is_same_v<remove_cvref_t<_Up>, in_place_t>)\n+\t  && is_constructible_v<_Tp&, _Up>\n+\t  && reference_constructs_from_temporary_v<_Tp&, _Up>\n+\texplicit(!is_convertible_v<_Up, _Tp&>)\n+\tconstexpr\n+\toptional(_Up&& __u) = delete;\n+\n+      // optional<U> &\n+      template<typename _Up>\n+\trequires (!is_same_v<remove_cv_t<_Tp>, optional<_Up>>)\n+\t  && (!is_same_v<_Tp&, _Up>)\n+\t  && is_constructible_v<_Tp&, _Up&>\n+\t  && (!reference_constructs_from_temporary_v<_Tp&, _Up&>)\n+\texplicit(!is_convertible_v<_Up&, _Tp&>)\n+\tconstexpr\n+\toptional(optional<_Up>& __rhs)\n+\tnoexcept(is_nothrow_constructible_v<_Tp&, _Up&>)\n+\t{\n+\t  if (__rhs)\n+\t    __convert_ref_init_val(*__rhs);\n+\t}\n+\n+      template<typename _Up>\n+\trequires (!is_same_v<remove_cv_t<_Tp>, optional<_Up>>)\n+\t  && (!is_same_v<_Tp&, _Up>)\n+\t  && is_constructible_v<_Tp&, _Up&>\n+\t  && reference_constructs_from_temporary_v<_Tp&, _Up&>\n+\texplicit(!is_convertible_v<_Up&, _Tp&>)\n+\tconstexpr\n+\toptional(optional<_Up>& __rhs) = delete;\n+\n+      // const optional<U>&\n+      template<typename _Up>\n+\trequires (!is_same_v<remove_cv_t<_Tp>, optional<_Up>>)\n+\t  && (!is_same_v<_Tp&, _Up>)\n+\t  && is_constructible_v<_Tp&, const _Up&>\n+\t  && (!reference_constructs_from_temporary_v<_Tp&, const _Up&>)\n+\texplicit(!is_convertible_v<const _Up&, _Tp&>)\n+\tconstexpr\n+\toptional(const optional<_Up>& __rhs)\n+\tnoexcept(is_nothrow_constructible_v<_Tp&, _Up&>)\n+\t{\n+\t  if (__rhs)\n+\t    __convert_ref_init_val(*__rhs);\n+\t}\n+\n+      template<typename _Up>\n+\trequires (!is_same_v<remove_cv_t<_Tp>, optional<_Up>>)\n+\t  && (!is_same_v<_Tp&, _Up>)\n+\t  && is_constructible_v<_Tp&, const _Up&>\n+\t  && reference_constructs_from_temporary_v<_Tp&, const _Up&>\n+\texplicit(!is_convertible_v<const _Up&, _Tp&>)\n+\tconstexpr\n+\toptional(const optional<_Up>& __rhs) = delete;\n+\n+      // optional<U>&&\n+      template<typename _Up>\n+\trequires (!is_same_v<remove_cv_t<_Tp>, optional<_Up>>)\n+\t  && (!is_same_v<_Tp&, _Up>)\n+\t  && is_constructible_v<_Tp&, _Up>\n+\t  && (!reference_constructs_from_temporary_v<_Tp&, _Up>)\n+\texplicit(!is_convertible_v<_Up, _Tp&>)\n+\tconstexpr\n+\toptional(optional<_Up>&& __rhs)\n+\tnoexcept(is_nothrow_constructible_v<_Tp&, _Up>)\n+\t{\n+\t  if (__rhs)\n+\t    __convert_ref_init_val(*std::move(__rhs));\n+\t}\n+\n+      template<typename _Up>\n+\trequires (!is_same_v<remove_cv_t<_Tp>, optional<_Up>>)\n+\t  && (!is_same_v<_Tp&, _Up>)\n+\t  && is_constructible_v<_Tp&, _Up>\n+\t  && reference_constructs_from_temporary_v<_Tp&, _Up>\n+\texplicit(!is_convertible_v<_Up, _Tp&>)\n+\tconstexpr\n+\toptional(optional<_Up>&& __rhs) = delete;\n+\n+      // const optional<U>&&\n+      template<typename _Up>\n+\trequires (!is_same_v<remove_cv_t<_Tp>, optional<_Up>>)\n+\t  && (!is_same_v<_Tp&, _Up>)\n+\t  && is_constructible_v<_Tp&, const _Up>\n+\t  && (!reference_constructs_from_temporary_v<_Tp&, _Up>)\n+\texplicit(!is_convertible_v<const _Up, _Tp&>)\n+\tconstexpr\n+\toptional(const optional<_Up>&& __rhs)\n+\tnoexcept(is_nothrow_constructible_v<_Tp&, const _Up>)\n+\t{\n+\t  if (__rhs)\n+\t    __convert_ref_init_val(*std::move(__rhs));\n+\t}\n+\n+      template<typename _Up>\n+\trequires (!is_same_v<remove_cv_t<_Tp>, optional<_Up>>)\n+\t  && (!is_same_v<_Tp&, _Up>)\n+\t  && is_constructible_v<_Tp&, const _Up>\n+\t  && reference_constructs_from_temporary_v<_Tp&, const _Up>\n+\texplicit(!is_convertible_v<const _Up, _Tp&>)\n+\tconstexpr\n+\toptional(const optional<_Up>&& __rhs) = delete;\n+\n+      constexpr ~optional() = default;\n+\n+      // Assignment.\n+      constexpr optional& operator=(nullopt_t) noexcept\n+      {\n+\t_M_val = nullptr;\n+\treturn *this;\n+      }\n+\n+      constexpr optional& operator=(const optional&) noexcept = default;\n+\n+      template<typename _Up>\n+\trequires is_constructible_v<_Tp&, _Up>\n+\t  && (!reference_constructs_from_temporary_v<_Tp&, _Up>)\n+\tconstexpr\n+\t_Tp&\n+\templace(_Up&& __u)\n+\tnoexcept(is_nothrow_constructible_v<_Tp&, _Up>)\n+\t{\n+\t  __convert_ref_init_val(std::forward<_Up>(__u));\n+\t  return *_M_val; // FIXME: this isn't specified in the paper as Returns:, but likely a typo? What else could it be?\n+\t}\n+\n+      // Swap.\n+      constexpr void swap(optional& __rhs) noexcept\n+      {\n+\tswap(_M_val, __rhs._M_val);\n+      }\n+\n+      // Iterator support.\n+      constexpr iterator begin() const noexcept\n+      {\n+\treturn iterator(_M_val);\n+      }\n+\n+      constexpr iterator end() const noexcept\n+      {\n+\treturn begin() + has_value();\n+      }\n+\n+      // Observers.\n+      constexpr _Tp* operator->() const noexcept\n+      {\n+\t__glibcxx_assert(_M_val); // hardened precondition\n+        return _M_val;\n+      }\n+\n+      constexpr _Tp& operator*() const noexcept\n+      {\n+\t__glibcxx_assert(_M_val); // hardened precondition\n+        return *_M_val;\n+      }\n+\n+      constexpr explicit operator bool() const noexcept\n+      {\n+        return _M_val;\n+      }\n+\n+      constexpr bool has_value() const noexcept\n+      {\n+        return _M_val;\n+      }\n+\n+      constexpr _Tp& value() const\n+      {\n+        if (_M_val)\n+          return *_M_val;\n+        __throw_bad_optional_access();\n+      }\n+\n+      template<typename _Up = remove_cv_t<_Tp>>\n+\tconstexpr remove_cv_t<_Tp>\n+\tvalue_or(_Up&& __u) const\n+\t{\n+          using _Xp = remove_cv_t<_Tp>;\n+\t  static_assert(is_constructible_v<_Xp, _Tp&>);\n+\t  static_assert(is_convertible_v<_Up, _Xp>);\n+\t  return _M_val ? *_M_val : static_cast<_Xp>(std::forward<_Up>(__u));\n+\t}\n+\n+      // Monadic operations.\n+      template<typename _Fn>\n+\tconstexpr auto\n+\tand_then(_Fn&& __f) const\n+\t{\n+\t  using _Up = invoke_result_t<_Fn, _Tp&>;\n+\t  static_assert(__is_optional_v<remove_cvref_t<_Up>>,\n+\t\t\t\"the function passed to std::optional<T&>::and_then \"\n+\t\t\t\"must return a std::optional\");\n+\t  if (has_value())\n+\t    return std::__invoke(std::forward<_Fn>(__f), *_M_val);\n+\t  else\n+\t    return remove_cvref_t<_Up>();\n+\t}\n+\n+      template<typename _Fn>\n+\tconstexpr\n+\toptional<remove_cv_t<invoke_result_t<_Fn, _Tp&>>> // TODO why is it spelled out in the paper instead of `auto`? Like the wording for the primary template\n+\ttransform(_Fn&& __f) const\n+\t{\n+\t  using _Up = remove_cv_t<invoke_result_t<_Fn, _Tp&>>;\n+\t  // FIXME not 100% sure yet how to express the Mandates here \"(The declaration U u(invoke(std::forward<F>(f), *val)); is well-formed for some invented variable u.)\".\n+\t  // TODO: It seems that this Mandates also missing from our implementation of the primary template...?\n+\n+\t  // FIXME why isn't there in the paper a Mandates that U is a valid contained type for optional? Like in the wording for the primary template.\n+\t  if (has_value())\n+\t    return optional<_Up>(_Optional_func<_Fn>{__f}, *_M_val); // TODO the sample impl in the paper seems wrong, as that requires U to be movable (?). This is our primary's template impl which builds in place, and that seems like a better idea\n+\t  else\n+\t    return optional<_Up>();\n+\t}\n+\n+      template<typename _Fn>\n+\trequires invocable<_Fn>\n+\tconstexpr\n+\toptional\n+\tor_else(_Fn&& __f) const\n+\t{\n+\t  static_assert(is_same_v<remove_cvref_t<invoke_result_t<_Fn>>, optional>,\n+\t\t\t\"the function passed to std::optional<T&>::or_else \"\n+\t\t\t\"must return a std::optional<T&>\");\n+\t  if (has_value())\n+\t    return *_M_val; // FIXME in the paper it's spelled like this. I'm not sure yet why it's not spelled `return *this`, like in the primary template's wording? Does this have implications on e.g. lifetime? Suppose one has an object T in some storage, creates an optional<T&> bound to that object, destroys the object, calls opt.or_else(). Is that UB because of the dereference or should it just copy the reference without accessing the (destroyed) object? Should it be UB? The object could be subsequently transparently replaced and the result of or_else bound to the new object...\n+\t  else\n+\t    return std::forward<_Fn>(__f)();\n+\t}\n+\n+      // Modifiers.\n+      constexpr void reset() noexcept\n+      {\n+\t_M_val = nullptr;\n+      }\n+\n+    private:\n+      _Tp *_M_val = nullptr;\n+\n+      template<typename _Up>\n+\tconstexpr\n+\tvoid\n+\t__convert_ref_init_val(_Up&& __u)\n+\tnoexcept\n+\t{\n+\t  _Tp& __r(std::forward<_Up>(__u));\n+\t  _M_val = std::addressof(__r);\n+\t}\n+\n+      template<typename _Up> friend class optional;\n+\n+      template<typename _Fn, typename _Value>\n+\texplicit constexpr\n+\toptional(_Optional_func<_Fn> __f, _Value&& __v)\n+\t{\n+          // TODO: double check this\n+\t  _Tp& __r = std::__invoke(std::forward<_Fn>(__f._M_f), std::forward<_Value>(__v));\n+\t  _M_val = std::addressof(__r);\n+\t}\n+    };\n+#endif // __cpp_lib_optional >= 202506L\n+\n   template<typename _Tp>\n     using __optional_relop_t =\n       enable_if_t<is_convertible_v<_Tp, bool>, bool>;\n@@ -1731,11 +2057,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n \n   // Swap and creation functions.\n \n+  template<typename _Tp>\n+    inline constexpr bool __is_optional_swappable =\n+#if __cpp_lib_optional >= 202506L\n+      is_reference_v<_Tp> ||\n+#endif\n+      (is_move_constructible_v<_Tp> && is_swappable_v<_Tp>);\n+\n   // _GLIBCXX_RESOLVE_LIB_DEFECTS\n   // 2748. swappable traits for optionals\n   template<typename _Tp>\n     _GLIBCXX20_CONSTEXPR\n-    inline enable_if_t<is_move_constructible_v<_Tp> && is_swappable_v<_Tp>>\n+    inline enable_if_t<__is_optional_swappable<_Tp>>\n     swap(optional<_Tp>& __lhs, optional<_Tp>& __rhs)\n     noexcept(noexcept(__lhs.swap(__rhs)))\n     { __lhs.swap(__rhs); }\n@@ -1743,10 +2076,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n   // _GLIBCXX_RESOLVE_LIB_DEFECTS\n   // 2766. Swapping non-swappable types\n   template<typename _Tp>\n-    enable_if_t<!(is_move_constructible_v<_Tp> && is_swappable_v<_Tp>)>\n+    enable_if_t<!__is_optional_swappable<_Tp>>\n     swap(optional<_Tp>&, optional<_Tp>&) = delete;\n \n+#if __cpp_lib_optional >= 202506L && 0 // FIXME. This change breaks make_optional<T>({braced init list}). Wanted?\n+  template<TODO> // \"Constraints: The call to make_optional does not use an explicit template-argument-list that begins with a type template-argument\"\n+#else\n   template<typename _Tp>\n+#endif\n     constexpr\n     enable_if_t<is_constructible_v<decay_t<_Tp>, _Tp>,\n \t\toptional<decay_t<_Tp>>>\ndiff --git a/libstdc++-v3/testsuite/20_util/optional/requirements.cc b/libstdc++-v3/testsuite/20_util/optional/requirements.cc\nindex 68e59057b5e3..3dc787bc89f5 100644\n--- a/libstdc++-v3/testsuite/20_util/optional/requirements.cc\n+++ b/libstdc++-v3/testsuite/20_util/optional/requirements.cc\n@@ -26,8 +26,10 @@\n # error \"Feature test macro for optional has wrong value in <optional>\"\n #elif __cplusplus == 202002L && __cpp_lib_optional != 202106L\n # error \"Feature test macro for optional has wrong value for C++20 in <optional>\"\n-#elif __cplusplus > 202002L && __cpp_lib_optional != 202110L\n+#elif __cplusplus == 202302L && __cpp_lib_optional != 202110L\n # error \"Feature test macro for optional has wrong value for C++23 in <version>\"\n+#elif __cplusplus > 202302L && __cpp_lib_optional != 202506L\n+# error \"Feature test macro for optional has wrong value for C++26 in <version>\"\n #endif\n \n #include <testsuite_hooks.h>\ndiff --git a/libstdc++-v3/testsuite/20_util/optional/requirements_neg.cc b/libstdc++-v3/testsuite/20_util/optional/requirements_neg.cc\nindex 688c305803e2..142fbbfc5151 100644\n--- a/libstdc++-v3/testsuite/20_util/optional/requirements_neg.cc\n+++ b/libstdc++-v3/testsuite/20_util/optional/requirements_neg.cc\n@@ -2,17 +2,32 @@\n \n #include <optional>\n \n+// C++ < 26:\n // T shall be a type other than cv in_place_t or cv nullopt_t\n // that meets the Cpp17Destructible requirements\n+// C++ >= 26:\n+// A type X is a valid contained type for optional if X is an lvalue reference\n+// type or a complete non-array object type, and remove_cvref_t<X> is a type\n+// other than in_place_t or nullopt_t. If a specialization of optional\n+// is instantiated with a type T that is not a valid contained type for\n+// optional, the program is ill-formed. If T is an object type,\n+// T shall meet the Cpp17Destructible requirements\n \n std::optional<std::nullopt_t> o1;        // { dg-error \"here\" }\n std::optional<const std::nullopt_t> o2;  // { dg-error \"here\" }\n std::optional<std::in_place_t> o3;       // { dg-error \"here\" }\n std::optional<const std::in_place_t> o4; // { dg-error \"here\" }\n-std::optional<int&> o5;                  // { dg-error \"here\" }\n+std::optional<int&> o5;                  // { dg-error \"here\" \"optional<T&> is a C++26 feature\" { target c++23_down } }\n std::optional<int[1]> o6;                // { dg-error \"here\" }\n std::optional<int[]> o7;                 // { dg-error \"here\" }\n std::optional<int()> o8;                 // { dg-error \"here\" }\n+std::optional<const int &> o9;           // { dg-error \"here\" \"optional<T&> is a C++26 feature\" { target c++23_down } }\n+std::optional<std::in_place_t &> o10;    // { dg-error \"here\" }\n+std::optional<const std::in_place_t &> o11; // { dg-error \"here\" }\n+std::optional<std::nullopt_t &> o12;     // { dg-error \"here\" }\n+std::optional<const std::nullopt_t &> o13; // { dg-error \"here\" }\n+std::optional<int &&> o14;               // { dg-error \"here\" }\n+std::optional<const int &&> o15;         // { dg-error \"here\" }\n \n // { dg-error \"static assertion failed\" \"\" { target *-*-* } 0 }\n \ndiff --git a/libstdc++-v3/testsuite/20_util/optional/version.cc b/libstdc++-v3/testsuite/20_util/optional/version.cc\nindex ba44aa525356..96b9c8341984 100644\n--- a/libstdc++-v3/testsuite/20_util/optional/version.cc\n+++ b/libstdc++-v3/testsuite/20_util/optional/version.cc\n@@ -9,8 +9,10 @@\n # error \"Feature test macro for optional has wrong value for C++17 in <version>\"\n #elif __cplusplus == 202002L && __cpp_lib_optional != 202106L\n # error \"Feature test macro for optional has wrong value for C++20 in <version>\"\n-#elif __cplusplus > 202002L && __cpp_lib_optional != 202110L\n+#elif __cplusplus == 202302L && __cpp_lib_optional != 202110L\n # error \"Feature test macro for optional has wrong value for C++23 in <version>\"\n+#elif __cplusplus > 202302L && __cpp_lib_optional != 202505L\n+# error \"Feature test macro for optional has wrong value for C++26 in <version>\"\n #endif\n \n #if __cplusplus >= 202302L\n",
    "prefixes": [
        "v1",
        "01/13"
    ]
}