Skip to content

Commit

Permalink
Unavailable I128 and U128 models (#152).
Browse files Browse the repository at this point in the history
* This patch adds **unavailable** `I128` and `U128` models (#143).

The underlying `Swift.Int128` and `Swift.UInt128` models fail some tests (crash). I have submitted some fixes that got merged into the `Swift 6.1` branch. I'll try again later and make the `I128` and `U128` available when all tests pass successfully.

* Conditionally add I128 and U128 to testing lists.

* Todos about 128-bit DoubleInt typee aliases.

* Add heterogeneous binary integer element alignment tests.

* Cleanup.
  • Loading branch information
oscbyspro authored Dec 17, 2024
1 parent a8af93f commit 76d83e7
Show file tree
Hide file tree
Showing 8 changed files with 289 additions and 41 deletions.
28 changes: 18 additions & 10 deletions Sources/CoreIop/BinaryInteger.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,22 @@ import CoreKit
// MARK: * Binary Integer
//*============================================================================*

extension IX: CompactIntegerInteroperable { }
extension I8: CompactIntegerInteroperable { }
extension I16: CompactIntegerInteroperable { }
extension I32: CompactIntegerInteroperable { }
extension I64: CompactIntegerInteroperable { }
extension IX: CompactIntegerInteroperable { }
extension I8: CompactIntegerInteroperable { }
extension I16: CompactIntegerInteroperable { }
extension I32: CompactIntegerInteroperable { }
extension I64: CompactIntegerInteroperable { }

extension UX: NaturalIntegerInteroperable { }
extension U8: NaturalIntegerInteroperable { }
extension U16: NaturalIntegerInteroperable { }
extension U32: NaturalIntegerInteroperable { }
extension U64: NaturalIntegerInteroperable { }
@available(*, unavailable)
@available(iOS 18.0, macOS 15.0, tvOS 18.0, visionOS 2.0, watchOS 11.0, *)
extension I128: CompactIntegerInteroperable { }

extension UX: NaturalIntegerInteroperable { }
extension U8: NaturalIntegerInteroperable { }
extension U16: NaturalIntegerInteroperable { }
extension U32: NaturalIntegerInteroperable { }
extension U64: NaturalIntegerInteroperable { }

@available(*, unavailable)
@available(iOS 18.0, macOS 15.0, tvOS 18.0, visionOS 2.0, watchOS 11.0, *)
extension U128: NaturalIntegerInteroperable { }
102 changes: 102 additions & 0 deletions Sources/CoreKit/Models/CoreInt.swift
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,57 @@
}
}

//*============================================================================*
// MARK: * Core Int x I128
//*============================================================================*

/// A 128-bit signed binary integer.
///
/// ### Development
///
/// - Todo: Remove `typealias I128 = DoubleInt<I64>` in `DoubleIntKit`.
///
@available(*, unavailable)
@available(iOS 18.0, macOS 15.0, tvOS 18.0, visionOS 2.0, watchOS 11.0, *)
@frozen public struct I128: CoreInteger, SignedInteger, CoreIntegerWhereIsNotByte, CoreIntegerWhereIsNotToken {

public typealias Stdlib = Swift.Int128

public typealias BitPattern = Stdlib.BitPattern

public typealias Element = Self

public typealias Signitude = Self

public typealias Magnitude = U128

//=------------------------------------------------------------------------=
// MARK: State
//=------------------------------------------------------------------------=

@usableFromInline var base: Stdlib

//=------------------------------------------------------------------------=
// MARK: Initializers
//=------------------------------------------------------------------------=

@inlinable public init(_ source: Stdlib) {
self.base = source
}

@inlinable public init(raw source: BitPattern) {
self.base = Stdlib(bitPattern: source)
}

@inlinable public init(integerLiteral source: Stdlib) {
self.base = source
}

@inlinable public consuming func stdlib() -> Stdlib {
self.base
}
}

//*============================================================================*
// MARK: * Core Int x UX
//*============================================================================*
Expand Down Expand Up @@ -453,3 +504,54 @@
self.base
}
}

//*============================================================================*
// MARK: * Core Int x U128
//*============================================================================*

