Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[API Proposal]: Add ToLowerOrdinal() & ToUpperOrdinal() #90999

Open
Neme12 opened this issue Aug 23, 2023 · 4 comments
Open

[API Proposal]: Add ToLowerOrdinal() & ToUpperOrdinal() #90999

Neme12 opened this issue Aug 23, 2023 · 4 comments
Assignees
Labels
api-suggestion Early API idea and discussion, it is NOT ready for implementation area-System.Globalization
Milestone

Comments

@Neme12
Copy link

Neme12 commented Aug 23, 2023

Background and motivation

Since #32247/#40910, this code

string.Equals(a, b, StringComparison.OrdinalIgnoreCase)

is no longer equivalent to this code

a.ToUpperInvariant() == b.ToUpperInvariant()

That's why I'm proposing to add ToLowerOrdinal() and ToUpperOrdinal() methods that would be guaranteed to have the same semantics as OrdinalIgnoreCase comparisons, and that would also be guaranteed to be case folded letter-by-letter and have the same length as the input string (and IMO, ToLowerInvariant and ToUpperInvariant should be changed to use proper ICU case semantics that wouldn't have to result in the same length, as per #32247 (comment), but that's a separate discussion).

API Proposal

 namespace System;

 public sealed partial class String
 {
     public string ToLower();
     public string ToLower(CultureInfo? culture);
     public string ToLowerInvariant();
+    public string ToLowerOrdinal();
     public string ToUpper();
     public string ToUpper(CultureInfo? culture);
     public string ToUpperInvariant();
+    public string ToUpperOrdinal();
 }

 public readonly partial struct Char
 {
     public static char ToLower(char c);
     public static char ToLower(char c, CultureInfo culture);
     public static char ToLowerInvariant(char c);
+    public static char ToLowerOrdinal(char c);
     public static char ToUpper(char c);
     public static char ToUpper(char c, CultureInfo culture);
     public static char ToUpperInvariant(char c);
+    public static char ToUpperOrdinal(char c);
 }

 namespace System.Text;

 public readonly partial struct Rune
 {
     public static Rune ToLower(Rune value, CultureInfo culture);
     public static Rune ToLowerInvariant(Rune value);
+    public static Rune ToLowerOrdinal(Rune value);
     public static Rune ToUpper(Rune value, CultureInfo culture);
     public static Rune ToUpperInvariant(Rune value);
+    public static Rune ToUpperOrdinal(Rune value);
 }

 namespace System;

 public static partial class MemoryExtensions
 {
     public static int ToLower(this ReadOnlySpan<char> source, Span<char> destination, CultureInfo? culture);
     public static int ToLowerInvariant(this ReadOnlySpan<char> source, Span<char> destination);
+    public static int ToLowerOrdinal(this ReadOnlySpan<char> source, Span<char> destination);
     public static int ToUpper(this ReadOnlySpan<char> source, Span<char> destination, CultureInfo? culture);
     public static int ToUpperInvariant(this ReadOnlySpan<char> source, Span<char> destination);
+    public static int ToUpperOrdinal(this ReadOnlySpan<char> source, Span<char> destination);
 }

API Usage

...

Alternative Designs

No response

Risks

No response

cc @GrabYourPitchforks

@Neme12 Neme12 added the api-suggestion Early API idea and discussion, it is NOT ready for implementation label Aug 23, 2023
@dotnet-issue-labeler dotnet-issue-labeler bot added the needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners label Aug 23, 2023
@ghost ghost added the untriaged New issue has not been triaged by the area owner label Aug 23, 2023
@Neme12 Neme12 changed the title [API Proposal]: [API Proposal]: Add ToLowerOrdinal() & ToUpperOrdinal() Aug 23, 2023
@vcsjones vcsjones added area-System.Globalization and removed needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners labels Aug 23, 2023
@ghost
Copy link

ghost commented Aug 23, 2023

Tagging subscribers to this area: @dotnet/area-system-globalization
See info in area-owners.md if you want to be subscribed.

Issue Details

Background and motivation

Since #32247/#40910, this code

string.Equals(a, b, StringComparison.OrdinalIgnoreCase)

is no longer equivalent to this code

a.ToUpperInvariant() == b.ToUpperInvariant()

That's why I'm proposing to add ToLowerOrdinal() and ToUpperOrdinal() methods that would be guaranteed to have the same semantics as OrdinalIgnoreCase comparisons, and that would also be guaranteed to be case folded letter-by-letter and have the same length as the input string (and IMO, ToLowerInvariant and ToUpperInvariant should be changed to use proper ICU case semantics that wouldn't have to result in the same length, as per #32247 (comment), but that's a separate discussion).

API Proposal

namespace System;

 public sealed partial class String
 {
     public string ToLower();
     public string ToLower(CultureInfo? culture);
     public string ToLowerInvariant();
+    public string ToLowerOrdinal();
     public string ToUpper();
     public string ToUpper(CultureInfo? culture);
     public string ToUpperInvariant();
+    public string ToUpperOrdinal();
 }

 public readonly partial struct Char
 {
     public static char ToLower(char c);
     public static char ToLower(char c, CultureInfo culture);
     public static char ToLowerInvariant(char c);
+    public static char ToLowerOrdinal(char c);
     public static char ToUpper(char c);
     public static char ToUpper(char c, CultureInfo culture);
     public static char ToUpperInvariant(char c);
+    public static char ToUpperOrdinal(char c);
 }

namespace System.Text;

 public readonly partial struct Rune
 {
     public static Rune ToLower(Rune value, CultureInfo culture);
     public static Rune ToLowerInvariant(Rune value);
+    public static Rune ToLowerOrdinal(Rune value);
     public static Rune ToUpper(Rune value, CultureInfo culture);
     public static Rune ToUpperInvariant(Rune value);
+    public static Rune ToUpperOrdinal(Rune value);
 }

namespace System;

 public static partial class MemoryExtensions
 {
     public static int ToLower(this ReadOnlySpan<char> source, Span<char> destination, CultureInfo? culture);
     public static int ToLowerInvariant(this ReadOnlySpan<char> source, Span<char> destination);
+    public static int ToLowerOrdinal(this ReadOnlySpan<char> source, Span<char> destination);
     public static int ToUpper(this ReadOnlySpan<char> source, Span<char> destination, CultureInfo? culture);
     public static int ToUpperInvariant(this ReadOnlySpan<char> source, Span<char> destination);
+    public static int ToUpperOrdinal(this ReadOnlySpan<char> source, Span<char> destination);
 }

API Usage

...

Alternative Designs

No response

Risks

No response

cc @GrabYourPitchforks

Author: Neme12
Assignees: -
Labels:

api-suggestion, area-System.Globalization, untriaged

Milestone: -

@tarekgh tarekgh added this to the 9.0.0 milestone Aug 23, 2023
@ghost ghost removed the untriaged New issue has not been triaged by the area owner label Aug 23, 2023
@tarekgh
Copy link
Member

tarekgh commented Aug 23, 2023

This proposal will help resolving #67873 too.

@stephentoub
Copy link
Member

@GrabYourPitchforks, is this something we should do now?

@tarekgh
Copy link
Member

tarekgh commented Jun 29, 2024

The proposal looks good to me. If we get someone to help with the implementation, we can consider it.

@stephentoub stephentoub modified the milestones: 9.0.0, 10.0.0 Jul 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api-suggestion Early API idea and discussion, it is NOT ready for implementation area-System.Globalization
Projects
None yet
Development

No branches or pull requests

4 participants