[libcxx-commits] [libcxx] [libc++] Implement P2988R12: `std::optional<T&>` (PR #155202)
William Tran-Viet via libcxx-commits
libcxx-commits at lists.llvm.org
Fri Nov 7 18:08:01 PST 2025
================
@@ -628,21 +629,89 @@ public:
using iterator = __wrap_iter<__pointer>;
using const_iterator = __wrap_iter<__const_pointer>;
# endif
+
+ // [optional.iterators], iterator support
+ _LIBCPP_HIDE_FROM_ABI constexpr iterator begin() noexcept {
+ auto& __derived_self = static_cast<optional<_Tp>&>(*this);
+ auto __ptr = [&__derived_self]() {
+ if constexpr (is_lvalue_reference_v<_Tp>) {
+ return __derived_self.has_value() ? std::addressof(__derived_self.__get()) : nullptr;
+ }
+ return std::addressof(__derived_self.__get());
+ }();
+
+# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_OPTIONAL
+ return std::__make_bounded_iter(
+ std::__wrap_iter<__pointer>(__ptr),
+ std::__wrap_iter<__pointer>(__ptr),
+ std::__wrap_iter<__pointer>(__ptr) + (__derived_self.has_value() ? 1 : 0));
+# else
+ return iterator(__ptr);
+# endif
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr const_iterator begin() const noexcept {
+ auto& __derived_self = static_cast<const optional<_Tp>&>(*this);
+ auto* __ptr = [&__derived_self]() {
+ if constexpr (is_lvalue_reference_v<_Tp>) {
+ return __derived_self.has_value() ? std::addressof(__derived_self.__get()) : nullptr;
+ }
+ return std::addressof(__derived_self.__get());
+ }();
+
+# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_OPTIONAL
+ return std::__make_bounded_iter(
+ std::__wrap_iter<__const_pointer>(__ptr),
+ std::__wrap_iter<__const_pointer>(__ptr),
+ std::__wrap_iter<__const_pointer>(__ptr) + (__derived_self.has_value() ? 1 : 0));
+# else
+ return const_iterator(__ptr);
+# endif
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr iterator end() noexcept {
+ return begin() + (static_cast<optional<_Tp>&>(*this).has_value() ? 1 : 0);
+ }
+ _LIBCPP_HIDE_FROM_ABI constexpr const_iterator end() const noexcept {
+ return begin() + (static_cast<const optional<_Tp>&>(*this).has_value() ? 1 : 0);
+ }
# endif
+};
+
+template <class _Tp>
+class _LIBCPP_DECLSPEC_EMPTY_BASES optional
+ : private __optional_move_assign_base<_Tp>,
+ private __optional_sfinae_ctor_base_t<_Tp>,
+ private __optional_sfinae_assign_base_t<_Tp>,
+ public __optional_iterator<_Tp> {
+ using __base _LIBCPP_NODEBUG = __optional_move_assign_base<_Tp>;
+
+public:
+ using value_type = _Tp;
----------------
smallp-o-p wrote:
Oh, good catch, that doesn't happen.
https://github.com/llvm/llvm-project/pull/155202
More information about the libcxx-commits
mailing list