[libcxx-commits] [libcxx] [libc++] P3168R2 Give std::optional Range Support (PR #146491)

Yanzuo Liu via libcxx-commits libcxx-commits at lists.llvm.org
Tue Jul 1 08:04:07 PDT 2025


================
@@ -578,6 +593,126 @@ struct __is_std_optional : false_type {};
 template <class _Tp>
 struct __is_std_optional<optional<_Tp>> : true_type {};
 
+#    if _LIBCPP_STD_VER >= 26
+
+template <class _T>
+constexpr bool ranges::enable_view<optional<_T>> = true;
+
+template <class _T>
+constexpr auto format_kind<optional<_T>> = range_format::disabled;
+
+template <typename _Tp>
+class __optional_iterator {
+  using _Base = __wrap_iter<_Tp*>;
+  _Base __it_;
+
+public:
+  using value_type        = _Tp;
+  using difference_type   = typename _Base::difference_type;
+  using pointer           = typename _Base::pointer;
+  using reference         = typename _Base::reference;
+  using iterator_category = random_access_iterator_tag;
+  using iterator_concept  = contiguous_iterator_tag;
+
+private:
+  _LIBCPP_HIDE_FROM_ABI constexpr explicit __optional_iterator(_Base __it) noexcept : __it_(__it) {}
+
+  _LIBCPP_HIDE_FROM_ABI friend class __wrap_iter<_Tp*>;
+  _LIBCPP_HIDE_FROM_ABI friend class __wrap_iter<const _Tp*>;
+
+  _LIBCPP_HIDE_FROM_ABI friend class optional<std::remove_const_t<_Tp>>;
+  _LIBCPP_HIDE_FROM_ABI friend class optional<const _Tp>;
+
+public:
+  _LIBCPP_HIDE_FROM_ABI constexpr __optional_iterator() : __it_(_Base()) {}
+
+  _LIBCPP_HIDE_FROM_ABI constexpr __optional_iterator(const __optional_iterator&)            = default;
+  _LIBCPP_HIDE_FROM_ABI constexpr __optional_iterator& operator=(const __optional_iterator&) = default;
+
+  _LIBCPP_HIDE_FROM_ABI constexpr reference operator*() const { return *__it_; }
+  _LIBCPP_HIDE_FROM_ABI constexpr pointer operator->() const { return *__it_.operator->(); }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr __optional_iterator& operator++() noexcept {
+    __it_ = _Base();
----------------
zwuis wrote:

Note that `std::contiguous_iterator` requires `std::to_address(iter2) == std::to_address(iter1) + std::iter_difference_t<Iter>(iter2 - iter1)` even if `iter1` is dereferenceable and `iter2` is NON-dereferenceable.

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


More information about the libcxx-commits mailing list