Implement LWG-3749 `common_iterator` should handle integer-class difference types (#4190)

This commit is contained in:
A. Jiang 2023-11-17 10:04:35 +08:00 коммит произвёл GitHub
Родитель 5abffb659c
Коммит d9d2a918d6
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
2 изменённых файлов: 33 добавлений и 7 удалений

Просмотреть файл

@ -1103,14 +1103,22 @@ concept _Has_forward_category = requires {
requires derived_from<_Iter_cat_t<_Iter>, forward_iterator_tag>;
};
template <input_iterator _Iter, class _Se>
struct iterator_traits<common_iterator<_Iter, _Se>> {
using iterator_concept = conditional_t<forward_iterator<_Iter>, forward_iterator_tag, input_iterator_tag>;
template <class _Iter>
struct _Common_iterator_category_base {};
template <class _Iter>
requires is_integral_v<iter_difference_t<_Iter>>
struct _Common_iterator_category_base<_Iter> {
using iterator_category = conditional_t<_Has_forward_category<_Iter>, forward_iterator_tag, input_iterator_tag>;
using value_type = iter_value_t<_Iter>;
using difference_type = iter_difference_t<_Iter>;
using pointer = typename _Common_iterator_pointer_type<_Iter, _Se>::pointer;
using reference = iter_reference_t<_Iter>;
};
template <input_iterator _Iter, class _Se>
struct iterator_traits<common_iterator<_Iter, _Se>> : _Common_iterator_category_base<_Iter> {
using iterator_concept = conditional_t<forward_iterator<_Iter>, forward_iterator_tag, input_iterator_tag>;
using value_type = iter_value_t<_Iter>;
using difference_type = iter_difference_t<_Iter>;
using pointer = typename _Common_iterator_pointer_type<_Iter, _Se>::pointer;
using reference = iter_reference_t<_Iter>;
};
template <class _Iter>

Просмотреть файл

@ -315,6 +315,24 @@ constexpr bool test_lwg_3574() {
return true;
}
template <class It, class Se>
concept common_iterator_has_iterator_category =
requires { typename iterator_traits<common_iterator<It, Se>>::iterator_category; };
// LWG-3749 common_iterator should handle integer-class difference types
void test_lwg_3749() { // COMPILE-ONLY
static_assert(common_iterator_has_iterator_category<int*, const int*>);
static_assert(common_iterator_has_iterator_category<int*, unreachable_sentinel_t>);
using small_unbounded_iota = decltype(views::iota(42));
static_assert(common_iterator_has_iterator_category<ranges::iterator_t<small_unbounded_iota>,
ranges::sentinel_t<small_unbounded_iota>>);
using large_unbounded_iota = decltype(views::iota(42ull));
static_assert(!common_iterator_has_iterator_category<ranges::iterator_t<large_unbounded_iota>,
ranges::sentinel_t<large_unbounded_iota>>);
}
// Validate that _Variantish works when fed with a non-trivially-destructible type
void test_non_trivially_destructible_type() { // COMPILE-ONLY
struct non_trivially_destructible_input_iterator {