2 use core
::convert
::TryFrom
;
3 use core
::sync
::atomic
::{AtomicUsize, Ordering}
;
7 let value
: String
= "Hello World!".into();
8 let arr
: &[String
; 1] = array
::from_ref(&value
);
9 assert_eq
!(&[value
.clone()], arr
);
11 const VALUE
: &&str = &"Hello World!";
12 const ARR
: &[&str; 1] = array
::from_ref(VALUE
);
13 assert_eq
!(&[*VALUE
], ARR
);
14 assert
!(core
::ptr
::eq(VALUE
, &ARR
[0]));
19 let mut value
: String
= "Hello World".into();
20 let arr
: &mut [String
; 1] = array
::from_mut(&mut value
);
22 assert_eq
!(&value
, "Hello World!");
30 type Array
= [u8; $N
];
31 let mut array
: Array
= [0; $N
];
32 let slice
: &[u8] = &array
[..];
34 let result
= <&Array
>::try_from(slice
);
35 assert_eq
!(&array
, result
.unwrap());
37 let result
= <Array
>::try_from(slice
);
38 assert_eq
!(&array
, &result
.unwrap());
40 let mut_slice
: &mut [u8] = &mut array
[..];
41 let result
= <&mut Array
>::try_from(mut_slice
);
42 assert_eq
!(&[0; $N
], result
.unwrap());
44 let mut_slice
: &mut [u8] = &mut array
[..];
45 let result
= <Array
>::try_from(mut_slice
);
46 assert_eq
!(&array
, &result
.unwrap());
52 10 11 12 13 14 15 16 17 18 19
53 20 21 22 23 24 25 26 27 28 29
59 fn iterator_collect() {
60 let arr
= [0, 1, 2, 5, 9];
61 let v
: Vec
<_
> = IntoIterator
::into_iter(arr
.clone()).collect();
62 assert_eq
!(&arr
[..], &v
[..]);
66 fn iterator_rev_collect() {
67 let arr
= [0, 1, 2, 5, 9];
68 let v
: Vec
<_
> = IntoIterator
::into_iter(arr
.clone()).rev().collect();
69 assert_eq
!(&v
[..], &[9, 5, 2, 1, 0]);
74 let v
= [0, 1, 2, 3, 4];
76 assert_eq
!(IntoIterator
::into_iter(v
.clone()).nth(i
).unwrap(), v
[i
]);
78 assert_eq
!(IntoIterator
::into_iter(v
.clone()).nth(v
.len()), None
);
80 let mut iter
= IntoIterator
::into_iter(v
);
81 assert_eq
!(iter
.nth(2).unwrap(), v
[2]);
82 assert_eq
!(iter
.nth(1).unwrap(), v
[4]);
87 let v
= [0, 1, 2, 3, 4];
88 assert_eq
!(IntoIterator
::into_iter(v
).last().unwrap(), 4);
89 assert_eq
!(IntoIterator
::into_iter([0]).last().unwrap(), 0);
91 let mut it
= IntoIterator
::into_iter([0, 9, 2, 4]);
92 assert_eq
!(it
.next_back(), Some(4));
93 assert_eq
!(it
.last(), Some(2));
98 let mut it
= IntoIterator
::into_iter([0, 2, 4, 6, 8]);
99 assert_eq
!(it
.next(), Some(0));
100 assert_eq
!(it
.next_back(), Some(8));
101 let mut clone
= it
.clone();
102 assert_eq
!(it
.next_back(), Some(6));
103 assert_eq
!(clone
.next_back(), Some(6));
104 assert_eq
!(it
.next_back(), Some(4));
105 assert_eq
!(clone
.next_back(), Some(4));
106 assert_eq
!(it
.next(), Some(2));
107 assert_eq
!(clone
.next(), Some(2));
111 fn iterator_fused() {
112 let mut it
= IntoIterator
::into_iter([0, 9, 2]);
113 assert_eq
!(it
.next(), Some(0));
114 assert_eq
!(it
.next(), Some(9));
115 assert_eq
!(it
.next(), Some(2));
116 assert_eq
!(it
.next(), None
);
117 assert_eq
!(it
.next(), None
);
118 assert_eq
!(it
.next(), None
);
119 assert_eq
!(it
.next(), None
);
120 assert_eq
!(it
.next(), None
);
125 let mut it
= IntoIterator
::into_iter([0, 1, 2, 5, 9]);
126 assert_eq
!(it
.size_hint(), (5, Some(5)));
127 assert_eq
!(it
.len(), 5);
128 assert_eq
!(it
.is_empty(), false);
130 assert_eq
!(it
.next(), Some(0));
131 assert_eq
!(it
.size_hint(), (4, Some(4)));
132 assert_eq
!(it
.len(), 4);
133 assert_eq
!(it
.is_empty(), false);
135 assert_eq
!(it
.next_back(), Some(9));
136 assert_eq
!(it
.size_hint(), (3, Some(3)));
137 assert_eq
!(it
.len(), 3);
138 assert_eq
!(it
.is_empty(), false);
141 let it
= IntoIterator
::into_iter([] as [String
; 0]);
142 assert_eq
!(it
.size_hint(), (0, Some(0)));
143 assert_eq
!(it
.len(), 0);
144 assert_eq
!(it
.is_empty(), true);
148 fn iterator_count() {
149 let v
= [0, 1, 2, 3, 4];
150 assert_eq
!(IntoIterator
::into_iter(v
.clone()).count(), 5);
152 let mut iter2
= IntoIterator
::into_iter(v
);
155 assert_eq
!(iter2
.count(), 3);
159 fn iterator_flat_map() {
160 assert
!((0..5).flat_map(|i
| IntoIterator
::into_iter([2 * i
, 2 * i
+ 1])).eq(0..10));
164 fn iterator_debug() {
165 let arr
= [0, 1, 2, 5, 9];
166 assert_eq
!(format
!("{:?}", IntoIterator
::into_iter(arr
)), "IntoIter([0, 1, 2, 5, 9])",);
170 fn iterator_drops() {
171 use core
::cell
::Cell
;
173 // This test makes sure the correct number of elements are dropped. The `R`
174 // type is just a reference to a `Cell` that is incremented when an `R` is
178 struct Foo
<'a
>(&'a Cell
<usize>);
180 impl Drop
for Foo
<'_
> {
182 self.0.set(self.0.get() + 1);
186 fn five(i
: &Cell
<usize>) -> [Foo
<'_
>; 5] {
187 // This is somewhat verbose because `Foo` does not implement `Copy`
188 // since it implements `Drop`. Consequently, we cannot write
190 [Foo(i
), Foo(i
), Foo(i
), Foo(i
), Foo(i
)]
193 // Simple: drop new iterator.
194 let i
= Cell
::new(0);
196 IntoIterator
::into_iter(five(&i
));
198 assert_eq
!(i
.get(), 5);
200 // Call `next()` once.
201 let i
= Cell
::new(0);
203 let mut iter
= IntoIterator
::into_iter(five(&i
));
204 let _x
= iter
.next();
205 assert_eq
!(i
.get(), 0);
206 assert_eq
!(iter
.count(), 4);
207 assert_eq
!(i
.get(), 4);
209 assert_eq
!(i
.get(), 5);
211 // Check `clone` and calling `next`/`next_back`.
212 let i
= Cell
::new(0);
214 let mut iter
= IntoIterator
::into_iter(five(&i
));
216 assert_eq
!(i
.get(), 1);
218 assert_eq
!(i
.get(), 2);
220 let mut clone
= iter
.clone();
221 assert_eq
!(i
.get(), 2);
224 assert_eq
!(i
.get(), 3);
227 assert_eq
!(i
.get(), 4);
229 assert_eq
!(clone
.count(), 2);
230 assert_eq
!(i
.get(), 6);
232 assert_eq
!(i
.get(), 8);
235 let i
= Cell
::new(0);
237 let mut iter
= IntoIterator
::into_iter(five(&i
));
238 let _x
= iter
.nth(2);
239 assert_eq
!(i
.get(), 2);
240 let _y
= iter
.last();
241 assert_eq
!(i
.get(), 3);
243 assert_eq
!(i
.get(), 5);
245 // Check every element.
246 let i
= Cell
::new(0);
247 for (index
, _x
) in IntoIterator
::into_iter(five(&i
)).enumerate() {
248 assert_eq
!(i
.get(), index
);
250 assert_eq
!(i
.get(), 5);
252 let i
= Cell
::new(0);
253 for (index
, _x
) in IntoIterator
::into_iter(five(&i
)).rev().enumerate() {
254 assert_eq
!(i
.get(), index
);
256 assert_eq
!(i
.get(), 5);
259 // This test does not work on targets without panic=unwind support.
260 // To work around this problem, test is marked is should_panic, so it will
261 // be automagically skipped on unsuitable targets, such as
262 // wasm32-unknown-unknown.
264 // It means that we use panic for indicating success.
266 #[should_panic(expected = "test succeeded")]
267 fn array_default_impl_avoids_leaks_on_panic() {
268 use core
::sync
::atomic
::{AtomicUsize, Ordering::Relaxed}
;
269 static COUNTER
: AtomicUsize
= AtomicUsize
::new(0);
273 impl Default
for Bomb
{
274 fn default() -> Bomb
{
275 if COUNTER
.load(Relaxed
) == 3 {
276 panic
!("bomb limit exceeded");
279 COUNTER
.fetch_add(1, Relaxed
);
280 Bomb(COUNTER
.load(Relaxed
))
286 COUNTER
.fetch_sub(1, Relaxed
);
290 let res
= std
::panic
::catch_unwind(|| <[Bomb
; 5]>::default());
291 let panic_msg
= match res
{
292 Ok(_
) => unreachable
!(),
293 Err(p
) => p
.downcast
::<&'
static str>().unwrap(),
295 assert_eq
!(*panic_msg
, "bomb limit exceeded");
296 // check that all bombs are successfully dropped
297 assert_eq
!(COUNTER
.load(Relaxed
), 0);
298 panic
!("test succeeded")
302 fn empty_array_is_always_default() {
303 struct DoesNotImplDefault
;
305 let _arr
= <[DoesNotImplDefault
; 0]>::default();
311 let b
= a
.map(|v
| v
+ 1);
312 assert_eq
!(b
, [2, 3, 4]);
315 let b
= a
.map(|v
| v
as u64);
316 assert_eq
!(b
, [1, 2, 3]);
319 // See note on above test for why `should_panic` is used.
321 #[should_panic(expected = "test succeeded")]
322 fn array_map_drop_safety() {
323 static DROPPED
: AtomicUsize
= AtomicUsize
::new(0);
325 impl Drop
for DropCounter
{
327 DROPPED
.fetch_add(1, Ordering
::SeqCst
);
331 let num_to_create
= 5;
332 let success
= std
::panic
::catch_unwind(|| {
336 assert
!(nth
< num_to_create
);
341 assert
!(success
.is_err());
342 assert_eq
!(DROPPED
.load(Ordering
::SeqCst
), num_to_create
);
343 panic
!("test succeeded")
347 fn cell_allows_array_cycle() {
348 use core
::cell
::Cell
;
352 a
: [Cell
<Option
<&'a B
<'a
>>>; 2],
357 B { a: [Cell::new(None), Cell::new(None)] }
365 b1
.a
[0].set(Some(&b2
));
366 b1
.a
[1].set(Some(&b3
));
368 b2
.a
[0].set(Some(&b2
));
369 b2
.a
[1].set(Some(&b3
));
371 b3
.a
[0].set(Some(&b1
));
372 b3
.a
[1].set(Some(&b2
));
377 let array
= core
::array
::from_fn(|idx
| idx
);
378 assert_eq
!(array
, [0, 1, 2, 3, 4]);
382 fn array_try_from_fn() {
383 #[derive(Debug, PartialEq)]
388 let array
= core
::array
::try_from_fn(|i
| Ok
::<_
, SomeError
>(i
));
389 assert_eq
!(array
, Ok([0, 1, 2, 3, 4]));
391 let another_array
= core
::array
::try_from_fn
::<Result
<(), _
>, 2, _
>(|_
| Err(SomeError
::Foo
));
392 assert_eq
!(another_array
, Err(SomeError
::Foo
));
395 #[cfg(not(panic = "abort"))]
397 fn array_try_from_fn_drops_inserted_elements_on_err() {
398 static DROP_COUNTER
: AtomicUsize
= AtomicUsize
::new(0);
401 impl Drop
for CountDrop
{
403 DROP_COUNTER
.fetch_add(1, Ordering
::SeqCst
);
407 let _
= catch_unwind_silent(move || {
408 let _
: Result
<[CountDrop
; 4], ()> = core
::array
::try_from_fn(|idx
| {
416 assert_eq
!(DROP_COUNTER
.load(Ordering
::SeqCst
), 2);
419 #[cfg(not(panic = "abort"))]
421 fn array_try_from_fn_drops_inserted_elements_on_panic() {
422 static DROP_COUNTER
: AtomicUsize
= AtomicUsize
::new(0);
425 impl Drop
for CountDrop
{
427 DROP_COUNTER
.fetch_add(1, Ordering
::SeqCst
);
431 let _
= catch_unwind_silent(move || {
432 let _
: Result
<[CountDrop
; 4], ()> = core
::array
::try_from_fn(|idx
| {
434 panic
!("peek a boo");
440 assert_eq
!(DROP_COUNTER
.load(Ordering
::SeqCst
), 2);
443 #[cfg(not(panic = "abort"))]
444 // https://stackoverflow.com/a/59211505
445 fn catch_unwind_silent
<F
, R
>(f
: F
) -> std
::thread
::Result
<R
>
447 F
: FnOnce() -> R
+ core
::panic
::UnwindSafe
,
449 let prev_hook
= std
::panic
::take_hook();
450 std
::panic
::set_hook(Box
::new(|_
| {}
));
451 let result
= std
::panic
::catch_unwind(f
);
452 std
::panic
::set_hook(prev_hook
);
457 fn array_split_array_mut() {
458 let mut v
= [1, 2, 3, 4, 5, 6];
461 let (left
, right
) = v
.split_array_mut
::<0>();
462 assert_eq
!(left
, &mut []);
463 assert_eq
!(right
, &mut [1, 2, 3, 4, 5, 6]);
467 let (left
, right
) = v
.split_array_mut
::<6>();
468 assert_eq
!(left
, &mut [1, 2, 3, 4, 5, 6]);
469 assert_eq
!(right
, &mut []);
474 fn array_rsplit_array_mut() {
475 let mut v
= [1, 2, 3, 4, 5, 6];
478 let (left
, right
) = v
.rsplit_array_mut
::<0>();
479 assert_eq
!(left
, &mut [1, 2, 3, 4, 5, 6]);
480 assert_eq
!(right
, &mut []);
484 let (left
, right
) = v
.rsplit_array_mut
::<6>();
485 assert_eq
!(left
, &mut []);
486 assert_eq
!(right
, &mut [1, 2, 3, 4, 5, 6]);
492 fn array_split_array_ref_out_of_bounds() {
493 let v
= [1, 2, 3, 4, 5, 6];
495 v
.split_array_ref
::<7>();
500 fn array_split_array_mut_out_of_bounds() {
501 let mut v
= [1, 2, 3, 4, 5, 6];
503 v
.split_array_mut
::<7>();
508 fn array_rsplit_array_ref_out_of_bounds() {
509 let v
= [1, 2, 3, 4, 5, 6];
511 v
.rsplit_array_ref
::<7>();
516 fn array_rsplit_array_mut_out_of_bounds() {
517 let mut v
= [1, 2, 3, 4, 5, 6];
519 v
.rsplit_array_mut
::<7>();
523 fn array_intoiter_advance_by() {
525 struct DropCounter
<'a
>(usize, &'a Cell
<usize>);
526 impl Drop
for DropCounter
<'_
> {
528 let x
= self.1.get();
533 let counter
= Cell
::new(0);
534 let a
: [_
; 100] = std
::array
::from_fn(|i
| DropCounter(i
, &counter
));
535 let mut it
= IntoIterator
::into_iter(a
);
537 let r
= it
.advance_by(1);
538 assert_eq
!(r
, Ok(()));
539 assert_eq
!(it
.len(), 99);
540 assert_eq
!(counter
.get(), 1);
542 let r
= it
.advance_by(0);
543 assert_eq
!(r
, Ok(()));
544 assert_eq
!(it
.len(), 99);
545 assert_eq
!(counter
.get(), 1);
547 let r
= it
.advance_by(11);
548 assert_eq
!(r
, Ok(()));
549 assert_eq
!(it
.len(), 88);
550 assert_eq
!(counter
.get(), 12);
553 assert_eq
!(x
.as_ref().map(|x
| x
.0), Some(12));
554 assert_eq
!(it
.len(), 87);
555 assert_eq
!(counter
.get(), 12);
557 assert_eq
!(counter
.get(), 13);
559 let r
= it
.advance_by(123456);
560 assert_eq
!(r
, Err(87));
561 assert_eq
!(it
.len(), 0);
562 assert_eq
!(counter
.get(), 100);
564 let r
= it
.advance_by(0);
565 assert_eq
!(r
, Ok(()));
566 assert_eq
!(it
.len(), 0);
567 assert_eq
!(counter
.get(), 100);
569 let r
= it
.advance_by(10);
570 assert_eq
!(r
, Err(0));
571 assert_eq
!(it
.len(), 0);
572 assert_eq
!(counter
.get(), 100);
576 fn array_intoiter_advance_back_by() {
578 struct DropCounter
<'a
>(usize, &'a Cell
<usize>);
579 impl Drop
for DropCounter
<'_
> {
581 let x
= self.1.get();
586 let counter
= Cell
::new(0);
587 let a
: [_
; 100] = std
::array
::from_fn(|i
| DropCounter(i
, &counter
));
588 let mut it
= IntoIterator
::into_iter(a
);
590 let r
= it
.advance_back_by(1);
591 assert_eq
!(r
, Ok(()));
592 assert_eq
!(it
.len(), 99);
593 assert_eq
!(counter
.get(), 1);
595 let r
= it
.advance_back_by(0);
596 assert_eq
!(r
, Ok(()));
597 assert_eq
!(it
.len(), 99);
598 assert_eq
!(counter
.get(), 1);
600 let r
= it
.advance_back_by(11);
601 assert_eq
!(r
, Ok(()));
602 assert_eq
!(it
.len(), 88);
603 assert_eq
!(counter
.get(), 12);
605 let x
= it
.next_back();
606 assert_eq
!(x
.as_ref().map(|x
| x
.0), Some(87));
607 assert_eq
!(it
.len(), 87);
608 assert_eq
!(counter
.get(), 12);
610 assert_eq
!(counter
.get(), 13);
612 let r
= it
.advance_back_by(123456);
613 assert_eq
!(r
, Err(87));
614 assert_eq
!(it
.len(), 0);
615 assert_eq
!(counter
.get(), 100);
617 let r
= it
.advance_back_by(0);
618 assert_eq
!(r
, Ok(()));
619 assert_eq
!(it
.len(), 0);
620 assert_eq
!(counter
.get(), 100);
622 let r
= it
.advance_back_by(10);
623 assert_eq
!(r
, Err(0));
624 assert_eq
!(it
.len(), 0);
625 assert_eq
!(counter
.get(), 100);
629 fn array_mixed_equality_integers() {
630 let array3
: [i32; 3] = [1, 2, 3];
631 let array3b
: [i32; 3] = [3, 2, 1];
632 let array4
: [i32; 4] = [1, 2, 3, 4];
634 let slice3
: &[i32] = &{ array3 }
;
635 let slice3b
: &[i32] = &{ array3b }
;
636 let slice4
: &[i32] = &{ array4 }
;
637 assert
!(array3
== slice3
);
638 assert
!(array3
!= slice3b
);
639 assert
!(array3
!= slice4
);
640 assert
!(slice3
== array3
);
641 assert
!(slice3b
!= array3
);
642 assert
!(slice4
!= array3
);
644 let mut3
: &mut [i32] = &mut { array3 }
;
645 let mut3b
: &mut [i32] = &mut { array3b }
;
646 let mut4
: &mut [i32] = &mut { array4 }
;
647 assert
!(array3
== mut3
);
648 assert
!(array3
!= mut3b
);
649 assert
!(array3
!= mut4
);
650 assert
!(mut3
== array3
);
651 assert
!(mut3b
!= array3
);
652 assert
!(mut4
!= array3
);
656 fn array_mixed_equality_nans() {
657 let array3
: [f32; 3] = [1.0, std
::f32::NAN
, 3.0];
659 let slice3
: &[f32] = &{ array3 }
;
660 assert
!(!(array3
== slice3
));
661 assert
!(array3
!= slice3
);
662 assert
!(!(slice3
== array3
));
663 assert
!(slice3
!= array3
);
665 let mut3
: &mut [f32] = &mut { array3 }
;
666 assert
!(!(array3
== mut3
));
667 assert
!(array3
!= mut3
);
668 assert
!(!(mut3
== array3
));
669 assert
!(mut3
!= array3
);
673 fn array_into_iter_fold() {
674 // Strings to help MIRI catch if we double-free or something
675 let a
= ["Aa".to_string(), "Bb".to_string(), "Cc".to_string()];
676 let mut s
= "s".to_string();
677 a
.into_iter().for_each(|b
| s
+= &b
);
678 assert_eq
!(s
, "sAaBbCc");
680 let a
= [1, 2, 3, 4, 5, 6];
681 let mut it
= a
.into_iter();
682 it
.advance_by(1).unwrap();
683 it
.advance_back_by(2).unwrap();
684 let s
= it
.fold(10, |a
, b
| 10 * a
+ b
);
685 assert_eq
!(s
, 10234);
689 fn array_into_iter_rfold() {
690 // Strings to help MIRI catch if we double-free or something
691 let a
= ["Aa".to_string(), "Bb".to_string(), "Cc".to_string()];
692 let mut s
= "s".to_string();
693 a
.into_iter().rev().for_each(|b
| s
+= &b
);
694 assert_eq
!(s
, "sCcBbAa");
696 let a
= [1, 2, 3, 4, 5, 6];
697 let mut it
= a
.into_iter();
698 it
.advance_by(1).unwrap();
699 it
.advance_back_by(2).unwrap();
700 let s
= it
.rfold(10, |a
, b
| 10 * a
+ b
);
701 assert_eq
!(s
, 10432);