Skip to content

Commit

Permalink
LWG-3875: ranges::repeat_view<T, IntegerClass>::iterator may be ill…
Browse files Browse the repository at this point in the history
…-formed (#3485)
  • Loading branch information
JMazurkiewicz authored Feb 23, 2023
1 parent b9b15d8 commit 10aab6d
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 3 deletions.
19 changes: 16 additions & 3 deletions stl/inc/ranges
Original file line number Diff line number Diff line change
Expand Up @@ -1389,9 +1389,23 @@ namespace ranges {
} // namespace views

#if _HAS_CXX23
template <class _Ty>
concept _Integer_like_with_usable_difference_type = _Signed_integer_like<_Ty>
|| (_Integer_like<_Ty> && weakly_incrementable<_Ty>);

template <class _Ty>
struct _Repeat_view_difference_type {
using type = _Iota_diff_t<_Ty>;
};

template <_Signed_integer_like _Ty>
struct _Repeat_view_difference_type<_Ty> {
using type = _Ty;
};

_EXPORT_STD template <move_constructible _Ty, semiregular _Bo = unreachable_sentinel_t>
requires (is_object_v<_Ty> && same_as<_Ty, remove_cv_t<_Ty>>
&& (_Integer_like<_Bo> || same_as<_Bo, unreachable_sentinel_t>) )
&& (_Integer_like_with_usable_difference_type<_Bo> || same_as<_Bo, unreachable_sentinel_t>) )
class repeat_view : public view_interface<repeat_view<_Ty, _Bo>> {
private:
friend views::_Take_fn;
Expand All @@ -1416,8 +1430,7 @@ namespace ranges {
using iterator_concept = random_access_iterator_tag;
using iterator_category = random_access_iterator_tag;
using value_type = _Ty;
using difference_type =
conditional_t<_Signed_integer_like<_Index_type>, _Index_type, _Iota_diff_t<_Index_type>>;
using difference_type = typename _Repeat_view_difference_type<_Index_type>::type;

_Iterator() = default;

Expand Down
11 changes: 11 additions & 0 deletions tests/std/tests/P2474R2_views_repeat/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,17 @@ constexpr bool test() {
return true;
}

// Check LWG-3875
static_assert(CanViewRepeat<string, long long>);
static_assert(CanViewRepeat<string, unsigned long long>);
static_assert(CanViewRepeat<string, _Signed128>);
static_assert(
!CanViewRepeat<string, _Unsigned128>); // _Unsigned128 does not satisfy 'integer-like-with-usable-difference-type'

// Check GH-3392
static_assert(ranges::range<decltype(views::repeat('3', 100ull) | views::take(3))>);
static_assert(ranges::range<decltype(views::repeat('3', 100ull) | views::drop(3))>);

int main() {
assert(test());
static_assert(test());
Expand Down

0 comments on commit 10aab6d

Please sign in to comment.