@@ -407,17 +407,23 @@ impl str {
407407 /// ```
408408 #[ unstable( feature = "round_char_boundary" , issue = "93743" ) ]
409409 #[ inline]
410- pub fn floor_char_boundary ( & self , index : usize ) -> usize {
410+ pub const fn floor_char_boundary ( & self , index : usize ) -> usize {
411411 if index >= self . len ( ) {
412412 self . len ( )
413413 } else {
414- let lower_bound = index. saturating_sub ( 3 ) ;
415- let new_index = self . as_bytes ( ) [ lower_bound..=index]
416- . iter ( )
417- . rposition ( |b| b. is_utf8_char_boundary ( ) ) ;
418-
419- // SAFETY: we know that the character boundary will be within four bytes
420- unsafe { lower_bound + new_index. unwrap_unchecked ( ) }
414+ let mut i = index;
415+ while i > 0 {
416+ if self . as_bytes ( ) [ i] . is_utf8_char_boundary ( ) {
417+ break ;
418+ }
419+ i -= 1 ;
420+ }
421+
422+ // The character boundary will be within four bytes of the index
423+ debug_assert ! ( i >= index. saturating_sub( 3 ) ) ;
424+ debug_assert ! ( self . is_char_boundary( i) ) ;
425+
426+ i
421427 }
422428 }
423429
@@ -445,15 +451,23 @@ impl str {
445451 /// ```
446452 #[ unstable( feature = "round_char_boundary" , issue = "93743" ) ]
447453 #[ inline]
448- pub fn ceil_char_boundary ( & self , index : usize ) -> usize {
454+ pub const fn ceil_char_boundary ( & self , index : usize ) -> usize {
449455 if index >= self . len ( ) {
450456 self . len ( )
451457 } else {
452- let upper_bound = Ord :: min ( index + 4 , self . len ( ) ) ;
453- self . as_bytes ( ) [ index..upper_bound]
454- . iter ( )
455- . position ( |b| b. is_utf8_char_boundary ( ) )
456- . map_or ( upper_bound, |pos| pos + index)
458+ let mut i = index;
459+ while i < self . len ( ) {
460+ if self . as_bytes ( ) [ i] . is_utf8_char_boundary ( ) {
461+ break ;
462+ }
463+ i += 1 ;
464+ }
465+
466+ // The character boundary will be within four bytes of the index
467+ debug_assert ! ( i <= index + 3 ) ;
468+ debug_assert ! ( self . is_char_boundary( i) ) ;
469+
470+ i
457471 }
458472 }
459473
0 commit comments