@@ -486,6 +486,12 @@ ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)),
486486 Unsafe . As < T , byte > ( ref value0 ) ,
487487 Unsafe . As < T , byte > ( ref value1 ) ,
488488 span . Length ) ;
489+ if ( typeof ( T ) == typeof ( char ) )
490+ return SpanHelpers . IndexOfAny (
491+ ref Unsafe . As < T , char > ( ref MemoryMarshal . GetReference ( span ) ) ,
492+ Unsafe . As < T , char > ( ref value0 ) ,
493+ Unsafe . As < T , char > ( ref value1 ) ,
494+ span . Length ) ;
489495
490496 return SpanHelpers . IndexOfAny ( ref MemoryMarshal . GetReference ( span ) , value0 , value1 , span . Length ) ;
491497 }
@@ -508,6 +514,13 @@ ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)),
508514 Unsafe . As < T , byte > ( ref value1 ) ,
509515 Unsafe . As < T , byte > ( ref value2 ) ,
510516 span . Length ) ;
517+ if ( typeof ( T ) == typeof ( char ) )
518+ return SpanHelpers . IndexOfAny (
519+ ref Unsafe . As < T , char > ( ref MemoryMarshal . GetReference ( span ) ) ,
520+ Unsafe . As < T , char > ( ref value0 ) ,
521+ Unsafe . As < T , char > ( ref value1 ) ,
522+ Unsafe . As < T , char > ( ref value2 ) ,
523+ span . Length ) ;
511524
512525 return SpanHelpers . IndexOfAny ( ref MemoryMarshal . GetReference ( span ) , value0 , value1 , value2 , span . Length ) ;
513526 }
@@ -522,11 +535,67 @@ public static int IndexOfAny<T>(this Span<T> span, ReadOnlySpan<T> values)
522535 where T : IEquatable < T >
523536 {
524537 if ( typeof ( T ) == typeof ( byte ) )
538+ {
525539 return SpanHelpers . IndexOfAny (
526540 ref Unsafe . As < T , byte > ( ref MemoryMarshal . GetReference ( span ) ) ,
527541 span . Length ,
528542 ref Unsafe . As < T , byte > ( ref MemoryMarshal . GetReference ( values ) ) ,
529543 values . Length ) ;
544+ }
545+ if ( typeof ( T ) == typeof ( char ) )
546+ {
547+ ref var valueRef = ref Unsafe . As < T , char > ( ref MemoryMarshal . GetReference ( values ) ) ;
548+ if ( values . Length == 5 )
549+ {
550+ // Length 5 is a common length for FileSystemName expression (", <, >, *, ?) and in preference to 2 as it has an explicit overload
551+ return SpanHelpers . IndexOfAny (
552+ ref Unsafe . As < T , char > ( ref MemoryMarshal . GetReference ( span ) ) ,
553+ valueRef ,
554+ Unsafe . Add ( ref valueRef , 1 ) ,
555+ Unsafe . Add ( ref valueRef , 2 ) ,
556+ Unsafe . Add ( ref valueRef , 3 ) ,
557+ Unsafe . Add ( ref valueRef , 4 ) ,
558+ span . Length ) ;
559+ }
560+ else if ( values . Length == 2 )
561+ {
562+ // Length 2 is a common length for simple wildcards (*, ?), directory separators (/, \), quotes (", '), brackets, etc
563+ return SpanHelpers . IndexOfAny (
564+ ref Unsafe . As < T , char > ( ref MemoryMarshal . GetReference ( span ) ) ,
565+ valueRef ,
566+ Unsafe . Add ( ref valueRef , 1 ) ,
567+ span . Length ) ;
568+ }
569+ else if ( values . Length == 4 )
570+ {
571+ // Length 4 before 3 as 3 has an explicit overload
572+ return SpanHelpers . IndexOfAny (
573+ ref Unsafe . As < T , char > ( ref MemoryMarshal . GetReference ( span ) ) ,
574+ valueRef ,
575+ Unsafe . Add ( ref valueRef , 1 ) ,
576+ Unsafe . Add ( ref valueRef , 2 ) ,
577+ Unsafe . Add ( ref valueRef , 3 ) ,
578+ span . Length ) ;
579+ }
580+ else if ( values . Length == 3 )
581+ {
582+ return SpanHelpers . IndexOfAny (
583+ ref Unsafe . As < T , char > ( ref MemoryMarshal . GetReference ( span ) ) ,
584+ valueRef ,
585+ Unsafe . Add ( ref valueRef , 1 ) ,
586+ Unsafe . Add ( ref valueRef , 2 ) ,
587+ span . Length ) ;
588+ }
589+ else if ( values . Length == 1 )
590+ {
591+ // Length 1 last, as ctoring a ReadOnlySpan to call this overload for a single value
592+ // is already throwing away a bunch of performance vs just calling IndexOf
593+ return SpanHelpers . IndexOf (
594+ ref Unsafe . As < T , char > ( ref MemoryMarshal . GetReference ( span ) ) ,
595+ valueRef ,
596+ span . Length ) ;
597+ }
598+ }
530599
531600 return SpanHelpers . IndexOfAny ( ref MemoryMarshal . GetReference ( span ) , span . Length , ref MemoryMarshal . GetReference ( values ) , values . Length ) ;
532601 }
@@ -547,6 +616,12 @@ ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)),
547616 Unsafe . As < T , byte > ( ref value0 ) ,
548617 Unsafe . As < T , byte > ( ref value1 ) ,
549618 span . Length ) ;
619+ if ( typeof ( T ) == typeof ( char ) )
620+ return SpanHelpers . IndexOfAny (
621+ ref Unsafe . As < T , char > ( ref MemoryMarshal . GetReference ( span ) ) ,
622+ Unsafe . As < T , char > ( ref value0 ) ,
623+ Unsafe . As < T , char > ( ref value1 ) ,
624+ span . Length ) ;
550625
551626 return SpanHelpers . IndexOfAny ( ref MemoryMarshal . GetReference ( span ) , value0 , value1 , span . Length ) ;
552627 }
@@ -569,6 +644,13 @@ ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)),
569644 Unsafe . As < T , byte > ( ref value1 ) ,
570645 Unsafe . As < T , byte > ( ref value2 ) ,
571646 span . Length ) ;
647+ if ( typeof ( T ) == typeof ( char ) )
648+ return SpanHelpers . IndexOfAny (
649+ ref Unsafe . As < T , char > ( ref MemoryMarshal . GetReference ( span ) ) ,
650+ Unsafe . As < T , char > ( ref value0 ) ,
651+ Unsafe . As < T , char > ( ref value1 ) ,
652+ Unsafe . As < T , char > ( ref value2 ) ,
653+ span . Length ) ;
572654
573655 return SpanHelpers . IndexOfAny ( ref MemoryMarshal . GetReference ( span ) , value0 , value1 , value2 , span . Length ) ;
574656 }
@@ -589,6 +671,61 @@ ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)),
589671 ref Unsafe . As < T , byte > ( ref MemoryMarshal . GetReference ( values ) ) ,
590672 values . Length ) ;
591673
674+ if ( typeof ( T ) == typeof ( char ) )
675+ {
676+ ref var valueRef = ref Unsafe . As < T , char > ( ref MemoryMarshal . GetReference ( values ) ) ;
677+ if ( values . Length == 5 )
678+ {
679+ // Length 5 is a common length for FileSystemName expression (", <, >, *, ?) and in preference to 2 as it has an explicit overload
680+ return SpanHelpers . IndexOfAny (
681+ ref Unsafe . As < T , char > ( ref MemoryMarshal . GetReference ( span ) ) ,
682+ valueRef ,
683+ Unsafe . Add ( ref valueRef , 1 ) ,
684+ Unsafe . Add ( ref valueRef , 2 ) ,
685+ Unsafe . Add ( ref valueRef , 3 ) ,
686+ Unsafe . Add ( ref valueRef , 4 ) ,
687+ span . Length ) ;
688+ }
689+ else if ( values . Length == 2 )
690+ {
691+ // Length 2 is a common length for simple wildcards (*, ?), directory separators (/, \), quotes (", '), brackets, etc
692+ return SpanHelpers . IndexOfAny (
693+ ref Unsafe . As < T , char > ( ref MemoryMarshal . GetReference ( span ) ) ,
694+ valueRef ,
695+ Unsafe . Add ( ref valueRef , 1 ) ,
696+ span . Length ) ;
697+ }
698+ else if ( values . Length == 4 )
699+ {
700+ // Length 4 before 3 as 3 has an explicit overload
701+ return SpanHelpers . IndexOfAny (
702+ ref Unsafe . As < T , char > ( ref MemoryMarshal . GetReference ( span ) ) ,
703+ valueRef ,
704+ Unsafe . Add ( ref valueRef , 1 ) ,
705+ Unsafe . Add ( ref valueRef , 2 ) ,
706+ Unsafe . Add ( ref valueRef , 3 ) ,
707+ span . Length ) ;
708+ }
709+ else if ( values . Length == 3 )
710+ {
711+ return SpanHelpers . IndexOfAny (
712+ ref Unsafe . As < T , char > ( ref MemoryMarshal . GetReference ( span ) ) ,
713+ valueRef ,
714+ Unsafe . Add ( ref valueRef , 1 ) ,
715+ Unsafe . Add ( ref valueRef , 2 ) ,
716+ span . Length ) ;
717+ }
718+ else if ( values . Length == 1 )
719+ {
720+ // Length 1 last, as ctoring a ReadOnlySpan to call this overload for a single value
721+ // is already throwing away a bunch of performance vs just calling IndexOf
722+ return SpanHelpers . IndexOf (
723+ ref Unsafe . As < T , char > ( ref MemoryMarshal . GetReference ( span ) ) ,
724+ valueRef ,
725+ span . Length ) ;
726+ }
727+ }
728+
592729 return SpanHelpers . IndexOfAny ( ref MemoryMarshal . GetReference ( span ) , span . Length , ref MemoryMarshal . GetReference ( values ) , values . Length ) ;
593730 }
594731
0 commit comments