Skip to content

Commit f659250

Browse files
gribozavrMax Moiseev
authored andcommitted
stdlib: move 'String : Comparable' conformance to a separate file
I'm about to add more code around it.
1 parent 457055d commit f659250

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
@@ -110,6 +110,7 @@ set(SWIFTLIB_ESSENTIAL
110110
String.swift
111111
StringBridge.swift
112112
StringBuffer.swift
113+
StringComparable.swift
113114
StringCore.swift
114115
StringInterpolation.swift.gyb
115116
StringLegacy.swift

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
"StringIndexConversions.swift",
1617
"StringInterpolation.swift",

stdlib/public/core/String.swift

Lines changed: 0 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -489,132 +489,6 @@ extension String {
489489
}
490490
}
491491

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

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)