[libcxx-commits] [libcxx] 9d20703 - [libc++] Implement LWG3749: `common_iterator` should handle integer-class difference types (#233606)
via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Oct 22 22:46:30 PDT 2026
Author: Vishank Singh
Date: 2026-10-23T13:46:26+08:00
New Revision: 9d207030224595de65c0ca54033bd9d71412921c
URL: https://github.com/llvm/llvm-project/commit/9d207030224595de65c0ca54033bd9d71412921c
DIFF: https://github.com/llvm/llvm-project/commit/9d207030224595de65c0ca54033bd9d71412921c.diff
LOG: [libc++] Implement LWG3749: `common_iterator` should handle integer-class difference types (#233606)
Make `iterator_category` of `iterator_traits<common_iterator<I,S>>`
conditionally present only when `iter_difference_t<I>` is an integral
type.
Fixes #105291
Added:
Modified:
libcxx/docs/Status/Cxx26Issues.csv
libcxx/include/__iterator/common_iterator.h
libcxx/test/std/iterators/predef.iterators/iterators.common/iterator_traits.compile.pass.cpp
Removed:
################################################################################
diff --git a/libcxx/docs/Status/Cxx26Issues.csv b/libcxx/docs/Status/Cxx26Issues.csv
index 8666436cc81e9d..022479ec72eb6b 100644
--- a/libcxx/docs/Status/Cxx26Issues.csv
+++ b/libcxx/docs/Status/Cxx26Issues.csv
@@ -21,7 +21,7 @@
"`LWG3203 <https://wg21.link/LWG3203>`__","``span`` element access invalidation","2023-11 (Kona)","|Nothing To Do|","","`#105288 <https://github.com/llvm/llvm-project/issues/105288>`__",""
"`LWG3305 <https://wg21.link/LWG3305>`__","``any_cast<void>``","2023-11 (Kona)","|Complete|","18","`#105289 <https://github.com/llvm/llvm-project/issues/105289>`__",""
"`LWG3431 <https://wg21.link/LWG3431>`__","``<=>`` for containers should require ``three_way_comparable<T>`` instead of ``<=>``","2023-11 (Kona)","","","`#105290 <https://github.com/llvm/llvm-project/issues/105290>`__",""
-"`LWG3749 <https://wg21.link/LWG3749>`__","``common_iterator`` should handle integer-class
diff erence types","2023-11 (Kona)","","","`#105291 <https://github.com/llvm/llvm-project/issues/105291>`__",""
+"`LWG3749 <https://wg21.link/LWG3749>`__","``common_iterator`` should handle integer-class
diff erence types","2023-11 (Kona)","|Complete|","24","`#105291 <https://github.com/llvm/llvm-project/issues/105291>`__",""
"`LWG3809 <https://wg21.link/LWG3809>`__","Is ``std::subtract_with_carry_engine<uint16_t>`` supposed to work","2023-11 (Kona)","","","`#105295 <https://github.com/llvm/llvm-project/issues/105295>`__",""
"`LWG3892 <https://wg21.link/LWG3892>`__","Incorrect formatting of nested ranges and tuples","2023-11 (Kona)","|Complete|","17","`#105296 <https://github.com/llvm/llvm-project/issues/105296>`__",""
"`LWG3897 <https://wg21.link/LWG3897>`__","``inout_ptr`` will not update raw pointer to 0","2023-11 (Kona)","|Complete|","19","`#105297 <https://github.com/llvm/llvm-project/issues/105297>`__",""
diff --git a/libcxx/include/__iterator/common_iterator.h b/libcxx/include/__iterator/common_iterator.h
index b234b3810308fe..02d4cac0e669aa 100644
--- a/libcxx/include/__iterator/common_iterator.h
+++ b/libcxx/include/__iterator/common_iterator.h
@@ -11,6 +11,7 @@
#define _LIBCPP___ITERATOR_COMMON_ITERATOR_H
#include <__assert>
+#include <__concepts/arithmetic.h>
#include <__concepts/assignable.h>
#include <__concepts/constructible.h>
#include <__concepts/convertible_to.h>
@@ -282,14 +283,22 @@ struct __arrow_type_or_void<_Iter, _Sent> {
using type _LIBCPP_NODEBUG = decltype(std::declval<const common_iterator<_Iter, _Sent>&>().operator->());
};
-template <input_iterator _Iter, class _Sent>
-struct iterator_traits<common_iterator<_Iter, _Sent>> {
- using iterator_concept = _If<forward_iterator<_Iter>, forward_iterator_tag, input_iterator_tag>;
+template <class _Iter>
+struct __common_iterator_category_base {};
+
+template <class _Iter>
+ requires integral<iter_
diff erence_t<_Iter>>
+struct __common_iterator_category_base<_Iter> {
using iterator_category = _If<__denotes_forward_iter<_Iter>, forward_iterator_tag, input_iterator_tag>;
- using pointer = typename __arrow_type_or_void<_Iter, _Sent>::type;
- using value_type = iter_value_t<_Iter>;
- using
diff erence_type = iter_
diff erence_t<_Iter>;
- using reference = iter_reference_t<_Iter>;
+};
+
+template <input_iterator _Iter, class _Sent>
+struct iterator_traits<common_iterator<_Iter, _Sent>> : __common_iterator_category_base<_Iter> {
+ using iterator_concept = _If<forward_iterator<_Iter>, forward_iterator_tag, input_iterator_tag>;
+ using pointer = typename __arrow_type_or_void<_Iter, _Sent>::type;
+ using value_type = iter_value_t<_Iter>;
+ using
diff erence_type = iter_
diff erence_t<_Iter>;
+ using reference = iter_reference_t<_Iter>;
};
#endif // _LIBCPP_STD_VER >= 20
diff --git a/libcxx/test/std/iterators/predef.iterators/iterators.common/iterator_traits.compile.pass.cpp b/libcxx/test/std/iterators/predef.iterators/iterators.common/iterator_traits.compile.pass.cpp
index 48946dbd7e6de6..b698dae65b5410 100644
--- a/libcxx/test/std/iterators/predef.iterators/iterators.common/iterator_traits.compile.pass.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/iterators.common/iterator_traits.compile.pass.cpp
@@ -11,9 +11,11 @@
// template<input_iterator I, class S>
// struct iterator_traits<common_iterator<I, S>>;
-#include <iterator>
-
+#include <concepts>
#include <cstddef>
+#include <cstdint>
+#include <iterator>
+#include <ranges>
#include "test_iterators.h"
#include "test_macros.h"
#include "types.h"
@@ -30,7 +32,20 @@ struct NonVoidOutputIterator {
void operator=(int) const;
};
+template <class It, class Se>
+concept has_iterator_category =
+ requires { typename std::iterator_traits<std::common_iterator<It, Se>>::iterator_category; };
+
void test() {
+ // LWG 3749: common_iterator should handle integer-class
diff erence types
+ {
+ using WideIota = decltype(std::views::iota(std::uint64_t{0}));
+ using WideIter = std::ranges::iterator_t<WideIota>;
+ using WideSent = std::ranges::sentinel_t<WideIota>;
+
+ constexpr bool is_
diff _integral = std::integral<std::iter_
diff erence_t<WideIter>>;
+ static_assert(has_iterator_category<WideIter, WideSent> == is_
diff _integral);
+ }
{
using Iter = simple_iterator<int*>;
using CommonIter = std::common_iterator<Iter, sentinel_type<int*>>;
More information about the libcxx-commits
mailing list