[libcxx-commits] [libcxx] [libc++] Implement P3168R2: Give optional range support (PR #149441)

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Mon Jul 21 09:44:28 PDT 2025


================
@@ -586,8 +614,17 @@ class _LIBCPP_DECLSPEC_EMPTY_BASES optional
       private __optional_sfinae_assign_base_t<_Tp> {
   using __base _LIBCPP_NODEBUG = __optional_move_assign_base<_Tp>;
 
+#    if _LIBCPP_STD_VER >= 26
+  using pointer       = std::add_pointer_t<std::remove_cvref_t<_Tp>>;
+  using const_pointer = std::add_pointer_t<const std::remove_cvref_t<_Tp>>;
+#    endif
+
 public:
   using value_type = _Tp;
+#    if _LIBCPP_STD_VER >= 26
+  using iterator       = __wrap_iter<pointer>;
----------------
ldionne wrote:

I wonder if `__wrap_iter` is the right tool for the job here. `__wrap_iter` is basically `__random_access_iterator` except it has a weird name due to historical reasons. Recently, we've been trying to maintain relevant static information in the type of the iterators, see for example [this discussion](https://github.com/llvm/llvm-project/pull/117445#discussion_r1858367600) or [this one](https://github.com/llvm/llvm-project/pull/98643#discussion_r1759243579) yielding [this issue](https://github.com/llvm/llvm-project/issues/108624).

As you have it right now, `std::optional` iterators would be interchangeable with `std::vector` iterators. I'm not certain that's what we want since that could lead to unintended misuse from users, and we're also dropping a lot of information on the floor (namely the fact that the range's size is at most 1).

My current thinking is that we should either:
- Define an iterator that is specific to `std::optional`, or
- Define an iterator type that encodes the static information about the maximum size of the range being `N`. Something like `__statically_bounded_iterator<Underlying, N>`, although that name clashes with [`libcxx/include/__iterator/static_bounded_iter.h`](https://github.com/llvm/llvm-project/blob/release/21.x/libcxx/include/__iterator/static_bounded_iter.h) which is used for hardening. The idea is similar, except the iterator used by `optional` doesn't need to physically maintain its bounds, it just wants to encode that static knowledge somewhere.

This actually makes me realize that there's something else we should probably do as well: we should probably provide an option to use hardened `__static_bounded_iter`s in `optional` (behind an ABI macro).

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


More information about the libcxx-commits mailing list