]> git.proxmox.com Git - rustc.git/blob - library/core/src/iter/adapters/flatten.rs
New upstream version 1.65.0+dfsg1
[rustc.git] / library / core / src / iter / adapters / flatten.rs
1 use crate::fmt;
2 use crate::iter::{DoubleEndedIterator, Fuse, FusedIterator, Iterator, Map, TrustedLen};
3 use crate::ops::{ControlFlow, Try};
4
5 /// An iterator that maps each element to an iterator, and yields the elements
6 /// of the produced iterators.
7 ///
8 /// This `struct` is created by [`Iterator::flat_map`]. See its documentation
9 /// for more.
10 #[must_use = "iterators are lazy and do nothing unless consumed"]
11 #[stable(feature = "rust1", since = "1.0.0")]
12 pub struct FlatMap<I, U: IntoIterator, F> {
13 inner: FlattenCompat<Map<I, F>, <U as IntoIterator>::IntoIter>,
14 }
15
16 impl<I: Iterator, U: IntoIterator, F: FnMut(I::Item) -> U> FlatMap<I, U, F> {
17 pub(in crate::iter) fn new(iter: I, f: F) -> FlatMap<I, U, F> {
18 FlatMap { inner: FlattenCompat::new(iter.map(f)) }
19 }
20 }
21
22 #[stable(feature = "rust1", since = "1.0.0")]
23 impl<I: Clone, U, F: Clone> Clone for FlatMap<I, U, F>
24 where
25 U: Clone + IntoIterator<IntoIter: Clone>,
26 {
27 fn clone(&self) -> Self {
28 FlatMap { inner: self.inner.clone() }
29 }
30 }
31
32 #[stable(feature = "core_impl_debug", since = "1.9.0")]
33 impl<I: fmt::Debug, U, F> fmt::Debug for FlatMap<I, U, F>
34 where
35 U: IntoIterator<IntoIter: fmt::Debug>,
36 {
37 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
38 f.debug_struct("FlatMap").field("inner", &self.inner).finish()
39 }
40 }
41
42 #[stable(feature = "rust1", since = "1.0.0")]
43 impl<I: Iterator, U: IntoIterator, F> Iterator for FlatMap<I, U, F>
44 where
45 F: FnMut(I::Item) -> U,
46 {
47 type Item = U::Item;
48
49 #[inline]
50 fn next(&mut self) -> Option<U::Item> {
51 self.inner.next()
52 }
53
54 #[inline]
55 fn size_hint(&self) -> (usize, Option<usize>) {
56 self.inner.size_hint()
57 }
58
59 #[inline]
60 fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
61 where
62 Self: Sized,
63 Fold: FnMut(Acc, Self::Item) -> R,
64 R: Try<Output = Acc>,
65 {
66 self.inner.try_fold(init, fold)
67 }
68
69 #[inline]
70 fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
71 where
72 Fold: FnMut(Acc, Self::Item) -> Acc,
73 {
74 self.inner.fold(init, fold)
75 }
76
77 #[inline]
78 fn advance_by(&mut self, n: usize) -> Result<(), usize> {
79 self.inner.advance_by(n)
80 }
81
82 #[inline]
83 fn count(self) -> usize {
84 self.inner.count()
85 }
86
87 #[inline]
88 fn last(self) -> Option<Self::Item> {
89 self.inner.last()
90 }
91 }
92
93 #[stable(feature = "rust1", since = "1.0.0")]
94 impl<I: DoubleEndedIterator, U, F> DoubleEndedIterator for FlatMap<I, U, F>
95 where
96 F: FnMut(I::Item) -> U,
97 U: IntoIterator<IntoIter: DoubleEndedIterator>,
98 {
99 #[inline]
100 fn next_back(&mut self) -> Option<U::Item> {
101 self.inner.next_back()
102 }
103
104 #[inline]
105 fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
106 where
107 Self: Sized,
108 Fold: FnMut(Acc, Self::Item) -> R,
109 R: Try<Output = Acc>,
110 {
111 self.inner.try_rfold(init, fold)
112 }
113
114 #[inline]
115 fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
116 where
117 Fold: FnMut(Acc, Self::Item) -> Acc,
118 {
119 self.inner.rfold(init, fold)
120 }
121
122 #[inline]
123 fn advance_back_by(&mut self, n: usize) -> Result<(), usize> {
124 self.inner.advance_back_by(n)
125 }
126 }
127
128 #[stable(feature = "fused", since = "1.26.0")]
129 impl<I, U, F> FusedIterator for FlatMap<I, U, F>
130 where
131 I: FusedIterator,
132 U: IntoIterator,
133 F: FnMut(I::Item) -> U,
134 {
135 }
136
137 #[unstable(feature = "trusted_len", issue = "37572")]
138 unsafe impl<T, I, F, const N: usize> TrustedLen for FlatMap<I, [T; N], F>
139 where
140 I: TrustedLen,
141 F: FnMut(I::Item) -> [T; N],
142 {
143 }
144
145 #[unstable(feature = "trusted_len", issue = "37572")]
146 unsafe impl<'a, T, I, F, const N: usize> TrustedLen for FlatMap<I, &'a [T; N], F>
147 where
148 I: TrustedLen,
149 F: FnMut(I::Item) -> &'a [T; N],
150 {
151 }
152
153 #[unstable(feature = "trusted_len", issue = "37572")]
154 unsafe impl<'a, T, I, F, const N: usize> TrustedLen for FlatMap<I, &'a mut [T; N], F>
155 where
156 I: TrustedLen,
157 F: FnMut(I::Item) -> &'a mut [T; N],
158 {
159 }
160
161 /// An iterator that flattens one level of nesting in an iterator of things
162 /// that can be turned into iterators.
163 ///
164 /// This `struct` is created by the [`flatten`] method on [`Iterator`]. See its
165 /// documentation for more.
166 ///
167 /// [`flatten`]: Iterator::flatten()
168 #[must_use = "iterators are lazy and do nothing unless consumed"]
169 #[stable(feature = "iterator_flatten", since = "1.29.0")]
170 pub struct Flatten<I: Iterator<Item: IntoIterator>> {
171 inner: FlattenCompat<I, <I::Item as IntoIterator>::IntoIter>,
172 }
173
174 impl<I: Iterator<Item: IntoIterator>> Flatten<I> {
175 pub(in super::super) fn new(iter: I) -> Flatten<I> {
176 Flatten { inner: FlattenCompat::new(iter) }
177 }
178 }
179
180 #[stable(feature = "iterator_flatten", since = "1.29.0")]
181 impl<I, U> fmt::Debug for Flatten<I>
182 where
183 I: fmt::Debug + Iterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
184 U: fmt::Debug + Iterator,
185 {
186 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
187 f.debug_struct("Flatten").field("inner", &self.inner).finish()
188 }
189 }
190
191 #[stable(feature = "iterator_flatten", since = "1.29.0")]
192 impl<I, U> Clone for Flatten<I>
193 where
194 I: Clone + Iterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
195 U: Clone + Iterator,
196 {
197 fn clone(&self) -> Self {
198 Flatten { inner: self.inner.clone() }
199 }
200 }
201
202 #[stable(feature = "iterator_flatten", since = "1.29.0")]
203 impl<I, U> Iterator for Flatten<I>
204 where
205 I: Iterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
206 U: Iterator,
207 {
208 type Item = U::Item;
209
210 #[inline]
211 fn next(&mut self) -> Option<U::Item> {
212 self.inner.next()
213 }
214
215 #[inline]
216 fn size_hint(&self) -> (usize, Option<usize>) {
217 self.inner.size_hint()
218 }
219
220 #[inline]
221 fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
222 where
223 Self: Sized,
224 Fold: FnMut(Acc, Self::Item) -> R,
225 R: Try<Output = Acc>,
226 {
227 self.inner.try_fold(init, fold)
228 }
229
230 #[inline]
231 fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
232 where
233 Fold: FnMut(Acc, Self::Item) -> Acc,
234 {
235 self.inner.fold(init, fold)
236 }
237
238 #[inline]
239 fn advance_by(&mut self, n: usize) -> Result<(), usize> {
240 self.inner.advance_by(n)
241 }
242
243 #[inline]
244 fn count(self) -> usize {
245 self.inner.count()
246 }
247
248 #[inline]
249 fn last(self) -> Option<Self::Item> {
250 self.inner.last()
251 }
252 }
253
254 #[stable(feature = "iterator_flatten", since = "1.29.0")]
255 impl<I, U> DoubleEndedIterator for Flatten<I>
256 where
257 I: DoubleEndedIterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
258 U: DoubleEndedIterator,
259 {
260 #[inline]
261 fn next_back(&mut self) -> Option<U::Item> {
262 self.inner.next_back()
263 }
264
265 #[inline]
266 fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
267 where
268 Self: Sized,
269 Fold: FnMut(Acc, Self::Item) -> R,
270 R: Try<Output = Acc>,
271 {
272 self.inner.try_rfold(init, fold)
273 }
274
275 #[inline]
276 fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
277 where
278 Fold: FnMut(Acc, Self::Item) -> Acc,
279 {
280 self.inner.rfold(init, fold)
281 }
282
283 #[inline]
284 fn advance_back_by(&mut self, n: usize) -> Result<(), usize> {
285 self.inner.advance_back_by(n)
286 }
287 }
288
289 #[stable(feature = "iterator_flatten", since = "1.29.0")]
290 impl<I, U> FusedIterator for Flatten<I>
291 where
292 I: FusedIterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
293 U: Iterator,
294 {
295 }
296
297 #[unstable(feature = "trusted_len", issue = "37572")]
298 unsafe impl<I> TrustedLen for Flatten<I>
299 where
300 I: TrustedLen,
301 <I as Iterator>::Item: TrustedConstSize,
302 {
303 }
304
305 /// Real logic of both `Flatten` and `FlatMap` which simply delegate to
306 /// this type.
307 #[derive(Clone, Debug)]
308 struct FlattenCompat<I, U> {
309 iter: Fuse<I>,
310 frontiter: Option<U>,
311 backiter: Option<U>,
312 }
313 impl<I, U> FlattenCompat<I, U>
314 where
315 I: Iterator,
316 {
317 /// Adapts an iterator by flattening it, for use in `flatten()` and `flat_map()`.
318 fn new(iter: I) -> FlattenCompat<I, U> {
319 FlattenCompat { iter: iter.fuse(), frontiter: None, backiter: None }
320 }
321 }
322
323 impl<I, U> FlattenCompat<I, U>
324 where
325 I: Iterator<Item: IntoIterator<IntoIter = U>>,
326 {
327 /// Folds the inner iterators into an accumulator by applying an operation.
328 ///
329 /// Folds over the inner iterators, not over their elements. Is used by the `fold`, `count`,
330 /// and `last` methods.
331 #[inline]
332 fn iter_fold<Acc, Fold>(self, mut acc: Acc, mut fold: Fold) -> Acc
333 where
334 Fold: FnMut(Acc, U) -> Acc,
335 {
336 #[inline]
337 fn flatten<T: IntoIterator, Acc>(
338 fold: &mut impl FnMut(Acc, T::IntoIter) -> Acc,
339 ) -> impl FnMut(Acc, T) -> Acc + '_ {
340 move |acc, iter| fold(acc, iter.into_iter())
341 }
342
343 if let Some(iter) = self.frontiter {
344 acc = fold(acc, iter);
345 }
346
347 acc = self.iter.fold(acc, flatten(&mut fold));
348
349 if let Some(iter) = self.backiter {
350 acc = fold(acc, iter);
351 }
352
353 acc
354 }
355
356 /// Folds over the inner iterators as long as the given function returns successfully,
357 /// always storing the most recent inner iterator in `self.frontiter`.
358 ///
359 /// Folds over the inner iterators, not over their elements. Is used by the `try_fold` and
360 /// `advance_by` methods.
361 #[inline]
362 fn iter_try_fold<Acc, Fold, R>(&mut self, mut acc: Acc, mut fold: Fold) -> R
363 where
364 Fold: FnMut(Acc, &mut U) -> R,
365 R: Try<Output = Acc>,
366 {
367 #[inline]
368 fn flatten<'a, T: IntoIterator, Acc, R: Try<Output = Acc>>(
369 frontiter: &'a mut Option<T::IntoIter>,
370 fold: &'a mut impl FnMut(Acc, &mut T::IntoIter) -> R,
371 ) -> impl FnMut(Acc, T) -> R + 'a {
372 move |acc, iter| fold(acc, frontiter.insert(iter.into_iter()))
373 }
374
375 if let Some(iter) = &mut self.frontiter {
376 acc = fold(acc, iter)?;
377 }
378 self.frontiter = None;
379
380 acc = self.iter.try_fold(acc, flatten(&mut self.frontiter, &mut fold))?;
381 self.frontiter = None;
382
383 if let Some(iter) = &mut self.backiter {
384 acc = fold(acc, iter)?;
385 }
386 self.backiter = None;
387
388 try { acc }
389 }
390 }
391
392 impl<I, U> FlattenCompat<I, U>
393 where
394 I: DoubleEndedIterator<Item: IntoIterator<IntoIter = U>>,
395 {
396 /// Folds the inner iterators into an accumulator by applying an operation, starting form the
397 /// back.
398 ///
399 /// Folds over the inner iterators, not over their elements. Is used by the `rfold` method.
400 #[inline]
401 fn iter_rfold<Acc, Fold>(self, mut acc: Acc, mut fold: Fold) -> Acc
402 where
403 Fold: FnMut(Acc, U) -> Acc,
404 {
405 #[inline]
406 fn flatten<T: IntoIterator, Acc>(
407 fold: &mut impl FnMut(Acc, T::IntoIter) -> Acc,
408 ) -> impl FnMut(Acc, T) -> Acc + '_ {
409 move |acc, iter| fold(acc, iter.into_iter())
410 }
411
412 if let Some(iter) = self.backiter {
413 acc = fold(acc, iter);
414 }
415
416 acc = self.iter.rfold(acc, flatten(&mut fold));
417
418 if let Some(iter) = self.frontiter {
419 acc = fold(acc, iter);
420 }
421
422 acc
423 }
424
425 /// Folds over the inner iterators in reverse order as long as the given function returns
426 /// successfully, always storing the most recent inner iterator in `self.backiter`.
427 ///
428 /// Folds over the inner iterators, not over their elements. Is used by the `try_rfold` and
429 /// `advance_back_by` methods.
430 #[inline]
431 fn iter_try_rfold<Acc, Fold, R>(&mut self, mut acc: Acc, mut fold: Fold) -> R
432 where
433 Fold: FnMut(Acc, &mut U) -> R,
434 R: Try<Output = Acc>,
435 {
436 #[inline]
437 fn flatten<'a, T: IntoIterator, Acc, R: Try>(
438 backiter: &'a mut Option<T::IntoIter>,
439 fold: &'a mut impl FnMut(Acc, &mut T::IntoIter) -> R,
440 ) -> impl FnMut(Acc, T) -> R + 'a {
441 move |acc, iter| fold(acc, backiter.insert(iter.into_iter()))
442 }
443
444 if let Some(iter) = &mut self.backiter {
445 acc = fold(acc, iter)?;
446 }
447 self.backiter = None;
448
449 acc = self.iter.try_rfold(acc, flatten(&mut self.backiter, &mut fold))?;
450 self.backiter = None;
451
452 if let Some(iter) = &mut self.frontiter {
453 acc = fold(acc, iter)?;
454 }
455 self.frontiter = None;
456
457 try { acc }
458 }
459 }
460
461 impl<I, U> Iterator for FlattenCompat<I, U>
462 where
463 I: Iterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
464 U: Iterator,
465 {
466 type Item = U::Item;
467
468 #[inline]
469 fn next(&mut self) -> Option<U::Item> {
470 loop {
471 if let elt @ Some(_) = and_then_or_clear(&mut self.frontiter, Iterator::next) {
472 return elt;
473 }
474 match self.iter.next() {
475 None => return and_then_or_clear(&mut self.backiter, Iterator::next),
476 Some(inner) => self.frontiter = Some(inner.into_iter()),
477 }
478 }
479 }
480
481 #[inline]
482 fn size_hint(&self) -> (usize, Option<usize>) {
483 let (flo, fhi) = self.frontiter.as_ref().map_or((0, Some(0)), U::size_hint);
484 let (blo, bhi) = self.backiter.as_ref().map_or((0, Some(0)), U::size_hint);
485 let lo = flo.saturating_add(blo);
486
487 if let Some(fixed_size) = <<I as Iterator>::Item as ConstSizeIntoIterator>::size() {
488 let (lower, upper) = self.iter.size_hint();
489
490 let lower = lower.saturating_mul(fixed_size).saturating_add(lo);
491 let upper =
492 try { fhi?.checked_add(bhi?)?.checked_add(fixed_size.checked_mul(upper?)?)? };
493
494 return (lower, upper);
495 }
496
497 match (self.iter.size_hint(), fhi, bhi) {
498 ((0, Some(0)), Some(a), Some(b)) => (lo, a.checked_add(b)),
499 _ => (lo, None),
500 }
501 }
502
503 #[inline]
504 fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
505 where
506 Self: Sized,
507 Fold: FnMut(Acc, Self::Item) -> R,
508 R: Try<Output = Acc>,
509 {
510 #[inline]
511 fn flatten<U: Iterator, Acc, R: Try<Output = Acc>>(
512 mut fold: impl FnMut(Acc, U::Item) -> R,
513 ) -> impl FnMut(Acc, &mut U) -> R {
514 move |acc, iter| iter.try_fold(acc, &mut fold)
515 }
516
517 self.iter_try_fold(init, flatten(fold))
518 }
519
520 #[inline]
521 fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
522 where
523 Fold: FnMut(Acc, Self::Item) -> Acc,
524 {
525 #[inline]
526 fn flatten<U: Iterator, Acc>(
527 mut fold: impl FnMut(Acc, U::Item) -> Acc,
528 ) -> impl FnMut(Acc, U) -> Acc {
529 move |acc, iter| iter.fold(acc, &mut fold)
530 }
531
532 self.iter_fold(init, flatten(fold))
533 }
534
535 #[inline]
536 #[rustc_inherit_overflow_checks]
537 fn advance_by(&mut self, n: usize) -> Result<(), usize> {
538 #[inline]
539 #[rustc_inherit_overflow_checks]
540 fn advance<U: Iterator>(n: usize, iter: &mut U) -> ControlFlow<(), usize> {
541 match iter.advance_by(n) {
542 Ok(()) => ControlFlow::BREAK,
543 Err(advanced) => ControlFlow::Continue(n - advanced),
544 }
545 }
546
547 match self.iter_try_fold(n, advance) {
548 ControlFlow::Continue(remaining) if remaining > 0 => Err(n - remaining),
549 _ => Ok(()),
550 }
551 }
552
553 #[inline]
554 fn count(self) -> usize {
555 #[inline]
556 #[rustc_inherit_overflow_checks]
557 fn count<U: Iterator>(acc: usize, iter: U) -> usize {
558 acc + iter.count()
559 }
560
561 self.iter_fold(0, count)
562 }
563
564 #[inline]
565 fn last(self) -> Option<Self::Item> {
566 #[inline]
567 fn last<U: Iterator>(last: Option<U::Item>, iter: U) -> Option<U::Item> {
568 iter.last().or(last)
569 }
570
571 self.iter_fold(None, last)
572 }
573 }
574
575 impl<I, U> DoubleEndedIterator for FlattenCompat<I, U>
576 where
577 I: DoubleEndedIterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
578 U: DoubleEndedIterator,
579 {
580 #[inline]
581 fn next_back(&mut self) -> Option<U::Item> {
582 loop {
583 if let elt @ Some(_) = and_then_or_clear(&mut self.backiter, |b| b.next_back()) {
584 return elt;
585 }
586 match self.iter.next_back() {
587 None => return and_then_or_clear(&mut self.frontiter, |f| f.next_back()),
588 Some(inner) => self.backiter = Some(inner.into_iter()),
589 }
590 }
591 }
592
593 #[inline]
594 fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
595 where
596 Self: Sized,
597 Fold: FnMut(Acc, Self::Item) -> R,
598 R: Try<Output = Acc>,
599 {
600 #[inline]
601 fn flatten<U: DoubleEndedIterator, Acc, R: Try<Output = Acc>>(
602 mut fold: impl FnMut(Acc, U::Item) -> R,
603 ) -> impl FnMut(Acc, &mut U) -> R {
604 move |acc, iter| iter.try_rfold(acc, &mut fold)
605 }
606
607 self.iter_try_rfold(init, flatten(fold))
608 }
609
610 #[inline]
611 fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
612 where
613 Fold: FnMut(Acc, Self::Item) -> Acc,
614 {
615 #[inline]
616 fn flatten<U: DoubleEndedIterator, Acc>(
617 mut fold: impl FnMut(Acc, U::Item) -> Acc,
618 ) -> impl FnMut(Acc, U) -> Acc {
619 move |acc, iter| iter.rfold(acc, &mut fold)
620 }
621
622 self.iter_rfold(init, flatten(fold))
623 }
624
625 #[inline]
626 #[rustc_inherit_overflow_checks]
627 fn advance_back_by(&mut self, n: usize) -> Result<(), usize> {
628 #[inline]
629 #[rustc_inherit_overflow_checks]
630 fn advance<U: DoubleEndedIterator>(n: usize, iter: &mut U) -> ControlFlow<(), usize> {
631 match iter.advance_back_by(n) {
632 Ok(()) => ControlFlow::BREAK,
633 Err(advanced) => ControlFlow::Continue(n - advanced),
634 }
635 }
636
637 match self.iter_try_rfold(n, advance) {
638 ControlFlow::Continue(remaining) if remaining > 0 => Err(n - remaining),
639 _ => Ok(()),
640 }
641 }
642 }
643
644 trait ConstSizeIntoIterator: IntoIterator {
645 // FIXME(#31844): convert to an associated const once specialization supports that
646 fn size() -> Option<usize>;
647 }
648
649 impl<T> ConstSizeIntoIterator for T
650 where
651 T: IntoIterator,
652 {
653 #[inline]
654 default fn size() -> Option<usize> {
655 None
656 }
657 }
658
659 impl<T, const N: usize> ConstSizeIntoIterator for [T; N] {
660 #[inline]
661 fn size() -> Option<usize> {
662 Some(N)
663 }
664 }
665
666 impl<T, const N: usize> ConstSizeIntoIterator for &[T; N] {
667 #[inline]
668 fn size() -> Option<usize> {
669 Some(N)
670 }
671 }
672
673 impl<T, const N: usize> ConstSizeIntoIterator for &mut [T; N] {
674 #[inline]
675 fn size() -> Option<usize> {
676 Some(N)
677 }
678 }
679
680 #[doc(hidden)]
681 #[unstable(feature = "std_internals", issue = "none")]
682 // FIXME(#20400): Instead of this helper trait there should be multiple impl TrustedLen for Flatten<>
683 // blocks with different bounds on Iterator::Item but the compiler erroneously considers them overlapping
684 pub unsafe trait TrustedConstSize: IntoIterator {}
685
686 #[unstable(feature = "std_internals", issue = "none")]
687 unsafe impl<T, const N: usize> TrustedConstSize for [T; N] {}
688 #[unstable(feature = "std_internals", issue = "none")]
689 unsafe impl<T, const N: usize> TrustedConstSize for &'_ [T; N] {}
690 #[unstable(feature = "std_internals", issue = "none")]
691 unsafe impl<T, const N: usize> TrustedConstSize for &'_ mut [T; N] {}
692
693 #[inline]
694 fn and_then_or_clear<T, U>(opt: &mut Option<T>, f: impl FnOnce(&mut T) -> Option<U>) -> Option<U> {
695 let x = f(opt.as_mut()?);
696 if x.is_none() {
697 *opt = None;
698 }
699 x
700 }