[libcxx-commits] [libcxx] a223164 - [libc++][NFC] Simplify `optional::iterator` (#183230)

via libcxx-commits libcxx-commits at lists.llvm.org
Sat Mar 7 17:58:11 PST 2026


Author: William Tran-Viet
Date: 2026-03-08T09:58:06+08:00
New Revision: a2231642b341c71ba184af2b3831502fded401da

URL: https://github.com/llvm/llvm-project/commit/a2231642b341c71ba184af2b3831502fded401da
DIFF: https://github.com/llvm/llvm-project/commit/a2231642b341c71ba184af2b3831502fded401da.diff

LOG: [libc++][NFC] Simplify `optional::iterator` (#183230)

- Rename `__optional_iterator` into `__optional_iterator_base` and make
it part of the `__optional_{meow}_base` inheritance chain. This allows
us to get rid of a sketchy-looking downcast and shorten some code.

Added: 
    

Modified: 
    libcxx/include/__iterator/wrap_iter.h
    libcxx/include/optional

Removed: 
    


################################################################################
diff  --git a/libcxx/include/__iterator/wrap_iter.h b/libcxx/include/__iterator/wrap_iter.h
index d20d7f3fc4c4c..c1b27b8242cd9 100644
--- a/libcxx/include/__iterator/wrap_iter.h
+++ b/libcxx/include/__iterator/wrap_iter.h
@@ -117,8 +117,6 @@ class __wrap_iter {
   friend class span;
   template <class _Tp, size_t _Size>
   friend struct array;
-  template <class _Tp, class>
-  friend struct __optional_iterator;
 
   _LIBCPP_HIDE_FROM_ABI friend _LIBCPP_CONSTEXPR bool
   operator==(const __wrap_iter& __x, const __wrap_iter& __y) _NOEXCEPT {

diff  --git a/libcxx/include/optional b/libcxx/include/optional
index a928769d65c90..c4b52dab6ea66 100644
--- a/libcxx/include/optional
+++ b/libcxx/include/optional
@@ -706,17 +706,21 @@ inline constexpr bool __is_constructible_for_optional_initializer_list_v<_Tp&, _
 #    endif
 
 template <class _Tp, class = void>
-struct __optional_iterator {};
+struct __optional_iterator_base : __optional_move_assign_base<_Tp> {
+  using __optional_move_assign_base<_Tp>::__optional_move_assign_base;
+};
 
 #    if _LIBCPP_STD_VER >= 26 && _LIBCPP_HAS_EXPERIMENTAL_OPTIONAL_ITERATOR
 
 template <class _Tp>
-struct __optional_iterator<_Tp, enable_if_t<is_object_v<_Tp>>> {
+struct __optional_iterator_base<_Tp, enable_if_t<is_object_v<_Tp>>> : __optional_move_assign_base<_Tp> {
 private:
   using __pointer _LIBCPP_NODEBUG       = add_pointer_t<_Tp>;
   using __const_pointer _LIBCPP_NODEBUG = add_pointer_t<const _Tp>;
 
 public:
+  using __optional_move_assign_base<_Tp>::__optional_move_assign_base;
+
 #      ifdef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_OPTIONAL
   using iterator       = __bounded_iter<__pointer>;
   using const_iterator = __bounded_iter<__const_pointer>;
@@ -727,41 +731,42 @@ public:
 
   // [optional.iterators], iterator support
   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr iterator begin() noexcept {
-    auto& __derived_self = static_cast<optional<_Tp>&>(*this);
-    auto* __ptr          = std::addressof(__derived_self.__get());
+    auto* __ptr = std::addressof(this->__get());
 
 #      ifdef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_OPTIONAL
-    return std::__make_bounded_iter(__ptr, __ptr, __ptr + (__derived_self.has_value() ? 1 : 0));
+    return std::__make_bounded_iter(__ptr, __ptr, __ptr + (this->has_value() ? 1 : 0));
 #      else
     return std::__make_capacity_aware_iterator<__pointer, optional<_Tp>, 1>(__ptr);
 #      endif
   }
 
   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const_iterator begin() const noexcept {
-    auto& __derived_self = static_cast<const optional<_Tp>&>(*this);
-    auto* __ptr          = std::addressof(__derived_self.__get());
+    auto* __ptr = std::addressof(this->__get());
 
 #      ifdef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_OPTIONAL
-    return std::__make_bounded_iter(__ptr, __ptr, __ptr + (__derived_self.has_value() ? 1 : 0));
+    return std::__make_bounded_iter(__ptr, __ptr, __ptr + (this->has_value() ? 1 : 0));
 #      else
     return std::__make_capacity_aware_iterator<__const_pointer, optional<_Tp>, 1>(__ptr);
 #      endif
   }
 
   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr iterator end() noexcept {
-    return begin() + (static_cast<optional<_Tp>&>(*this).has_value() ? 1 : 0);
+    return begin() + (this->has_value() ? 1 : 0);
   }
   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const_iterator end() const noexcept {
-    return begin() + (static_cast<const optional<_Tp>&>(*this).has_value() ? 1 : 0);
+    return begin() + (this->has_value() ? 1 : 0);
   }
 };
 
 template <class _Tp>
-struct __optional_iterator<_Tp&, enable_if_t<is_object_v<_Tp> && !__is_unbounded_array_v<_Tp> >> {
+struct __optional_iterator_base<_Tp&, enable_if_t<is_object_v<_Tp> && !__is_unbounded_array_v<_Tp> >>
+    : __optional_move_assign_base<_Tp&> {
 private:
   using __pointer _LIBCPP_NODEBUG = add_pointer_t<_Tp>;
 
 public:
+  using __optional_move_assign_base<_Tp&>::__optional_move_assign_base;
+
 #      ifdef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_OPTIONAL
   using iterator = __bounded_iter<__pointer>;
 #      else
@@ -771,18 +776,17 @@ public:
   // [optional.ref.iterators], iterator support
 
   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto begin() const noexcept {
-    auto& __derived_self = static_cast<const optional<_Tp&>&>(*this);
-    auto* __ptr          = __derived_self.has_value() ? std::addressof(__derived_self.__get()) : nullptr;
+    auto* __ptr = this->has_value() ? std::addressof(this->__get()) : nullptr;
 
 #      ifdef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_OPTIONAL
-    return std::__make_bounded_iter(__ptr, __ptr, __ptr + (__derived_self.has_value() ? 1 : 0));
+    return std::__make_bounded_iter(__ptr, __ptr, __ptr + (this->has_value() ? 1 : 0));
 #      else
-    return std::__make_capacity_aware_iterator<__pointer, optional<_Tp&>, 1>(__pointer(__ptr));
+    return std::__make_capacity_aware_iterator<__pointer, optional<_Tp&>, 1>(__ptr);
 #      endif
   }
 
   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto end() const noexcept {
-    return begin() + (static_cast<const optional<_Tp&>&>(*this).has_value() ? 1 : 0);
+    return begin() + (this->has_value() ? 1 : 0);
   }
 };
 
@@ -790,11 +794,10 @@ public:
 
 template <class _Tp>
 class _LIBCPP_DECLSPEC_EMPTY_BASES optional
-    : private __optional_move_assign_base<_Tp>,
+    : public __optional_iterator_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>;
+      private __optional_sfinae_assign_base_t<_Tp> {
+  using __base _LIBCPP_NODEBUG = __optional_iterator_base<_Tp>;
 
 public:
   using value_type = __libcpp_remove_reference_t<_Tp>;


        


More information about the libcxx-commits mailing list