[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