diff --git a/Sources/UInt128/UInt128+UUID.swift b/Sources/UInt128/UInt128+UUID.swift new file mode 100644 index 0000000..afcbfcf --- /dev/null +++ b/Sources/UInt128/UInt128+UUID.swift @@ -0,0 +1,46 @@ +// +// UInt128+UUID.swift +// UInt128 +// +// Created by Alfons Hoogervorst on 15/08/2023. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import Foundation + +extension UInt128 { + + /// Creates a UInt128 from a UUID. Since a UUID is always 128 bits, + /// no truncation is needed. + public init(uuid: UUID) { + let val = uuid.uuid + let lowerBits: UInt64 = UInt64(val.0) << (0 * 8) | + UInt64(val.1) << (1 * 8) | + UInt64(val.2) << (2 * 8) | + UInt64(val.3) << (3 * 8) | + UInt64(val.4) << (4 * 8) | + UInt64(val.5) << (5 * 8) | + UInt64(val.6) << (6 * 8) | + UInt64(val.7) << (7 * 8) + let upperBits: UInt64 = UInt64(val.8) << (0 * 8) | + UInt64(val.9) << (1 * 8) | + UInt64(val.10) << (2 * 8) | + UInt64(val.11) << (3 * 8) | + UInt64(val.12) << (4 * 8) | + UInt64(val.13) << (5 * 8) | + UInt64(val.14) << (6 * 8) | + UInt64(val.15) << (7 * 8) + self = .init(upperBits: upperBits, lowerBits: lowerBits) + } + +} diff --git a/Sources/UInt128/UUID+UInt128.swift b/Sources/UInt128/UUID+UInt128.swift new file mode 100644 index 0000000..c6ac918 --- /dev/null +++ b/Sources/UInt128/UUID+UInt128.swift @@ -0,0 +1,50 @@ +// +// UUID+UInt128.swift +// UInt128 +// +// Created by Alfons Hoogervorst on 15/08/2023. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import Foundation + + +extension UUID { + + /// Creates a UUID representation of a UInt128. Since a UUID is always + /// 128 bits, no truncation occurs. + public init(_ longInt: UInt128) { + let lowerBits = longInt.value.lowerBits + let upperBits = longInt.value.upperBits + let val: uuid_t = ( + UInt8((lowerBits >> (0 * 8)) & 0xFF), + UInt8((lowerBits >> (1 * 8)) & 0xFF), + UInt8((lowerBits >> (2 * 8)) & 0xFF), + UInt8((lowerBits >> (3 * 8)) & 0xFF), + UInt8((lowerBits >> (4 * 8)) & 0xFF), + UInt8((lowerBits >> (5 * 8)) & 0xFF), + UInt8((lowerBits >> (6 * 8)) & 0xFF), + UInt8((lowerBits >> (7 * 8)) & 0xFF), + UInt8((upperBits >> (0 * 8)) & 0xFF), + UInt8((upperBits >> (1 * 8)) & 0xFF), + UInt8((upperBits >> (2 * 8)) & 0xFF), + UInt8((upperBits >> (3 * 8)) & 0xFF), + UInt8((upperBits >> (4 * 8)) & 0xFF), + UInt8((upperBits >> (5 * 8)) & 0xFF), + UInt8((upperBits >> (6 * 8)) & 0xFF), + UInt8((upperBits >> (7 * 8)) & 0xFF) + ) + self = .init(uuid: val) + } + +} diff --git a/Tests/UInt128Tests/UInt128PerformanceTests.swift b/Tests/UInt128Tests/UInt128PerformanceTests.swift index a0d0910..1ef71b4 100644 --- a/Tests/UInt128Tests/UInt128PerformanceTests.swift +++ b/Tests/UInt128Tests/UInt128PerformanceTests.swift @@ -40,4 +40,18 @@ final class CustomStringConvertiblePerformanceTests: XCTestCase { _ = UInt128("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF")! } } + +} + +final class UUIDConvertibalePerformanceTests: XCTestCase { + + func testUUIDConversion() { + let uuid = UUID(uuidString: "1F349019-F3F5-489F-85F5-9CD214D6BD69")! + let options = XCTMeasureOptions() + options.iterationCount = 1000 + self.measure(options: options) { + _ = UInt128(uuid: uuid) + } + } + } diff --git a/Tests/UInt128Tests/UInt128Tests.swift b/Tests/UInt128Tests/UInt128Tests.swift index 78941e8..b77a4ed 100644 --- a/Tests/UInt128Tests/UInt128Tests.swift +++ b/Tests/UInt128Tests/UInt128Tests.swift @@ -1413,3 +1413,22 @@ class FloatingPointInterworkingTests: XCTestCase { } } } + +class UUIDTests: XCTestCase { + func testConvertUUID() { + let uuid = UUID(uuidString: "1F349019-F3F5-489F-85F5-9CD214D6BD69")! + let uint128 = UInt128(uuid: uuid) + let uuid128 = UUID(uint128) + XCTAssertEqual(uuid128, uuid) + + let uuid0 = UUID(uuidString: "00000000-0000-0000-0000-000000000000")! + let uint1280 = UInt128(uuid: uuid0) + let uuid1280 = UUID(uint1280) + XCTAssertEqual(uuid1280, uuid0) + + let uuidf = UUID(uuidString: "FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF")! + let uint128f = UInt128(uuid: uuidf) + let uuid128f = UUID(uint128f) + XCTAssertEqual(uuid128f, uuidf) + } +} diff --git a/UInt128.xcodeproj/project.pbxproj b/UInt128.xcodeproj/project.pbxproj index 84a8750..9d75f90 100644 --- a/UInt128.xcodeproj/project.pbxproj +++ b/UInt128.xcodeproj/project.pbxproj @@ -13,6 +13,14 @@ 481A30BA1F02FC6600C4438A /* UInt128.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_8 /* UInt128.swift */; }; 481A30BB1F02FC6600C4438A /* UInt128.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_8 /* UInt128.swift */; }; 482193E72A20168800B90A8D /* UInt128PerformanceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 482193E62A20168800B90A8D /* UInt128PerformanceTests.swift */; }; + 8609A4172A8CC63A00539492 /* UInt128+UUID.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8609A4152A8CC63A00539492 /* UInt128+UUID.swift */; }; + 8609A4182A8CC63A00539492 /* UInt128+UUID.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8609A4152A8CC63A00539492 /* UInt128+UUID.swift */; }; + 8609A4192A8CC63A00539492 /* UInt128+UUID.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8609A4152A8CC63A00539492 /* UInt128+UUID.swift */; }; + 8609A41A2A8CC63A00539492 /* UInt128+UUID.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8609A4152A8CC63A00539492 /* UInt128+UUID.swift */; }; + 8609A41B2A8CC63A00539492 /* UUID+UInt128.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8609A4162A8CC63A00539492 /* UUID+UInt128.swift */; }; + 8609A41C2A8CC63A00539492 /* UUID+UInt128.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8609A4162A8CC63A00539492 /* UUID+UInt128.swift */; }; + 8609A41D2A8CC63A00539492 /* UUID+UInt128.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8609A4162A8CC63A00539492 /* UUID+UInt128.swift */; }; + 8609A41E2A8CC63A00539492 /* UUID+UInt128.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8609A4162A8CC63A00539492 /* UUID+UInt128.swift */; }; OBJ_21 /* UInt128.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_8 /* UInt128.swift */; }; OBJ_28 /* UInt128Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_11 /* UInt128Tests.swift */; }; OBJ_30 /* UInt128.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = OBJ_14 /* UInt128.framework */; }; @@ -48,6 +56,8 @@ 481A30AF1F02FB9F00C4438A /* UInt128.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = UInt128.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 482193E62A20168800B90A8D /* UInt128PerformanceTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UInt128PerformanceTests.swift; sourceTree = ""; }; 48389B601EDB9F78008C1177 /* Playground.playground */ = {isa = PBXFileReference; lastKnownFileType = file.playground; path = Playground.playground; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; + 8609A4152A8CC63A00539492 /* UInt128+UUID.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "UInt128+UUID.swift"; path = "UInt128/UInt128+UUID.swift"; sourceTree = ""; }; + 8609A4162A8CC63A00539492 /* UUID+UInt128.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "UUID+UInt128.swift"; path = "UInt128/UUID+UInt128.swift"; sourceTree = ""; }; OBJ_11 /* UInt128Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UInt128Tests.swift; sourceTree = ""; }; OBJ_14 /* UInt128.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = UInt128.framework; sourceTree = BUILT_PRODUCTS_DIR; }; OBJ_15 /* UInt128Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; path = UInt128Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -134,6 +144,8 @@ isa = PBXGroup; children = ( OBJ_8 /* UInt128.swift */, + 8609A4152A8CC63A00539492 /* UInt128+UUID.swift */, + 8609A4162A8CC63A00539492 /* UUID+UInt128.swift */, ); path = Sources; sourceTree = SOURCE_ROOT; @@ -326,6 +338,8 @@ isa = PBXSourcesBuildPhase; buildActionMask = 0; files = ( + 8609A4172A8CC63A00539492 /* UInt128+UUID.swift in Sources */, + 8609A41B2A8CC63A00539492 /* UUID+UInt128.swift in Sources */, 167CA9BD1EFCF3E50091689C /* UInt128.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -334,6 +348,8 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 8609A4192A8CC63A00539492 /* UInt128+UUID.swift in Sources */, + 8609A41D2A8CC63A00539492 /* UUID+UInt128.swift in Sources */, 481A30BA1F02FC6600C4438A /* UInt128.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -342,6 +358,8 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 8609A41A2A8CC63A00539492 /* UInt128+UUID.swift in Sources */, + 8609A41E2A8CC63A00539492 /* UUID+UInt128.swift in Sources */, 481A30BB1F02FC6600C4438A /* UInt128.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -350,6 +368,8 @@ isa = PBXSourcesBuildPhase; buildActionMask = 0; files = ( + 8609A4182A8CC63A00539492 /* UInt128+UUID.swift in Sources */, + 8609A41C2A8CC63A00539492 /* UUID+UInt128.swift in Sources */, OBJ_21 /* UInt128.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0;