1 use std
::sync
::atomic
::{AtomicUsize, Ordering::SeqCst}
;
3 #[cfg(not(panic = "abort"))]
5 //! These tests mainly make sure the elements are correctly dropped.
6 use std
::sync
::atomic
::{AtomicBool, AtomicUsize, Ordering::SeqCst}
;
10 dropped_twice
: AtomicBool
,
11 alive_count
: AtomicUsize
,
15 const fn new() -> Self {
16 Self { dropped_twice: AtomicBool::new(false), alive_count: AtomicUsize::new(0) }
21 assert
!(!self.dropped_twice
.load(SeqCst
), "a value was dropped twice");
22 assert_eq
!(self.alive_count
.load(SeqCst
), 0);
27 struct DropCheck
<'a
> {
32 impl<'a
> DropCheck
<'a
> {
33 fn new(info
: &'a DropInfo
) -> Self {
34 info
.alive_count
.fetch_add(1, SeqCst
);
36 Self { info, was_dropped: false }
40 impl Drop
for DropCheck
<'_
> {
43 self.info
.dropped_twice
.store(true, SeqCst
);
45 self.was_dropped
= true;
47 self.info
.alive_count
.fetch_sub(1, SeqCst
);
51 fn iter(info
: &DropInfo
, len
: usize, panic_at
: usize) -> impl Iterator
<Item
= DropCheck
<'_
>> {
52 (0..len
).map(move |i
| {
54 panic
!("intended panic");
61 fn check
<const N
: usize>(len
: usize, panic_at
: usize) {
63 iter(info
, len
, panic_at
).map_windows(|_
: &[_
; N
]| {}
).last();
68 fn check_drops(f
: impl FnOnce(&DropInfo
)) {
69 let info
= DropInfo
::new();
70 let _
= std
::panic
::catch_unwind(std
::panic
::AssertUnwindSafe(|| {
77 fn no_iter_panic_n1() {
85 fn no_iter_panic_n2() {
94 fn no_iter_panic_n5() {
103 fn panic_in_first_batch() {
115 fn panic_in_middle() {
147 assert_eq
!("".chars().map_windows(|[c
]| *c
).collect
::<Vec
<_
>>(), vec
![]);
148 assert_eq
!("x".chars().map_windows(|[c
]| *c
).collect
::<Vec
<_
>>(), vec
!['x'
]);
149 assert_eq
!("abcd".chars().map_windows(|[c
]| *c
).collect
::<Vec
<_
>>(), vec
!['a'
, 'b'
, 'c'
, 'd'
]);
155 "".chars().map_windows(|a
: &[_
; 2]| *a
).collect
::<Vec
<_
>>(),
156 <Vec
<[char; 2]>>::new(),
158 assert_eq
!("ab".chars().map_windows(|a
: &[_
; 2]| *a
).collect
::<Vec
<_
>>(), vec
![['a'
, 'b'
]]);
160 "abcd".chars().map_windows(|a
: &[_
; 2]| *a
).collect
::<Vec
<_
>>(),
161 vec
![['a'
, 'b'
], ['b'
, 'c'
], ['c'
, 'd'
]],
166 fn test_case_from_pr_82413_comment() {
167 for () in std
::iter
::repeat("0".to_owned()).map_windows(|_
: &[_
; 3]| {}
).take(4) {}
171 #[should_panic = "array in `Iterator::map_windows` must contain more than 0 elements"]
172 fn check_zero_window() {
173 let _
= std
::iter
::repeat(0).map_windows(|_
: &[_
; 0]| ());
177 fn test_zero_sized_type() {
178 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
181 std
::iter
::repeat(Data
).take(10).map_windows(|arr
: &[Data
; 5]| *arr
).collect();
182 assert_eq
!(data
, [[Data
; 5]; 6]);
186 #[should_panic = "array size of `Iterator::map_windows` is too large"]
187 fn test_too_large_array_size() {
188 let _
= std
::iter
::repeat(()).map_windows(|arr
: &[(); usize::MAX
]| *arr
);
193 let counter
= AtomicUsize
::new(0);
194 let mut iter
= (0..5)
196 counter
.fetch_add(1, SeqCst
);
198 .map_windows(|arr
: &[i32; 2]| *arr
);
199 assert_eq
!(counter
.load(SeqCst
), 0);
201 assert_eq
!(iter
.next(), Some([0, 1]));
202 // The first iteration consumes N items (N = 2).
203 assert_eq
!(counter
.load(SeqCst
), 2);
205 assert_eq
!(iter
.next(), Some([1, 2]));
206 assert_eq
!(counter
.load(SeqCst
), 3);
208 assert_eq
!(iter
.next(), Some([2, 3]));
209 assert_eq
!(counter
.load(SeqCst
), 4);
211 assert_eq
!(iter
.next(), Some([3, 4]));
212 assert_eq
!(counter
.load(SeqCst
), 5);
214 assert_eq
!(iter
.next(), None
);
215 assert_eq
!(counter
.load(SeqCst
), 5);
219 fn test_size_hint() {
220 struct SizeHintCheckHelper((usize, Option
<usize>));
222 impl Iterator
for SizeHintCheckHelper
{
225 fn next(&mut self) -> Option
<i32> {
226 let (ref mut lo
, ref mut hi
) = self.0;
227 let next
= (*hi
!= Some(0)).then_some(0);
228 *lo
= lo
.saturating_sub(1);
229 if let Some(hi
) = hi
{
230 *hi
= hi
.saturating_sub(1);
235 fn size_hint(&self) -> (usize, Option
<usize>) {
240 fn check_size_hint
<const N
: usize>(
241 size_hint
: (usize, Option
<usize>),
242 mut mapped_size_hint
: (usize, Option
<usize>),
244 let mut iter
= SizeHintCheckHelper(size_hint
);
245 let mut mapped_iter
= iter
.by_ref().map_windows(|_
: &[_
; N
]| ());
246 while mapped_iter
.size_hint().0 > 0 {
247 assert_eq
!(mapped_iter
.size_hint(), mapped_size_hint
);
248 assert
!(mapped_iter
.next().is_some());
249 mapped_size_hint
.0 -= 1;
250 mapped_size_hint
.1 = mapped_size_hint
.1.map(|hi
| hi
.saturating_sub(1));
254 check_size_hint
::<1>((0, None
), (0, None
));
255 check_size_hint
::<1>((0, Some(0)), (0, Some(0)));
256 check_size_hint
::<1>((0, Some(2)), (0, Some(2)));
257 check_size_hint
::<1>((1, None
), (1, None
));
258 check_size_hint
::<1>((1, Some(1)), (1, Some(1)));
259 check_size_hint
::<1>((1, Some(4)), (1, Some(4)));
260 check_size_hint
::<1>((5, None
), (5, None
));
261 check_size_hint
::<1>((5, Some(5)), (5, Some(5)));
262 check_size_hint
::<1>((5, Some(10)), (5, Some(10)));
264 check_size_hint
::<2>((0, None
), (0, None
));
265 check_size_hint
::<2>((0, Some(0)), (0, Some(0)));
266 check_size_hint
::<2>((0, Some(2)), (0, Some(1)));
267 check_size_hint
::<2>((1, None
), (0, None
));
268 check_size_hint
::<2>((1, Some(1)), (0, Some(0)));
269 check_size_hint
::<2>((1, Some(4)), (0, Some(3)));
270 check_size_hint
::<2>((5, None
), (4, None
));
271 check_size_hint
::<2>((5, Some(5)), (4, Some(4)));
272 check_size_hint
::<2>((5, Some(10)), (4, Some(9)));
274 check_size_hint
::<5>((0, None
), (0, None
));
275 check_size_hint
::<5>((0, Some(0)), (0, Some(0)));
276 check_size_hint
::<5>((0, Some(2)), (0, Some(0)));
277 check_size_hint
::<5>((1, None
), (0, None
));
278 check_size_hint
::<5>((1, Some(1)), (0, Some(0)));
279 check_size_hint
::<5>((1, Some(4)), (0, Some(0)));
280 check_size_hint
::<5>((5, None
), (1, None
));
281 check_size_hint
::<5>((5, Some(5)), (1, Some(1)));
282 check_size_hint
::<5>((5, Some(10)), (1, Some(6)));