Skip to content

Commit fc6add3

Browse files
committed
stdlib: move 'String : Comparable' conformance to a separate file
I'm about to add more code around it.
1 parent 5aa005f commit fc6add3

File tree

4 files changed

+142
-126
lines changed

4 files changed

+142
-126
lines changed

stdlib/public/core/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ set(SWIFTLIB_ESSENTIAL
115115
String.swift
116116
StringBridge.swift
117117
StringBuffer.swift
118+
StringComparable.swift
118119
StringCore.swift
119120
StringHashable.swift
120121
StringInterpolation.swift.gyb

stdlib/public/core/GroupInfo.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
"StringBridge.swift",
1212
"StringBuffer.swift",
1313
"StringCharacterView.swift",
14+
"StringComparable.swift",
1415
"StringCore.swift",
1516
"StringHashable.swift",
1617
"StringIndexConversions.swift",

stdlib/public/core/String.swift

Lines changed: 0 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -485,132 +485,6 @@ extension String {
485485
}
486486
}
487487

488-
#if _runtime(_ObjC)
489-
/// Compare two strings using the Unicode collation algorithm in the
490-
/// deterministic comparison mode. (The strings which are equivalent according
491-
/// to their NFD form are considered equal. Strings which are equivalent
492-
/// according to the plain Unicode collation algorithm are additionally ordered
493-
/// based on their NFD.)
494-
///
495-
/// See Unicode Technical Standard #10.
496-
///
497-
/// The behavior is equivalent to `NSString.compare()` with default options.
498-
///
499-
/// - returns:
500-
/// * an unspecified value less than zero if `lhs < rhs`,
501-
/// * zero if `lhs == rhs`,
502-
/// * an unspecified value greater than zero if `lhs > rhs`.
503-
@_silgen_name("swift_stdlib_compareNSStringDeterministicUnicodeCollation")
504-
public func _stdlib_compareNSStringDeterministicUnicodeCollation(
505-
_ lhs: AnyObject, _ rhs: AnyObject
506-
) -> Int32
507-
508-
@_silgen_name("swift_stdlib_compareNSStringDeterministicUnicodeCollationPtr")
509-
public func _stdlib_compareNSStringDeterministicUnicodeCollationPointer(
510-
_ lhs: OpaquePointer, _ rhs: OpaquePointer
511-
) -> Int32
512-
#endif
513-
514-
extension String : Equatable {
515-
public static func == (lhs: String, rhs: String) -> Bool {
516-
if lhs._core.isASCII && rhs._core.isASCII {
517-
if lhs._core.count != rhs._core.count {
518-
return false
519-
}
520-
return _swift_stdlib_memcmp(
521-
lhs._core.startASCII, rhs._core.startASCII,
522-
rhs._core.count) == 0
523-
}
524-
return lhs._compareString(rhs) == 0
525-
}
526-
}
527-
528-
extension String : Comparable {
529-
public static func < (lhs: String, rhs: String) -> Bool {
530-
return lhs._compareString(rhs) < 0
531-
}
532-
}
533-
534-
extension String {
535-
#if _runtime(_ObjC)
536-
/// This is consistent with Foundation, but incorrect as defined by Unicode.
537-
/// Unicode weights some ASCII punctuation in a different order than ASCII
538-
/// value. Such as:
539-
///
540-
/// 0022 ; [*02FF.0020.0002] # QUOTATION MARK
541-
/// 0023 ; [*038B.0020.0002] # NUMBER SIGN
542-
/// 0025 ; [*038C.0020.0002] # PERCENT SIGN
543-
/// 0026 ; [*0389.0020.0002] # AMPERSAND
544-
/// 0027 ; [*02F8.0020.0002] # APOSTROPHE
545-
///
546-
/// - Precondition: Both `self` and `rhs` are ASCII strings.
547-
public // @testable
548-
func _compareASCII(_ rhs: String) -> Int {
549-
var compare = Int(_swift_stdlib_memcmp(
550-
self._core.startASCII, rhs._core.startASCII,
551-
min(self._core.count, rhs._core.count)))
552-
if compare == 0 {
553-
compare = self._core.count - rhs._core.count
554-
}
555-
// This efficiently normalizes the result to -1, 0, or 1 to match the
556-
// behavior of NSString's compare function.
557-
return (compare > 0 ? 1 : 0) - (compare < 0 ? 1 : 0)
558-
}
559-
#endif
560-
561-
/// Compares two strings with the Unicode Collation Algorithm.
562-
@inline(never)
563-
@_semantics("stdlib_binary_only") // Hide the CF/ICU dependency
564-
public // @testable
565-
func _compareDeterministicUnicodeCollation(_ rhs: String) -> Int {
566-
// Note: this operation should be consistent with equality comparison of
567-
// Character.
568-
#if _runtime(_ObjC)
569-
if self._core.hasContiguousStorage && rhs._core.hasContiguousStorage {
570-
let lhsStr = _NSContiguousString(self._core)
571-
let rhsStr = _NSContiguousString(rhs._core)
572-
let res = lhsStr._unsafeWithNotEscapedSelfPointerPair(rhsStr) {
573-
return Int(
574-
_stdlib_compareNSStringDeterministicUnicodeCollationPointer($0, $1))
575-
}
576-
return res
577-
}
578-
return Int(_stdlib_compareNSStringDeterministicUnicodeCollation(
579-
_bridgeToObjectiveCImpl(), rhs._bridgeToObjectiveCImpl()))
580-
#else
581-
switch (_core.isASCII, rhs._core.isASCII) {
582-
case (true, false):
583-
return Int(_swift_stdlib_unicode_compare_utf8_utf16(
584-
_core.startASCII, Int32(_core.count),
585-
rhs._core.startUTF16, Int32(rhs._core.count)))
586-
case (false, true):
587-
// Just invert it and recurse for this case.
588-
return -rhs._compareDeterministicUnicodeCollation(self)
589-
case (false, false):
590-
return Int(_swift_stdlib_unicode_compare_utf16_utf16(
591-
_core.startUTF16, Int32(_core.count),
592-
rhs._core.startUTF16, Int32(rhs._core.count)))
593-
case (true, true):
594-
return Int(_swift_stdlib_unicode_compare_utf8_utf8(
595-
_core.startASCII, Int32(_core.count),
596-
rhs._core.startASCII, Int32(rhs._core.count)))
597-
}
598-
#endif
599-
}
600-
601-
public // @testable
602-
func _compareString(_ rhs: String) -> Int {
603-
#if _runtime(_ObjC)
604-
// We only want to perform this optimization on objc runtimes. Elsewhere,
605-
// we will make it follow the unicode collation algorithm even for ASCII.
606-
if _core.isASCII && rhs._core.isASCII {
607-
return _compareASCII(rhs)
608-
}
609-
#endif
610-
return _compareDeterministicUnicodeCollation(rhs)
611-
}
612-
}
613-
614488
// Support for copy-on-write
615489
extension String {
616490

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See http://swift.org/LICENSE.txt for license information
9+
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
import SwiftShims
14+
15+
#if _runtime(_ObjC)
16+
/// Compare two strings using the Unicode collation algorithm in the
17+
/// deterministic comparison mode. (The strings which are equivalent according
18+
/// to their NFD form are considered equal. Strings which are equivalent
19+
/// according to the plain Unicode collation algorithm are additionally ordered
20+
/// based on their NFD.)
21+
///
22+
/// See Unicode Technical Standard #10.
23+
///
24+
/// The behavior is equivalent to `NSString.compare()` with default options.
25+
///
26+
/// - returns:
27+
/// * an unspecified value less than zero if `lhs < rhs`,
28+
/// * zero if `lhs == rhs`,
29+
/// * an unspecified value greater than zero if `lhs > rhs`.
30+
@_silgen_name("swift_stdlib_compareNSStringDeterministicUnicodeCollation")
31+
public func _stdlib_compareNSStringDeterministicUnicodeCollation(
32+
_ lhs: AnyObject, _ rhs: AnyObject
33+
) -> Int32
34+
35+
@_silgen_name("swift_stdlib_compareNSStringDeterministicUnicodeCollationPtr")
36+
public func _stdlib_compareNSStringDeterministicUnicodeCollationPointer(
37+
_ lhs: OpaquePointer, _ rhs: OpaquePointer
38+
) -> Int32
39+
#endif
40+
41+
extension String {
42+
#if _runtime(_ObjC)
43+
/// This is consistent with Foundation, but incorrect as defined by Unicode.
44+
/// Unicode weights some ASCII punctuation in a different order than ASCII
45+
/// value. Such as:
46+
///
47+
/// 0022 ; [*02FF.0020.0002] # QUOTATION MARK
48+
/// 0023 ; [*038B.0020.0002] # NUMBER SIGN
49+
/// 0025 ; [*038C.0020.0002] # PERCENT SIGN
50+
/// 0026 ; [*0389.0020.0002] # AMPERSAND
51+
/// 0027 ; [*02F8.0020.0002] # APOSTROPHE
52+
///
53+
/// - Precondition: Both `self` and `rhs` are ASCII strings.
54+
public // @testable
55+
func _compareASCII(_ rhs: String) -> Int {
56+
var compare = Int(_swift_stdlib_memcmp(
57+
self._core.startASCII, rhs._core.startASCII,
58+
min(self._core.count, rhs._core.count)))
59+
if compare == 0 {
60+
compare = self._core.count - rhs._core.count
61+
}
62+
// This efficiently normalizes the result to -1, 0, or 1 to match the
63+
// behavior of NSString's compare function.
64+
return (compare > 0 ? 1 : 0) - (compare < 0 ? 1 : 0)
65+
}
66+
#endif
67+
68+
/// Compares two strings with the Unicode Collation Algorithm.
69+
@inline(never)
70+
@_semantics("stdlib_binary_only") // Hide the CF/ICU dependency
71+
public // @testable
72+
func _compareDeterministicUnicodeCollation(_ rhs: String) -> Int {
73+
// Note: this operation should be consistent with equality comparison of
74+
// Character.
75+
#if _runtime(_ObjC)
76+
if self._core.hasContiguousStorage && rhs._core.hasContiguousStorage {
77+
let lhsStr = _NSContiguousString(self._core)
78+
let rhsStr = _NSContiguousString(rhs._core)
79+
let res = lhsStr._unsafeWithNotEscapedSelfPointerPair(rhsStr) {
80+
return Int(
81+
_stdlib_compareNSStringDeterministicUnicodeCollationPointer($0, $1))
82+
}
83+
return res
84+
}
85+
return Int(_stdlib_compareNSStringDeterministicUnicodeCollation(
86+
_bridgeToObjectiveCImpl(), rhs._bridgeToObjectiveCImpl()))
87+
#else
88+
switch (_core.isASCII, rhs._core.isASCII) {
89+
case (true, false):
90+
return Int(_swift_stdlib_unicode_compare_utf8_utf16(
91+
_core.startASCII, Int32(_core.count),
92+
rhs._core.startUTF16, Int32(rhs._core.count)))
93+
case (false, true):
94+
// Just invert it and recurse for this case.
95+
return -rhs._compareDeterministicUnicodeCollation(self)
96+
case (false, false):
97+
return Int(_swift_stdlib_unicode_compare_utf16_utf16(
98+
_core.startUTF16, Int32(_core.count),
99+
rhs._core.startUTF16, Int32(rhs._core.count)))
100+
case (true, true):
101+
return Int(_swift_stdlib_unicode_compare_utf8_utf8(
102+
_core.startASCII, Int32(_core.count),
103+
rhs._core.startASCII, Int32(rhs._core.count)))
104+
}
105+
#endif
106+
}
107+
108+
public // @testable
109+
func _compareString(_ rhs: String) -> Int {
110+
#if _runtime(_ObjC)
111+
// We only want to perform this optimization on objc runtimes. Elsewhere,
112+
// we will make it follow the unicode collation algorithm even for ASCII.
113+
if _core.isASCII && rhs._core.isASCII {
114+
return _compareASCII(rhs)
115+
}
116+
#endif
117+
return _compareDeterministicUnicodeCollation(rhs)
118+
}
119+
}
120+
121+
extension String : Equatable {
122+
public static func == (lhs: String, rhs: String) -> Bool {
123+
if lhs._core.isASCII && rhs._core.isASCII {
124+
if lhs._core.count != rhs._core.count {
125+
return false
126+
}
127+
return _swift_stdlib_memcmp(
128+
lhs._core.startASCII, rhs._core.startASCII,
129+
rhs._core.count) == 0
130+
}
131+
return lhs._compareString(rhs) == 0
132+
}
133+
}
134+
135+
extension String : Comparable {
136+
public static func < (lhs: String, rhs: String) -> Bool {
137+
return lhs._compareString(rhs) < 0
138+
}
139+
}
140+

0 commit comments

Comments
 (0)