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