[libcxx-commits] [libcxx] Make std::nullopt_t comparable (PR #195549)

Mohamed Atef via libcxx-commits libcxx-commits at lists.llvm.org
Sun May 3 13:29:50 PDT 2026


https://github.com/elhewaty created https://github.com/llvm/llvm-project/pull/195549

None

>From c2fa68ff7f73c45227ecb7be8917d98f356e1bb3 Mon Sep 17 00:00:00 2001
From: Mohamed Atef <mohamedatef1698 at gmail.com>
Date: Sun, 3 May 2026 23:22:57 +0300
Subject: [PATCH] Make std::nullopt_t comparable

---
 libcxx/docs/Status/Cxx2cIssues.csv            |  2 +-
 libcxx/include/optional                       |  4 ++++
 .../optional.nullopt/nullopt_t.pass.cpp       | 24 +++++++++++++++++--
 3 files changed, 27 insertions(+), 3 deletions(-)

diff --git a/libcxx/docs/Status/Cxx2cIssues.csv b/libcxx/docs/Status/Cxx2cIssues.csv
index e825e9633bdb9..ef17e8261ebe2 100644
--- a/libcxx/docs/Status/Cxx2cIssues.csv
+++ b/libcxx/docs/Status/Cxx2cIssues.csv
@@ -309,7 +309,7 @@
 "`LWG4492 <https://wg21.link/LWG4492>`__","``std::generate`` and ``std::ranges::generate`` wording is unclear for parallel algorithms","2026-03 (Croydon)","","","`#189851 <https://github.com/llvm/llvm-project/issues/189851>`__",""
 "`LWG4493 <https://wg21.link/LWG4493>`__","Specification for some functions of bit reference types seems missing","2026-03 (Croydon)","","","`#189852 <https://github.com/llvm/llvm-project/issues/189852>`__",""
 "`LWG4496 <https://wg21.link/LWG4496>`__","Precedes vs Reachable in [meta.reflection]","2026-03 (Croydon)","","","`#189853 <https://github.com/llvm/llvm-project/issues/189853>`__",""
-"`LWG4497 <https://wg21.link/LWG4497>`__","``std::nullopt_t`` should be comparable","2026-03 (Croydon)","","","`#189854 <https://github.com/llvm/llvm-project/issues/189854>`__",""
+"`LWG4497 <https://wg21.link/LWG4497>`__","``std::nullopt_t`` should be comparable","2026-03 (Croydon)","|Complete|","23","`#189854 <https://github.com/llvm/llvm-project/issues/189854>`__",""
 "`LWG4499 <https://wg21.link/LWG4499>`__","``flat_set::insert_range`` specification may be problematic","2026-03 (Croydon)","","","`#189855 <https://github.com/llvm/llvm-project/issues/189855>`__",""
 "`LWG4500 <https://wg21.link/LWG4500>`__","``constant_wrapper`` wording problems","2026-03 (Croydon)","|Complete|","23","`#189856 <https://github.com/llvm/llvm-project/issues/189856>`__",""
 "`LWG4504 <https://wg21.link/LWG4504>`__","Wording problem in ``{simple_}counting_scope``","2026-03 (Croydon)","","","`#189857 <https://github.com/llvm/llvm-project/issues/189857>`__",""
diff --git a/libcxx/include/optional b/libcxx/include/optional
index f7e12f84beba0..424f5dd07e0dc 100644
--- a/libcxx/include/optional
+++ b/libcxx/include/optional
@@ -362,6 +362,10 @@ struct nullopt_t {
     explicit __secret_tag() = default;
   };
   _LIBCPP_HIDE_FROM_ABI constexpr explicit nullopt_t(__secret_tag, __secret_tag) noexcept {}
+  _LIBCPP_HIDE_FROM_ABI constexpr nullopt_t(const nullopt_t&) noexcept = default;
+#if _LIBCPP_STD_VER >= 26
+  _LIBCPP_HIDE_FROM_ABI constexpr strong_ordering operator<=>(const nullopt_t&) const noexcept = default;
+#endif
 };
 
 inline constexpr nullopt_t nullopt{nullopt_t::__secret_tag{}, nullopt_t::__secret_tag{}};
diff --git a/libcxx/test/std/utilities/optional/optional.nullopt/nullopt_t.pass.cpp b/libcxx/test/std/utilities/optional/optional.nullopt/nullopt_t.pass.cpp
index 842b75893cbe4..7fd1bbb9521c6 100644
--- a/libcxx/test/std/utilities/optional/optional.nullopt/nullopt_t.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.nullopt/nullopt_t.pass.cpp
@@ -13,11 +13,17 @@
 // inline constexpr nullopt_t nullopt(unspecified);
 
 // [optional.nullopt]/2:
-//   Type nullopt_t shall not have a default constructor or an initializer-list
-//   constructor, and shall not be an aggregate.
+//   Type nullopt_t does not have a default constructor or an initializer-list
+//   constructor, and is not an aggregate. nullopt_t models copyable and
+//   three_way_comparable<strong_ordering>.
 
 #include <optional>
 #include <type_traits>
+#if _LIBCPP_STD_VER >= 26
+#include <vector>
+#include <ranges>
+#include <cassert>
+#endif
 
 #include "test_macros.h"
 
@@ -38,6 +44,20 @@ int main(int, char**)
 
     static_assert(std::is_same_v<const nullopt_t, decltype(nullopt)>);
     static_assert(test());
+#if TEST_STD_VER >= 26
+    // Test comparisons between nullopt_t
+    static_assert(nullopt == nullopt);
+    static_assert(!(nullopt != nullopt));
+    static_assert(nullopt <= nullopt);
+    static_assert(nullopt >= nullopt);
+    static_assert((nullopt <=> nullopt) == std::strong_ordering::equal);
+
+    // Test ranges::find with nullopt
+    std::vector<std::optional<int>> v = {1, 2, nullopt, 4, 5};
+    auto itr = std::ranges::find(v, nullopt);
+    assert(itr != v.end());
+    assert(*itr == nullopt);
+#endif
 
   return 0;
 }



More information about the libcxx-commits mailing list