/// A 128-bit unsigned binary integer.
///
/// ### Development
///
/// - Todo: Remove `typealias U128 = DoubleInt<U64>` in `DoubleIntKit`.
///
@available(*, unavailable)
@available(iOS 18.0, macOS 15.0, tvOS 18.0, visionOS 2.0, watchOS 11.0, *)
@frozen public struct U128: CoreInteger, UnsignedInteger, CoreIntegerWhereIsNotByte, CoreIntegerWhereIsNotToken {

public typealias Stdlib = Swift.UInt128

public typealias BitPattern = Stdlib.BitPattern

public typealias Element = Self

public typealias Signitude = I128

public typealias Magnitude = Self

//=------------------------------------------------------------------------=
// MARK: State
//=------------------------------------------------------------------------=

@usableFromInline var base: Stdlib

//=------------------------------------------------------------------------=
// MARK: Initializers
//=------------------------------------------------------------------------=

@inlinable public init(_ source: Stdlib) {
self.base = source
}

@inlinable public init(raw source: BitPattern) {
self.base = source
}

@inlinable public init(integerLiteral source: Stdlib) {
self.base = source
}

@inlinable public consuming func stdlib() -> Stdlib {
self.base
}
}
21 changes: 21 additions & 0 deletions Sources/CoreKit/Stdlib/Swift+Int.swift
Original file line number Diff line number Diff line change
Expand Up @@ -101,3 +101,24 @@ extension Int64: BitCastable {
Magnitude(bitPattern: self)
}
}

//*============================================================================*
// MARK: * Swift x Int128
//*============================================================================*

@available(*, unavailable)
@available(iOS 18.0, macOS 15.0, tvOS 18.0, visionOS 2.0, watchOS 11.0, *)
extension Int128: BitCastable {

//=------------------------------------------------------------------------=
// MARK: Initializers
//=------------------------------------------------------------------------=

@inlinable public init(raw source: consuming Magnitude) {
self.init(bitPattern: source)
}

@inlinable public consuming func load(as type: Magnitude.Type) -> Magnitude {
Magnitude(bitPattern: self)
}
}
8 changes: 8 additions & 0 deletions Sources/CoreKit/Stdlib/Swift+UInt.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,11 @@ extension UInt32: BitCastable { public typealias BitPattern = Magnitude }
//*============================================================================*

extension UInt64: BitCastable { public typealias BitPattern = Magnitude }

//*============================================================================*
// MARK: * Swift x UInt128
//*============================================================================*

@available(*, unavailable)
@available(iOS 18.0, macOS 15.0, tvOS 18.0, visionOS 2.0, watchOS 11.0, *)
extension UInt128: BitCastable { public typealias BitPattern = Magnitude }
32 changes: 26 additions & 6 deletions Sources/TestKit/Global+Types.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,33 @@ public let typesAsCoreIntegerAsByte: [any CoreInteger.Type] = [
U8.self,
]

public let typesAsCoreIntegerAsSigned: [any CoreIntegerAsSigned.Type] = [
IX.self, I8.self, I16.self, I32.self, I64.self,
]
public let typesAsCoreIntegerAsSigned: [any CoreIntegerAsSigned.Type] = reduce([]) {
$0.append(IX .self)
$0.append(I8 .self)
$0.append(I16.self)
$0.append(I32.self)
$0.append(I64.self)

#if false
if #available(iOS 18.0, macOS 15.0, tvOS 18.0, visionOS 2.0, watchOS 11.0, *) {
$0.append(CoreKit.I128.self)
}
#endif
}

public let typesAsCoreIntegerAsUnsigned: [any CoreIntegerAsUnsigned.Type] = [
UX.self, U8.self, U16.self, U32.self, U64.self,
]
public let typesAsCoreIntegerAsUnsigned: [any CoreIntegerAsUnsigned.Type] = reduce([]) {
$0.append(UX .self)
$0.append(U8 .self)
$0.append(U16.self)
$0.append(U32.self)
$0.append(U64.self)

#if false
if #available(iOS 18.0, macOS 15.0, tvOS 18.0, visionOS 2.0, watchOS 11.0, *) {
$0.append(CoreKit.U128.self)
}
#endif
}

//=----------------------------------------------------------------------------=
// MARK: + Floats
Expand Down
46 changes: 36 additions & 10 deletions Tests/UltimathiopTests/Utilities/Globals.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,40 @@ let typesAsLenientIntegerInteroperable: [any LenientIntegerInteroperable.Type] =
InfiniInt<IX>.self,
]

