@@ -79,9 +79,13 @@ use crate::alloc::Global;
7979#[ cfg( not( no_global_oom_handling) ) ]
8080use crate :: borrow:: ToOwned ;
8181use crate :: boxed:: Box ;
82- use crate :: collections:: VecDeque ;
8382use crate :: vec:: Vec ;
8483
84+ // Using a module here allows having the no_global_oom_handling
85+ // in only one place
86+ #[ cfg( not( no_global_oom_handling) ) ]
87+ mod byte_slice_make_case;
88+
8589// HACK(japaric): With cfg(test) `impl [T]` is not available, these three
8690// functions are actually methods that are in `impl [T]` but not in
8791// `core::slice::SliceExt` - we need to supply these functions for the
@@ -666,167 +670,6 @@ impl<T> [T] {
666670 }
667671}
668672
669- #[ cfg( not( test) ) ]
670- impl [ u8 ] {
671- #[ rustc_allow_incoherent_impl]
672- #[ unstable( issue = "none" , feature = "std_internals" ) ]
673- #[ allow( dead_code) ]
674- /// Safety:
675- /// - Must be valid UTF-8
676- pub unsafe fn make_utf8_uppercase ( & mut self ) -> Result < usize , VecDeque < u8 > > {
677- let mut queue = VecDeque :: new ( ) ;
678-
679- let mut read_offset = 0 ;
680- let mut write_offset = 0 ;
681-
682- while let Some ( ( codepoint, width) ) =
683- unsafe { core:: str:: next_code_point_with_width ( & mut self [ read_offset..] . iter ( ) ) }
684- {
685- read_offset += width;
686- // Queue must be flushed before encode_to_slice_or_else_to_queue is
687- // called to ensure proper order of bytes
688- dump_queue ( & mut queue, & mut self [ ..read_offset] , & mut write_offset) ;
689- let lowercase_char = unsafe { char:: from_u32_unchecked ( codepoint) } ;
690- for c in lowercase_char. to_uppercase ( ) {
691- encode_to_slice_or_else_to_queue (
692- c,
693- & mut queue,
694- & mut self [ ..read_offset] ,
695- & mut write_offset,
696- ) ;
697- }
698- }
699- assert_eq ! ( read_offset, self . len( ) ) ;
700- if write_offset < read_offset { Ok ( write_offset) } else { Err ( queue) }
701- }
702-
703- #[ rustc_allow_incoherent_impl]
704- #[ unstable( issue = "none" , feature = "std_internals" ) ]
705- #[ allow( dead_code) ]
706- /// Safety:
707- /// - Must be valid UTF-8
708- pub unsafe fn make_utf8_lowercase ( & mut self ) -> Result < usize , VecDeque < u8 > > {
709- let mut queue = VecDeque :: new ( ) ;
710-
711- let mut read_offset = 0 ;
712- let mut write_offset = 0 ;
713-
714- let mut final_sigma_automata = FinalSigmaAutomata :: new ( ) ;
715- while let Some ( ( codepoint, width) ) =
716- unsafe { core:: str:: next_code_point_with_width ( & mut self [ read_offset..] . iter ( ) ) }
717- {
718- read_offset += width;
719- // Queue must be flushed before encode_to_slice_or_else_to_queue is
720- // called to ensure proper order of bytes
721- dump_queue ( & mut queue, & mut self [ ..read_offset] , & mut write_offset) ;
722- let uppercase_char = unsafe { char:: from_u32_unchecked ( codepoint) } ;
723- if uppercase_char == 'Σ' {
724- // Σ maps to σ, except at the end of a word where it maps to ς.
725- // See core::str::to_lowercase
726- let rest = unsafe { core:: str:: from_utf8_unchecked ( & self [ read_offset..] ) } ;
727- let is_word_final =
728- final_sigma_automata. is_accepting ( ) && !case_ignorable_then_cased ( rest. chars ( ) ) ;
729- let sigma_lowercase = if is_word_final { 'ς' } else { 'σ' } ;
730- encode_to_slice_or_else_to_queue (
731- sigma_lowercase,
732- & mut queue,
733- & mut self [ ..read_offset] ,
734- & mut write_offset,
735- ) ;
736- } else {
737- for c in uppercase_char. to_lowercase ( ) {
738- encode_to_slice_or_else_to_queue (
739- c,
740- & mut queue,
741- & mut self [ ..read_offset] ,
742- & mut write_offset,
743- ) ;
744- }
745- }
746- final_sigma_automata. step ( uppercase_char) ;
747- }
748- assert_eq ! ( read_offset, self . len( ) ) ;
749- return if write_offset < read_offset { Ok ( write_offset) } else { Err ( queue) } ;
750-
751- // For now this is copy pasted from core::str, FIXME: DRY
752- fn case_ignorable_then_cased < I : Iterator < Item = char > > ( iter : I ) -> bool {
753- use core:: unicode:: { Case_Ignorable , Cased } ;
754- match iter. skip_while ( |& c| Case_Ignorable ( c) ) . next ( ) {
755- Some ( c) => Cased ( c) ,
756- None => false ,
757- }
758- }
759- }
760- }
761-
762- fn encode_to_slice_or_else_to_queue (
763- c : char ,
764- queue : & mut VecDeque < u8 > ,
765- slice : & mut [ u8 ] ,
766- write_offset : & mut usize ,
767- ) {
768- let mut buffer = [ 0 ; 4 ] ;
769- let len = c. encode_utf8 ( & mut buffer) . len ( ) ;
770- let writable_slice = & mut slice[ * write_offset..] ;
771- let direct_copy_length = core:: cmp:: min ( len, writable_slice. len ( ) ) ;
772- writable_slice[ ..direct_copy_length] . copy_from_slice ( & buffer[ ..direct_copy_length] ) ;
773- * write_offset += direct_copy_length;
774- queue. extend ( & buffer[ direct_copy_length..len] ) ;
775- }
776-
777- fn dump_queue ( queue : & mut VecDeque < u8 > , slice : & mut [ u8 ] , write_offset : & mut usize ) {
778- while * write_offset < slice. len ( ) {
779- match queue. pop_front ( ) {
780- Some ( b) => {
781- slice[ * write_offset] = b;
782- * write_offset += 1 ;
783- }
784- None => break ,
785- }
786- }
787- }
788-
789- #[ derive( Clone ) ]
790- enum FinalSigmaAutomata {
791- Init ,
792- Accepted ,
793- }
794-
795- impl FinalSigmaAutomata {
796- fn new ( ) -> Self {
797- Self :: Init
798- }
799-
800- fn is_accepting ( & self ) -> bool {
801- match self {
802- FinalSigmaAutomata :: Accepted => true ,
803- FinalSigmaAutomata :: Init => false ,
804- }
805- }
806-
807- fn step ( & mut self , c : char ) {
808- use core:: unicode:: { Case_Ignorable , Cased } ;
809-
810- use FinalSigmaAutomata :: * ;
811- * self = match self {
812- Init => {
813- if Cased ( c) {
814- Accepted
815- } else {
816- Init
817- }
818- }
819- Accepted => {
820- if Cased ( c) || Case_Ignorable ( c) {
821- Accepted
822- } else {
823- Init
824- }
825- }
826- }
827- }
828- }
829-
830673#[ cfg( not( test) ) ]
831674impl [ u8 ] {
832675 /// Returns a vector containing a copy of this slice where each byte
0 commit comments