Skip to content

Commit baa372f

Browse files
committed
data identical
1 parent 5cf1d36 commit baa372f

File tree

1 file changed

+100
-0
lines changed

1 file changed

+100
-0
lines changed

Sources/FoundationEssentials/Data/Data.swift

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2974,3 +2974,103 @@ extension Data : Codable {
29742974
}
29752975
}
29762976
}
2977+
2978+
// TODO: remove once _overrideLifetime is public in the standard library
2979+
/// Unsafely discard any lifetime dependency on the `dependent` argument. Return
2980+
/// a value identical to `dependent` with a lifetime dependency on the caller's
2981+
/// borrow scope of the `source` argument.
2982+
@unsafe
2983+
@_unsafeNonescapableResult
2984+
@_alwaysEmitIntoClient
2985+
@_transparent
2986+
@lifetime(borrow source)
2987+
internal func _overrideLifetime<
2988+
T: ~Copyable & ~Escapable, U: ~Copyable & ~Escapable
2989+
>(
2990+
_ dependent: consuming T, borrowing source: borrowing U
2991+
) -> T {
2992+
dependent
2993+
}
2994+
2995+
/// Unsafely discard any lifetime dependency on the `dependent` argument. Return
2996+
/// a value identical to `dependent` that inherits all lifetime dependencies from
2997+
/// the `source` argument.
2998+
@unsafe
2999+
@_unsafeNonescapableResult
3000+
@_alwaysEmitIntoClient
3001+
@_transparent
3002+
@lifetime(copy source)
3003+
internal func _overrideLifetime<
3004+
T: ~Copyable & ~Escapable, U: ~Copyable & ~Escapable
3005+
>(
3006+
_ dependent: consuming T, copying source: borrowing U
3007+
) -> T {
3008+
dependent
3009+
}
3010+
3011+
/// Unsafely discard any lifetime dependency on the `dependent` argument.
3012+
/// Return a value identical to `dependent` with a lifetime dependency
3013+
/// on the caller's exclusive borrow scope of the `source` argument.
3014+
@unsafe
3015+
@_unsafeNonescapableResult
3016+
@_alwaysEmitIntoClient
3017+
@_transparent
3018+
@lifetime(&source)
3019+
internal func _overrideLifetime<
3020+
T: ~Copyable & ~Escapable, U: ~Copyable & ~Escapable
3021+
>(
3022+
_ dependent: consuming T,
3023+
mutating source: inout U
3024+
) -> T {
3025+
dependent
3026+
}
3027+
3028+
extension Data {
3029+
/// Returns a boolean value indicating whether this data is identical to
3030+
/// `other`.
3031+
///
3032+
/// Two data values are identical if there is no way to distinguish between
3033+
/// them.
3034+
///
3035+
/// Comparing data this way includes comparing (normally) hidden
3036+
/// implementation details such as the memory location of any underlying
3037+
/// data storage object. Therefore, identical data are guaranteed to
3038+
/// compare equal with `==`, but not all equal data are considered
3039+
/// identical.
3040+
///
3041+
/// - Performance: O(1)
3042+
@_alwaysEmitIntoClient
3043+
public func isIdentical(to other: Self) -> Bool {
3044+
// See if both are empty
3045+
switch (self._representation, other._representation) {
3046+
case (.empty, .empty):
3047+
return true
3048+
case (.inline, .inline), (.slice, .slice), (.large, .large):
3049+
// Continue on to checks below
3050+
break
3051+
default:
3052+
return false
3053+
}
3054+
3055+
let length1 = self.count
3056+
let length2 = other.count
3057+
3058+
// Unequal length data can never be equal
3059+
guard length1 == length2 else {
3060+
return false
3061+
}
3062+
3063+
if length1 > 0 {
3064+
return self.withUnsafeBytes { (b1: UnsafeRawBufferPointer) in
3065+
return other.withUnsafeBytes { (b2: UnsafeRawBufferPointer) in
3066+
// If they have the same base address and same count, it is equal
3067+
let b1Address = b1.baseAddress!
3068+
let b2Address = b2.baseAddress!
3069+
3070+
return b1Address == b2Address
3071+
}
3072+
}
3073+
}
3074+
return true
3075+
}
3076+
}

0 commit comments

Comments
 (0)