[libcxx-commits] [libcxx] [libc++] Merge the private iterator_traits aliases with their ranges versions (PR #162661)

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Wed Oct 15 08:44:01 PDT 2025


================
@@ -419,31 +422,60 @@ using __has_exactly_bidirectional_iterator_category _LIBCPP_NODEBUG =
                       __has_iterator_category_convertible_to<_Tp, bidirectional_iterator_tag>::value &&
                           !__has_iterator_category_convertible_to<_Tp, random_access_iterator_tag>::value>;
 
-template <class _InputIterator>
-using __iterator_value_type _LIBCPP_NODEBUG = typename iterator_traits<_InputIterator>::value_type;
+#if _LIBCPP_STD_VER >= 20
+
+// [readable.traits]
+
+// Let `RI` be `remove_cvref_t<I>`. The type `iter_value_t<I>` denotes
+// `indirectly_readable_traits<RI>::value_type` if `iterator_traits<RI>` names a specialization
+// generated from the primary template, and `iterator_traits<RI>::value_type` otherwise.
+// This has to be in this file and not readable_traits.h to break the include cycle between the two.
+template <class _Ip>
+using iter_value_t =
+    typename conditional_t<__is_primary_template<iterator_traits<remove_cvref_t<_Ip> > >::value,
+                           indirectly_readable_traits<remove_cvref_t<_Ip> >,
+                           iterator_traits<remove_cvref_t<_Ip> > >::value_type;
+
+template <class _Iter>
+using __iter_value_t _LIBCPP_NODEBUG = iter_value_t<_Iter>;
+
+template <class _Iter>
+using __iter_difference_t _LIBCPP_NODEBUG = iter_difference_t<_Iter>;
+
+template <class _Iter>
+using __iter_reference_t _LIBCPP_NODEBUG = iter_reference_t<_Iter>;
+
+#else
+
+template <class _Iter>
+using __iter_value_t _LIBCPP_NODEBUG = typename iterator_traits<_Iter>::value_type;
+
+template <class _Iter>
+using __iter_difference_t _LIBCPP_NODEBUG = typename iterator_traits<_Iter>::difference_type;
+
+#endif // _LIBCPP_STD_VER >= 20
 
 #if _LIBCPP_STD_VER >= 23
 template <class _InputIterator>
-using __iter_key_type _LIBCPP_NODEBUG = remove_const_t<tuple_element_t<0, __iterator_value_type<_InputIterator>>>;
+using __iter_key_type _LIBCPP_NODEBUG = remove_const_t<tuple_element_t<0, __iter_value_t<_InputIterator>>>;
----------------
ldionne wrote:

We were using this in the deduction guides for e.g. `flat_map`: https://github.com/llvm/llvm-project/blob/aa435772780ec17fda440f58d00d3d8703d7bfda/libcxx/include/__flat_map/flat_map.h#L1198

Were we conforming prior to this change since we were always using `iterator_traits`? It would be surprising.

I imagine that either there's a LWG issue because the spec is using `iterator_traits` for `flat_map` when it should use something more recent, or we used to have a slight conformance bug. If the latter, let's add test coverage for that.

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


More information about the libcxx-commits mailing list