2 use core::convert::TryFrom;
6 let value: String = "Hello World!".into();
7 let arr: &[String; 1] = array::from_ref(&value);
8 assert_eq!(&[value.clone()], arr);
13 let mut value: String = "Hello World".into();
14 let arr: &mut [String; 1] = array::from_mut(&mut value);
16 assert_eq!(&value, "Hello World!");
24 type Array = [u8; $N];
25 let array: Array = [0; $N];
26 let slice: &[u8] = &array[..];
28 let result = <&Array>::try_from(slice);
29 assert_eq!(&array, result.unwrap());
35 10 11 12 13 14 15 16 17 18 19
36 20 21 22 23 24 25 26 27 28 29
42 fn iterator_collect() {
43 let arr = [0, 1, 2, 5, 9];
44 let v: Vec<_> = IntoIterator::into_iter(arr.clone()).collect();
45 assert_eq!(&arr[..], &v[..]);
49 fn iterator_rev_collect() {
50 let arr = [0, 1, 2, 5, 9];
51 let v: Vec<_> = IntoIterator::into_iter(arr.clone()).rev().collect();
52 assert_eq!(&v[..], &[9, 5, 2, 1, 0]);
57 let v = [0, 1, 2, 3, 4];
59 assert_eq!(IntoIterator::into_iter(v.clone()).nth(i).unwrap(), v[i]);
61 assert_eq!(IntoIterator::into_iter(v.clone()).nth(v.len()), None);
63 let mut iter = IntoIterator::into_iter(v);
64 assert_eq!(iter.nth(2).unwrap(), v[2]);
65 assert_eq!(iter.nth(1).unwrap(), v[4]);
70 let v = [0, 1, 2, 3, 4];
71 assert_eq!(IntoIterator::into_iter(v).last().unwrap(), 4);
72 assert_eq!(IntoIterator::into_iter([0]).last().unwrap(), 0);
74 let mut it = IntoIterator::into_iter([0, 9, 2, 4]);
75 assert_eq!(it.next_back(), Some(4));
76 assert_eq!(it.last(), Some(2));
81 let mut it = IntoIterator::into_iter([0, 2, 4, 6, 8]);
82 assert_eq!(it.next(), Some(0));
83 assert_eq!(it.next_back(), Some(8));
84 let mut clone = it.clone();
85 assert_eq!(it.next_back(), Some(6));
86 assert_eq!(clone.next_back(), Some(6));
87 assert_eq!(it.next_back(), Some(4));
88 assert_eq!(clone.next_back(), Some(4));
89 assert_eq!(it.next(), Some(2));
90 assert_eq!(clone.next(), Some(2));
95 let mut it = IntoIterator::into_iter([0, 9, 2]);
96 assert_eq!(it.next(), Some(0));
97 assert_eq!(it.next(), Some(9));
98 assert_eq!(it.next(), Some(2));
99 assert_eq!(it.next(), None);
100 assert_eq!(it.next(), None);
101 assert_eq!(it.next(), None);
102 assert_eq!(it.next(), None);
103 assert_eq!(it.next(), None);
108 let mut it = IntoIterator::into_iter([0, 1, 2, 5, 9]);
109 assert_eq!(it.size_hint(), (5, Some(5)));
110 assert_eq!(it.len(), 5);
111 assert_eq!(it.is_empty(), false);
113 assert_eq!(it.next(), Some(0));
114 assert_eq!(it.size_hint(), (4, Some(4)));
115 assert_eq!(it.len(), 4);
116 assert_eq!(it.is_empty(), false);
118 assert_eq!(it.next_back(), Some(9));
119 assert_eq!(it.size_hint(), (3, Some(3)));
120 assert_eq!(it.len(), 3);
121 assert_eq!(it.is_empty(), false);
124 let it = IntoIterator::into_iter([] as [String; 0]);
125 assert_eq!(it.size_hint(), (0, Some(0)));
126 assert_eq!(it.len(), 0);
127 assert_eq!(it.is_empty(), true);
131 fn iterator_count() {
132 let v = [0, 1, 2, 3, 4];
133 assert_eq!(IntoIterator::into_iter(v.clone()).count(), 5);
135 let mut iter2 = IntoIterator::into_iter(v);
138 assert_eq!(iter2.count(), 3);
142 fn iterator_flat_map() {
143 assert!((0..5).flat_map(|i| IntoIterator::into_iter([2 * i, 2 * i + 1])).eq(0..10));
147 fn iterator_debug() {
148 let arr = [0, 1, 2, 5, 9];
149 assert_eq!(format!("{:?}", IntoIterator::into_iter(arr)), "IntoIter([0, 1, 2, 5, 9])",);
153 fn iterator_drops() {
154 use core::cell::Cell;
156 // This test makes sure the correct number of elements are dropped. The `R`
157 // type is just a reference to a `Cell` that is incremented when an `R` is
161 struct Foo<'a>(&'a Cell<usize>);
163 impl Drop for Foo<'_> {
165 self.0.set(self.0.get() + 1);
169 fn five(i: &Cell<usize>) -> [Foo<'_>; 5] {
170 // This is somewhat verbose because `Foo` does not implement `Copy`
171 // since it implements `Drop`. Consequently, we cannot write
173 [Foo(i), Foo(i), Foo(i), Foo(i), Foo(i)]
176 // Simple: drop new iterator.
177 let i = Cell::new(0);
179 IntoIterator::into_iter(five(&i));
181 assert_eq!(i.get(), 5);
183 // Call `next()` once.
184 let i = Cell::new(0);
186 let mut iter = IntoIterator::into_iter(five(&i));
187 let _x = iter.next();
188 assert_eq!(i.get(), 0);
189 assert_eq!(iter.count(), 4);
190 assert_eq!(i.get(), 4);
192 assert_eq!(i.get(), 5);
194 // Check `clone` and calling `next`/`next_back`.
195 let i = Cell::new(0);
197 let mut iter = IntoIterator::into_iter(five(&i));
199 assert_eq!(i.get(), 1);
201 assert_eq!(i.get(), 2);
203 let mut clone = iter.clone();
204 assert_eq!(i.get(), 2);
207 assert_eq!(i.get(), 3);
210 assert_eq!(i.get(), 4);
212 assert_eq!(clone.count(), 2);
213 assert_eq!(i.get(), 6);
215 assert_eq!(i.get(), 8);
218 let i = Cell::new(0);
220 let mut iter = IntoIterator::into_iter(five(&i));
221 let _x = iter.nth(2);
222 assert_eq!(i.get(), 2);
223 let _y = iter.last();
224 assert_eq!(i.get(), 3);
226 assert_eq!(i.get(), 5);
228 // Check every element.
229 let i = Cell::new(0);
230 for (index, _x) in IntoIterator::into_iter(five(&i)).enumerate() {
231 assert_eq!(i.get(), index);
233 assert_eq!(i.get(), 5);
235 let i = Cell::new(0);
236 for (index, _x) in IntoIterator::into_iter(five(&i)).rev().enumerate() {
237 assert_eq!(i.get(), index);
239 assert_eq!(i.get(), 5);
242 // This test does not work on targets without panic=unwind support.
243 // To work around this problem, test is marked is should_panic, so it will
244 // be automagically skipped on unsuitable targets, such as
245 // wasm32-unknown-unkown.
247 // It means that we use panic for indicating success.
249 #[should_panic(expected = "test succeeded")]
250 fn array_default_impl_avoids_leaks_on_panic() {
251 use core::sync::atomic::{AtomicUsize, Ordering::Relaxed};
252 static COUNTER: AtomicUsize = AtomicUsize::new(0);
256 impl Default for Bomb {
257 fn default() -> Bomb {
258 if COUNTER.load(Relaxed) == 3 {
259 panic!("bomb limit exceeded");
262 COUNTER.fetch_add(1, Relaxed);
263 Bomb(COUNTER.load(Relaxed))
269 COUNTER.fetch_sub(1, Relaxed);
273 let res = std::panic::catch_unwind(|| <[Bomb; 5]>::default());
274 let panic_msg = match res {
275 Ok(_) => unreachable!(),
276 Err(p) => p.downcast::<&'static str>().unwrap(),
278 assert_eq!(*panic_msg, "bomb limit exceeded");
279 // check that all bombs are successfully dropped
280 assert_eq!(COUNTER.load(Relaxed), 0);
281 panic!("test succeeded")
285 fn empty_array_is_always_default() {
286 struct DoesNotImplDefault;
288 let _arr = <[DoesNotImplDefault; 0]>::default();
294 let b = a.map(|v| v + 1);
295 assert_eq!(b, [2, 3, 4]);
298 let b = a.map(|v| v as u64);
299 assert_eq!(b, [1, 2, 3]);
302 // See note on above test for why `should_panic` is used.
304 #[should_panic(expected = "test succeeded")]
305 fn array_map_drop_safety() {
306 use core::sync::atomic::AtomicUsize;
307 use core::sync::atomic::Ordering;
308 static DROPPED: AtomicUsize = AtomicUsize::new(0);
310 impl Drop for DropCounter {
312 DROPPED.fetch_add(1, Ordering::SeqCst);
316 let num_to_create = 5;
317 let success = std::panic::catch_unwind(|| {
321 assert!(nth < num_to_create);
326 assert!(success.is_err());
327 assert_eq!(DROPPED.load(Ordering::SeqCst), num_to_create);
328 panic!("test succeeded")
332 fn cell_allows_array_cycle() {
333 use core::cell::Cell;
337 a: [Cell<Option<&'a B<'a>>>; 2],
342 B { a: [Cell::new(None), Cell::new(None)] }
350 b1.a[0].set(Some(&b2));
351 b1.a[1].set(Some(&b3));
353 b2.a[0].set(Some(&b2));
354 b2.a[1].set(Some(&b3));
356 b3.a[0].set(Some(&b1));
357 b3.a[1].set(Some(&b2));