Skip to main content

core/str/
iter.rs

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