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