]> git.lizzy.rs Git - rust.git/blob - library/core/src/iter/adapters/flatten.rs
Auto merge of #102655 - joboet:windows_tls_opt, r=ChrisDenton
[rust.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 }