mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[stdlib] string identical
Co-Authored-By: Karoy Lorentey <klorentey@apple.com>
This commit is contained in:
@@ -49,6 +49,14 @@ public var benchmarks: [BenchmarkInfo] {
|
||||
runFunction: run_iterateWords,
|
||||
tags: [.validation, .String]))
|
||||
}
|
||||
|
||||
if #available(macOS 9999, iOS 9999, tvOS 9999, watchOS 9999, visionOS 9999, *) {
|
||||
result.append(
|
||||
BenchmarkInfo(
|
||||
name: "StringIdentical",
|
||||
runFunction: run_StringIdentical,
|
||||
tags: [.validation, .api, .String]))
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -1676,3 +1684,14 @@ public func run_iterateWords(_ n: Int) {
|
||||
blackHole(swiftOrgHTML._words)
|
||||
}
|
||||
}
|
||||
|
||||
@available(macOS 9999, iOS 9999, tvOS 9999, watchOS 9999, visionOS 9999, *)
|
||||
public func run_StringIdentical(_ n: Int) {
|
||||
let str1 = "The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. "
|
||||
let str2 = str1
|
||||
for _ in 0 ..< n {
|
||||
for _ in 0 ..< 100_000 {
|
||||
check(str1.isTriviallyIdentical(to: str2))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,25 +12,34 @@
|
||||
|
||||
import TestsUtils
|
||||
|
||||
public let benchmarks = [
|
||||
BenchmarkInfo(name: "EqualStringSubstring", runFunction: run_EqualStringSubstring, tags: [.validation, .api, .String]),
|
||||
BenchmarkInfo(name: "EqualSubstringString", runFunction: run_EqualSubstringString, tags: [.validation, .api, .String]),
|
||||
BenchmarkInfo(name: "EqualSubstringSubstring", runFunction: run_EqualSubstringSubstring, tags: [.validation, .api, .String]),
|
||||
BenchmarkInfo(name: "EqualSubstringSubstringGenericEquatable", runFunction: run_EqualSubstringSubstringGenericEquatable, tags: [.validation, .api, .String]),
|
||||
BenchmarkInfo(name: "SubstringRemoveFirst1", runFunction: run_SubstringRemoveFirst1, tags: [.validation, .api, .String]),
|
||||
BenchmarkInfo(name: "SubstringRemoveLast1", runFunction: run_SubstringRemoveLast1, tags: [.validation, .api, .String]),
|
||||
BenchmarkInfo(name: "LessSubstringSubstring", runFunction: run_LessSubstringSubstring, tags: [.validation, .api, .String]),
|
||||
BenchmarkInfo(name: "LessSubstringSubstringGenericComparable", runFunction: run_LessSubstringSubstringGenericComparable, tags: [.validation, .api, .String]),
|
||||
BenchmarkInfo(name: "StringFromLongWholeSubstring", runFunction: run_StringFromLongWholeSubstring, tags: [.validation, .api, .String]),
|
||||
BenchmarkInfo(name: "StringFromLongWholeSubstringGeneric", runFunction: run_StringFromLongWholeSubstringGeneric, tags: [.validation, .api, .String]),
|
||||
BenchmarkInfo(name: "SubstringComparable", runFunction: run_SubstringComparable, tags: [.validation, .api, .String],
|
||||
setUpFunction: { blackHole(_comparison) }),
|
||||
BenchmarkInfo(name: "SubstringEqualString", runFunction: run_SubstringEqualString, tags: [.validation, .api, .String]),
|
||||
BenchmarkInfo(name: "SubstringEquatable", runFunction: run_SubstringEquatable, tags: [.validation, .api, .String]),
|
||||
BenchmarkInfo(name: "SubstringFromLongString2", runFunction: run_SubstringFromLongString, tags: [.validation, .api, .String]),
|
||||
BenchmarkInfo(name: "SubstringFromLongStringGeneric2", runFunction: run_SubstringFromLongStringGeneric, tags: [.validation, .api, .String]),
|
||||
BenchmarkInfo(name: "SubstringTrimmingASCIIWhitespace", runFunction: run_SubstringTrimmingASCIIWhitespace, tags: [.validation, .api, .String]),
|
||||
]
|
||||
public var benchmarks: [BenchmarkInfo] {
|
||||
var result = [
|
||||
BenchmarkInfo(name: "EqualStringSubstring", runFunction: run_EqualStringSubstring, tags: [.validation, .api, .String]),
|
||||
BenchmarkInfo(name: "EqualSubstringString", runFunction: run_EqualSubstringString, tags: [.validation, .api, .String]),
|
||||
BenchmarkInfo(name: "EqualSubstringSubstring", runFunction: run_EqualSubstringSubstring, tags: [.validation, .api, .String]),
|
||||
BenchmarkInfo(name: "EqualSubstringSubstringGenericEquatable", runFunction: run_EqualSubstringSubstringGenericEquatable, tags: [.validation, .api, .String]),
|
||||
BenchmarkInfo(name: "SubstringRemoveFirst1", runFunction: run_SubstringRemoveFirst1, tags: [.validation, .api, .String]),
|
||||
BenchmarkInfo(name: "SubstringRemoveLast1", runFunction: run_SubstringRemoveLast1, tags: [.validation, .api, .String]),
|
||||
BenchmarkInfo(name: "LessSubstringSubstring", runFunction: run_LessSubstringSubstring, tags: [.validation, .api, .String]),
|
||||
BenchmarkInfo(name: "LessSubstringSubstringGenericComparable", runFunction: run_LessSubstringSubstringGenericComparable, tags: [.validation, .api, .String]),
|
||||
BenchmarkInfo(name: "StringFromLongWholeSubstring", runFunction: run_StringFromLongWholeSubstring, tags: [.validation, .api, .String]),
|
||||
BenchmarkInfo(name: "StringFromLongWholeSubstringGeneric", runFunction: run_StringFromLongWholeSubstringGeneric, tags: [.validation, .api, .String]),
|
||||
BenchmarkInfo(name: "SubstringComparable", runFunction: run_SubstringComparable, tags: [.validation, .api, .String],
|
||||
setUpFunction: { blackHole(_comparison) }),
|
||||
BenchmarkInfo(name: "SubstringEqualString", runFunction: run_SubstringEqualString, tags: [.validation, .api, .String]),
|
||||
BenchmarkInfo(name: "SubstringEquatable", runFunction: run_SubstringEquatable, tags: [.validation, .api, .String]),
|
||||
BenchmarkInfo(name: "SubstringFromLongString2", runFunction: run_SubstringFromLongString, tags: [.validation, .api, .String]),
|
||||
BenchmarkInfo(name: "SubstringFromLongStringGeneric2", runFunction: run_SubstringFromLongStringGeneric, tags: [.validation, .api, .String]),
|
||||
BenchmarkInfo(name: "SubstringTrimmingASCIIWhitespace", runFunction: run_SubstringTrimmingASCIIWhitespace, tags: [.validation, .api, .String]),
|
||||
]
|
||||
|
||||
if #available(macOS 9999, iOS 9999, tvOS 9999, watchOS 9999, visionOS 9999, *) {
|
||||
result.append(
|
||||
BenchmarkInfo(name: "SubstringIdentical", runFunction: run_SubstringIdentical, tags: [.validation, .String]),
|
||||
)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// A string that doesn't fit in small string storage and doesn't fit in Latin-1
|
||||
let longWide = "fὢasὢodὢijὢadὢolὢsjὢalὢsdὢjlὢasὢdfὢijὢliὢsdὢjøὢslὢdiὢalὢiὢ"
|
||||
@@ -332,3 +341,12 @@ public func run _LessSubstringSubstringGenericStringProtocol(_ n: Int) {
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
@inline(never)
|
||||
@available(macOS 9999, iOS 9999, tvOS 9999, watchOS 9999, visionOS 9999, *)
|
||||
public func run_SubstringIdentical(_ n: Int) {
|
||||
let (a, b) = (ss1, ss1)
|
||||
for _ in 1...n*500 {
|
||||
blackHole(a.isTriviallyIdentical(to: b))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1112,4 +1112,42 @@ extension String {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
extension String {
|
||||
/// Returns a boolean value indicating whether this string is identical to
|
||||
/// `other`.
|
||||
///
|
||||
/// Two string values are identical if there is no way to distinguish between
|
||||
/// them.
|
||||
///
|
||||
/// For any values `a`, `b`, and `c`:
|
||||
///
|
||||
/// - `a.isTriviallyIdentical(to: a)` is always `true`. (Reflexivity)
|
||||
/// - `a.isTriviallyIdentical(to: b)` implies `b.isTriviallyIdentical(to: a)`.
|
||||
/// (Symmetry)
|
||||
/// - If `a.isTriviallyIdentical(to: b)` and `b.isTriviallyIdentical(to: c)`
|
||||
/// are both `true`, then `a.isTriviallyIdentical(to: c)` is also `true`.
|
||||
/// (Transitivity)
|
||||
/// - `a.isTriviallyIdentical(b)` implies `a == b`
|
||||
/// - `a == b` does not imply `a.isTriviallyIdentical(b)`
|
||||
///
|
||||
/// Values produced by copying the same value, with no intervening mutations,
|
||||
/// will compare identical:
|
||||
///
|
||||
/// ```swift
|
||||
/// let d = c
|
||||
/// print(c.isTriviallyIdentical(to: d))
|
||||
/// // Prints true
|
||||
/// ```
|
||||
///
|
||||
/// Comparing strings this way includes comparing (normally) hidden
|
||||
/// implementation details such as the memory location of any underlying
|
||||
/// string storage object. Therefore, identical strings are guaranteed to
|
||||
/// compare equal with `==`, but not all equal strings are considered
|
||||
/// identical.
|
||||
///
|
||||
/// - Complexity: O(1)
|
||||
@available(SwiftStdlib 9999, *)
|
||||
public func isTriviallyIdentical(to other: Self) -> Bool {
|
||||
self._guts.rawBits == other._guts.rawBits
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1385,3 +1385,44 @@ extension Substring {
|
||||
return Substring(_unchecked: Slice(base: base, bounds: r))
|
||||
}
|
||||
}
|
||||
|
||||
extension Substring {
|
||||
/// Returns a boolean value indicating whether this substring is identical to
|
||||
/// `other`.
|
||||
///
|
||||
/// Two substring values are identical if there is no way to distinguish
|
||||
/// between them.
|
||||
///
|
||||
/// For any values `a`, `b`, and `c`:
|
||||
///
|
||||
/// - `a.isTriviallyIdentical(to: a)` is always `true`. (Reflexivity)
|
||||
/// - `a.isTriviallyIdentical(to: b)` implies `b.isTriviallyIdentical(to: a)`.
|
||||
/// (Symmetry)
|
||||
/// - If `a.isTriviallyIdentical(to: b)` and `b.isTriviallyIdentical(to: c)`
|
||||
/// are both `true`, then `a.isTriviallyIdentical(to: c)` is also `true`.
|
||||
/// (Transitivity)
|
||||
/// - `a.isTriviallyIdentical(b)` implies `a == b`
|
||||
/// - `a == b` does not imply `a.isTriviallyIdentical(b)`
|
||||
///
|
||||
/// Values produced by copying the same value, with no intervening mutations,
|
||||
/// will compare identical:
|
||||
///
|
||||
/// ```swift
|
||||
/// let d = c
|
||||
/// print(c.isTriviallyIdentical(to: d))
|
||||
/// // Prints true
|
||||
/// ```
|
||||
///
|
||||
/// Comparing substrings this way includes comparing (normally) hidden
|
||||
/// implementation details such as the memory location of any underlying
|
||||
/// substring storage object. Therefore, identical substrings are guaranteed
|
||||
/// to compare equal with `==`, but not all equal substrings are considered
|
||||
/// identical.
|
||||
///
|
||||
/// - Complexity: O(1)
|
||||
@available(SwiftStdlib 9999, *)
|
||||
public func isTriviallyIdentical(to other: Self) -> Bool {
|
||||
self._wholeGuts.rawBits == other._wholeGuts.rawBits &&
|
||||
self._offsetRange == other._offsetRange
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1285,6 +1285,7 @@ _$sSS19_uncheckedFromUTF16ySSSRys6UInt16VGFZ
|
||||
_$sSS19stringInterpolationSSs013DefaultStringB0V_tcfC
|
||||
_$sSS1loiySbSS_SStFZ
|
||||
_$sSS1poiyS2S_SStFZ
|
||||
_$sSS20isTriviallyIdentical2toSbSS_tF
|
||||
_$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC
|
||||
_$sSS21withMutableCharactersyxxSSzXElF
|
||||
_$sSS23_bridgeToObjectiveCImplyXlyF
|
||||
@@ -3614,6 +3615,7 @@ _$sSs17UnicodeScalarViewVyABSnySS5IndexVGcipMV
|
||||
_$sSs17UnicodeScalarViewVys0A0O0B0VSS5IndexVcig
|
||||
_$sSs17UnicodeScalarViewVys0A0O0B0VSS5IndexVcipMV
|
||||
_$sSs19stringInterpolationSss013DefaultStringB0V_tcfC
|
||||
_$sSs20isTriviallyIdentical2toSbSs_tF
|
||||
_$sSs20unicodeScalarLiteralSsSS_tcfC
|
||||
_$sSs21withMutableCharactersyxxSszXElF
|
||||
_$sSs25customPlaygroundQuickLooks01_bcD0Ovg
|
||||
|
||||
@@ -1285,6 +1285,7 @@ _$sSS19_uncheckedFromUTF16ySSSRys6UInt16VGFZ
|
||||
_$sSS19stringInterpolationSSs013DefaultStringB0V_tcfC
|
||||
_$sSS1loiySbSS_SStFZ
|
||||
_$sSS1poiyS2S_SStFZ
|
||||
_$sSS20isTriviallyIdentical2toSbSS_tF
|
||||
_$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC
|
||||
_$sSS21withMutableCharactersyxxSSzXElF
|
||||
_$sSS23_bridgeToObjectiveCImplyXlyF
|
||||
@@ -3614,6 +3615,7 @@ _$sSs17UnicodeScalarViewVyABSnySS5IndexVGcipMV
|
||||
_$sSs17UnicodeScalarViewVys0A0O0B0VSS5IndexVcig
|
||||
_$sSs17UnicodeScalarViewVys0A0O0B0VSS5IndexVcipMV
|
||||
_$sSs19stringInterpolationSss013DefaultStringB0V_tcfC
|
||||
_$sSs20isTriviallyIdentical2toSbSs_tF
|
||||
_$sSs20unicodeScalarLiteralSsSS_tcfC
|
||||
_$sSs21withMutableCharactersyxxSszXElF
|
||||
_$sSs25customPlaygroundQuickLooks01_bcD0Ovg
|
||||
|
||||
@@ -1287,6 +1287,7 @@ _$sSS19_uncheckedFromUTF16ySSSRys6UInt16VGFZ
|
||||
_$sSS19stringInterpolationSSs013DefaultStringB0V_tcfC
|
||||
_$sSS1loiySbSS_SStFZ
|
||||
_$sSS1poiyS2S_SStFZ
|
||||
_$sSS20isTriviallyIdentical2toSbSS_tF
|
||||
_$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC
|
||||
_$sSS21withMutableCharactersyxxSSzXElF
|
||||
_$sSS23_bridgeToObjectiveCImplyXlyF
|
||||
@@ -3616,6 +3617,7 @@ _$sSs17UnicodeScalarViewVyABSnySS5IndexVGcipMV
|
||||
_$sSs17UnicodeScalarViewVys0A0O0B0VSS5IndexVcig
|
||||
_$sSs17UnicodeScalarViewVys0A0O0B0VSS5IndexVcipMV
|
||||
_$sSs19stringInterpolationSss013DefaultStringB0V_tcfC
|
||||
_$sSs20isTriviallyIdentical2toSbSs_tF
|
||||
_$sSs20unicodeScalarLiteralSsSS_tcfC
|
||||
_$sSs21withMutableCharactersyxxSszXElF
|
||||
_$sSs25customPlaygroundQuickLooks01_bcD0Ovg
|
||||
|
||||
@@ -1287,6 +1287,7 @@ _$sSS19_uncheckedFromUTF16ySSSRys6UInt16VGFZ
|
||||
_$sSS19stringInterpolationSSs013DefaultStringB0V_tcfC
|
||||
_$sSS1loiySbSS_SStFZ
|
||||
_$sSS1poiyS2S_SStFZ
|
||||
_$sSS20isTriviallyIdentical2toSbSS_tF
|
||||
_$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC
|
||||
_$sSS21withMutableCharactersyxxSSzXElF
|
||||
_$sSS23_bridgeToObjectiveCImplyXlyF
|
||||
@@ -3616,6 +3617,7 @@ _$sSs17UnicodeScalarViewVyABSnySS5IndexVGcipMV
|
||||
_$sSs17UnicodeScalarViewVys0A0O0B0VSS5IndexVcig
|
||||
_$sSs17UnicodeScalarViewVys0A0O0B0VSS5IndexVcipMV
|
||||
_$sSs19stringInterpolationSss013DefaultStringB0V_tcfC
|
||||
_$sSs20isTriviallyIdentical2toSbSs_tF
|
||||
_$sSs20unicodeScalarLiteralSsSS_tcfC
|
||||
_$sSs21withMutableCharactersyxxSszXElF
|
||||
_$sSs25customPlaygroundQuickLooks01_bcD0Ovg
|
||||
|
||||
@@ -533,4 +533,62 @@ StringTests.test("hasPrefix/hasSuffix vs Character boundaries") {
|
||||
expectFalse(s2.hasSuffix("\n"))
|
||||
}
|
||||
|
||||
StringTests.test("isTriviallyIdentical(to:) small ascii")
|
||||
.skip(.custom(
|
||||
{ if #available(SwiftStdlib 9999, *) { false } else { true } },
|
||||
reason: "Requires Swift 6.3's standard library"
|
||||
))
|
||||
.code {
|
||||
guard #available(SwiftStdlib 9999, *) else { return }
|
||||
|
||||
let a = "Hello"
|
||||
let b = "Hello"
|
||||
|
||||
precondition(a == b)
|
||||
|
||||
expectTrue(a.isTriviallyIdentical(to: a))
|
||||
expectTrue(b.isTriviallyIdentical(to: b))
|
||||
expectTrue(a.isTriviallyIdentical(to: b)) // Both small ASCII strings
|
||||
expectTrue(b.isTriviallyIdentical(to: a))
|
||||
}
|
||||
|
||||
StringTests.test("isTriviallyIdentical(to:) small unicode")
|
||||
.skip(.custom(
|
||||
{ if #available(SwiftStdlib 9999, *) { false } else { true } },
|
||||
reason: "Requires Swift 6.3's standard library"
|
||||
))
|
||||
.code {
|
||||
guard #available(SwiftStdlib 9999, *) else { return }
|
||||
|
||||
let a = "Cafe\u{301}"
|
||||
let b = "Cafe\u{301}"
|
||||
let c = "Café"
|
||||
|
||||
precondition(a == b)
|
||||
precondition(b == c)
|
||||
|
||||
expectTrue(a.isTriviallyIdentical(to: b))
|
||||
expectTrue(b.isTriviallyIdentical(to: a))
|
||||
expectFalse(a.isTriviallyIdentical(to: c))
|
||||
expectFalse(b.isTriviallyIdentical(to: c))
|
||||
}
|
||||
|
||||
StringTests.test("isTriviallyIdentical(to:) large ascii")
|
||||
.skip(.custom(
|
||||
{ if #available(SwiftStdlib 9999, *) { false } else { true } },
|
||||
reason: "Requires Swift 6.3's standard library"
|
||||
))
|
||||
.code {
|
||||
guard #available(SwiftStdlib 9999, *) else { return }
|
||||
|
||||
let a = String(repeating: "foo", count: 1000)
|
||||
let b = String(repeating: "foo", count: 1000)
|
||||
|
||||
precondition(a == b)
|
||||
|
||||
expectFalse(a.isTriviallyIdentical(to: b)) // Two large, distinct native strings
|
||||
expectTrue(a.isTriviallyIdentical(to: a))
|
||||
expectTrue(b.isTriviallyIdentical(to: b))
|
||||
}
|
||||
|
||||
runAllTests()
|
||||
|
||||
@@ -31,6 +31,41 @@ func checkHasContiguousStorageSubstring(_ x: Substring.UTF8View) {
|
||||
expectTrue(hasStorage)
|
||||
}
|
||||
|
||||
fileprivate func slices(
|
||||
_ s: String,
|
||||
from: Int,
|
||||
to: Int
|
||||
) -> (
|
||||
Substring,
|
||||
Substring,
|
||||
Substring
|
||||
) {
|
||||
let s1 = s[s.index(s.startIndex, offsetBy: from) ..<
|
||||
s.index(s.startIndex, offsetBy: to)]
|
||||
let s2 = s1[s1.startIndex..<s1.endIndex]
|
||||
let s3 = s2[s1.startIndex..<s1.endIndex]
|
||||
return (s1, s2, s3)
|
||||
}
|
||||
|
||||
fileprivate func allNotEmpty(
|
||||
_ s: Substring...
|
||||
) -> Bool {
|
||||
s.allSatisfy { $0.isEmpty == false }
|
||||
}
|
||||
|
||||
fileprivate func allEqual(
|
||||
_ s: Substring...
|
||||
) -> Bool {
|
||||
for i in 0..<s.count {
|
||||
for j in (i + 1)..<s.count {
|
||||
if s[i] != s[j] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
SubstringTests.test("Equality") {
|
||||
let s = "abcdefg"
|
||||
let s1 = s[s.index(s.startIndex, offsetBy: 2) ..<
|
||||
@@ -282,4 +317,157 @@ SubstringTests.test("Substring.base") {
|
||||
}
|
||||
}
|
||||
|
||||
SubstringTests.test("isTriviallyIdentical(to:) small ascii")
|
||||
.skip(.custom(
|
||||
{ if #available(SwiftStdlib 9999, *) { false } else { true } },
|
||||
reason: "Requires Swift 6.3's standard library"
|
||||
))
|
||||
.code {
|
||||
guard #available(SwiftStdlib 9999, *) else { return }
|
||||
|
||||
let a = "Hello"
|
||||
let b = "Hello"
|
||||
|
||||
precondition(a == b)
|
||||
|
||||
let (a1, a2, a3) = slices(a, from: 2, to: 4)
|
||||
let (b1, b2, b3) = slices(b, from: 2, to: 4)
|
||||
|
||||
precondition(allNotEmpty(a1, a2, a3, b1, b2, b3))
|
||||
precondition(allEqual(a1, a2, a3, b1, b2, b3))
|
||||
|
||||
expectTrue(a1.isTriviallyIdentical(to: a1))
|
||||
expectTrue(a1.isTriviallyIdentical(to: a2))
|
||||
expectTrue(a1.isTriviallyIdentical(to: a3))
|
||||
expectTrue(a1.isTriviallyIdentical(to: b1))
|
||||
expectTrue(a1.isTriviallyIdentical(to: b2))
|
||||
expectTrue(a1.isTriviallyIdentical(to: b3))
|
||||
|
||||
expectTrue(a2.isTriviallyIdentical(to: a1))
|
||||
expectTrue(a2.isTriviallyIdentical(to: a2))
|
||||
expectTrue(a2.isTriviallyIdentical(to: a3))
|
||||
expectTrue(a2.isTriviallyIdentical(to: b1))
|
||||
expectTrue(a2.isTriviallyIdentical(to: b2))
|
||||
expectTrue(a2.isTriviallyIdentical(to: b3))
|
||||
|
||||
expectTrue(a3.isTriviallyIdentical(to: a1))
|
||||
expectTrue(a3.isTriviallyIdentical(to: a2))
|
||||
expectTrue(a3.isTriviallyIdentical(to: a3))
|
||||
expectTrue(a3.isTriviallyIdentical(to: b1))
|
||||
expectTrue(a3.isTriviallyIdentical(to: b2))
|
||||
expectTrue(a3.isTriviallyIdentical(to: b3))
|
||||
|
||||
let c = "Hello"
|
||||
|
||||
precondition(b == c)
|
||||
|
||||
let (c1, c2, c3) = slices(c, from: 1, to: 3)
|
||||
|
||||
expectFalse(a1.isTriviallyIdentical(to: c1))
|
||||
expectFalse(a1.isTriviallyIdentical(to: c2))
|
||||
expectFalse(a1.isTriviallyIdentical(to: c3))
|
||||
|
||||
expectFalse(a2.isTriviallyIdentical(to: c1))
|
||||
expectFalse(a2.isTriviallyIdentical(to: c2))
|
||||
expectFalse(a2.isTriviallyIdentical(to: c3))
|
||||
|
||||
expectFalse(a3.isTriviallyIdentical(to: c1))
|
||||
expectFalse(a3.isTriviallyIdentical(to: c2))
|
||||
expectFalse(a3.isTriviallyIdentical(to: c3))
|
||||
}
|
||||
|
||||
SubstringTests.test("isTriviallyIdentical(to:) small unicode")
|
||||
.skip(.custom(
|
||||
{ if #available(SwiftStdlib 9999, *) { false } else { true } },
|
||||
reason: "Requires Swift 6.3's standard library"
|
||||
))
|
||||
.code {
|
||||
guard #available(SwiftStdlib 9999, *) else { return }
|
||||
|
||||
let a = "Cafe\u{301}"
|
||||
let b = "Cafe\u{301}"
|
||||
let c = "Café"
|
||||
|
||||
precondition(a == b)
|
||||
precondition(b == c)
|
||||
|
||||
let (a1, a2, a3) = slices(a, from: 2, to: 4)
|
||||
let (b1, b2, b3) = slices(b, from: 2, to: 4)
|
||||
let (c1, c2, c3) = slices(c, from: 2, to: 4)
|
||||
|
||||
precondition(allNotEmpty(a1, a2, a3, b1, b2, b3, c1, c2, c3))
|
||||
precondition(allEqual(a1, a2, a3, b1, b2, b3, c1, c2, c3))
|
||||
|
||||
expectTrue(a1.isTriviallyIdentical(to: a1))
|
||||
expectTrue(a1.isTriviallyIdentical(to: a2))
|
||||
expectTrue(a1.isTriviallyIdentical(to: a3))
|
||||
expectTrue(a1.isTriviallyIdentical(to: b1))
|
||||
expectTrue(a1.isTriviallyIdentical(to: b2))
|
||||
expectTrue(a1.isTriviallyIdentical(to: b3))
|
||||
expectFalse(a1.isTriviallyIdentical(to: c1))
|
||||
expectFalse(a1.isTriviallyIdentical(to: c2))
|
||||
expectFalse(a1.isTriviallyIdentical(to: c3))
|
||||
|
||||
expectTrue(a2.isTriviallyIdentical(to: a1))
|
||||
expectTrue(a2.isTriviallyIdentical(to: a2))
|
||||
expectTrue(a2.isTriviallyIdentical(to: a3))
|
||||
expectTrue(a2.isTriviallyIdentical(to: b1))
|
||||
expectTrue(a2.isTriviallyIdentical(to: b2))
|
||||
expectTrue(a2.isTriviallyIdentical(to: b3))
|
||||
expectFalse(a2.isTriviallyIdentical(to: c1))
|
||||
expectFalse(a2.isTriviallyIdentical(to: c2))
|
||||
expectFalse(a2.isTriviallyIdentical(to: c3))
|
||||
|
||||
expectTrue(a3.isTriviallyIdentical(to: a1))
|
||||
expectTrue(a3.isTriviallyIdentical(to: a2))
|
||||
expectTrue(a3.isTriviallyIdentical(to: a3))
|
||||
expectTrue(a3.isTriviallyIdentical(to: b1))
|
||||
expectTrue(a3.isTriviallyIdentical(to: b2))
|
||||
expectTrue(a3.isTriviallyIdentical(to: b3))
|
||||
expectFalse(a3.isTriviallyIdentical(to: c1))
|
||||
expectFalse(a3.isTriviallyIdentical(to: c2))
|
||||
expectFalse(a3.isTriviallyIdentical(to: c3))
|
||||
}
|
||||
|
||||
SubstringTests.test("isTriviallyIdentical(to:) large ascii")
|
||||
.skip(.custom(
|
||||
{ if #available(SwiftStdlib 9999, *) { false } else { true } },
|
||||
reason: "Requires Swift 6.3's standard library"
|
||||
))
|
||||
.code {
|
||||
guard #available(SwiftStdlib 9999, *) else { return }
|
||||
|
||||
let a = String(repeating: "foo", count: 1000)
|
||||
let b = String(repeating: "foo", count: 1000)
|
||||
|
||||
precondition(a == b)
|
||||
|
||||
let (a1, a2, a3) = slices(a, from: 2, to: 4)
|
||||
let (b1, b2, b3) = slices(b, from: 2, to: 4)
|
||||
|
||||
precondition(allNotEmpty(a1, a2, a3, b1, b2, b3))
|
||||
precondition(allEqual(a1, a2, a3, b1, b2, b3))
|
||||
|
||||
expectTrue(a1.isTriviallyIdentical(to: a1))
|
||||
expectTrue(a1.isTriviallyIdentical(to: a2))
|
||||
expectTrue(a1.isTriviallyIdentical(to: a3))
|
||||
expectFalse(a1.isTriviallyIdentical(to: b1))
|
||||
expectFalse(a1.isTriviallyIdentical(to: b2))
|
||||
expectFalse(a1.isTriviallyIdentical(to: b3))
|
||||
|
||||
expectTrue(a2.isTriviallyIdentical(to: a1))
|
||||
expectTrue(a2.isTriviallyIdentical(to: a2))
|
||||
expectTrue(a2.isTriviallyIdentical(to: a3))
|
||||
expectFalse(a2.isTriviallyIdentical(to: b1))
|
||||
expectFalse(a2.isTriviallyIdentical(to: b2))
|
||||
expectFalse(a2.isTriviallyIdentical(to: b3))
|
||||
|
||||
expectTrue(a3.isTriviallyIdentical(to: a1))
|
||||
expectTrue(a3.isTriviallyIdentical(to: a2))
|
||||
expectTrue(a3.isTriviallyIdentical(to: a3))
|
||||
expectFalse(a3.isTriviallyIdentical(to: b1))
|
||||
expectFalse(a3.isTriviallyIdentical(to: b2))
|
||||
expectFalse(a3.isTriviallyIdentical(to: b3))
|
||||
}
|
||||
|
||||
runAllTests()
|
||||
|
||||
Reference in New Issue
Block a user