[libcxx-commits] [libcxx] [libc++] Correct `optional<T&>` implementation (PR #174537)

William Tran-Viet via libcxx-commits libcxx-commits at lists.llvm.org
Thu Jan 8 13:47:17 PST 2026


================
@@ -1013,69 +1073,85 @@ public:
     return *this;
   }
 
-  template <class... _Args, enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0>
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp& emplace(_Args&&... __args) {
+  template <class... _Args, enable_if_t<__is_constructible_for_optional_v<_Tp, _Args...>, int> = 0>
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp& emplace(_Args&&... __args)
+#    if _LIBCPP_STD_VER >= 26
+      noexcept(is_lvalue_reference_v<_Tp> && is_nothrow_constructible_v<_Tp, _Args...>)
+#    endif
+  {
     reset();
     this->__construct(std::forward<_Args>(__args)...);
     return this->__get();
   }
 
   template <class _Up,
             class... _Args,
-            enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>
-#    if _LIBCPP_STD_VER >= 26
-                            && !reference_constructs_from_temporary_v<_Tp&, _Up>
-#    endif
-                        ,
-                        int> = 0>
+            enable_if_t<__is_constructible_for_optional_initializer_list_v<_Tp, _Up, _Args...>, int> = 0>
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp& emplace(initializer_list<_Up> __il, _Args&&... __args) {
     reset();
     this->__construct(__il, std::forward<_Args>(__args)...);
     return this->__get();
   }
 
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
-  swap(optional& __opt) noexcept(is_nothrow_move_constructible_v<_Tp> && is_nothrow_swappable_v<_Tp>) {
-    if (this->has_value() == __opt.has_value()) {
-      if (this->has_value())
-        this->__swap(__opt);
-    } else {
-      if (this->has_value()) {
-        __opt.__construct(std::move(this->__get()));
-        reset();
-      } else {
-        this->__construct(std::move(__opt.__get()));
-        __opt.reset();
-      }
-    }
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(optional& __opt) noexcept(
+      (is_nothrow_move_constructible_v<_Tp> && is_nothrow_swappable_v<_Tp>)
+#    if _LIBCPP_STD_VER >= 26
+      || is_lvalue_reference_v<_Tp>
+#    endif
+  ) {
+    this->__swap(__opt);
   }
 
-  _LIBCPP_HIDE_FROM_ABI constexpr add_pointer_t<_Tp const> operator->() const noexcept {
+  _LIBCPP_HIDE_FROM_ABI constexpr add_pointer_t<_Tp const> operator->() const noexcept
----------------
smallp-o-p wrote:

...or would this be an ABI break? [sad if so...](https://quuxplusone.github.io/blog/2021/05/07/std-iterator-as-a-base-class/)

https://github.com/llvm/llvm-project/pull/174537


More information about the libcxx-commits mailing list