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

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Fri Aug 1 09:27:08 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:

Ah, that's a good point. That's LWG issue territory then, isn't it? What would you think of *not* providing the `iterator` typedef in the cases that we know the resulting typedef is not going to be a proper iterator? That would close this door for the time being, until WG21 decides what to do with it design-wise.

If you agree @frederick-vs-ja, then @smallp-o-p this patch should basically change to something like this:

```c++
template <class _Tp, class = void>
struct __optional_iterator_aliases { };

template <class _Tp>
struct __optional_iterator_aliases<_Tp, __enable_if_t<!is_function<__libcpp_remove_reference_t<_Tp> >::value &&
                                                      !is_unbounded_array<__libcpp_remove_reference_t<_Tp> >::value> > {
private:
  // note: I am purposefully using private names here because I believe we want
  // to provide ::pointer and ::const_pointer unconditionally.
  using __pointer = std::add_pointer_t<_Tp>;
  using __const_pointer = std::add_pointer_t<const _Tp>;

public:
# if _LIBCPP_STD_VER >= 26
#   ifdef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_OPTIONAL
  using iterator       = __bounded_iter<__wrap_iter<__pointer>>;
  using const_iterator = __bounded_iter<__wrap_iter<__const_pointer>>;
 #      else
   using iterator       = __wrap_iter<__pointer>;
   using const_iterator = __wrap_iter<__const_pointer>;
#   endif
# 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_aliases<_Tp> {
  // ...
```

We would also want to add a negative test like this one:

```c++
template <class T>
concept has_iterator_aliases = requires {
  typename T::iterator;
  typename T::const_iterator;
};

static_assert(!has_iterator_aliases<std::optional<int (&)[]>>);
static_assert(!has_iterator_aliases<std::optional<void (&)(int, char)>>);
```

That test would need to live under `libcxx/test/libcxx/utilities/optional/optional.iterator/iterator.compile.pass.cpp`. Notice how this is under `libcxx/test/libcxx` instead of `libcxx/test/std`: that is because this test would be specific to libc++ (until WG21 decides what's the Standard behavior). We put tests that check libc++ specific implementation details under a separate directory so that other standard libraries can reuse the `libcxx/test/std` directory to check their own conformance status.

Finally, we'd also need to make sure that we have *positive* testing coverage for `std::optional<int (&)[]>::pointer` and `std::optional<void (&)(int, char)>::pointer` under `libcxx/test/std`. That actually makes me realize that this patch is missing such coverage even for `std::optional<int>` (unless I missed it) -- so it should be added. We generally test such things in a test named `some/path/types.pass.cpp`, and it looks like we already have one for `std::optional` here: `libcxx/test/std/utilities/optional/optional.object/types.pass.cpp`. You will want to augment it with additional tests guarded under `TEST_STD_VER >= 26`, a macro that can be found in `test_macros.h`.

Sorry if you already know some of that, I'm trying to give you as much context as possible since I know this is amongst your first patches.


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


More information about the libcxx-commits mailing list