let typesAsCompactIntegerInteroperable: [any CompactIntegerInteroperable.Type] = [
IX.self, I8 .self, I16.self, I32.self, I64 .self,
DoubleInt<I8>.self, DoubleInt<DoubleInt<I8>>.self,
DoubleInt<IX>.self, DoubleInt<DoubleInt<IX>>.self,
]
let typesAsCompactIntegerInteroperable: [any CompactIntegerInteroperable.Type] = reduce([]) {
$0.append(IX .self)
$0.append(I8 .self)
$0.append(I16.self)
$0.append(I32.self)
$0.append(I64.self)

#if false
if #available(iOS 18.0, macOS 15.0, tvOS 18.0, visionOS 2.0, watchOS 11.0, *) {
$0.append(CoreKit.I128.self)
}
#endif

$0.append(DoubleInt<I8>.self)
$0.append(DoubleInt<IX>.self)
$0.append(DoubleInt<DoubleInt<I8>>.self)
$0.append(DoubleInt<DoubleInt<IX>>.self)
}

let typesAsNaturalIntegerInteroperable: [any NaturalIntegerInteroperable.Type] = [
UX.self, U8 .self, U16.self, U32.self, U64 .self,
DoubleInt<U8>.self, DoubleInt<DoubleInt<U8>>.self,
DoubleInt<UX>.self, DoubleInt<DoubleInt<UX>>.self,
]
let typesAsNaturalIntegerInteroperable: [any NaturalIntegerInteroperable.Type] = reduce([]) {
$0.append(UX .self)
$0.append(U8 .self)
$0.append(U16.self)
$0.append(U32.self)
$0.append(U64.self)

#if false
if #available(iOS 18.0, macOS 15.0, tvOS 18.0, visionOS 2.0, watchOS 11.0, *) {
$0.append(CoreKit.U128.self)
}
#endif

$0.append(DoubleInt<U8>.self)
$0.append(DoubleInt<UX>.self)
$0.append(DoubleInt<DoubleInt<U8>>.self)
$0.append(DoubleInt<DoubleInt<UX>>.self)
}
44 changes: 40 additions & 4 deletions Tests/UltimathnumTests/BinaryInteger+Metadata.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@ import TestKit
// MARK: * Binary Integer x Metadata
//*============================================================================*

@Suite(.tags(.documentation)) struct BinaryIntegerTestsOnMetadata {
@Suite struct BinaryIntegerTestsOnMetadata {

//=------------------------------------------------------------------------=
// MARK: Tests
//=------------------------------------------------------------------------=

@Test(
"BinaryInteger/metadata: mode",
Tag.List.tags(.generic),
Tag.List.tags(.documentation, .generic),
arguments: typesAsBinaryInteger
) func modes(type: any BinaryInteger.Type) throws {

Expand All @@ -37,7 +37,7 @@ import TestKit

@Test(
"BinaryInteger/metadata: size",
Tag.List.tags(.generic),
Tag.List.tags(.documentation, .generic),
arguments: typesAsBinaryInteger
) func sizes(type: any BinaryInteger.Type) throws {

Expand Down Expand Up @@ -66,7 +66,7 @@ import TestKit

@Test(
"BinaryInteger/metadata: quadrants",
Tag.List.tags(.generic),
Tag.List.tags(.documentation, .generic),
arguments: typesAsBinaryInteger
) func quadrants(type: any BinaryInteger.Type) throws {

Expand Down Expand Up @@ -94,3 +94,39 @@ import TestKit
}
}
}

//*============================================================================*
// MARK: * Binary Integer x Metadata x Elements
//*============================================================================*

@Suite struct BinaryIntegerTestsOnMetadataAboutElements {

//=------------------------------------------------------------------------=
// MARK: Tests
//=------------------------------------------------------------------------=

/// - Seealso: https://github.com/oscbyspro/Ultimathnum/pull/152
@Test(
"BinaryInteger/metadata/elements: A.alignment vs B.alignment",
Tag.List.tags(.documentation, .generic),
arguments: CollectionOfOne(typesAsCoreInteger)
) func heterogeneousAlignmentComparisons(list: [any CoreInteger.Type]) throws {

for type in list {
for other in list {
try whereIs(type, versus: other)
}
}

func whereIs<A, B>(_ type: A.Type, versus other: B.Type) throws where A: CoreInteger, B: CoreInteger {
let a = MemoryLayout<A>.self
let b = MemoryLayout<B>.self

switch A.size.compared(to: B.size) {
case Signum.negative: try #require(a.alignment <= b.alignment)
case Signum.zero: try #require(a.alignment == b.alignment)
case Signum.positive: try #require(a.alignment >= b.alignment)
}
}
}
}
Loading

0 comments on commit 76d83e7

Please sign in to comment.