// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System; using System.Collections.Generic; namespace osu.Game.Utils { /// /// This string comparer is something of a cross-over between and . /// is used first, but is used as a tie-breaker. /// /// /// This comparer's behaviour somewhat emulates , /// but non-ordinal comparers - both culture-aware and culture-invariant - have huge performance overheads due to i18n factors (up to 5x slower). /// /// /// Given the following strings to sort: [A, B, C, D, a, b, c, d, A] and a stable sorting algorithm: /// /// /// would return [A, A, B, C, D, a, b, c, d]. /// This is undesirable as letters are interleaved. /// /// /// would return [A, a, A, B, b, C, c, D, d]. /// Different letters are not interleaved, but because case is ignored, the As are left in arbitrary order. /// /// /// /// would return [a, A, A, b, B, c, C, d, D], which is the expected behaviour. /// /// public class OrdinalSortByCaseStringComparer : IComparer { public static readonly OrdinalSortByCaseStringComparer DEFAULT = new OrdinalSortByCaseStringComparer(); private OrdinalSortByCaseStringComparer() { } public int Compare(string? a, string? b) { int result = StringComparer.OrdinalIgnoreCase.Compare(a, b); if (result == 0) result = -StringComparer.Ordinal.Compare(a, b); // negative to place lowercase letters before uppercase. return result; } } }