core/str/
iter.rs

1//! Iterators for `str` methods.
2
3#[cfg(not(feature = "ferrocene_certified"))]
4use super::pattern::{DoubleEndedSearcher, Pattern, ReverseSearcher, Searcher};
5#[cfg(not(feature = "ferrocene_certified"))]
6use super::validations::{next_code_point, next_code_point_reverse};
7#[cfg(not(feature = "ferrocene_certified"))]
8use super::{
9    BytesIsNotEmpty, CharEscapeDebugContinue, CharEscapeDefault, CharEscapeUnicode,
10    IsAsciiWhitespace, IsNotEmpty, IsWhitespace, LinesMap, UnsafeBytesToStr, from_utf8_unchecked,
11};
12#[cfg(not(feature = "ferrocene_certified"))]
13use crate::fmt::{self, Write};
14#[cfg(not(feature = "ferrocene_certified"))]
15use crate::iter::{
16    Chain, Copied, Filter, FlatMap, Flatten, FusedIterator, Map, TrustedLen, TrustedRandomAccess,
17    TrustedRandomAccessNoCoerce,
18};
19use crate::num::NonZero;
20#[cfg(not(feature = "ferrocene_certified"))]
21use crate::ops::Try;
22#[cfg(not(feature = "ferrocene_certified"))]
23use crate::slice::{self, Split as SliceSplit};
24#[cfg(not(feature = "ferrocene_certified"))]
25use crate::{char as char_mod, option};
26
27// Ferrocene addition: imports for certified subset
28#[cfg(feature = "ferrocene_certified")]
29#[rustfmt::skip]
30use {super::validations::next_code_point, crate::slice};
31
32/// An iterator over the [`char`]s of a string slice.
33///
34///
35/// This struct is created by the [`chars`] method on [`str`].
36/// See its documentation for more.
37///
38/// [`char`]: prim@char
39/// [`chars`]: str::chars
40#[cfg_attr(not(feature = "ferrocene_certified"), derive(Clone))]
41#[must_use = "iterators are lazy and do nothing unless consumed"]
42#[stable(feature = "rust1", since = "1.0.0")]
43pub struct Chars<'a> {
44    pub(super) iter: slice::Iter<'a, u8>,
45}
46
47#[stable(feature = "rust1", since = "1.0.0")]
48impl<'a> Iterator for Chars<'a> {
49    type Item = char;
50
51    #[inline]
52    fn next(&mut self) -> Option<char> {
53        // SAFETY: `str` invariant says `self.iter` is a valid UTF-8 string and
54        // the resulting `ch` is a valid Unicode Scalar Value.
55        unsafe { next_code_point(&mut self.iter).map(|ch| char::from_u32_unchecked(ch)) }
56    }
57
58    #[cfg(not(feature = "ferrocene_certified"))]
59    #[inline]
60    fn count(self) -> usize {
61        super::count::count_chars(self.as_str())
62    }
63
64    #[inline]
65    fn advance_by(&mut self, mut remainder: usize) -> Result<(), NonZero<usize>> {
66        const CHUNK_SIZE: usize = 32;
67
68        if remainder >= CHUNK_SIZE {
69            let mut chunks = self.iter.as_slice().as_chunks::<CHUNK_SIZE>().0.iter();
70            let mut bytes_skipped: usize = 0;
71
72            while remainder > CHUNK_SIZE
73                && let Some(chunk) = chunks.next()
74            {
75                bytes_skipped += CHUNK_SIZE;
76
77                let mut start_bytes = [false; CHUNK_SIZE];
78
79                for i in 0..CHUNK_SIZE {
80                    start_bytes[i] = !super::validations::utf8_is_cont_byte(chunk[i]);
81                }
82
83                remainder -= start_bytes.into_iter().map(|i| i as u8).sum::<u8>() as usize;
84            }
85
86            // SAFETY: The amount of bytes exists since we just iterated over them,
87            // so advance_by will succeed.
88            unsafe { self.iter.advance_by(bytes_skipped).unwrap_unchecked() };
89
90            // skip trailing continuation bytes
91            while self.iter.len() > 0 {
92                let b = self.iter.as_slice()[0];
93                if !super::validations::utf8_is_cont_byte(b) {
94                    break;
95                }
96                // SAFETY: We just peeked at the byte, therefore it exists
97                unsafe { self.iter.advance_by(1).unwrap_unchecked() };
98            }
99        }
100
101        while (remainder > 0) && (self.iter.len() > 0) {
102            remainder -= 1;
103            let b = self.iter.as_slice()[0];
104            let slurp = super::validations::utf8_char_width(b);
105            // SAFETY: utf8 validity requires that the string must contain
106            // the continuation bytes (if any)
107            unsafe { self.iter.advance_by(slurp).unwrap_unchecked() };
108        }
109
110        NonZero::new(remainder).map_or(Ok(()), Err)
111    }
112
113    #[inline]
114    fn size_hint(&self) -> (usize, Option<usize>) {
115        let len = self.iter.len();
116        // `(len + 3)` can't overflow, because we know that the `slice::Iter`
117        // belongs to a slice in memory which has a maximum length of
118        // `isize::MAX` (that's well below `usize::MAX`).
119        (len.div_ceil(4), Some(len))
120    }
121
122    #[cfg(not(feature = "ferrocene_certified"))]
123    #[inline]
124    fn last(mut self) -> Option<char> {
125        // No need to go through the entire string.
126        self.next_back()
127    }
128}
129
130#[cfg(not(feature = "ferrocene_certified"))]
131#[stable(feature = "chars_debug_impl", since = "1.38.0")]
132impl fmt::Debug for Chars<'_> {
133    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
134        write!(f, "Chars(")?;
135        f.debug_list().entries(self.clone()).finish()?;
136        write!(f, ")")?;
137        Ok(())
138    }
139}
140
141#[cfg(not(feature = "ferrocene_certified"))]
142#[stable(feature = "rust1", since = "1.0.0")]
143impl<'a> DoubleEndedIterator for Chars<'a> {
144    #[inline]
145    fn next_back(&mut self) -> Option<char> {
146        // SAFETY: `str` invariant says `self.iter` is a valid UTF-8 string and
147        // the resulting `ch` is a valid Unicode Scalar Value.
148        unsafe { next_code_point_reverse(&mut self.iter).map(|ch| char::from_u32_unchecked(ch)) }
149    }
150}
151
152#[cfg(not(feature = "ferrocene_certified"))]
153#[stable(feature = "fused", since = "1.26.0")]
154impl FusedIterator for Chars<'_> {}
155
156#[cfg(not(feature = "ferrocene_certified"))]
157impl<'a> Chars<'a> {
158    /// Views the underlying data as a subslice of the original data.
159    ///
160    /// This has the same lifetime as the original slice, and so the
161    /// iterator can continue to be used while this exists.
162    ///
163    /// # Examples
164    ///
165    /// ```
166    /// let mut chars = "abc".chars();
167    ///
168    /// assert_eq!(chars.as_str(), "abc");
169    /// chars.next();
170    /// assert_eq!(chars.as_str(), "bc");
171    /// chars.next();
172    /// chars.next();
173    /// assert_eq!(chars.as_str(), "");
174    /// ```
175    #[stable(feature = "iter_to_slice", since = "1.4.0")]
176    #[must_use]
177    #[inline]
178    pub fn as_str(&self) -> &'a str {
179        // SAFETY: `Chars` is only made from a str, which guarantees the iter is valid UTF-8.
180        unsafe { from_utf8_unchecked(self.iter.as_slice()) }
181    }
182}
183
184/// An iterator over the [`char`]s of a string slice, and their positions.
185///
186/// This struct is created by the [`char_indices`] method on [`str`].
187/// See its documentation for more.
188///
189/// [`char`]: prim@char
190/// [`char_indices`]: str::char_indices
191#[cfg(not(feature = "ferrocene_certified"))]
192#[derive(Clone, Debug)]
193#[must_use = "iterators are lazy and do nothing unless consumed"]
194#[stable(feature = "rust1", since = "1.0.0")]
195pub struct CharIndices<'a> {
196    pub(super) front_offset: usize,
197    pub(super) iter: Chars<'a>,
198}
199
200#[cfg(not(feature = "ferrocene_certified"))]
201#[stable(feature = "rust1", since = "1.0.0")]
202impl<'a> Iterator for CharIndices<'a> {
203    type Item = (usize, char);
204
205    #[inline]
206    fn next(&mut self) -> Option<(usize, char)> {
207        let pre_len = self.iter.iter.len();
208        match self.iter.next() {
209            None => None,
210            Some(ch) => {
211                let index = self.front_offset;
212                let len = self.iter.iter.len();
213                self.front_offset += pre_len - len;
214                Some((index, ch))
215            }
216        }
217    }
218
219    #[inline]
220    fn count(self) -> usize {
221        self.iter.count()
222    }
223
224    #[inline]
225    fn size_hint(&self) -> (usize, Option<usize>) {
226        self.iter.size_hint()
227    }
228
229    #[inline]
230    fn last(mut self) -> Option<(usize, char)> {
231        // No need to go through the entire string.
232        self.next_back()
233    }
234}
235
236#[cfg(not(feature = "ferrocene_certified"))]
237#[stable(feature = "rust1", since = "1.0.0")]
238impl<'a> DoubleEndedIterator for CharIndices<'a> {
239    #[inline]
240    fn next_back(&mut self) -> Option<(usize, char)> {
241        self.iter.next_back().map(|ch| {
242            let index = self.front_offset + self.iter.iter.len();
243            (index, ch)
244        })
245    }
246}
247
248#[cfg(not(feature = "ferrocene_certified"))]
249#[stable(feature = "fused", since = "1.26.0")]
250impl FusedIterator for CharIndices<'_> {}
251
252#[cfg(not(feature = "ferrocene_certified"))]
253impl<'a> CharIndices<'a> {
254    /// Views the underlying data as a subslice of the original data.
255    ///
256    /// This has the same lifetime as the original slice, and so the
257    /// iterator can continue to be used while this exists.
258    #[stable(feature = "iter_to_slice", since = "1.4.0")]
259    #[must_use]
260    #[inline]
261    pub fn as_str(&self) -> &'a str {
262        self.iter.as_str()
263    }
264
265    /// Returns the byte position of the next character, or the length
266    /// of the underlying string if there are no more characters.
267    ///
268    /// This means that, when the iterator has not been fully consumed,
269    /// the returned value will match the index that will be returned
270    /// by the next call to [`next()`](Self::next).
271    ///
272    /// # Examples
273    ///
274    /// ```
275    /// let mut chars = "a楽".char_indices();
276    ///
277    /// // `next()` has not been called yet, so `offset()` returns the byte
278    /// // index of the first character of the string, which is always 0.
279    /// assert_eq!(chars.offset(), 0);
280    /// // As expected, the first call to `next()` also returns 0 as index.
281    /// assert_eq!(chars.next(), Some((0, 'a')));
282    ///
283    /// // `next()` has been called once, so `offset()` returns the byte index
284    /// // of the second character ...
285    /// assert_eq!(chars.offset(), 1);
286    /// // ... which matches the index returned by the next call to `next()`.
287    /// assert_eq!(chars.next(), Some((1, '楽')));
288    ///
289    /// // Once the iterator has been consumed, `offset()` returns the length
290    /// // in bytes of the string.
291    /// assert_eq!(chars.offset(), 4);
292    /// assert_eq!(chars.next(), None);
293    /// ```
294    #[inline]
295    #[must_use]
296    #[stable(feature = "char_indices_offset", since = "1.82.0")]
297    pub fn offset(&self) -> usize {
298        self.front_offset
299    }
300}
301
302/// An iterator over the bytes of a string slice.
303///
304/// This struct is created by the [`bytes`] method on [`str`].
305/// See its documentation for more.
306///
307/// [`bytes`]: str::bytes
308#[cfg(not(feature = "ferrocene_certified"))]
309#[must_use = "iterators are lazy and do nothing unless consumed"]
310#[stable(feature = "rust1", since = "1.0.0")]
311#[derive(Clone, Debug)]
312pub struct Bytes<'a>(pub(super) Copied<slice::Iter<'a, u8>>);
313
314#[cfg(not(feature = "ferrocene_certified"))]
315#[stable(feature = "rust1", since = "1.0.0")]
316impl Iterator for Bytes<'_> {
317    type Item = u8;
318
319    #[inline]
320    fn next(&mut self) -> Option<u8> {
321        self.0.next()
322    }
323
324    #[inline]
325    fn size_hint(&self) -> (usize, Option<usize>) {
326        self.0.size_hint()
327    }
328
329    #[inline]
330    fn count(self) -> usize {
331        self.0.count()
332    }
333
334    #[inline]
335    fn last(self) -> Option<Self::Item> {
336        self.0.last()
337    }
338
339    #[inline]
340    fn nth(&mut self, n: usize) -> Option<Self::Item> {
341        self.0.nth(n)
342    }
343
344    #[inline]
345    fn all<F>(&mut self, f: F) -> bool
346    where
347        F: FnMut(Self::Item) -> bool,
348    {
349        self.0.all(f)
350    }
351
352    #[inline]
353    fn any<F>(&mut self, f: F) -> bool
354    where
355        F: FnMut(Self::Item) -> bool,
356    {
357        self.0.any(f)
358    }
359
360    #[inline]
361    fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
362    where
363        P: FnMut(&Self::Item) -> bool,
364    {
365        self.0.find(predicate)
366    }
367
368    #[inline]
369    fn position<P>(&mut self, predicate: P) -> Option<usize>
370    where
371        P: FnMut(Self::Item) -> bool,
372    {
373        self.0.position(predicate)
374    }
375
376    #[inline]
377    fn rposition<P>(&mut self, predicate: P) -> Option<usize>
378    where
379        P: FnMut(Self::Item) -> bool,
380    {
381        self.0.rposition(predicate)
382    }
383
384    #[inline]
385    unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> u8 {
386        // SAFETY: the caller must uphold the safety contract
387        // for `Iterator::__iterator_get_unchecked`.
388        unsafe { self.0.__iterator_get_unchecked(idx) }
389    }
390}
391
392#[cfg(not(feature = "ferrocene_certified"))]
393#[stable(feature = "rust1", since = "1.0.0")]
394impl DoubleEndedIterator for Bytes<'_> {
395    #[inline]
396    fn next_back(&mut self) -> Option<u8> {
397        self.0.next_back()
398    }
399
400    #[inline]
401    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
402        self.0.nth_back(n)
403    }
404
405    #[inline]
406    fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
407    where
408        P: FnMut(&Self::Item) -> bool,
409    {
410        self.0.rfind(predicate)
411    }
412}
413
414#[cfg(not(feature = "ferrocene_certified"))]
415#[stable(feature = "rust1", since = "1.0.0")]
416impl ExactSizeIterator for Bytes<'_> {
417    #[inline]
418    fn len(&self) -> usize {
419        self.0.len()
420    }
421
422    #[inline]
423    fn is_empty(&self) -> bool {
424        self.0.is_empty()
425    }
426}
427
428#[cfg(not(feature = "ferrocene_certified"))]
429#[stable(feature = "fused", since = "1.26.0")]
430impl FusedIterator for Bytes<'_> {}
431
432#[cfg(not(feature = "ferrocene_certified"))]
433#[unstable(feature = "trusted_len", issue = "37572")]
434unsafe impl TrustedLen for Bytes<'_> {}
435
436#[cfg(not(feature = "ferrocene_certified"))]
437#[doc(hidden)]
438#[unstable(feature = "trusted_random_access", issue = "none")]
439unsafe impl TrustedRandomAccess for Bytes<'_> {}
440
441#[cfg(not(feature = "ferrocene_certified"))]
442#[doc(hidden)]
443#[unstable(feature = "trusted_random_access", issue = "none")]
444unsafe impl TrustedRandomAccessNoCoerce for Bytes<'_> {
445    const MAY_HAVE_SIDE_EFFECT: bool = false;
446}
447
448/// This macro generates a Clone impl for string pattern API
449/// wrapper types of the form X<'a, P>
450#[cfg(not(feature = "ferrocene_certified"))]
451macro_rules! derive_pattern_clone {
452    (clone $t:ident with |$s:ident| $e:expr) => {
453        impl<'a, P> Clone for $t<'a, P>
454        where
455            P: Pattern<Searcher<'a>: Clone>,
456        {
457            fn clone(&self) -> Self {
458                let $s = self;
459                $e
460            }
461        }
462    };
463}
464
465/// This macro generates two public iterator structs
466/// wrapping a private internal one that makes use of the `Pattern` API.
467///
468/// For all patterns `P: Pattern` the following items will be
469/// generated (generics omitted):
470///
471/// struct $forward_iterator($internal_iterator);
472/// struct $reverse_iterator($internal_iterator);
473///
474/// impl Iterator for $forward_iterator
475/// { /* internal ends up calling Searcher::next_match() */ }
476///
477/// impl DoubleEndedIterator for $forward_iterator
478///       where P::Searcher: DoubleEndedSearcher
479/// { /* internal ends up calling Searcher::next_match_back() */ }
480///
481/// impl Iterator for $reverse_iterator
482///       where P::Searcher: ReverseSearcher
483/// { /* internal ends up calling Searcher::next_match_back() */ }
484///
485/// impl DoubleEndedIterator for $reverse_iterator
486///       where P::Searcher: DoubleEndedSearcher
487/// { /* internal ends up calling Searcher::next_match() */ }
488///
489/// The internal one is defined outside the macro, and has almost the same
490/// semantic as a DoubleEndedIterator by delegating to `pattern::Searcher` and
491/// `pattern::ReverseSearcher` for both forward and reverse iteration.
492///
493/// "Almost", because a `Searcher` and a `ReverseSearcher` for a given
494/// `Pattern` might not return the same elements, so actually implementing
495/// `DoubleEndedIterator` for it would be incorrect.
496/// (See the docs in `str::pattern` for more details)
497///
498/// However, the internal struct still represents a single ended iterator from
499/// either end, and depending on pattern is also a valid double ended iterator,
500/// so the two wrapper structs implement `Iterator`
501/// and `DoubleEndedIterator` depending on the concrete pattern type, leading
502/// to the complex impls seen above.
503#[cfg(not(feature = "ferrocene_certified"))]
504macro_rules! generate_pattern_iterators {
505    {
506        // Forward iterator
507        forward:
508            $(#[$forward_iterator_attribute:meta])*
509            struct $forward_iterator:ident;
510
511        // Reverse iterator
512        reverse:
513            $(#[$reverse_iterator_attribute:meta])*
514            struct $reverse_iterator:ident;
515
516        // Stability of all generated items
517        stability:
518            $(#[$common_stability_attribute:meta])*
519
520        // Internal almost-iterator that is being delegated to
521        internal:
522            $internal_iterator:ident yielding ($iterty:ty);
523
524        // Kind of delegation - either single ended or double ended
525        delegate $($t:tt)*
526    } => {
527        $(#[$forward_iterator_attribute])*
528        $(#[$common_stability_attribute])*
529        pub struct $forward_iterator<'a, P: Pattern>(pub(super) $internal_iterator<'a, P>);
530
531        $(#[$common_stability_attribute])*
532        impl<'a, P> fmt::Debug for $forward_iterator<'a, P>
533        where
534            P: Pattern<Searcher<'a>: fmt::Debug>,
535        {
536            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
537                f.debug_tuple(stringify!($forward_iterator))
538                    .field(&self.0)
539                    .finish()
540            }
541        }
542
543        $(#[$common_stability_attribute])*
544        impl<'a, P: Pattern> Iterator for $forward_iterator<'a, P> {
545            type Item = $iterty;
546
547            #[inline]
548            fn next(&mut self) -> Option<$iterty> {
549                self.0.next()
550            }
551        }
552
553        $(#[$common_stability_attribute])*
554        impl<'a, P> Clone for $forward_iterator<'a, P>
555        where
556            P: Pattern<Searcher<'a>: Clone>,
557        {
558            fn clone(&self) -> Self {
559                $forward_iterator(self.0.clone())
560            }
561        }
562
563        $(#[$reverse_iterator_attribute])*
564        $(#[$common_stability_attribute])*
565        pub struct $reverse_iterator<'a, P: Pattern>(pub(super) $internal_iterator<'a, P>);
566
567        $(#[$common_stability_attribute])*
568        impl<'a, P> fmt::Debug for $reverse_iterator<'a, P>
569        where
570            P: Pattern<Searcher<'a>: fmt::Debug>,
571        {
572            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
573                f.debug_tuple(stringify!($reverse_iterator))
574                    .field(&self.0)
575                    .finish()
576            }
577        }
578
579        $(#[$common_stability_attribute])*
580        impl<'a, P> Iterator for $reverse_iterator<'a, P>
581        where
582            P: Pattern<Searcher<'a>: ReverseSearcher<'a>>,
583        {
584            type Item = $iterty;
585
586            #[inline]
587            fn next(&mut self) -> Option<$iterty> {
588                self.0.next_back()
589            }
590        }
591
592        $(#[$common_stability_attribute])*
593        impl<'a, P> Clone for $reverse_iterator<'a, P>
594        where
595            P: Pattern<Searcher<'a>: Clone>,
596        {
597            fn clone(&self) -> Self {
598                $reverse_iterator(self.0.clone())
599            }
600        }
601
602        #[stable(feature = "fused", since = "1.26.0")]
603        impl<'a, P: Pattern> FusedIterator for $forward_iterator<'a, P> {}
604
605        #[stable(feature = "fused", since = "1.26.0")]
606        impl<'a, P> FusedIterator for $reverse_iterator<'a, P>
607        where
608            P: Pattern<Searcher<'a>: ReverseSearcher<'a>>,
609        {}
610
611        generate_pattern_iterators!($($t)* with $(#[$common_stability_attribute])*,
612                                                $forward_iterator,
613                                                $reverse_iterator, $iterty);
614    };
615    {
616        double ended; with $(#[$common_stability_attribute:meta])*,
617                           $forward_iterator:ident,
618                           $reverse_iterator:ident, $iterty:ty
619    } => {
620        $(#[$common_stability_attribute])*
621        impl<'a, P> DoubleEndedIterator for $forward_iterator<'a, P>
622        where
623            P: Pattern<Searcher<'a>: DoubleEndedSearcher<'a>>,
624        {
625            #[inline]
626            fn next_back(&mut self) -> Option<$iterty> {
627                self.0.next_back()
628            }
629        }
630
631        $(#[$common_stability_attribute])*
632        impl<'a, P> DoubleEndedIterator for $reverse_iterator<'a, P>
633        where
634            P: Pattern<Searcher<'a>: DoubleEndedSearcher<'a>>,
635        {
636            #[inline]
637            fn next_back(&mut self) -> Option<$iterty> {
638                self.0.next()
639            }
640        }
641    };
642    {
643        single ended; with $(#[$common_stability_attribute:meta])*,
644                           $forward_iterator:ident,
645                           $reverse_iterator:ident, $iterty:ty
646    } => {}
647}
648
649#[cfg(not(feature = "ferrocene_certified"))]
650derive_pattern_clone! {
651    clone SplitInternal
652    with |s| SplitInternal { matcher: s.matcher.clone(), ..*s }
653}
654
655#[cfg(not(feature = "ferrocene_certified"))]
656pub(super) struct SplitInternal<'a, P: Pattern> {
657    pub(super) start: usize,
658    pub(super) end: usize,
659    pub(super) matcher: P::Searcher<'a>,
660    pub(super) allow_trailing_empty: bool,
661    pub(super) finished: bool,
662}
663
664#[cfg(not(feature = "ferrocene_certified"))]
665impl<'a, P> fmt::Debug for SplitInternal<'a, P>
666where
667    P: Pattern<Searcher<'a>: fmt::Debug>,
668{
669    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
670        f.debug_struct("SplitInternal")
671            .field("start", &self.start)
672            .field("end", &self.end)
673            .field("matcher", &self.matcher)
674            .field("allow_trailing_empty", &self.allow_trailing_empty)
675            .field("finished", &self.finished)
676            .finish()
677    }
678}
679
680#[cfg(not(feature = "ferrocene_certified"))]
681impl<'a, P: Pattern> SplitInternal<'a, P> {
682    #[inline]
683    fn get_end(&mut self) -> Option<&'a str> {
684        if !self.finished {
685            self.finished = true;
686
687            if self.allow_trailing_empty || self.end - self.start > 0 {
688                // SAFETY: `self.start` and `self.end` always lie on unicode boundaries.
689                let string = unsafe { self.matcher.haystack().get_unchecked(self.start..self.end) };
690                return Some(string);
691            }
692        }
693
694        None
695    }
696
697    #[inline]
698    fn next(&mut self) -> Option<&'a str> {
699        if self.finished {
700            return None;
701        }
702
703        let haystack = self.matcher.haystack();
704        match self.matcher.next_match() {
705            // SAFETY: `Searcher` guarantees that `a` and `b` lie on unicode boundaries.
706            Some((a, b)) => unsafe {
707                let elt = haystack.get_unchecked(self.start..a);
708                self.start = b;
709                Some(elt)
710            },
711            None => self.get_end(),
712        }
713    }
714
715    #[inline]
716    fn next_inclusive(&mut self) -> Option<&'a str> {
717        if self.finished {
718            return None;
719        }
720
721        let haystack = self.matcher.haystack();
722        match self.matcher.next_match() {
723            // SAFETY: `Searcher` guarantees that `b` lies on unicode boundary,
724            // and self.start is either the start of the original string,
725            // or `b` was assigned to it, so it also lies on unicode boundary.
726            Some((_, b)) => unsafe {
727                let elt = haystack.get_unchecked(self.start..b);
728                self.start = b;
729                Some(elt)
730            },
731            None => self.get_end(),
732        }
733    }
734
735    #[inline]
736    fn next_back(&mut self) -> Option<&'a str>
737    where
738        P::Searcher<'a>: ReverseSearcher<'a>,
739    {
740        if self.finished {
741            return None;
742        }
743
744        if !self.allow_trailing_empty {
745            self.allow_trailing_empty = true;
746            match self.next_back() {
747                Some(elt) if !elt.is_empty() => return Some(elt),
748                _ => {
749                    if self.finished {
750                        return None;
751                    }
752                }
753            }
754        }
755
756        let haystack = self.matcher.haystack();
757        match self.matcher.next_match_back() {
758            // SAFETY: `Searcher` guarantees that `a` and `b` lie on unicode boundaries.
759            Some((a, b)) => unsafe {
760                let elt = haystack.get_unchecked(b..self.end);
761                self.end = a;
762                Some(elt)
763            },
764            // SAFETY: `self.start` and `self.end` always lie on unicode boundaries.
765            None => unsafe {
766                self.finished = true;
767                Some(haystack.get_unchecked(self.start..self.end))
768            },
769        }
770    }
771
772    #[inline]
773    fn next_back_inclusive(&mut self) -> Option<&'a str>
774    where
775        P::Searcher<'a>: ReverseSearcher<'a>,
776    {
777        if self.finished {
778            return None;
779        }
780
781        if !self.allow_trailing_empty {
782            self.allow_trailing_empty = true;
783            match self.next_back_inclusive() {
784                Some(elt) if !elt.is_empty() => return Some(elt),
785                _ => {
786                    if self.finished {
787                        return None;
788                    }
789                }
790            }
791        }
792
793        let haystack = self.matcher.haystack();
794        match self.matcher.next_match_back() {
795            // SAFETY: `Searcher` guarantees that `b` lies on unicode boundary,
796            // and self.end is either the end of the original string,
797            // or `b` was assigned to it, so it also lies on unicode boundary.
798            Some((_, b)) => unsafe {
799                let elt = haystack.get_unchecked(b..self.end);
800                self.end = b;
801                Some(elt)
802            },
803            // SAFETY: self.start is either the start of the original string,
804            // or start of a substring that represents the part of the string that hasn't
805            // iterated yet. Either way, it is guaranteed to lie on unicode boundary.
806            // self.end is either the end of the original string,
807            // or `b` was assigned to it, so it also lies on unicode boundary.
808            None => unsafe {
809                self.finished = true;
810                Some(haystack.get_unchecked(self.start..self.end))
811            },
812        }
813    }
814
815    #[inline]
816    fn remainder(&self) -> Option<&'a str> {
817        // `Self::get_end` doesn't change `self.start`
818        if self.finished {
819            return None;
820        }
821
822        // SAFETY: `self.start` and `self.end` always lie on unicode boundaries.
823        Some(unsafe { self.matcher.haystack().get_unchecked(self.start..self.end) })
824    }
825}
826
827#[cfg(not(feature = "ferrocene_certified"))]
828generate_pattern_iterators! {
829    forward:
830        /// Created with the method [`split`].
831        ///
832        /// [`split`]: str::split
833        struct Split;
834    reverse:
835        /// Created with the method [`rsplit`].
836        ///
837        /// [`rsplit`]: str::rsplit
838        struct RSplit;
839    stability:
840        #[stable(feature = "rust1", since = "1.0.0")]
841    internal:
842        SplitInternal yielding (&'a str);
843    delegate double ended;
844}
845
846#[cfg(not(feature = "ferrocene_certified"))]
847impl<'a, P: Pattern> Split<'a, P> {
848    /// Returns remainder of the split string.
849    ///
850    /// If the iterator is empty, returns `None`.
851    ///
852    /// # Examples
853    ///
854    /// ```
855    /// #![feature(str_split_remainder)]
856    /// let mut split = "Mary had a little lamb".split(' ');
857    /// assert_eq!(split.remainder(), Some("Mary had a little lamb"));
858    /// split.next();
859    /// assert_eq!(split.remainder(), Some("had a little lamb"));
860    /// split.by_ref().for_each(drop);
861    /// assert_eq!(split.remainder(), None);
862    /// ```
863    #[inline]
864    #[unstable(feature = "str_split_remainder", issue = "77998")]
865    pub fn remainder(&self) -> Option<&'a str> {
866        self.0.remainder()
867    }
868}
869
870#[cfg(not(feature = "ferrocene_certified"))]
871impl<'a, P: Pattern> RSplit<'a, P> {
872    /// Returns remainder of the split string.
873    ///
874    /// If the iterator is empty, returns `None`.
875    ///
876    /// # Examples
877    ///
878    /// ```
879    /// #![feature(str_split_remainder)]
880    /// let mut split = "Mary had a little lamb".rsplit(' ');
881    /// assert_eq!(split.remainder(), Some("Mary had a little lamb"));
882    /// split.next();
883    /// assert_eq!(split.remainder(), Some("Mary had a little"));
884    /// split.by_ref().for_each(drop);
885    /// assert_eq!(split.remainder(), None);
886    /// ```
887    #[inline]
888    #[unstable(feature = "str_split_remainder", issue = "77998")]
889    pub fn remainder(&self) -> Option<&'a str> {
890        self.0.remainder()
891    }
892}
893
894#[cfg(not(feature = "ferrocene_certified"))]
895generate_pattern_iterators! {
896    forward:
897        /// Created with the method [`split_terminator`].
898        ///
899        /// [`split_terminator`]: str::split_terminator
900        struct SplitTerminator;
901    reverse:
902        /// Created with the method [`rsplit_terminator`].
903        ///
904        /// [`rsplit_terminator`]: str::rsplit_terminator
905        struct RSplitTerminator;
906    stability:
907        #[stable(feature = "rust1", since = "1.0.0")]
908    internal:
909        SplitInternal yielding (&'a str);
910    delegate double ended;
911}
912
913#[cfg(not(feature = "ferrocene_certified"))]
914impl<'a, P: Pattern> SplitTerminator<'a, P> {
915    /// Returns remainder of the split string.
916    ///
917    /// If the iterator is empty, returns `None`.
918    ///
919    /// # Examples
920    ///
921    /// ```
922    /// #![feature(str_split_remainder)]
923    /// let mut split = "A..B..".split_terminator('.');
924    /// assert_eq!(split.remainder(), Some("A..B.."));
925    /// split.next();
926    /// assert_eq!(split.remainder(), Some(".B.."));
927    /// split.by_ref().for_each(drop);
928    /// assert_eq!(split.remainder(), None);
929    /// ```
930    #[inline]
931    #[unstable(feature = "str_split_remainder", issue = "77998")]
932    pub fn remainder(&self) -> Option<&'a str> {
933        self.0.remainder()
934    }
935}
936
937#[cfg(not(feature = "ferrocene_certified"))]
938impl<'a, P: Pattern> RSplitTerminator<'a, P> {
939    /// Returns remainder of the split string.
940    ///
941    /// If the iterator is empty, returns `None`.
942    ///
943    /// # Examples
944    ///
945    /// ```
946    /// #![feature(str_split_remainder)]
947    /// let mut split = "A..B..".rsplit_terminator('.');
948    /// assert_eq!(split.remainder(), Some("A..B.."));
949    /// split.next();
950    /// assert_eq!(split.remainder(), Some("A..B"));
951    /// split.by_ref().for_each(drop);
952    /// assert_eq!(split.remainder(), None);
953    /// ```
954    #[inline]
955    #[unstable(feature = "str_split_remainder", issue = "77998")]
956    pub fn remainder(&self) -> Option<&'a str> {
957        self.0.remainder()
958    }
959}
960
961#[cfg(not(feature = "ferrocene_certified"))]
962derive_pattern_clone! {
963    clone SplitNInternal
964    with |s| SplitNInternal { iter: s.iter.clone(), ..*s }
965}
966
967#[cfg(not(feature = "ferrocene_certified"))]
968pub(super) struct SplitNInternal<'a, P: Pattern> {
969    pub(super) iter: SplitInternal<'a, P>,
970    /// The number of splits remaining
971    pub(super) count: usize,
972}
973
974#[cfg(not(feature = "ferrocene_certified"))]
975impl<'a, P> fmt::Debug for SplitNInternal<'a, P>
976where
977    P: Pattern<Searcher<'a>: fmt::Debug>,
978{
979    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
980        f.debug_struct("SplitNInternal")
981            .field("iter", &self.iter)
982            .field("count", &self.count)
983            .finish()
984    }
985}
986
987#[cfg(not(feature = "ferrocene_certified"))]
988impl<'a, P: Pattern> SplitNInternal<'a, P> {
989    #[inline]
990    fn next(&mut self) -> Option<&'a str> {
991        match self.count {
992            0 => None,
993            1 => {
994                self.count = 0;
995                self.iter.get_end()
996            }
997            _ => {
998                self.count -= 1;
999                self.iter.next()
1000            }
1001        }
1002    }
1003
1004    #[inline]
1005    fn next_back(&mut self) -> Option<&'a str>
1006    where
1007        P::Searcher<'a>: ReverseSearcher<'a>,
1008    {
1009        match self.count {
1010            0 => None,
1011            1 => {
1012                self.count = 0;
1013                self.iter.get_end()
1014            }
1015            _ => {
1016                self.count -= 1;
1017                self.iter.next_back()
1018            }
1019        }
1020    }
1021
1022    #[inline]
1023    fn remainder(&self) -> Option<&'a str> {
1024        self.iter.remainder()
1025    }
1026}
1027
1028#[cfg(not(feature = "ferrocene_certified"))]
1029generate_pattern_iterators! {
1030    forward:
1031        /// Created with the method [`splitn`].
1032        ///
1033        /// [`splitn`]: str::splitn
1034        struct SplitN;
1035    reverse:
1036        /// Created with the method [`rsplitn`].
1037        ///
1038        /// [`rsplitn`]: str::rsplitn
1039        struct RSplitN;
1040    stability:
1041        #[stable(feature = "rust1", since = "1.0.0")]
1042    internal:
1043        SplitNInternal yielding (&'a str);
1044    delegate single ended;
1045}
1046
1047#[cfg(not(feature = "ferrocene_certified"))]
1048impl<'a, P: Pattern> SplitN<'a, P> {
1049    /// Returns remainder of the split string.
1050    ///
1051    /// If the iterator is empty, returns `None`.
1052    ///
1053    /// # Examples
1054    ///
1055    /// ```
1056    /// #![feature(str_split_remainder)]
1057    /// let mut split = "Mary had a little lamb".splitn(3, ' ');
1058    /// assert_eq!(split.remainder(), Some("Mary had a little lamb"));
1059    /// split.next();
1060    /// assert_eq!(split.remainder(), Some("had a little lamb"));
1061    /// split.by_ref().for_each(drop);
1062    /// assert_eq!(split.remainder(), None);
1063    /// ```
1064    #[inline]
1065    #[unstable(feature = "str_split_remainder", issue = "77998")]
1066    pub fn remainder(&self) -> Option<&'a str> {
1067        self.0.remainder()
1068    }
1069}
1070
1071#[cfg(not(feature = "ferrocene_certified"))]
1072impl<'a, P: Pattern> RSplitN<'a, P> {
1073    /// Returns remainder of the split string.
1074    ///
1075    /// If the iterator is empty, returns `None`.
1076    ///
1077    /// # Examples
1078    ///
1079    /// ```
1080    /// #![feature(str_split_remainder)]
1081    /// let mut split = "Mary had a little lamb".rsplitn(3, ' ');
1082    /// assert_eq!(split.remainder(), Some("Mary had a little lamb"));
1083    /// split.next();
1084    /// assert_eq!(split.remainder(), Some("Mary had a little"));
1085    /// split.by_ref().for_each(drop);
1086    /// assert_eq!(split.remainder(), None);
1087    /// ```
1088    #[inline]
1089    #[unstable(feature = "str_split_remainder", issue = "77998")]
1090    pub fn remainder(&self) -> Option<&'a str> {
1091        self.0.remainder()
1092    }
1093}
1094
1095#[cfg(not(feature = "ferrocene_certified"))]
1096derive_pattern_clone! {
1097    clone MatchIndicesInternal
1098    with |s| MatchIndicesInternal(s.0.clone())
1099}
1100
1101#[cfg(not(feature = "ferrocene_certified"))]
1102pub(super) struct MatchIndicesInternal<'a, P: Pattern>(pub(super) P::Searcher<'a>);
1103
1104#[cfg(not(feature = "ferrocene_certified"))]
1105impl<'a, P> fmt::Debug for MatchIndicesInternal<'a, P>
1106where
1107    P: Pattern<Searcher<'a>: fmt::Debug>,
1108{
1109    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1110        f.debug_tuple("MatchIndicesInternal").field(&self.0).finish()
1111    }
1112}
1113
1114#[cfg(not(feature = "ferrocene_certified"))]
1115impl<'a, P: Pattern> MatchIndicesInternal<'a, P> {
1116    #[inline]
1117    fn next(&mut self) -> Option<(usize, &'a str)> {
1118        self.0
1119            .next_match()
1120            // SAFETY: `Searcher` guarantees that `start` and `end` lie on unicode boundaries.
1121            .map(|(start, end)| unsafe { (start, self.0.haystack().get_unchecked(start..end)) })
1122    }
1123
1124    #[inline]
1125    fn next_back(&mut self) -> Option<(usize, &'a str)>
1126    where
1127        P::Searcher<'a>: ReverseSearcher<'a>,
1128    {
1129        self.0
1130            .next_match_back()
1131            // SAFETY: `Searcher` guarantees that `start` and `end` lie on unicode boundaries.
1132            .map(|(start, end)| unsafe { (start, self.0.haystack().get_unchecked(start..end)) })
1133    }
1134}
1135
1136#[cfg(not(feature = "ferrocene_certified"))]
1137generate_pattern_iterators! {
1138    forward:
1139        /// Created with the method [`match_indices`].
1140        ///
1141        /// [`match_indices`]: str::match_indices
1142        struct MatchIndices;
1143    reverse:
1144        /// Created with the method [`rmatch_indices`].
1145        ///
1146        /// [`rmatch_indices`]: str::rmatch_indices
1147        struct RMatchIndices;
1148    stability:
1149        #[stable(feature = "str_match_indices", since = "1.5.0")]
1150    internal:
1151        MatchIndicesInternal yielding ((usize, &'a str));
1152    delegate double ended;
1153}
1154
1155#[cfg(not(feature = "ferrocene_certified"))]
1156derive_pattern_clone! {
1157    clone MatchesInternal
1158    with |s| MatchesInternal(s.0.clone())
1159}
1160
1161#[cfg(not(feature = "ferrocene_certified"))]
1162pub(super) struct MatchesInternal<'a, P: Pattern>(pub(super) P::Searcher<'a>);
1163
1164#[cfg(not(feature = "ferrocene_certified"))]
1165impl<'a, P> fmt::Debug for MatchesInternal<'a, P>
1166where
1167    P: Pattern<Searcher<'a>: fmt::Debug>,
1168{
1169    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1170        f.debug_tuple("MatchesInternal").field(&self.0).finish()
1171    }
1172}
1173
1174#[cfg(not(feature = "ferrocene_certified"))]
1175impl<'a, P: Pattern> MatchesInternal<'a, P> {
1176    #[inline]
1177    fn next(&mut self) -> Option<&'a str> {
1178        // SAFETY: `Searcher` guarantees that `start` and `end` lie on unicode boundaries.
1179        self.0.next_match().map(|(a, b)| unsafe {
1180            // Indices are known to be on utf8 boundaries
1181            self.0.haystack().get_unchecked(a..b)
1182        })
1183    }
1184
1185    #[inline]
1186    fn next_back(&mut self) -> Option<&'a str>
1187    where
1188        P::Searcher<'a>: ReverseSearcher<'a>,
1189    {
1190        // SAFETY: `Searcher` guarantees that `start` and `end` lie on unicode boundaries.
1191        self.0.next_match_back().map(|(a, b)| unsafe {
1192            // Indices are known to be on utf8 boundaries
1193            self.0.haystack().get_unchecked(a..b)
1194        })
1195    }
1196}
1197
1198#[cfg(not(feature = "ferrocene_certified"))]
1199generate_pattern_iterators! {
1200    forward:
1201        /// Created with the method [`matches`].
1202        ///
1203        /// [`matches`]: str::matches
1204        struct Matches;
1205    reverse:
1206        /// Created with the method [`rmatches`].
1207        ///
1208        /// [`rmatches`]: str::rmatches
1209        struct RMatches;
1210    stability:
1211        #[stable(feature = "str_matches", since = "1.2.0")]
1212    internal:
1213        MatchesInternal yielding (&'a str);
1214    delegate double ended;
1215}
1216
1217/// An iterator over the lines of a string, as string slices.
1218///
1219/// This struct is created with the [`lines`] method on [`str`].
1220/// See its documentation for more.
1221///
1222/// [`lines`]: str::lines
1223#[cfg(not(feature = "ferrocene_certified"))]
1224#[stable(feature = "rust1", since = "1.0.0")]
1225#[must_use = "iterators are lazy and do nothing unless consumed"]
1226#[derive(Clone, Debug)]
1227pub struct Lines<'a>(pub(super) Map<SplitInclusive<'a, char>, LinesMap>);
1228
1229#[cfg(not(feature = "ferrocene_certified"))]
1230#[stable(feature = "rust1", since = "1.0.0")]
1231impl<'a> Iterator for Lines<'a> {
1232    type Item = &'a str;
1233
1234    #[inline]
1235    fn next(&mut self) -> Option<&'a str> {
1236        self.0.next()
1237    }
1238
1239    #[inline]
1240    fn size_hint(&self) -> (usize, Option<usize>) {
1241        self.0.size_hint()
1242    }
1243
1244    #[inline]
1245    fn last(mut self) -> Option<&'a str> {
1246        self.next_back()
1247    }
1248}
1249
1250#[cfg(not(feature = "ferrocene_certified"))]
1251#[stable(feature = "rust1", since = "1.0.0")]
1252impl<'a> DoubleEndedIterator for Lines<'a> {
1253    #[inline]
1254    fn next_back(&mut self) -> Option<&'a str> {
1255        self.0.next_back()
1256    }
1257}
1258
1259#[cfg(not(feature = "ferrocene_certified"))]
1260#[stable(feature = "fused", since = "1.26.0")]
1261impl FusedIterator for Lines<'_> {}
1262
1263#[cfg(not(feature = "ferrocene_certified"))]
1264impl<'a> Lines<'a> {
1265    /// Returns the remaining lines of the split string.
1266    ///
1267    /// # Examples
1268    ///
1269    /// ```
1270    /// #![feature(str_lines_remainder)]
1271    ///
1272    /// let mut lines = "a\nb\nc\nd".lines();
1273    /// assert_eq!(lines.remainder(), Some("a\nb\nc\nd"));
1274    ///
1275    /// lines.next();
1276    /// assert_eq!(lines.remainder(), Some("b\nc\nd"));
1277    ///
1278    /// lines.by_ref().for_each(drop);
1279    /// assert_eq!(lines.remainder(), None);
1280    /// ```
1281    #[inline]
1282    #[must_use]
1283    #[unstable(feature = "str_lines_remainder", issue = "77998")]
1284    pub fn remainder(&self) -> Option<&'a str> {
1285        self.0.iter.remainder()
1286    }
1287}
1288
1289/// Created with the method [`lines_any`].
1290///
1291/// [`lines_any`]: str::lines_any
1292#[cfg(not(feature = "ferrocene_certified"))]
1293#[stable(feature = "rust1", since = "1.0.0")]
1294#[deprecated(since = "1.4.0", note = "use lines()/Lines instead now")]
1295#[must_use = "iterators are lazy and do nothing unless consumed"]
1296#[derive(Clone, Debug)]
1297#[allow(deprecated)]
1298pub struct LinesAny<'a>(pub(super) Lines<'a>);
1299
1300#[cfg(not(feature = "ferrocene_certified"))]
1301#[stable(feature = "rust1", since = "1.0.0")]
1302#[allow(deprecated)]
1303impl<'a> Iterator for LinesAny<'a> {
1304    type Item = &'a str;
1305
1306    #[inline]
1307    fn next(&mut self) -> Option<&'a str> {
1308        self.0.next()
1309    }
1310
1311    #[inline]
1312    fn size_hint(&self) -> (usize, Option<usize>) {
1313        self.0.size_hint()
1314    }
1315}
1316
1317#[cfg(not(feature = "ferrocene_certified"))]
1318#[stable(feature = "rust1", since = "1.0.0")]
1319#[allow(deprecated)]
1320impl<'a> DoubleEndedIterator for LinesAny<'a> {
1321    #[inline]
1322    fn next_back(&mut self) -> Option<&'a str> {
1323        self.0.next_back()
1324    }
1325}
1326
1327#[cfg(not(feature = "ferrocene_certified"))]
1328#[stable(feature = "fused", since = "1.26.0")]
1329#[allow(deprecated)]
1330impl FusedIterator for LinesAny<'_> {}
1331
1332/// An iterator over the non-whitespace substrings of a string,
1333/// separated by any amount of whitespace.
1334///
1335/// This struct is created by the [`split_whitespace`] method on [`str`].
1336/// See its documentation for more.
1337///
1338/// [`split_whitespace`]: str::split_whitespace
1339#[cfg(not(feature = "ferrocene_certified"))]
1340#[stable(feature = "split_whitespace", since = "1.1.0")]
1341#[derive(Clone, Debug)]
1342pub struct SplitWhitespace<'a> {
1343    pub(super) inner: Filter<Split<'a, IsWhitespace>, IsNotEmpty>,
1344}
1345
1346/// An iterator over the non-ASCII-whitespace substrings of a string,
1347/// separated by any amount of ASCII whitespace.
1348///
1349/// This struct is created by the [`split_ascii_whitespace`] method on [`str`].
1350/// See its documentation for more.
1351///
1352/// [`split_ascii_whitespace`]: str::split_ascii_whitespace
1353#[cfg(not(feature = "ferrocene_certified"))]
1354#[stable(feature = "split_ascii_whitespace", since = "1.34.0")]
1355#[derive(Clone, Debug)]
1356pub struct SplitAsciiWhitespace<'a> {
1357    pub(super) inner:
1358        Map<Filter<SliceSplit<'a, u8, IsAsciiWhitespace>, BytesIsNotEmpty>, UnsafeBytesToStr>,
1359}
1360
1361/// An iterator over the substrings of a string,
1362/// terminated by a substring matching to a predicate function
1363/// Unlike `Split`, it contains the matched part as a terminator
1364/// of the subslice.
1365///
1366/// This struct is created by the [`split_inclusive`] method on [`str`].
1367/// See its documentation for more.
1368///
1369/// [`split_inclusive`]: str::split_inclusive
1370#[cfg(not(feature = "ferrocene_certified"))]
1371#[stable(feature = "split_inclusive", since = "1.51.0")]
1372pub struct SplitInclusive<'a, P: Pattern>(pub(super) SplitInternal<'a, P>);
1373
1374#[cfg(not(feature = "ferrocene_certified"))]
1375#[stable(feature = "split_whitespace", since = "1.1.0")]
1376impl<'a> Iterator for SplitWhitespace<'a> {
1377    type Item = &'a str;
1378
1379    #[inline]
1380    fn next(&mut self) -> Option<&'a str> {
1381        self.inner.next()
1382    }
1383
1384    #[inline]
1385    fn size_hint(&self) -> (usize, Option<usize>) {
1386        self.inner.size_hint()
1387    }
1388
1389    #[inline]
1390    fn last(mut self) -> Option<&'a str> {
1391        self.next_back()
1392    }
1393}
1394
1395#[cfg(not(feature = "ferrocene_certified"))]
1396#[stable(feature = "split_whitespace", since = "1.1.0")]
1397impl<'a> DoubleEndedIterator for SplitWhitespace<'a> {
1398    #[inline]
1399    fn next_back(&mut self) -> Option<&'a str> {
1400        self.inner.next_back()
1401    }
1402}
1403
1404#[cfg(not(feature = "ferrocene_certified"))]
1405#[stable(feature = "fused", since = "1.26.0")]
1406impl FusedIterator for SplitWhitespace<'_> {}
1407
1408#[cfg(not(feature = "ferrocene_certified"))]
1409impl<'a> SplitWhitespace<'a> {
1410    /// Returns remainder of the split string
1411    ///
1412    /// # Examples
1413    ///
1414    /// ```
1415    /// #![feature(str_split_whitespace_remainder)]
1416    ///
1417    /// let mut split = "Mary had a little lamb".split_whitespace();
1418    /// assert_eq!(split.remainder(), Some("Mary had a little lamb"));
1419    ///
1420    /// split.next();
1421    /// assert_eq!(split.remainder(), Some("had a little lamb"));
1422    ///
1423    /// split.by_ref().for_each(drop);
1424    /// assert_eq!(split.remainder(), None);
1425    /// ```
1426    #[inline]
1427    #[must_use]
1428    #[unstable(feature = "str_split_whitespace_remainder", issue = "77998")]
1429    pub fn remainder(&self) -> Option<&'a str> {
1430        self.inner.iter.remainder()
1431    }
1432}
1433
1434#[cfg(not(feature = "ferrocene_certified"))]
1435#[stable(feature = "split_ascii_whitespace", since = "1.34.0")]
1436impl<'a> Iterator for SplitAsciiWhitespace<'a> {
1437    type Item = &'a str;
1438
1439    #[inline]
1440    fn next(&mut self) -> Option<&'a str> {
1441        self.inner.next()
1442    }
1443
1444    #[inline]
1445    fn size_hint(&self) -> (usize, Option<usize>) {
1446        self.inner.size_hint()
1447    }
1448
1449    #[inline]
1450    fn last(mut self) -> Option<&'a str> {
1451        self.next_back()
1452    }
1453}
1454
1455#[cfg(not(feature = "ferrocene_certified"))]
1456#[stable(feature = "split_ascii_whitespace", since = "1.34.0")]
1457impl<'a> DoubleEndedIterator for SplitAsciiWhitespace<'a> {
1458    #[inline]
1459    fn next_back(&mut self) -> Option<&'a str> {
1460        self.inner.next_back()
1461    }
1462}
1463
1464#[cfg(not(feature = "ferrocene_certified"))]
1465#[stable(feature = "split_ascii_whitespace", since = "1.34.0")]
1466impl FusedIterator for SplitAsciiWhitespace<'_> {}
1467
1468#[cfg(not(feature = "ferrocene_certified"))]
1469impl<'a> SplitAsciiWhitespace<'a> {
1470    /// Returns remainder of the split string.
1471    ///
1472    /// If the iterator is empty, returns `None`.
1473    ///
1474    /// # Examples
1475    ///
1476    /// ```
1477    /// #![feature(str_split_whitespace_remainder)]
1478    ///
1479    /// let mut split = "Mary had a little lamb".split_ascii_whitespace();
1480    /// assert_eq!(split.remainder(), Some("Mary had a little lamb"));
1481    ///
1482    /// split.next();
1483    /// assert_eq!(split.remainder(), Some("had a little lamb"));
1484    ///
1485    /// split.by_ref().for_each(drop);
1486    /// assert_eq!(split.remainder(), None);
1487    /// ```
1488    #[inline]
1489    #[must_use]
1490    #[unstable(feature = "str_split_whitespace_remainder", issue = "77998")]
1491    pub fn remainder(&self) -> Option<&'a str> {
1492        if self.inner.iter.iter.finished {
1493            return None;
1494        }
1495
1496        // SAFETY: Slice is created from str.
1497        Some(unsafe { crate::str::from_utf8_unchecked(&self.inner.iter.iter.v) })
1498    }
1499}
1500
1501#[cfg(not(feature = "ferrocene_certified"))]
1502#[stable(feature = "split_inclusive", since = "1.51.0")]
1503impl<'a, P: Pattern> Iterator for SplitInclusive<'a, P> {
1504    type Item = &'a str;
1505
1506    #[inline]
1507    fn next(&mut self) -> Option<&'a str> {
1508        self.0.next_inclusive()
1509    }
1510}
1511
1512#[cfg(not(feature = "ferrocene_certified"))]
1513#[stable(feature = "split_inclusive", since = "1.51.0")]
1514impl<'a, P: Pattern<Searcher<'a>: fmt::Debug>> fmt::Debug for SplitInclusive<'a, P> {
1515    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1516        f.debug_struct("SplitInclusive").field("0", &self.0).finish()
1517    }
1518}
1519
1520// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
1521#[cfg(not(feature = "ferrocene_certified"))]
1522#[stable(feature = "split_inclusive", since = "1.51.0")]
1523impl<'a, P: Pattern<Searcher<'a>: Clone>> Clone for SplitInclusive<'a, P> {
1524    fn clone(&self) -> Self {
1525        SplitInclusive(self.0.clone())
1526    }
1527}
1528
1529#[cfg(not(feature = "ferrocene_certified"))]
1530#[stable(feature = "split_inclusive", since = "1.51.0")]
1531impl<'a, P: Pattern<Searcher<'a>: DoubleEndedSearcher<'a>>> DoubleEndedIterator
1532    for SplitInclusive<'a, P>
1533{
1534    #[inline]
1535    fn next_back(&mut self) -> Option<&'a str> {
1536        self.0.next_back_inclusive()
1537    }
1538}
1539
1540#[cfg(not(feature = "ferrocene_certified"))]
1541#[stable(feature = "split_inclusive", since = "1.51.0")]
1542impl<'a, P: Pattern> FusedIterator for SplitInclusive<'a, P> {}
1543
1544#[cfg(not(feature = "ferrocene_certified"))]
1545impl<'a, P: Pattern> SplitInclusive<'a, P> {
1546    /// Returns remainder of the split string.
1547    ///
1548    /// If the iterator is empty, returns `None`.
1549    ///
1550    /// # Examples
1551    ///
1552    /// ```
1553    /// #![feature(str_split_inclusive_remainder)]
1554    /// let mut split = "Mary had a little lamb".split_inclusive(' ');
1555    /// assert_eq!(split.remainder(), Some("Mary had a little lamb"));
1556    /// split.next();
1557    /// assert_eq!(split.remainder(), Some("had a little lamb"));
1558    /// split.by_ref().for_each(drop);
1559    /// assert_eq!(split.remainder(), None);
1560    /// ```
1561    #[inline]
1562    #[unstable(feature = "str_split_inclusive_remainder", issue = "77998")]
1563    pub fn remainder(&self) -> Option<&'a str> {
1564        self.0.remainder()
1565    }
1566}
1567
1568/// An iterator of [`u16`] over the string encoded as UTF-16.
1569///
1570/// This struct is created by the [`encode_utf16`] method on [`str`].
1571/// See its documentation for more.
1572///
1573/// [`encode_utf16`]: str::encode_utf16
1574#[cfg(not(feature = "ferrocene_certified"))]
1575#[derive(Clone)]
1576#[stable(feature = "encode_utf16", since = "1.8.0")]
1577pub struct EncodeUtf16<'a> {
1578    pub(super) chars: Chars<'a>,
1579    pub(super) extra: u16,
1580}
1581
1582#[cfg(not(feature = "ferrocene_certified"))]
1583#[stable(feature = "collection_debug", since = "1.17.0")]
1584impl fmt::Debug for EncodeUtf16<'_> {
1585    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1586        f.debug_struct("EncodeUtf16").finish_non_exhaustive()
1587    }
1588}
1589
1590#[cfg(not(feature = "ferrocene_certified"))]
1591#[stable(feature = "encode_utf16", since = "1.8.0")]
1592impl<'a> Iterator for EncodeUtf16<'a> {
1593    type Item = u16;
1594
1595    #[inline]
1596    fn next(&mut self) -> Option<u16> {
1597        if self.extra != 0 {
1598            let tmp = self.extra;
1599            self.extra = 0;
1600            return Some(tmp);
1601        }
1602
1603        let mut buf = [0; 2];
1604        self.chars.next().map(|ch| {
1605            let n = ch.encode_utf16(&mut buf).len();
1606            if n == 2 {
1607                self.extra = buf[1];
1608            }
1609            buf[0]
1610        })
1611    }
1612
1613    #[inline]
1614    fn size_hint(&self) -> (usize, Option<usize>) {
1615        let len = self.chars.iter.len();
1616        // The highest bytes:code units ratio occurs for 3-byte sequences,
1617        // since a 4-byte sequence results in 2 code units. The lower bound
1618        // is therefore determined by assuming the remaining bytes contain as
1619        // many 3-byte sequences as possible. The highest bytes:code units
1620        // ratio is for 1-byte sequences, so use this for the upper bound.
1621        // `(len + 2)` can't overflow, because we know that the `slice::Iter`
1622        // belongs to a slice in memory which has a maximum length of
1623        // `isize::MAX` (that's well below `usize::MAX`)
1624        if self.extra == 0 {
1625            (len.div_ceil(3), Some(len))
1626        } else {
1627            // We're in the middle of a surrogate pair, so add the remaining
1628            // surrogate to the bounds.
1629            (len.div_ceil(3) + 1, Some(len + 1))
1630        }
1631    }
1632}
1633
1634#[cfg(not(feature = "ferrocene_certified"))]
1635#[stable(feature = "fused", since = "1.26.0")]
1636impl FusedIterator for EncodeUtf16<'_> {}
1637
1638/// The return type of [`str::escape_debug`].
1639#[cfg(not(feature = "ferrocene_certified"))]
1640#[stable(feature = "str_escape", since = "1.34.0")]
1641#[derive(Clone, Debug)]
1642pub struct EscapeDebug<'a> {
1643    pub(super) inner: Chain<
1644        Flatten<option::IntoIter<char_mod::EscapeDebug>>,
1645        FlatMap<Chars<'a>, char_mod::EscapeDebug, CharEscapeDebugContinue>,
1646    >,
1647}
1648
1649/// The return type of [`str::escape_default`].
1650#[cfg(not(feature = "ferrocene_certified"))]
1651#[stable(feature = "str_escape", since = "1.34.0")]
1652#[derive(Clone, Debug)]
1653pub struct EscapeDefault<'a> {
1654    pub(super) inner: FlatMap<Chars<'a>, char_mod::EscapeDefault, CharEscapeDefault>,
1655}
1656
1657/// The return type of [`str::escape_unicode`].
1658#[cfg(not(feature = "ferrocene_certified"))]
1659#[stable(feature = "str_escape", since = "1.34.0")]
1660#[derive(Clone, Debug)]
1661pub struct EscapeUnicode<'a> {
1662    pub(super) inner: FlatMap<Chars<'a>, char_mod::EscapeUnicode, CharEscapeUnicode>,
1663}
1664
1665#[cfg(not(feature = "ferrocene_certified"))]
1666macro_rules! escape_types_impls {
1667    ($( $Name: ident ),+) => {$(
1668        #[stable(feature = "str_escape", since = "1.34.0")]
1669        impl<'a> fmt::Display for $Name<'a> {
1670            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1671                self.clone().try_for_each(|c| f.write_char(c))
1672            }
1673        }
1674
1675        #[stable(feature = "str_escape", since = "1.34.0")]
1676        impl<'a> Iterator for $Name<'a> {
1677            type Item = char;
1678
1679            #[inline]
1680            fn next(&mut self) -> Option<char> { self.inner.next() }
1681
1682            #[inline]
1683            fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
1684
1685            #[inline]
1686            fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R where
1687                Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Output = Acc>
1688            {
1689                self.inner.try_fold(init, fold)
1690            }
1691
1692            #[inline]
1693            fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
1694                where Fold: FnMut(Acc, Self::Item) -> Acc,
1695            {
1696                self.inner.fold(init, fold)
1697            }
1698        }
1699
1700        #[stable(feature = "str_escape", since = "1.34.0")]
1701        impl<'a> FusedIterator for $Name<'a> {}
1702    )+}
1703}
1704
1705#[cfg(not(feature = "ferrocene_certified"))]
1706escape_types_impls!(EscapeDebug, EscapeDefault, EscapeUnicode);