[libcxx-commits] [libcxx] [libc++] Reimplement `optional<T&>` and granularize `<optional>` header (PR #199138)

William Tran-Viet via libcxx-commits libcxx-commits at lists.llvm.org
Sun May 24 19:42:23 PDT 2026


================
@@ -0,0 +1,595 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// std::bad_optional_access
+// optional base classes
+
+#ifndef _LIBCPP_OPTIONAL_COMMON_H
+#define _LIBCPP_OPTIONAL_COMMON_H
+
+#include <__assert>
+#include <__config>
+#include <__exception/exception.h>
+#include <__functional/invoke.h>
+#include <__fwd/format.h>
+#include <__iterator/bounded_iter.h>
+#include <__iterator/capacity_aware_iterator.h>
+#include <__memory/addressof.h>
+#include <__memory/construct_at.h>
+#include <__ranges/enable_borrowed_range.h>
+#include <__ranges/enable_view.h>
+#include <__tuple/sfinae_helpers.h>
+#include <__type_traits/add_pointer.h>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/invoke.h>
+#include <__type_traits/is_array.h>
+#include <__type_traits/is_assignable.h>
+#include <__type_traits/is_constructible.h>
+#include <__type_traits/is_convertible.h>
+#include <__type_traits/is_destructible.h>
+#include <__type_traits/is_nothrow_assignable.h>
+#include <__type_traits/is_nothrow_constructible.h>
+#include <__type_traits/is_object.h>
+#include <__type_traits/is_reference.h>
+#include <__type_traits/is_same.h>
+#include <__type_traits/is_swappable.h>
+#include <__type_traits/is_trivially_assignable.h>
+#include <__type_traits/is_trivially_constructible.h>
+#include <__type_traits/is_trivially_destructible.h>
+#include <__type_traits/reference_constructs_from_temporary.h>
+#include <__type_traits/remove_const.h>
+#include <__type_traits/remove_cv.h>
+#include <__type_traits/remove_reference.h>
+#include <__utility/forward.h>
+#include <__utility/in_place.h>
+#include <__utility/move.h>
+#include <__utility/swap.h>
+#include <__verbose_abort>
+#include <initializer_list>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+namespace std // purposefully not using versioning namespace
+{
+
+class _LIBCPP_EXPORTED_FROM_ABI bad_optional_access : public exception {
+public:
+  bad_optional_access() _NOEXCEPT                                      = default;
+  bad_optional_access(const bad_optional_access&) _NOEXCEPT            = default;
+  bad_optional_access& operator=(const bad_optional_access&) _NOEXCEPT = default;
+  // Get the key function ~bad_optional_access() into the dylib
+  ~bad_optional_access() _NOEXCEPT override;
+  [[__nodiscard__]] const char* what() const _NOEXCEPT override;
+};
+} // namespace std
+
+#if _LIBCPP_STD_VER >= 17
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+[[noreturn]] inline void __throw_bad_optional_access() {
+#  if _LIBCPP_HAS_EXCEPTIONS
+  throw bad_optional_access();
+#  else
+  _LIBCPP_VERBOSE_ABORT("bad_optional_access was thrown in -fno-exceptions mode");
+#  endif
+}
+
+struct __optional_construct_from_invoke_tag {};
+
+template <class _Tp, bool = is_trivially_destructible<_Tp>::value>
+struct __optional_destruct_base;
----------------
smallp-o-p wrote:

I think the only base classes needed for `optional<T&>` is the reference overload of `__optional_storage_base` and the reference specialization of `__optional_iterator_base`. Would it be better to just cut those out directly to use inside `optional_ref.h`? We can then simplify the `optional<T>` base but I fear there may be concerns w.r.t ABI .

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


More information about the libcxx-commits mailing list