1use super::pattern::{DoubleEndedSearcher, Pattern, ReverseSearcher, Searcher};
4use super::validations::{next_code_point, next_code_point_reverse};
5use super::{
6 BytesIsNotEmpty, CharEscapeDebugContinue, CharEscapeDefault, CharEscapeUnicode,
7 IsAsciiWhitespace, IsNotEmpty, IsWhitespace, LinesMap, UnsafeBytesToStr, from_utf8_unchecked,
8};
9use crate::fmt::{self, Write};
10use crate::iter::{
11 Chain, Copied, Filter, FlatMap, Flatten, FusedIterator, Map, TrustedLen, TrustedRandomAccess,
12 TrustedRandomAccessNoCoerce,
13};
14use crate::num::NonZero;
15use crate::ops::Try;
16use crate::slice::{self, Split as SliceSplit};
17use crate::{char as char_mod, option};
18
19#[derive(Clone)]
28#[must_use = "iterators are lazy and do nothing unless consumed"]
29#[stable(feature = "rust1", since = "1.0.0")]
30#[ferrocene::prevalidated]
31pub struct Chars<'a> {
32 pub(super) iter: slice::Iter<'a, u8>,
33}
34
35#[stable(feature = "rust1", since = "1.0.0")]
36impl<'a> Iterator for Chars<'a> {
37 type Item = char;
38
39 #[inline]
40 #[ferrocene::prevalidated]
41 fn next(&mut self) -> Option<char> {
42 unsafe { next_code_point(&mut self.iter).map(|ch| char::from_u32_unchecked(ch)) }
45 }
46
47 #[inline]
48 #[ferrocene::prevalidated]
49 fn count(self) -> usize {
50 super::count::count_chars(self.as_str())
51 }
52
53 #[inline]
54 #[ferrocene::prevalidated]
55 fn advance_by(&mut self, mut remainder: usize) -> Result<(), NonZero<usize>> {
56 const CHUNK_SIZE: usize = 32;
57
58 if remainder >= CHUNK_SIZE {
59 let mut chunks = self.iter.as_slice().as_chunks::<CHUNK_SIZE>().0.iter();
60 let mut bytes_skipped: usize = 0;
61
62 while remainder > CHUNK_SIZE
63 && let Some(chunk) = chunks.next()
64 {
65 bytes_skipped += CHUNK_SIZE;
66
67 let mut start_bytes = [false; CHUNK_SIZE];
68
69 for i in 0..CHUNK_SIZE {
70 start_bytes[i] = !super::validations::utf8_is_cont_byte(chunk[i]);
71 }
72
73 remainder -= start_bytes.into_iter().map(|i| i as u8).sum::<u8>() as usize;
74 }
75
76 unsafe { self.iter.advance_by(bytes_skipped).unwrap_unchecked() };
79
80 while self.iter.len() > 0 {
82 let b = self.iter.as_slice()[0];
83 if !super::validations::utf8_is_cont_byte(b) {
84 break;
85 }
86 unsafe { self.iter.advance_by(1).unwrap_unchecked() };
88 }
89 }
90
91 while (remainder > 0) && (self.iter.len() > 0) {
92 remainder -= 1;
93 let b = self.iter.as_slice()[0];
94 let slurp = super::validations::utf8_char_width(b);
95 unsafe { self.iter.advance_by(slurp).unwrap_unchecked() };
98 }
99
100 NonZero::new(remainder).map_or(Ok(()), Err)
101 }
102
103 #[inline]
104 #[ferrocene::prevalidated]
105 fn size_hint(&self) -> (usize, Option<usize>) {
106 let len = self.iter.len();
107 (len.div_ceil(4), Some(len))
108 }
109
110 #[inline]
111 #[ferrocene::prevalidated]
112 fn last(mut self) -> Option<char> {
113 self.next_back()
115 }
116}
117
118#[stable(feature = "chars_debug_impl", since = "1.38.0")]
119impl fmt::Debug for Chars<'_> {
120 #[ferrocene::prevalidated]
121 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
122 write!(f, "Chars(")?;
123 f.debug_list().entries(self.clone()).finish()?;
124 write!(f, ")")?;
125 Ok(())
126 }
127}
128
129#[stable(feature = "rust1", since = "1.0.0")]
130impl<'a> DoubleEndedIterator for Chars<'a> {
131 #[inline]
132 #[ferrocene::prevalidated]
133 fn next_back(&mut self) -> Option<char> {
134 unsafe { next_code_point_reverse(&mut self.iter).map(|ch| char::from_u32_unchecked(ch)) }
137 }
138}
139
140#[stable(feature = "fused", since = "1.26.0")]
141impl FusedIterator for Chars<'_> {}
142
143impl<'a> Chars<'a> {
144 #[stable(feature = "iter_to_slice", since = "1.4.0")]
162 #[must_use]
163 #[inline]
164 #[ferrocene::prevalidated]
165 pub fn as_str(&self) -> &'a str {
166 unsafe { from_utf8_unchecked(self.iter.as_slice()) }
168 }
169}
170
171#[derive(Clone, Debug)]
179#[must_use = "iterators are lazy and do nothing unless consumed"]
180#[stable(feature = "rust1", since = "1.0.0")]
181#[ferrocene::prevalidated]
182pub struct CharIndices<'a> {
183 pub(super) front_offset: usize,
184 pub(super) iter: Chars<'a>,
185}
186
187#[stable(feature = "rust1", since = "1.0.0")]
188impl<'a> Iterator for CharIndices<'a> {
189 type Item = (usize, char);
190
191 #[inline]
192 #[ferrocene::prevalidated]
193 fn next(&mut self) -> Option<(usize, char)> {
194 let pre_len = self.iter.iter.len();
195 match self.iter.next() {
196 None => None,
197 Some(ch) => {
198 let index = self.front_offset;
199 let len = self.iter.iter.len();
200 self.front_offset += pre_len - len;
201 Some((index, ch))
202 }
203 }
204 }
205
206 #[inline]
207 #[ferrocene::prevalidated]
208 fn count(self) -> usize {
209 self.iter.count()
210 }
211
212 #[inline]
213 #[ferrocene::prevalidated]
214 fn size_hint(&self) -> (usize, Option<usize>) {
215 self.iter.size_hint()
216 }
217
218 #[inline]
219 #[ferrocene::prevalidated]
220 fn last(mut self) -> Option<(usize, char)> {
221 self.next_back()
223 }
224}
225
226#[stable(feature = "rust1", since = "1.0.0")]
227impl<'a> DoubleEndedIterator for CharIndices<'a> {
228 #[inline]
229 #[ferrocene::prevalidated]
230 fn next_back(&mut self) -> Option<(usize, char)> {
231 self.iter.next_back().map(|ch| {
232 let index = self.front_offset + self.iter.iter.len();
233 (index, ch)
234 })
235 }
236}
237
238#[stable(feature = "fused", since = "1.26.0")]
239impl FusedIterator for CharIndices<'_> {}
240
241impl<'a> CharIndices<'a> {
242 #[stable(feature = "iter_to_slice", since = "1.4.0")]
247 #[must_use]
248 #[inline]
249 #[ferrocene::prevalidated]
250 pub fn as_str(&self) -> &'a str {
251 self.iter.as_str()
252 }
253
254 #[inline]
284 #[must_use]
285 #[stable(feature = "char_indices_offset", since = "1.82.0")]
286 #[ferrocene::prevalidated]
287 pub fn offset(&self) -> usize {
288 self.front_offset
289 }
290}
291
292#[must_use = "iterators are lazy and do nothing unless consumed"]
299#[stable(feature = "rust1", since = "1.0.0")]
300#[derive(Clone, Debug)]
301#[ferrocene::prevalidated]
302pub struct Bytes<'a>(pub(super) Copied<slice::Iter<'a, u8>>);
303
304#[stable(feature = "rust1", since = "1.0.0")]
305impl Iterator for Bytes<'_> {
306 type Item = u8;
307
308 #[inline]
309 #[ferrocene::prevalidated]
310 fn next(&mut self) -> Option<u8> {
311 self.0.next()
312 }
313
314 #[inline]
315 #[ferrocene::prevalidated]
316 fn size_hint(&self) -> (usize, Option<usize>) {
317 self.0.size_hint()
318 }
319
320 #[inline]
321 #[ferrocene::prevalidated]
322 fn count(self) -> usize {
323 self.0.count()
324 }
325
326 #[inline]
327 #[ferrocene::prevalidated]
328 fn last(self) -> Option<Self::Item> {
329 self.0.last()
330 }
331
332 #[inline]
333 #[ferrocene::prevalidated]
334 fn nth(&mut self, n: usize) -> Option<Self::Item> {
335 self.0.nth(n)
336 }
337
338 #[inline]
339 #[ferrocene::prevalidated]
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 #[ferrocene::prevalidated]
349 fn any<F>(&mut self, f: F) -> bool
350 where
351 F: FnMut(Self::Item) -> bool,
352 {
353 self.0.any(f)
354 }
355
356 #[inline]
357 #[ferrocene::prevalidated]
358 fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
359 where
360 P: FnMut(&Self::Item) -> bool,
361 {
362 self.0.find(predicate)
363 }
364
365 #[inline]
366 #[ferrocene::prevalidated]
367 fn position<P>(&mut self, predicate: P) -> Option<usize>
368 where
369 P: FnMut(Self::Item) -> bool,
370 {
371 self.0.position(predicate)
372 }
373
374 #[inline]
375 #[ferrocene::prevalidated]
376 fn rposition<P>(&mut self, predicate: P) -> Option<usize>
377 where
378 P: FnMut(Self::Item) -> bool,
379 {
380 self.0.rposition(predicate)
381 }
382
383 #[inline]
384 unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> u8 {
385 unsafe { self.0.__iterator_get_unchecked(idx) }
388 }
389}
390
391#[stable(feature = "rust1", since = "1.0.0")]
392impl DoubleEndedIterator for Bytes<'_> {
393 #[inline]
394 fn next_back(&mut self) -> Option<u8> {
395 self.0.next_back()
396 }
397
398 #[inline]
399 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
400 self.0.nth_back(n)
401 }
402
403 #[inline]
404 fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
405 where
406 P: FnMut(&Self::Item) -> bool,
407 {
408 self.0.rfind(predicate)
409 }
410}
411
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#[stable(feature = "fused", since = "1.26.0")]
426impl FusedIterator for Bytes<'_> {}
427
428#[unstable(feature = "trusted_len", issue = "37572")]
429unsafe impl TrustedLen for Bytes<'_> {}
430
431#[doc(hidden)]
432#[unstable(feature = "trusted_random_access", issue = "none")]
433unsafe impl TrustedRandomAccess for Bytes<'_> {}
434
435#[doc(hidden)]
436#[unstable(feature = "trusted_random_access", issue = "none")]
437unsafe impl TrustedRandomAccessNoCoerce for Bytes<'_> {
438 const MAY_HAVE_SIDE_EFFECT: bool = false;
439}
440
441macro_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
457macro_rules! generate_pattern_iterators {
496 {
497 forward:
499 $(#[$forward_iterator_attribute:meta])*
500 struct $forward_iterator:ident;
501
502 reverse:
504 $(#[$reverse_iterator_attribute:meta])*
505 struct $reverse_iterator:ident;
506
507 stability:
509 $(#[$common_stability_attribute:meta])*
510
511 internal:
513 $internal_iterator:ident yielding ($iterty:ty);
514
515 delegate $($t:tt)*
517 } => {
518 $(#[$forward_iterator_attribute])*
519 $(#[$common_stability_attribute])*
520 pub struct $forward_iterator<'a, P: Pattern>(pub(super) $internal_iterator<'a, P>);
521
522 $(#[$common_stability_attribute])*
523 impl<'a, P> fmt::Debug for $forward_iterator<'a, P>
524 where
525 P: Pattern<Searcher<'a>: fmt::Debug>,
526 {
527 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
528 f.debug_tuple(stringify!($forward_iterator))
529 .field(&self.0)
530 .finish()
531 }
532 }
533
534 $(#[$common_stability_attribute])*
535 impl<'a, P: Pattern> Iterator for $forward_iterator<'a, P> {
536 type Item = $iterty;
537
538 #[inline]
539 fn next(&mut self) -> Option<$iterty> {
540 self.0.next()
541 }
542 }
543
544 $(#[$common_stability_attribute])*
545 impl<'a, P> Clone for $forward_iterator<'a, P>
546 where
547 P: Pattern<Searcher<'a>: Clone>,
548 {
549 fn clone(&self) -> Self {
550 $forward_iterator(self.0.clone())
551 }
552 }
553
554 $(#[$reverse_iterator_attribute])*
555 $(#[$common_stability_attribute])*
556 pub struct $reverse_iterator<'a, P: Pattern>(pub(super) $internal_iterator<'a, P>);
557
558 $(#[$common_stability_attribute])*
559 impl<'a, P> fmt::Debug for $reverse_iterator<'a, P>
560 where
561 P: Pattern<Searcher<'a>: fmt::Debug>,
562 {
563 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
564 f.debug_tuple(stringify!($reverse_iterator))
565 .field(&self.0)
566 .finish()
567 }
568 }
569
570 $(#[$common_stability_attribute])*
571 impl<'a, P> Iterator for $reverse_iterator<'a, P>
572 where
573 P: Pattern<Searcher<'a>: ReverseSearcher<'a>>,
574 {
575 type Item = $iterty;
576
577 #[inline]
578 fn next(&mut self) -> Option<$iterty> {
579 self.0.next_back()
580 }
581 }
582
583 $(#[$common_stability_attribute])*
584 impl<'a, P> Clone for $reverse_iterator<'a, P>
585 where
586 P: Pattern<Searcher<'a>: Clone>,
587 {
588 fn clone(&self) -> Self {
589 $reverse_iterator(self.0.clone())
590 }
591 }
592
593 #[stable(feature = "fused", since = "1.26.0")]
594 impl<'a, P: Pattern> FusedIterator for $forward_iterator<'a, P> {}
595
596 #[stable(feature = "fused", since = "1.26.0")]
597 impl<'a, P> FusedIterator for $reverse_iterator<'a, P>
598 where
599 P: Pattern<Searcher<'a>: ReverseSearcher<'a>>,
600 {}
601
602 generate_pattern_iterators!($($t)* with $(#[$common_stability_attribute])*,
603 $forward_iterator,
604 $reverse_iterator, $iterty);
605 };
606 {
607 double ended; with $(#[$common_stability_attribute:meta])*,
608 $forward_iterator:ident,
609 $reverse_iterator:ident, $iterty:ty
610 } => {
611 $(#[$common_stability_attribute])*
612 impl<'a, P> DoubleEndedIterator for $forward_iterator<'a, P>
613 where
614 P: Pattern<Searcher<'a>: DoubleEndedSearcher<'a>>,
615 {
616 #[inline]
617 fn next_back(&mut self) -> Option<$iterty> {
618 self.0.next_back()
619 }
620 }
621
622 $(#[$common_stability_attribute])*
623 impl<'a, P> DoubleEndedIterator for $reverse_iterator<'a, P>
624 where
625 P: Pattern<Searcher<'a>: DoubleEndedSearcher<'a>>,
626 {
627 #[inline]
628 fn next_back(&mut self) -> Option<$iterty> {
629 self.0.next()
630 }
631 }
632 };
633 {
634 single ended; with $(#[$common_stability_attribute:meta])*,
635 $forward_iterator:ident,
636 $reverse_iterator:ident, $iterty:ty
637 } => {}
638}
639
640derive_pattern_clone! {
641 clone SplitInternal
642 with |s| SplitInternal { matcher: s.matcher.clone(), ..*s }
643}
644
645#[ferrocene::prevalidated]
646pub(super) struct SplitInternal<'a, P: Pattern> {
647 pub(super) start: usize,
648 pub(super) end: usize,
649 pub(super) matcher: P::Searcher<'a>,
650 pub(super) allow_trailing_empty: bool,
651 pub(super) finished: bool,
652}
653
654impl<'a, P> fmt::Debug for SplitInternal<'a, P>
655where
656 P: Pattern<Searcher<'a>: fmt::Debug>,
657{
658 #[ferrocene::prevalidated]
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 #[ferrocene::prevalidated]
673 fn get_end(&mut self) -> Option<&'a str> {
674 if !self.finished {
675 self.finished = true;
676
677 if self.allow_trailing_empty || self.end - self.start > 0 {
678 let string = unsafe { self.matcher.haystack().get_unchecked(self.start..self.end) };
680 return Some(string);
681 }
682 }
683
684 None
685 }
686
687 #[inline]
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 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 #[ferrocene::prevalidated]
707 fn next_inclusive(&mut self) -> Option<&'a str> {
708 if self.finished {
709 return None;
710 }
711
712 let haystack = self.matcher.haystack();
713 match self.matcher.next_match() {
714 Some((_, b)) => unsafe {
718 let elt = haystack.get_unchecked(self.start..b);
719 self.start = b;
720 Some(elt)
721 },
722 None => self.get_end(),
723 }
724 }
725
726 #[inline]
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 Some((a, b)) => unsafe {
751 let elt = haystack.get_unchecked(b..self.end);
752 self.end = a;
753 Some(elt)
754 },
755 None => unsafe {
757 self.finished = true;
758 Some(haystack.get_unchecked(self.start..self.end))
759 },
760 }
761 }
762
763 #[inline]
764 fn next_back_inclusive(&mut self) -> Option<&'a str>
765 where
766 P::Searcher<'a>: ReverseSearcher<'a>,
767 {
768 if self.finished {
769 return None;
770 }
771
772 if !self.allow_trailing_empty {
773 self.allow_trailing_empty = true;
774 match self.next_back_inclusive() {
775 Some(elt) if !elt.is_empty() => return Some(elt),
776 _ => {
777 if self.finished {
778 return None;
779 }
780 }
781 }
782 }
783
784 let haystack = self.matcher.haystack();
785 match self.matcher.next_match_back() {
786 Some((_, b)) => unsafe {
790 let elt = haystack.get_unchecked(b..self.end);
791 self.end = b;
792 Some(elt)
793 },
794 None => unsafe {
800 self.finished = true;
801 Some(haystack.get_unchecked(self.start..self.end))
802 },
803 }
804 }
805
806 #[inline]
807 fn remainder(&self) -> Option<&'a str> {
808 if self.finished {
810 return None;
811 }
812
813 Some(unsafe { self.matcher.haystack().get_unchecked(self.start..self.end) })
815 }
816}
817
818generate_pattern_iterators! {
819 forward:
820 struct Split;
824 reverse:
825 struct RSplit;
829 stability:
830 #[stable(feature = "rust1", since = "1.0.0")]
831 internal:
832 SplitInternal yielding (&'a str);
833 delegate double ended;
834}
835
836impl<'a, P: Pattern> Split<'a, P> {
837 #[inline]
853 #[unstable(feature = "str_split_remainder", issue = "77998")]
854 pub fn remainder(&self) -> Option<&'a str> {
855 self.0.remainder()
856 }
857}
858
859impl<'a, P: Pattern> RSplit<'a, P> {
860 #[inline]
876 #[unstable(feature = "str_split_remainder", issue = "77998")]
877 pub fn remainder(&self) -> Option<&'a str> {
878 self.0.remainder()
879 }
880}
881
882generate_pattern_iterators! {
883 forward:
884 struct SplitTerminator;
888 reverse:
889 struct RSplitTerminator;
893 stability:
894 #[stable(feature = "rust1", since = "1.0.0")]
895 internal:
896 SplitInternal yielding (&'a str);
897 delegate double ended;
898}
899
900impl<'a, P: Pattern> SplitTerminator<'a, P> {
901 #[inline]
917 #[unstable(feature = "str_split_remainder", issue = "77998")]
918 pub fn remainder(&self) -> Option<&'a str> {
919 self.0.remainder()
920 }
921}
922
923impl<'a, P: Pattern> RSplitTerminator<'a, P> {
924 #[inline]
940 #[unstable(feature = "str_split_remainder", issue = "77998")]
941 pub fn remainder(&self) -> Option<&'a str> {
942 self.0.remainder()
943 }
944}
945
946derive_pattern_clone! {
947 clone SplitNInternal
948 with |s| SplitNInternal { iter: s.iter.clone(), ..*s }
949}
950
951pub(super) struct SplitNInternal<'a, P: Pattern> {
952 pub(super) iter: SplitInternal<'a, P>,
953 pub(super) count: usize,
955}
956
957impl<'a, P> fmt::Debug for SplitNInternal<'a, P>
958where
959 P: Pattern<Searcher<'a>: fmt::Debug>,
960{
961 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
962 f.debug_struct("SplitNInternal")
963 .field("iter", &self.iter)
964 .field("count", &self.count)
965 .finish()
966 }
967}
968
969impl<'a, P: Pattern> SplitNInternal<'a, P> {
970 #[inline]
971 fn next(&mut self) -> Option<&'a str> {
972 match self.count {
973 0 => None,
974 1 => {
975 self.count = 0;
976 self.iter.get_end()
977 }
978 _ => {
979 self.count -= 1;
980 self.iter.next()
981 }
982 }
983 }
984
985 #[inline]
986 fn next_back(&mut self) -> Option<&'a str>
987 where
988 P::Searcher<'a>: ReverseSearcher<'a>,
989 {
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_back()
999 }
1000 }
1001 }
1002
1003 #[inline]
1004 fn remainder(&self) -> Option<&'a str> {
1005 self.iter.remainder()
1006 }
1007}
1008
1009generate_pattern_iterators! {
1010 forward:
1011 struct SplitN;
1015 reverse:
1016 struct RSplitN;
1020 stability:
1021 #[stable(feature = "rust1", since = "1.0.0")]
1022 internal:
1023 SplitNInternal yielding (&'a str);
1024 delegate single ended;
1025}
1026
1027impl<'a, P: Pattern> SplitN<'a, P> {
1028 #[inline]
1044 #[unstable(feature = "str_split_remainder", issue = "77998")]
1045 pub fn remainder(&self) -> Option<&'a str> {
1046 self.0.remainder()
1047 }
1048}
1049
1050impl<'a, P: Pattern> RSplitN<'a, P> {
1051 #[inline]
1067 #[unstable(feature = "str_split_remainder", issue = "77998")]
1068 pub fn remainder(&self) -> Option<&'a str> {
1069 self.0.remainder()
1070 }
1071}
1072
1073derive_pattern_clone! {
1074 clone MatchIndicesInternal
1075 with |s| MatchIndicesInternal(s.0.clone())
1076}
1077
1078pub(super) struct MatchIndicesInternal<'a, P: Pattern>(pub(super) P::Searcher<'a>);
1079
1080impl<'a, P> fmt::Debug for MatchIndicesInternal<'a, P>
1081where
1082 P: Pattern<Searcher<'a>: fmt::Debug>,
1083{
1084 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1085 f.debug_tuple("MatchIndicesInternal").field(&self.0).finish()
1086 }
1087}
1088
1089impl<'a, P: Pattern> MatchIndicesInternal<'a, P> {
1090 #[inline]
1091 fn next(&mut self) -> Option<(usize, &'a str)> {
1092 self.0
1093 .next_match()
1094 .map(|(start, end)| unsafe { (start, self.0.haystack().get_unchecked(start..end)) })
1096 }
1097
1098 #[inline]
1099 fn next_back(&mut self) -> Option<(usize, &'a str)>
1100 where
1101 P::Searcher<'a>: ReverseSearcher<'a>,
1102 {
1103 self.0
1104 .next_match_back()
1105 .map(|(start, end)| unsafe { (start, self.0.haystack().get_unchecked(start..end)) })
1107 }
1108}
1109
1110generate_pattern_iterators! {
1111 forward:
1112 struct MatchIndices;
1116 reverse:
1117 struct RMatchIndices;
1121 stability:
1122 #[stable(feature = "str_match_indices", since = "1.5.0")]
1123 internal:
1124 MatchIndicesInternal yielding ((usize, &'a str));
1125 delegate double ended;
1126}
1127
1128derive_pattern_clone! {
1129 clone MatchesInternal
1130 with |s| MatchesInternal(s.0.clone())
1131}
1132
1133pub(super) struct MatchesInternal<'a, P: Pattern>(pub(super) P::Searcher<'a>);
1134
1135impl<'a, P> fmt::Debug for MatchesInternal<'a, P>
1136where
1137 P: Pattern<Searcher<'a>: fmt::Debug>,
1138{
1139 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1140 f.debug_tuple("MatchesInternal").field(&self.0).finish()
1141 }
1142}
1143
1144impl<'a, P: Pattern> MatchesInternal<'a, P> {
1145 #[inline]
1146 fn next(&mut self) -> Option<&'a str> {
1147 self.0.next_match().map(|(a, b)| unsafe {
1149 self.0.haystack().get_unchecked(a..b)
1151 })
1152 }
1153
1154 #[inline]
1155 fn next_back(&mut self) -> Option<&'a str>
1156 where
1157 P::Searcher<'a>: ReverseSearcher<'a>,
1158 {
1159 self.0.next_match_back().map(|(a, b)| unsafe {
1161 self.0.haystack().get_unchecked(a..b)
1163 })
1164 }
1165}
1166
1167generate_pattern_iterators! {
1168 forward:
1169 struct Matches;
1173 reverse:
1174 struct RMatches;
1178 stability:
1179 #[stable(feature = "str_matches", since = "1.2.0")]
1180 internal:
1181 MatchesInternal yielding (&'a str);
1182 delegate double ended;
1183}
1184
1185#[stable(feature = "rust1", since = "1.0.0")]
1192#[must_use = "iterators are lazy and do nothing unless consumed"]
1193#[derive(Clone, Debug)]
1194pub struct Lines<'a>(pub(super) Map<SplitInclusive<'a, char>, LinesMap>);
1195
1196#[stable(feature = "rust1", since = "1.0.0")]
1197impl<'a> Iterator for Lines<'a> {
1198 type Item = &'a str;
1199
1200 #[inline]
1201 fn next(&mut self) -> Option<&'a str> {
1202 self.0.next()
1203 }
1204
1205 #[inline]
1206 fn size_hint(&self) -> (usize, Option<usize>) {
1207 self.0.size_hint()
1208 }
1209
1210 #[inline]
1211 fn last(mut self) -> Option<&'a str> {
1212 self.next_back()
1213 }
1214}
1215
1216#[stable(feature = "rust1", since = "1.0.0")]
1217impl<'a> DoubleEndedIterator for Lines<'a> {
1218 #[inline]
1219 fn next_back(&mut self) -> Option<&'a str> {
1220 self.0.next_back()
1221 }
1222}
1223
1224#[stable(feature = "fused", since = "1.26.0")]
1225impl FusedIterator for Lines<'_> {}
1226
1227impl<'a> Lines<'a> {
1228 #[inline]
1245 #[must_use]
1246 #[unstable(feature = "str_lines_remainder", issue = "77998")]
1247 pub fn remainder(&self) -> Option<&'a str> {
1248 self.0.iter.remainder()
1249 }
1250}
1251
1252#[stable(feature = "rust1", since = "1.0.0")]
1256#[deprecated(since = "1.4.0", note = "use lines()/Lines instead now")]
1257#[must_use = "iterators are lazy and do nothing unless consumed"]
1258#[derive(Clone, Debug)]
1259#[allow(deprecated)]
1260pub struct LinesAny<'a>(pub(super) Lines<'a>);
1261
1262#[stable(feature = "rust1", since = "1.0.0")]
1263#[allow(deprecated)]
1264impl<'a> Iterator for LinesAny<'a> {
1265 type Item = &'a str;
1266
1267 #[inline]
1268 fn next(&mut self) -> Option<&'a str> {
1269 self.0.next()
1270 }
1271
1272 #[inline]
1273 fn size_hint(&self) -> (usize, Option<usize>) {
1274 self.0.size_hint()
1275 }
1276}
1277
1278#[stable(feature = "rust1", since = "1.0.0")]
1279#[allow(deprecated)]
1280impl<'a> DoubleEndedIterator for LinesAny<'a> {
1281 #[inline]
1282 fn next_back(&mut self) -> Option<&'a str> {
1283 self.0.next_back()
1284 }
1285}
1286
1287#[stable(feature = "fused", since = "1.26.0")]
1288#[allow(deprecated)]
1289impl FusedIterator for LinesAny<'_> {}
1290
1291#[stable(feature = "split_whitespace", since = "1.1.0")]
1299#[derive(Clone, Debug)]
1300pub struct SplitWhitespace<'a> {
1301 pub(super) inner: Filter<Split<'a, IsWhitespace>, IsNotEmpty>,
1302}
1303
1304#[stable(feature = "split_ascii_whitespace", since = "1.34.0")]
1312#[derive(Clone, Debug)]
1313pub struct SplitAsciiWhitespace<'a> {
1314 pub(super) inner:
1315 Map<Filter<SliceSplit<'a, u8, IsAsciiWhitespace>, BytesIsNotEmpty>, UnsafeBytesToStr>,
1316}
1317
1318#[stable(feature = "split_inclusive", since = "1.51.0")]
1328#[ferrocene::prevalidated]
1329pub struct SplitInclusive<'a, P: Pattern>(pub(super) SplitInternal<'a, P>);
1330
1331#[stable(feature = "split_whitespace", since = "1.1.0")]
1332impl<'a> Iterator for SplitWhitespace<'a> {
1333 type Item = &'a str;
1334
1335 #[inline]
1336 fn next(&mut self) -> Option<&'a str> {
1337 self.inner.next()
1338 }
1339
1340 #[inline]
1341 fn size_hint(&self) -> (usize, Option<usize>) {
1342 self.inner.size_hint()
1343 }
1344
1345 #[inline]
1346 fn last(mut self) -> Option<&'a str> {
1347 self.next_back()
1348 }
1349}
1350
1351#[stable(feature = "split_whitespace", since = "1.1.0")]
1352impl<'a> DoubleEndedIterator for SplitWhitespace<'a> {
1353 #[inline]
1354 fn next_back(&mut self) -> Option<&'a str> {
1355 self.inner.next_back()
1356 }
1357}
1358
1359#[stable(feature = "fused", since = "1.26.0")]
1360impl FusedIterator for SplitWhitespace<'_> {}
1361
1362impl<'a> SplitWhitespace<'a> {
1363 #[inline]
1380 #[must_use]
1381 #[unstable(feature = "str_split_whitespace_remainder", issue = "77998")]
1382 pub fn remainder(&self) -> Option<&'a str> {
1383 self.inner.iter.remainder()
1384 }
1385}
1386
1387#[stable(feature = "split_ascii_whitespace", since = "1.34.0")]
1388impl<'a> Iterator for SplitAsciiWhitespace<'a> {
1389 type Item = &'a str;
1390
1391 #[inline]
1392 fn next(&mut self) -> Option<&'a str> {
1393 self.inner.next()
1394 }
1395
1396 #[inline]
1397 fn size_hint(&self) -> (usize, Option<usize>) {
1398 self.inner.size_hint()
1399 }
1400
1401 #[inline]
1402 fn last(mut self) -> Option<&'a str> {
1403 self.next_back()
1404 }
1405}
1406
1407#[stable(feature = "split_ascii_whitespace", since = "1.34.0")]
1408impl<'a> DoubleEndedIterator for SplitAsciiWhitespace<'a> {
1409 #[inline]
1410 fn next_back(&mut self) -> Option<&'a str> {
1411 self.inner.next_back()
1412 }
1413}
1414
1415#[stable(feature = "split_ascii_whitespace", since = "1.34.0")]
1416impl FusedIterator for SplitAsciiWhitespace<'_> {}
1417
1418impl<'a> SplitAsciiWhitespace<'a> {
1419 #[inline]
1438 #[must_use]
1439 #[unstable(feature = "str_split_whitespace_remainder", issue = "77998")]
1440 pub fn remainder(&self) -> Option<&'a str> {
1441 if self.inner.iter.iter.finished {
1442 return None;
1443 }
1444
1445 Some(unsafe { crate::str::from_utf8_unchecked(&self.inner.iter.iter.v) })
1447 }
1448}
1449
1450#[stable(feature = "split_inclusive", since = "1.51.0")]
1451impl<'a, P: Pattern> Iterator for SplitInclusive<'a, P> {
1452 type Item = &'a str;
1453
1454 #[inline]
1455 #[ferrocene::prevalidated]
1456 fn next(&mut self) -> Option<&'a str> {
1457 self.0.next_inclusive()
1458 }
1459}
1460
1461#[stable(feature = "split_inclusive", since = "1.51.0")]
1462impl<'a, P: Pattern<Searcher<'a>: fmt::Debug>> fmt::Debug for SplitInclusive<'a, P> {
1463 #[ferrocene::prevalidated]
1464 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1465 f.debug_struct("SplitInclusive").field("0", &self.0).finish()
1466 }
1467}
1468
1469#[stable(feature = "split_inclusive", since = "1.51.0")]
1471impl<'a, P: Pattern<Searcher<'a>: Clone>> Clone for SplitInclusive<'a, P> {
1472 fn clone(&self) -> Self {
1473 SplitInclusive(self.0.clone())
1474 }
1475}
1476
1477#[stable(feature = "split_inclusive", since = "1.51.0")]
1478impl<'a, P: Pattern<Searcher<'a>: DoubleEndedSearcher<'a>>> DoubleEndedIterator
1479 for SplitInclusive<'a, P>
1480{
1481 #[inline]
1482 fn next_back(&mut self) -> Option<&'a str> {
1483 self.0.next_back_inclusive()
1484 }
1485}
1486
1487#[stable(feature = "split_inclusive", since = "1.51.0")]
1488impl<'a, P: Pattern> FusedIterator for SplitInclusive<'a, P> {}
1489
1490impl<'a, P: Pattern> SplitInclusive<'a, P> {
1491 #[inline]
1507 #[unstable(feature = "str_split_inclusive_remainder", issue = "77998")]
1508 pub fn remainder(&self) -> Option<&'a str> {
1509 self.0.remainder()
1510 }
1511}
1512
1513#[derive(Clone)]
1520#[stable(feature = "encode_utf16", since = "1.8.0")]
1521pub struct EncodeUtf16<'a> {
1522 pub(super) chars: Chars<'a>,
1523 pub(super) extra: u16,
1524}
1525
1526#[stable(feature = "collection_debug", since = "1.17.0")]
1527impl fmt::Debug for EncodeUtf16<'_> {
1528 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1529 f.debug_struct("EncodeUtf16").finish_non_exhaustive()
1530 }
1531}
1532
1533#[stable(feature = "encode_utf16", since = "1.8.0")]
1534impl<'a> Iterator for EncodeUtf16<'a> {
1535 type Item = u16;
1536
1537 #[inline]
1538 fn next(&mut self) -> Option<u16> {
1539 if self.extra != 0 {
1540 let tmp = self.extra;
1541 self.extra = 0;
1542 return Some(tmp);
1543 }
1544
1545 let mut buf = [0; 2];
1546 self.chars.next().map(|ch| {
1547 let n = ch.encode_utf16(&mut buf).len();
1548 if n == 2 {
1549 self.extra = buf[1];
1550 }
1551 buf[0]
1552 })
1553 }
1554
1555 #[inline]
1556 fn size_hint(&self) -> (usize, Option<usize>) {
1557 let len = self.chars.iter.len();
1558 if self.extra == 0 {
1564 (len.div_ceil(3), Some(len))
1565 } else {
1566 (len.div_ceil(3) + 1, Some(len + 1))
1569 }
1570 }
1571}
1572
1573#[stable(feature = "fused", since = "1.26.0")]
1574impl FusedIterator for EncodeUtf16<'_> {}
1575
1576#[stable(feature = "str_escape", since = "1.34.0")]
1578#[derive(Clone, Debug)]
1579pub struct EscapeDebug<'a> {
1580 pub(super) inner: Chain<
1581 Flatten<option::IntoIter<char_mod::EscapeDebug>>,
1582 FlatMap<Chars<'a>, char_mod::EscapeDebug, CharEscapeDebugContinue>,
1583 >,
1584}
1585
1586#[stable(feature = "str_escape", since = "1.34.0")]
1588#[derive(Clone, Debug)]
1589pub struct EscapeDefault<'a> {
1590 pub(super) inner: FlatMap<Chars<'a>, char_mod::EscapeDefault, CharEscapeDefault>,
1591}
1592
1593#[stable(feature = "str_escape", since = "1.34.0")]
1595#[derive(Clone, Debug)]
1596pub struct EscapeUnicode<'a> {
1597 pub(super) inner: FlatMap<Chars<'a>, char_mod::EscapeUnicode, CharEscapeUnicode>,
1598}
1599
1600macro_rules! escape_types_impls {
1601 ($( $Name: ident ),+) => {$(
1602 #[stable(feature = "str_escape", since = "1.34.0")]
1603 impl<'a> fmt::Display for $Name<'a> {
1604 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1605 self.clone().try_for_each(|c| f.write_char(c))
1606 }
1607 }
1608
1609 #[stable(feature = "str_escape", since = "1.34.0")]
1610 impl<'a> Iterator for $Name<'a> {
1611 type Item = char;
1612
1613 #[inline]
1614 fn next(&mut self) -> Option<char> { self.inner.next() }
1615
1616 #[inline]
1617 fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
1618
1619 #[inline]
1620 fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R where
1621 Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Output = Acc>
1622 {
1623 self.inner.try_fold(init, fold)
1624 }
1625
1626 #[inline]
1627 fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
1628 where Fold: FnMut(Acc, Self::Item) -> Acc,
1629 {
1630 self.inner.fold(init, fold)
1631 }
1632 }
1633
1634 #[stable(feature = "str_escape", since = "1.34.0")]
1635 impl<'a> FusedIterator for $Name<'a> {}
1636 )+}
1637}
1638
1639escape_types_impls!(EscapeDebug, EscapeDefault, EscapeUnicode);