1#[cfg(not(feature = "ferrocene_certified"))]
4use super::pattern::{DoubleEndedSearcher, Pattern, ReverseSearcher, Searcher};
5#[cfg(not(feature = "ferrocene_certified"))]
6use super::validations::{next_code_point, next_code_point_reverse};
7#[cfg(not(feature = "ferrocene_certified"))]
8use super::{
9 BytesIsNotEmpty, CharEscapeDebugContinue, CharEscapeDefault, CharEscapeUnicode,
10 IsAsciiWhitespace, IsNotEmpty, IsWhitespace, LinesMap, UnsafeBytesToStr, from_utf8_unchecked,
11};
12#[cfg(not(feature = "ferrocene_certified"))]
13use crate::fmt::{self, Write};
14#[cfg(not(feature = "ferrocene_certified"))]
15use crate::iter::{
16 Chain, Copied, Filter, FlatMap, Flatten, FusedIterator, Map, TrustedLen, TrustedRandomAccess,
17 TrustedRandomAccessNoCoerce,
18};
19use crate::num::NonZero;
20#[cfg(not(feature = "ferrocene_certified"))]
21use crate::ops::Try;
22#[cfg(not(feature = "ferrocene_certified"))]
23use crate::slice::{self, Split as SliceSplit};
24#[cfg(not(feature = "ferrocene_certified"))]
25use crate::{char as char_mod, option};
26
27#[cfg(feature = "ferrocene_certified")]
29#[rustfmt::skip]
30use {super::validations::next_code_point, crate::slice};
31
32#[cfg_attr(not(feature = "ferrocene_certified"), derive(Clone))]
41#[must_use = "iterators are lazy and do nothing unless consumed"]
42#[stable(feature = "rust1", since = "1.0.0")]
43pub struct Chars<'a> {
44 pub(super) iter: slice::Iter<'a, u8>,
45}
46
47#[stable(feature = "rust1", since = "1.0.0")]
48impl<'a> Iterator for Chars<'a> {
49 type Item = char;
50
51 #[inline]
52 fn next(&mut self) -> Option<char> {
53 unsafe { next_code_point(&mut self.iter).map(|ch| char::from_u32_unchecked(ch)) }
56 }
57
58 #[cfg(not(feature = "ferrocene_certified"))]
59 #[inline]
60 fn count(self) -> usize {
61 super::count::count_chars(self.as_str())
62 }
63
64 #[inline]
65 fn advance_by(&mut self, mut remainder: usize) -> Result<(), NonZero<usize>> {
66 const CHUNK_SIZE: usize = 32;
67
68 if remainder >= CHUNK_SIZE {
69 let mut chunks = self.iter.as_slice().as_chunks::<CHUNK_SIZE>().0.iter();
70 let mut bytes_skipped: usize = 0;
71
72 while remainder > CHUNK_SIZE
73 && let Some(chunk) = chunks.next()
74 {
75 bytes_skipped += CHUNK_SIZE;
76
77 let mut start_bytes = [false; CHUNK_SIZE];
78
79 for i in 0..CHUNK_SIZE {
80 start_bytes[i] = !super::validations::utf8_is_cont_byte(chunk[i]);
81 }
82
83 remainder -= start_bytes.into_iter().map(|i| i as u8).sum::<u8>() as usize;
84 }
85
86 unsafe { self.iter.advance_by(bytes_skipped).unwrap_unchecked() };
89
90 while self.iter.len() > 0 {
92 let b = self.iter.as_slice()[0];
93 if !super::validations::utf8_is_cont_byte(b) {
94 break;
95 }
96 unsafe { self.iter.advance_by(1).unwrap_unchecked() };
98 }
99 }
100
101 while (remainder > 0) && (self.iter.len() > 0) {
102 remainder -= 1;
103 let b = self.iter.as_slice()[0];
104 let slurp = super::validations::utf8_char_width(b);
105 unsafe { self.iter.advance_by(slurp).unwrap_unchecked() };
108 }
109
110 NonZero::new(remainder).map_or(Ok(()), Err)
111 }
112
113 #[inline]
114 fn size_hint(&self) -> (usize, Option<usize>) {
115 let len = self.iter.len();
116 (len.div_ceil(4), Some(len))
120 }
121
122 #[cfg(not(feature = "ferrocene_certified"))]
123 #[inline]
124 fn last(mut self) -> Option<char> {
125 self.next_back()
127 }
128}
129
130#[cfg(not(feature = "ferrocene_certified"))]
131#[stable(feature = "chars_debug_impl", since = "1.38.0")]
132impl fmt::Debug for Chars<'_> {
133 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
134 write!(f, "Chars(")?;
135 f.debug_list().entries(self.clone()).finish()?;
136 write!(f, ")")?;
137 Ok(())
138 }
139}
140
141#[cfg(not(feature = "ferrocene_certified"))]
142#[stable(feature = "rust1", since = "1.0.0")]
143impl<'a> DoubleEndedIterator for Chars<'a> {
144 #[inline]
145 fn next_back(&mut self) -> Option<char> {
146 unsafe { next_code_point_reverse(&mut self.iter).map(|ch| char::from_u32_unchecked(ch)) }
149 }
150}
151
152#[cfg(not(feature = "ferrocene_certified"))]
153#[stable(feature = "fused", since = "1.26.0")]
154impl FusedIterator for Chars<'_> {}
155
156#[cfg(not(feature = "ferrocene_certified"))]
157impl<'a> Chars<'a> {
158 #[stable(feature = "iter_to_slice", since = "1.4.0")]
176 #[must_use]
177 #[inline]
178 pub fn as_str(&self) -> &'a str {
179 unsafe { from_utf8_unchecked(self.iter.as_slice()) }
181 }
182}
183
184#[cfg(not(feature = "ferrocene_certified"))]
192#[derive(Clone, Debug)]
193#[must_use = "iterators are lazy and do nothing unless consumed"]
194#[stable(feature = "rust1", since = "1.0.0")]
195pub struct CharIndices<'a> {
196 pub(super) front_offset: usize,
197 pub(super) iter: Chars<'a>,
198}
199
200#[cfg(not(feature = "ferrocene_certified"))]
201#[stable(feature = "rust1", since = "1.0.0")]
202impl<'a> Iterator for CharIndices<'a> {
203 type Item = (usize, char);
204
205 #[inline]
206 fn next(&mut self) -> Option<(usize, char)> {
207 let pre_len = self.iter.iter.len();
208 match self.iter.next() {
209 None => None,
210 Some(ch) => {
211 let index = self.front_offset;
212 let len = self.iter.iter.len();
213 self.front_offset += pre_len - len;
214 Some((index, ch))
215 }
216 }
217 }
218
219 #[inline]
220 fn count(self) -> usize {
221 self.iter.count()
222 }
223
224 #[inline]
225 fn size_hint(&self) -> (usize, Option<usize>) {
226 self.iter.size_hint()
227 }
228
229 #[inline]
230 fn last(mut self) -> Option<(usize, char)> {
231 self.next_back()
233 }
234}
235
236#[cfg(not(feature = "ferrocene_certified"))]
237#[stable(feature = "rust1", since = "1.0.0")]
238impl<'a> DoubleEndedIterator for CharIndices<'a> {
239 #[inline]
240 fn next_back(&mut self) -> Option<(usize, char)> {
241 self.iter.next_back().map(|ch| {
242 let index = self.front_offset + self.iter.iter.len();
243 (index, ch)
244 })
245 }
246}
247
248#[cfg(not(feature = "ferrocene_certified"))]
249#[stable(feature = "fused", since = "1.26.0")]
250impl FusedIterator for CharIndices<'_> {}
251
252#[cfg(not(feature = "ferrocene_certified"))]
253impl<'a> CharIndices<'a> {
254 #[stable(feature = "iter_to_slice", since = "1.4.0")]
259 #[must_use]
260 #[inline]
261 pub fn as_str(&self) -> &'a str {
262 self.iter.as_str()
263 }
264
265 #[inline]
295 #[must_use]
296 #[stable(feature = "char_indices_offset", since = "1.82.0")]
297 pub fn offset(&self) -> usize {
298 self.front_offset
299 }
300}
301
302#[cfg(not(feature = "ferrocene_certified"))]
309#[must_use = "iterators are lazy and do nothing unless consumed"]
310#[stable(feature = "rust1", since = "1.0.0")]
311#[derive(Clone, Debug)]
312pub struct Bytes<'a>(pub(super) Copied<slice::Iter<'a, u8>>);
313
314#[cfg(not(feature = "ferrocene_certified"))]
315#[stable(feature = "rust1", since = "1.0.0")]
316impl Iterator for Bytes<'_> {
317 type Item = u8;
318
319 #[inline]
320 fn next(&mut self) -> Option<u8> {
321 self.0.next()
322 }
323
324 #[inline]
325 fn size_hint(&self) -> (usize, Option<usize>) {
326 self.0.size_hint()
327 }
328
329 #[inline]
330 fn count(self) -> usize {
331 self.0.count()
332 }
333
334 #[inline]
335 fn last(self) -> Option<Self::Item> {
336 self.0.last()
337 }
338
339 #[inline]
340 fn nth(&mut self, n: usize) -> Option<Self::Item> {
341 self.0.nth(n)
342 }
343
344 #[inline]
345 fn all<F>(&mut self, f: F) -> bool
346 where
347 F: FnMut(Self::Item) -> bool,
348 {
349 self.0.all(f)
350 }
351
352 #[inline]
353 fn any<F>(&mut self, f: F) -> bool
354 where
355 F: FnMut(Self::Item) -> bool,
356 {
357 self.0.any(f)
358 }
359
360 #[inline]
361 fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
362 where
363 P: FnMut(&Self::Item) -> bool,
364 {
365 self.0.find(predicate)
366 }
367
368 #[inline]
369 fn position<P>(&mut self, predicate: P) -> Option<usize>
370 where
371 P: FnMut(Self::Item) -> bool,
372 {
373 self.0.position(predicate)
374 }
375
376 #[inline]
377 fn rposition<P>(&mut self, predicate: P) -> Option<usize>
378 where
379 P: FnMut(Self::Item) -> bool,
380 {
381 self.0.rposition(predicate)
382 }
383
384 #[inline]
385 unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> u8 {
386 unsafe { self.0.__iterator_get_unchecked(idx) }
389 }
390}
391
392#[cfg(not(feature = "ferrocene_certified"))]
393#[stable(feature = "rust1", since = "1.0.0")]
394impl DoubleEndedIterator for Bytes<'_> {
395 #[inline]
396 fn next_back(&mut self) -> Option<u8> {
397 self.0.next_back()
398 }
399
400 #[inline]
401 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
402 self.0.nth_back(n)
403 }
404
405 #[inline]
406 fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
407 where
408 P: FnMut(&Self::Item) -> bool,
409 {
410 self.0.rfind(predicate)
411 }
412}
413
414#[cfg(not(feature = "ferrocene_certified"))]
415#[stable(feature = "rust1", since = "1.0.0")]
416impl ExactSizeIterator for Bytes<'_> {
417 #[inline]
418 fn len(&self) -> usize {
419 self.0.len()
420 }
421
422 #[inline]
423 fn is_empty(&self) -> bool {
424 self.0.is_empty()
425 }
426}
427
428#[cfg(not(feature = "ferrocene_certified"))]
429#[stable(feature = "fused", since = "1.26.0")]
430impl FusedIterator for Bytes<'_> {}
431
432#[cfg(not(feature = "ferrocene_certified"))]
433#[unstable(feature = "trusted_len", issue = "37572")]
434unsafe impl TrustedLen for Bytes<'_> {}
435
436#[cfg(not(feature = "ferrocene_certified"))]
437#[doc(hidden)]
438#[unstable(feature = "trusted_random_access", issue = "none")]
439unsafe impl TrustedRandomAccess for Bytes<'_> {}
440
441#[cfg(not(feature = "ferrocene_certified"))]
442#[doc(hidden)]
443#[unstable(feature = "trusted_random_access", issue = "none")]
444unsafe impl TrustedRandomAccessNoCoerce for Bytes<'_> {
445 const MAY_HAVE_SIDE_EFFECT: bool = false;
446}
447
448#[cfg(not(feature = "ferrocene_certified"))]
451macro_rules! derive_pattern_clone {
452 (clone $t:ident with |$s:ident| $e:expr) => {
453 impl<'a, P> Clone for $t<'a, P>
454 where
455 P: Pattern<Searcher<'a>: Clone>,
456 {
457 fn clone(&self) -> Self {
458 let $s = self;
459 $e
460 }
461 }
462 };
463}
464
465#[cfg(not(feature = "ferrocene_certified"))]
504macro_rules! generate_pattern_iterators {
505 {
506 forward:
508 $(#[$forward_iterator_attribute:meta])*
509 struct $forward_iterator:ident;
510
511 reverse:
513 $(#[$reverse_iterator_attribute:meta])*
514 struct $reverse_iterator:ident;
515
516 stability:
518 $(#[$common_stability_attribute:meta])*
519
520 internal:
522 $internal_iterator:ident yielding ($iterty:ty);
523
524 delegate $($t:tt)*
526 } => {
527 $(#[$forward_iterator_attribute])*
528 $(#[$common_stability_attribute])*
529 pub struct $forward_iterator<'a, P: Pattern>(pub(super) $internal_iterator<'a, P>);
530
531 $(#[$common_stability_attribute])*
532 impl<'a, P> fmt::Debug for $forward_iterator<'a, P>
533 where
534 P: Pattern<Searcher<'a>: fmt::Debug>,
535 {
536 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
537 f.debug_tuple(stringify!($forward_iterator))
538 .field(&self.0)
539 .finish()
540 }
541 }
542
543 $(#[$common_stability_attribute])*
544 impl<'a, P: Pattern> Iterator for $forward_iterator<'a, P> {
545 type Item = $iterty;
546
547 #[inline]
548 fn next(&mut self) -> Option<$iterty> {
549 self.0.next()
550 }
551 }
552
553 $(#[$common_stability_attribute])*
554 impl<'a, P> Clone for $forward_iterator<'a, P>
555 where
556 P: Pattern<Searcher<'a>: Clone>,
557 {
558 fn clone(&self) -> Self {
559 $forward_iterator(self.0.clone())
560 }
561 }
562
563 $(#[$reverse_iterator_attribute])*
564 $(#[$common_stability_attribute])*
565 pub struct $reverse_iterator<'a, P: Pattern>(pub(super) $internal_iterator<'a, P>);
566
567 $(#[$common_stability_attribute])*
568 impl<'a, P> fmt::Debug for $reverse_iterator<'a, P>
569 where
570 P: Pattern<Searcher<'a>: fmt::Debug>,
571 {
572 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
573 f.debug_tuple(stringify!($reverse_iterator))
574 .field(&self.0)
575 .finish()
576 }
577 }
578
579 $(#[$common_stability_attribute])*
580 impl<'a, P> Iterator for $reverse_iterator<'a, P>
581 where
582 P: Pattern<Searcher<'a>: ReverseSearcher<'a>>,
583 {
584 type Item = $iterty;
585
586 #[inline]
587 fn next(&mut self) -> Option<$iterty> {
588 self.0.next_back()
589 }
590 }
591
592 $(#[$common_stability_attribute])*
593 impl<'a, P> Clone for $reverse_iterator<'a, P>
594 where
595 P: Pattern<Searcher<'a>: Clone>,
596 {
597 fn clone(&self) -> Self {
598 $reverse_iterator(self.0.clone())
599 }
600 }
601
602 #[stable(feature = "fused", since = "1.26.0")]
603 impl<'a, P: Pattern> FusedIterator for $forward_iterator<'a, P> {}
604
605 #[stable(feature = "fused", since = "1.26.0")]
606 impl<'a, P> FusedIterator for $reverse_iterator<'a, P>
607 where
608 P: Pattern<Searcher<'a>: ReverseSearcher<'a>>,
609 {}
610
611 generate_pattern_iterators!($($t)* with $(#[$common_stability_attribute])*,
612 $forward_iterator,
613 $reverse_iterator, $iterty);
614 };
615 {
616 double ended; with $(#[$common_stability_attribute:meta])*,
617 $forward_iterator:ident,
618 $reverse_iterator:ident, $iterty:ty
619 } => {
620 $(#[$common_stability_attribute])*
621 impl<'a, P> DoubleEndedIterator for $forward_iterator<'a, P>
622 where
623 P: Pattern<Searcher<'a>: DoubleEndedSearcher<'a>>,
624 {
625 #[inline]
626 fn next_back(&mut self) -> Option<$iterty> {
627 self.0.next_back()
628 }
629 }
630
631 $(#[$common_stability_attribute])*
632 impl<'a, P> DoubleEndedIterator for $reverse_iterator<'a, P>
633 where
634 P: Pattern<Searcher<'a>: DoubleEndedSearcher<'a>>,
635 {
636 #[inline]
637 fn next_back(&mut self) -> Option<$iterty> {
638 self.0.next()
639 }
640 }
641 };
642 {
643 single ended; with $(#[$common_stability_attribute:meta])*,
644 $forward_iterator:ident,
645 $reverse_iterator:ident, $iterty:ty
646 } => {}
647}
648
649#[cfg(not(feature = "ferrocene_certified"))]
650derive_pattern_clone! {
651 clone SplitInternal
652 with |s| SplitInternal { matcher: s.matcher.clone(), ..*s }
653}
654
655#[cfg(not(feature = "ferrocene_certified"))]
656pub(super) struct SplitInternal<'a, P: Pattern> {
657 pub(super) start: usize,
658 pub(super) end: usize,
659 pub(super) matcher: P::Searcher<'a>,
660 pub(super) allow_trailing_empty: bool,
661 pub(super) finished: bool,
662}
663
664#[cfg(not(feature = "ferrocene_certified"))]
665impl<'a, P> fmt::Debug for SplitInternal<'a, P>
666where
667 P: Pattern<Searcher<'a>: fmt::Debug>,
668{
669 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
670 f.debug_struct("SplitInternal")
671 .field("start", &self.start)
672 .field("end", &self.end)
673 .field("matcher", &self.matcher)
674 .field("allow_trailing_empty", &self.allow_trailing_empty)
675 .field("finished", &self.finished)
676 .finish()
677 }
678}
679
680#[cfg(not(feature = "ferrocene_certified"))]
681impl<'a, P: Pattern> SplitInternal<'a, P> {
682 #[inline]
683 fn get_end(&mut self) -> Option<&'a str> {
684 if !self.finished {
685 self.finished = true;
686
687 if self.allow_trailing_empty || self.end - self.start > 0 {
688 let string = unsafe { self.matcher.haystack().get_unchecked(self.start..self.end) };
690 return Some(string);
691 }
692 }
693
694 None
695 }
696
697 #[inline]
698 fn next(&mut self) -> Option<&'a str> {
699 if self.finished {
700 return None;
701 }
702
703 let haystack = self.matcher.haystack();
704 match self.matcher.next_match() {
705 Some((a, b)) => unsafe {
707 let elt = haystack.get_unchecked(self.start..a);
708 self.start = b;
709 Some(elt)
710 },
711 None => self.get_end(),
712 }
713 }
714
715 #[inline]
716 fn next_inclusive(&mut self) -> Option<&'a str> {
717 if self.finished {
718 return None;
719 }
720
721 let haystack = self.matcher.haystack();
722 match self.matcher.next_match() {
723 Some((_, b)) => unsafe {
727 let elt = haystack.get_unchecked(self.start..b);
728 self.start = b;
729 Some(elt)
730 },
731 None => self.get_end(),
732 }
733 }
734
735 #[inline]
736 fn next_back(&mut self) -> Option<&'a str>
737 where
738 P::Searcher<'a>: ReverseSearcher<'a>,
739 {
740 if self.finished {
741 return None;
742 }
743
744 if !self.allow_trailing_empty {
745 self.allow_trailing_empty = true;
746 match self.next_back() {
747 Some(elt) if !elt.is_empty() => return Some(elt),
748 _ => {
749 if self.finished {
750 return None;
751 }
752 }
753 }
754 }
755
756 let haystack = self.matcher.haystack();
757 match self.matcher.next_match_back() {
758 Some((a, b)) => unsafe {
760 let elt = haystack.get_unchecked(b..self.end);
761 self.end = a;
762 Some(elt)
763 },
764 None => unsafe {
766 self.finished = true;
767 Some(haystack.get_unchecked(self.start..self.end))
768 },
769 }
770 }
771
772 #[inline]
773 fn next_back_inclusive(&mut self) -> Option<&'a str>
774 where
775 P::Searcher<'a>: ReverseSearcher<'a>,
776 {
777 if self.finished {
778 return None;
779 }
780
781 if !self.allow_trailing_empty {
782 self.allow_trailing_empty = true;
783 match self.next_back_inclusive() {
784 Some(elt) if !elt.is_empty() => return Some(elt),
785 _ => {
786 if self.finished {
787 return None;
788 }
789 }
790 }
791 }
792
793 let haystack = self.matcher.haystack();
794 match self.matcher.next_match_back() {
795 Some((_, b)) => unsafe {
799 let elt = haystack.get_unchecked(b..self.end);
800 self.end = b;
801 Some(elt)
802 },
803 None => unsafe {
809 self.finished = true;
810 Some(haystack.get_unchecked(self.start..self.end))
811 },
812 }
813 }
814
815 #[inline]
816 fn remainder(&self) -> Option<&'a str> {
817 if self.finished {
819 return None;
820 }
821
822 Some(unsafe { self.matcher.haystack().get_unchecked(self.start..self.end) })
824 }
825}
826
827#[cfg(not(feature = "ferrocene_certified"))]
828generate_pattern_iterators! {
829 forward:
830 struct Split;
834 reverse:
835 struct RSplit;
839 stability:
840 #[stable(feature = "rust1", since = "1.0.0")]
841 internal:
842 SplitInternal yielding (&'a str);
843 delegate double ended;
844}
845
846#[cfg(not(feature = "ferrocene_certified"))]
847impl<'a, P: Pattern> Split<'a, P> {
848 #[inline]
864 #[unstable(feature = "str_split_remainder", issue = "77998")]
865 pub fn remainder(&self) -> Option<&'a str> {
866 self.0.remainder()
867 }
868}
869
870#[cfg(not(feature = "ferrocene_certified"))]
871impl<'a, P: Pattern> RSplit<'a, P> {
872 #[inline]
888 #[unstable(feature = "str_split_remainder", issue = "77998")]
889 pub fn remainder(&self) -> Option<&'a str> {
890 self.0.remainder()
891 }
892}
893
894#[cfg(not(feature = "ferrocene_certified"))]
895generate_pattern_iterators! {
896 forward:
897 struct SplitTerminator;
901 reverse:
902 struct RSplitTerminator;
906 stability:
907 #[stable(feature = "rust1", since = "1.0.0")]
908 internal:
909 SplitInternal yielding (&'a str);
910 delegate double ended;
911}
912
913#[cfg(not(feature = "ferrocene_certified"))]
914impl<'a, P: Pattern> SplitTerminator<'a, P> {
915 #[inline]
931 #[unstable(feature = "str_split_remainder", issue = "77998")]
932 pub fn remainder(&self) -> Option<&'a str> {
933 self.0.remainder()
934 }
935}
936
937#[cfg(not(feature = "ferrocene_certified"))]
938impl<'a, P: Pattern> RSplitTerminator<'a, P> {
939 #[inline]
955 #[unstable(feature = "str_split_remainder", issue = "77998")]
956 pub fn remainder(&self) -> Option<&'a str> {
957 self.0.remainder()
958 }
959}
960
961#[cfg(not(feature = "ferrocene_certified"))]
962derive_pattern_clone! {
963 clone SplitNInternal
964 with |s| SplitNInternal { iter: s.iter.clone(), ..*s }
965}
966
967#[cfg(not(feature = "ferrocene_certified"))]
968pub(super) struct SplitNInternal<'a, P: Pattern> {
969 pub(super) iter: SplitInternal<'a, P>,
970 pub(super) count: usize,
972}
973
974#[cfg(not(feature = "ferrocene_certified"))]
975impl<'a, P> fmt::Debug for SplitNInternal<'a, P>
976where
977 P: Pattern<Searcher<'a>: fmt::Debug>,
978{
979 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
980 f.debug_struct("SplitNInternal")
981 .field("iter", &self.iter)
982 .field("count", &self.count)
983 .finish()
984 }
985}
986
987#[cfg(not(feature = "ferrocene_certified"))]
988impl<'a, P: Pattern> SplitNInternal<'a, P> {
989 #[inline]
990 fn next(&mut self) -> Option<&'a str> {
991 match self.count {
992 0 => None,
993 1 => {
994 self.count = 0;
995 self.iter.get_end()
996 }
997 _ => {
998 self.count -= 1;
999 self.iter.next()
1000 }
1001 }
1002 }
1003
1004 #[inline]
1005 fn next_back(&mut self) -> Option<&'a str>
1006 where
1007 P::Searcher<'a>: ReverseSearcher<'a>,
1008 {
1009 match self.count {
1010 0 => None,
1011 1 => {
1012 self.count = 0;
1013 self.iter.get_end()
1014 }
1015 _ => {
1016 self.count -= 1;
1017 self.iter.next_back()
1018 }
1019 }
1020 }
1021
1022 #[inline]
1023 fn remainder(&self) -> Option<&'a str> {
1024 self.iter.remainder()
1025 }
1026}
1027
1028#[cfg(not(feature = "ferrocene_certified"))]
1029generate_pattern_iterators! {
1030 forward:
1031 struct SplitN;
1035 reverse:
1036 struct RSplitN;
1040 stability:
1041 #[stable(feature = "rust1", since = "1.0.0")]
1042 internal:
1043 SplitNInternal yielding (&'a str);
1044 delegate single ended;
1045}
1046
1047#[cfg(not(feature = "ferrocene_certified"))]
1048impl<'a, P: Pattern> SplitN<'a, P> {
1049 #[inline]
1065 #[unstable(feature = "str_split_remainder", issue = "77998")]
1066 pub fn remainder(&self) -> Option<&'a str> {
1067 self.0.remainder()
1068 }
1069}
1070
1071#[cfg(not(feature = "ferrocene_certified"))]
1072impl<'a, P: Pattern> RSplitN<'a, P> {
1073 #[inline]
1089 #[unstable(feature = "str_split_remainder", issue = "77998")]
1090 pub fn remainder(&self) -> Option<&'a str> {
1091 self.0.remainder()
1092 }
1093}
1094
1095#[cfg(not(feature = "ferrocene_certified"))]
1096derive_pattern_clone! {
1097 clone MatchIndicesInternal
1098 with |s| MatchIndicesInternal(s.0.clone())
1099}
1100
1101#[cfg(not(feature = "ferrocene_certified"))]
1102pub(super) struct MatchIndicesInternal<'a, P: Pattern>(pub(super) P::Searcher<'a>);
1103
1104#[cfg(not(feature = "ferrocene_certified"))]
1105impl<'a, P> fmt::Debug for MatchIndicesInternal<'a, P>
1106where
1107 P: Pattern<Searcher<'a>: fmt::Debug>,
1108{
1109 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1110 f.debug_tuple("MatchIndicesInternal").field(&self.0).finish()
1111 }
1112}
1113
1114#[cfg(not(feature = "ferrocene_certified"))]
1115impl<'a, P: Pattern> MatchIndicesInternal<'a, P> {
1116 #[inline]
1117 fn next(&mut self) -> Option<(usize, &'a str)> {
1118 self.0
1119 .next_match()
1120 .map(|(start, end)| unsafe { (start, self.0.haystack().get_unchecked(start..end)) })
1122 }
1123
1124 #[inline]
1125 fn next_back(&mut self) -> Option<(usize, &'a str)>
1126 where
1127 P::Searcher<'a>: ReverseSearcher<'a>,
1128 {
1129 self.0
1130 .next_match_back()
1131 .map(|(start, end)| unsafe { (start, self.0.haystack().get_unchecked(start..end)) })
1133 }
1134}
1135
1136#[cfg(not(feature = "ferrocene_certified"))]
1137generate_pattern_iterators! {
1138 forward:
1139 struct MatchIndices;
1143 reverse:
1144 struct RMatchIndices;
1148 stability:
1149 #[stable(feature = "str_match_indices", since = "1.5.0")]
1150 internal:
1151 MatchIndicesInternal yielding ((usize, &'a str));
1152 delegate double ended;
1153}
1154
1155#[cfg(not(feature = "ferrocene_certified"))]
1156derive_pattern_clone! {
1157 clone MatchesInternal
1158 with |s| MatchesInternal(s.0.clone())
1159}
1160
1161#[cfg(not(feature = "ferrocene_certified"))]
1162pub(super) struct MatchesInternal<'a, P: Pattern>(pub(super) P::Searcher<'a>);
1163
1164#[cfg(not(feature = "ferrocene_certified"))]
1165impl<'a, P> fmt::Debug for MatchesInternal<'a, P>
1166where
1167 P: Pattern<Searcher<'a>: fmt::Debug>,
1168{
1169 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1170 f.debug_tuple("MatchesInternal").field(&self.0).finish()
1171 }
1172}
1173
1174#[cfg(not(feature = "ferrocene_certified"))]
1175impl<'a, P: Pattern> MatchesInternal<'a, P> {
1176 #[inline]
1177 fn next(&mut self) -> Option<&'a str> {
1178 self.0.next_match().map(|(a, b)| unsafe {
1180 self.0.haystack().get_unchecked(a..b)
1182 })
1183 }
1184
1185 #[inline]
1186 fn next_back(&mut self) -> Option<&'a str>
1187 where
1188 P::Searcher<'a>: ReverseSearcher<'a>,
1189 {
1190 self.0.next_match_back().map(|(a, b)| unsafe {
1192 self.0.haystack().get_unchecked(a..b)
1194 })
1195 }
1196}
1197
1198#[cfg(not(feature = "ferrocene_certified"))]
1199generate_pattern_iterators! {
1200 forward:
1201 struct Matches;
1205 reverse:
1206 struct RMatches;
1210 stability:
1211 #[stable(feature = "str_matches", since = "1.2.0")]
1212 internal:
1213 MatchesInternal yielding (&'a str);
1214 delegate double ended;
1215}
1216
1217#[cfg(not(feature = "ferrocene_certified"))]
1224#[stable(feature = "rust1", since = "1.0.0")]
1225#[must_use = "iterators are lazy and do nothing unless consumed"]
1226#[derive(Clone, Debug)]
1227pub struct Lines<'a>(pub(super) Map<SplitInclusive<'a, char>, LinesMap>);
1228
1229#[cfg(not(feature = "ferrocene_certified"))]
1230#[stable(feature = "rust1", since = "1.0.0")]
1231impl<'a> Iterator for Lines<'a> {
1232 type Item = &'a str;
1233
1234 #[inline]
1235 fn next(&mut self) -> Option<&'a str> {
1236 self.0.next()
1237 }
1238
1239 #[inline]
1240 fn size_hint(&self) -> (usize, Option<usize>) {
1241 self.0.size_hint()
1242 }
1243
1244 #[inline]
1245 fn last(mut self) -> Option<&'a str> {
1246 self.next_back()
1247 }
1248}
1249
1250#[cfg(not(feature = "ferrocene_certified"))]
1251#[stable(feature = "rust1", since = "1.0.0")]
1252impl<'a> DoubleEndedIterator for Lines<'a> {
1253 #[inline]
1254 fn next_back(&mut self) -> Option<&'a str> {
1255 self.0.next_back()
1256 }
1257}
1258
1259#[cfg(not(feature = "ferrocene_certified"))]
1260#[stable(feature = "fused", since = "1.26.0")]
1261impl FusedIterator for Lines<'_> {}
1262
1263#[cfg(not(feature = "ferrocene_certified"))]
1264impl<'a> Lines<'a> {
1265 #[inline]
1282 #[must_use]
1283 #[unstable(feature = "str_lines_remainder", issue = "77998")]
1284 pub fn remainder(&self) -> Option<&'a str> {
1285 self.0.iter.remainder()
1286 }
1287}
1288
1289#[cfg(not(feature = "ferrocene_certified"))]
1293#[stable(feature = "rust1", since = "1.0.0")]
1294#[deprecated(since = "1.4.0", note = "use lines()/Lines instead now")]
1295#[must_use = "iterators are lazy and do nothing unless consumed"]
1296#[derive(Clone, Debug)]
1297#[allow(deprecated)]
1298pub struct LinesAny<'a>(pub(super) Lines<'a>);
1299
1300#[cfg(not(feature = "ferrocene_certified"))]
1301#[stable(feature = "rust1", since = "1.0.0")]
1302#[allow(deprecated)]
1303impl<'a> Iterator for LinesAny<'a> {
1304 type Item = &'a str;
1305
1306 #[inline]
1307 fn next(&mut self) -> Option<&'a str> {
1308 self.0.next()
1309 }
1310
1311 #[inline]
1312 fn size_hint(&self) -> (usize, Option<usize>) {
1313 self.0.size_hint()
1314 }
1315}
1316
1317#[cfg(not(feature = "ferrocene_certified"))]
1318#[stable(feature = "rust1", since = "1.0.0")]
1319#[allow(deprecated)]
1320impl<'a> DoubleEndedIterator for LinesAny<'a> {
1321 #[inline]
1322 fn next_back(&mut self) -> Option<&'a str> {
1323 self.0.next_back()
1324 }
1325}
1326
1327#[cfg(not(feature = "ferrocene_certified"))]
1328#[stable(feature = "fused", since = "1.26.0")]
1329#[allow(deprecated)]
1330impl FusedIterator for LinesAny<'_> {}
1331
1332#[cfg(not(feature = "ferrocene_certified"))]
1340#[stable(feature = "split_whitespace", since = "1.1.0")]
1341#[derive(Clone, Debug)]
1342pub struct SplitWhitespace<'a> {
1343 pub(super) inner: Filter<Split<'a, IsWhitespace>, IsNotEmpty>,
1344}
1345
1346#[cfg(not(feature = "ferrocene_certified"))]
1354#[stable(feature = "split_ascii_whitespace", since = "1.34.0")]
1355#[derive(Clone, Debug)]
1356pub struct SplitAsciiWhitespace<'a> {
1357 pub(super) inner:
1358 Map<Filter<SliceSplit<'a, u8, IsAsciiWhitespace>, BytesIsNotEmpty>, UnsafeBytesToStr>,
1359}
1360
1361#[cfg(not(feature = "ferrocene_certified"))]
1371#[stable(feature = "split_inclusive", since = "1.51.0")]
1372pub struct SplitInclusive<'a, P: Pattern>(pub(super) SplitInternal<'a, P>);
1373
1374#[cfg(not(feature = "ferrocene_certified"))]
1375#[stable(feature = "split_whitespace", since = "1.1.0")]
1376impl<'a> Iterator for SplitWhitespace<'a> {
1377 type Item = &'a str;
1378
1379 #[inline]
1380 fn next(&mut self) -> Option<&'a str> {
1381 self.inner.next()
1382 }
1383
1384 #[inline]
1385 fn size_hint(&self) -> (usize, Option<usize>) {
1386 self.inner.size_hint()
1387 }
1388
1389 #[inline]
1390 fn last(mut self) -> Option<&'a str> {
1391 self.next_back()
1392 }
1393}
1394
1395#[cfg(not(feature = "ferrocene_certified"))]
1396#[stable(feature = "split_whitespace", since = "1.1.0")]
1397impl<'a> DoubleEndedIterator for SplitWhitespace<'a> {
1398 #[inline]
1399 fn next_back(&mut self) -> Option<&'a str> {
1400 self.inner.next_back()
1401 }
1402}
1403
1404#[cfg(not(feature = "ferrocene_certified"))]
1405#[stable(feature = "fused", since = "1.26.0")]
1406impl FusedIterator for SplitWhitespace<'_> {}
1407
1408#[cfg(not(feature = "ferrocene_certified"))]
1409impl<'a> SplitWhitespace<'a> {
1410 #[inline]
1427 #[must_use]
1428 #[unstable(feature = "str_split_whitespace_remainder", issue = "77998")]
1429 pub fn remainder(&self) -> Option<&'a str> {
1430 self.inner.iter.remainder()
1431 }
1432}
1433
1434#[cfg(not(feature = "ferrocene_certified"))]
1435#[stable(feature = "split_ascii_whitespace", since = "1.34.0")]
1436impl<'a> Iterator for SplitAsciiWhitespace<'a> {
1437 type Item = &'a str;
1438
1439 #[inline]
1440 fn next(&mut self) -> Option<&'a str> {
1441 self.inner.next()
1442 }
1443
1444 #[inline]
1445 fn size_hint(&self) -> (usize, Option<usize>) {
1446 self.inner.size_hint()
1447 }
1448
1449 #[inline]
1450 fn last(mut self) -> Option<&'a str> {
1451 self.next_back()
1452 }
1453}
1454
1455#[cfg(not(feature = "ferrocene_certified"))]
1456#[stable(feature = "split_ascii_whitespace", since = "1.34.0")]
1457impl<'a> DoubleEndedIterator for SplitAsciiWhitespace<'a> {
1458 #[inline]
1459 fn next_back(&mut self) -> Option<&'a str> {
1460 self.inner.next_back()
1461 }
1462}
1463
1464#[cfg(not(feature = "ferrocene_certified"))]
1465#[stable(feature = "split_ascii_whitespace", since = "1.34.0")]
1466impl FusedIterator for SplitAsciiWhitespace<'_> {}
1467
1468#[cfg(not(feature = "ferrocene_certified"))]
1469impl<'a> SplitAsciiWhitespace<'a> {
1470 #[inline]
1489 #[must_use]
1490 #[unstable(feature = "str_split_whitespace_remainder", issue = "77998")]
1491 pub fn remainder(&self) -> Option<&'a str> {
1492 if self.inner.iter.iter.finished {
1493 return None;
1494 }
1495
1496 Some(unsafe { crate::str::from_utf8_unchecked(&self.inner.iter.iter.v) })
1498 }
1499}
1500
1501#[cfg(not(feature = "ferrocene_certified"))]
1502#[stable(feature = "split_inclusive", since = "1.51.0")]
1503impl<'a, P: Pattern> Iterator for SplitInclusive<'a, P> {
1504 type Item = &'a str;
1505
1506 #[inline]
1507 fn next(&mut self) -> Option<&'a str> {
1508 self.0.next_inclusive()
1509 }
1510}
1511
1512#[cfg(not(feature = "ferrocene_certified"))]
1513#[stable(feature = "split_inclusive", since = "1.51.0")]
1514impl<'a, P: Pattern<Searcher<'a>: fmt::Debug>> fmt::Debug for SplitInclusive<'a, P> {
1515 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1516 f.debug_struct("SplitInclusive").field("0", &self.0).finish()
1517 }
1518}
1519
1520#[cfg(not(feature = "ferrocene_certified"))]
1522#[stable(feature = "split_inclusive", since = "1.51.0")]
1523impl<'a, P: Pattern<Searcher<'a>: Clone>> Clone for SplitInclusive<'a, P> {
1524 fn clone(&self) -> Self {
1525 SplitInclusive(self.0.clone())
1526 }
1527}
1528
1529#[cfg(not(feature = "ferrocene_certified"))]
1530#[stable(feature = "split_inclusive", since = "1.51.0")]
1531impl<'a, P: Pattern<Searcher<'a>: DoubleEndedSearcher<'a>>> DoubleEndedIterator
1532 for SplitInclusive<'a, P>
1533{
1534 #[inline]
1535 fn next_back(&mut self) -> Option<&'a str> {
1536 self.0.next_back_inclusive()
1537 }
1538}
1539
1540#[cfg(not(feature = "ferrocene_certified"))]
1541#[stable(feature = "split_inclusive", since = "1.51.0")]
1542impl<'a, P: Pattern> FusedIterator for SplitInclusive<'a, P> {}
1543
1544#[cfg(not(feature = "ferrocene_certified"))]
1545impl<'a, P: Pattern> SplitInclusive<'a, P> {
1546 #[inline]
1562 #[unstable(feature = "str_split_inclusive_remainder", issue = "77998")]
1563 pub fn remainder(&self) -> Option<&'a str> {
1564 self.0.remainder()
1565 }
1566}
1567
1568#[cfg(not(feature = "ferrocene_certified"))]
1575#[derive(Clone)]
1576#[stable(feature = "encode_utf16", since = "1.8.0")]
1577pub struct EncodeUtf16<'a> {
1578 pub(super) chars: Chars<'a>,
1579 pub(super) extra: u16,
1580}
1581
1582#[cfg(not(feature = "ferrocene_certified"))]
1583#[stable(feature = "collection_debug", since = "1.17.0")]
1584impl fmt::Debug for EncodeUtf16<'_> {
1585 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1586 f.debug_struct("EncodeUtf16").finish_non_exhaustive()
1587 }
1588}
1589
1590#[cfg(not(feature = "ferrocene_certified"))]
1591#[stable(feature = "encode_utf16", since = "1.8.0")]
1592impl<'a> Iterator for EncodeUtf16<'a> {
1593 type Item = u16;
1594
1595 #[inline]
1596 fn next(&mut self) -> Option<u16> {
1597 if self.extra != 0 {
1598 let tmp = self.extra;
1599 self.extra = 0;
1600 return Some(tmp);
1601 }
1602
1603 let mut buf = [0; 2];
1604 self.chars.next().map(|ch| {
1605 let n = ch.encode_utf16(&mut buf).len();
1606 if n == 2 {
1607 self.extra = buf[1];
1608 }
1609 buf[0]
1610 })
1611 }
1612
1613 #[inline]
1614 fn size_hint(&self) -> (usize, Option<usize>) {
1615 let len = self.chars.iter.len();
1616 if self.extra == 0 {
1625 (len.div_ceil(3), Some(len))
1626 } else {
1627 (len.div_ceil(3) + 1, Some(len + 1))
1630 }
1631 }
1632}
1633
1634#[cfg(not(feature = "ferrocene_certified"))]
1635#[stable(feature = "fused", since = "1.26.0")]
1636impl FusedIterator for EncodeUtf16<'_> {}
1637
1638#[cfg(not(feature = "ferrocene_certified"))]
1640#[stable(feature = "str_escape", since = "1.34.0")]
1641#[derive(Clone, Debug)]
1642pub struct EscapeDebug<'a> {
1643 pub(super) inner: Chain<
1644 Flatten<option::IntoIter<char_mod::EscapeDebug>>,
1645 FlatMap<Chars<'a>, char_mod::EscapeDebug, CharEscapeDebugContinue>,
1646 >,
1647}
1648
1649#[cfg(not(feature = "ferrocene_certified"))]
1651#[stable(feature = "str_escape", since = "1.34.0")]
1652#[derive(Clone, Debug)]
1653pub struct EscapeDefault<'a> {
1654 pub(super) inner: FlatMap<Chars<'a>, char_mod::EscapeDefault, CharEscapeDefault>,
1655}
1656
1657#[cfg(not(feature = "ferrocene_certified"))]
1659#[stable(feature = "str_escape", since = "1.34.0")]
1660#[derive(Clone, Debug)]
1661pub struct EscapeUnicode<'a> {
1662 pub(super) inner: FlatMap<Chars<'a>, char_mod::EscapeUnicode, CharEscapeUnicode>,
1663}
1664
1665#[cfg(not(feature = "ferrocene_certified"))]
1666macro_rules! escape_types_impls {
1667 ($( $Name: ident ),+) => {$(
1668 #[stable(feature = "str_escape", since = "1.34.0")]
1669 impl<'a> fmt::Display for $Name<'a> {
1670 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1671 self.clone().try_for_each(|c| f.write_char(c))
1672 }
1673 }
1674
1675 #[stable(feature = "str_escape", since = "1.34.0")]
1676 impl<'a> Iterator for $Name<'a> {
1677 type Item = char;
1678
1679 #[inline]
1680 fn next(&mut self) -> Option<char> { self.inner.next() }
1681
1682 #[inline]
1683 fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
1684
1685 #[inline]
1686 fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R where
1687 Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Output = Acc>
1688 {
1689 self.inner.try_fold(init, fold)
1690 }
1691
1692 #[inline]
1693 fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
1694 where Fold: FnMut(Acc, Self::Item) -> Acc,
1695 {
1696 self.inner.fold(init, fold)
1697 }
1698 }
1699
1700 #[stable(feature = "str_escape", since = "1.34.0")]
1701 impl<'a> FusedIterator for $Name<'a> {}
1702 )+}
1703}
1704
1705#[cfg(not(feature = "ferrocene_certified"))]
1706escape_types_impls!(EscapeDebug, EscapeDefault, EscapeUnicode);