Skip to content

Commit

Permalink
Conform integer types to BitFieldProjectable (apple#129)
Browse files Browse the repository at this point in the history
Adds a default implementation of `BitFieldProjectable` for
`FixedWidthInteger` types and conforms all standard sized integer types
to `BitFieldProjectable`, e.g. `UInt8`, `UInt16`, `UInt32`, `UInt64`,
`Int8`, `Int16`, `Int32`, and `Int64`.

Fixes apple#41
  • Loading branch information
rauhul authored Oct 7, 2024
1 parent a28dcd8 commit 1f84beb
Showing 1 changed file with 72 additions and 5 deletions.
77 changes: 72 additions & 5 deletions Sources/MMIO/BitFieldProjectable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,80 @@ extension Bool: BitFieldProjectable {
}
}

/// Default implementation of `BitFieldProjectable` for `FixedWidthInteger`
/// types.
///
/// Conforming a `FixedWidthInteger` type to `BitFieldProjectable` does not
/// require any customization.
extension BitFieldProjectable where Self: FixedWidthInteger {
@inlinable @inline(__always)
public init<Storage>(storage: Storage)
where Storage: FixedWidthInteger & UnsignedInteger {
// Ensure the storage type can fully represent all the bits of `Self`.
let storageBitWidth = MemoryLayout<Storage>.size * 8
#if hasFeature(Embedded)
// FIXME: Embedded doesn't have static interpolated strings yet
precondition(
storageBitWidth >= Self.bitWidth,
"Value cannot be formed from storage type")
#else
precondition(
storageBitWidth >= Self.bitWidth,
"""
Value type '\(Self.self)' of bit width '\(Self.bitWidth)' cannot be \
formed from storage '\(storage)' of bit width '\(storageBitWidth)'
""")
#endif

// Convert the storage integer type to `Self`.
self = Self(storage)
}

@inlinable @inline(__always)
public func storage<Storage>(_: Storage.Type) -> Storage
where Storage: FixedWidthInteger & UnsignedInteger {
// Ensure the storage type can fully represent all the bits of `Self`.
let storageBitWidth = MemoryLayout<Storage>.size * 8
#if hasFeature(Embedded)
// FIXME: Embedded doesn't have static interpolated strings yet
precondition(
storageBitWidth >= Self.bitWidth,
"Storage type cannot represent value")
#else
precondition(
storageBitWidth >= Self.bitWidth,
"""
Storage type '\(Storage.self)' of bit width '\(storageBitWidth)' cannot \
represent value '\(self)' of bit width '\(Self.bitWidth)'
""")
#endif
return Storage(self)
}
}

extension UInt8: BitFieldProjectable {}

extension UInt16: BitFieldProjectable {}

extension UInt32: BitFieldProjectable {}

extension UInt64: BitFieldProjectable {}

extension Int8: BitFieldProjectable {}

extension Int16: BitFieldProjectable {}

extension Int32: BitFieldProjectable {}

extension Int64: BitFieldProjectable {}

/// Default implementation of `BitFieldProjectable` for `RawRepresentable`
/// types.
///
/// Conforming a `RawRepresentable` type to `BitFieldProjectable` only needs to
/// implement ``BitFieldProjectable.bitWidth``.
extension RawRepresentable
where Self: BitFieldProjectable, RawValue: FixedWidthInteger {
extension BitFieldProjectable
where Self: RawRepresentable, RawValue: FixedWidthInteger {
@inlinable @inline(__always)
public init<Storage>(storage: Storage)
where Storage: FixedWidthInteger & UnsignedInteger {
Expand All @@ -70,8 +137,8 @@ where Self: BitFieldProjectable, RawValue: FixedWidthInteger {
precondition(
storageBitWidth >= Self.bitWidth,
"""
Value type '\(Self.self)' of bit width '\(storageBitWidth)' cannot be \
formed from storage '\(storage)' of bit width '\(Self.bitWidth)'
Value type '\(Self.self)' of bit width '\(Self.bitWidth)' cannot be \
formed from storage '\(storage)' of bit width '\(storageBitWidth)'
""")
#endif

Expand Down Expand Up @@ -112,7 +179,7 @@ where Self: BitFieldProjectable, RawValue: FixedWidthInteger {
precondition(
storageBitWidth >= Self.bitWidth,
"""
Storage type '\(Self.self)' of bit width '\(storageBitWidth)' cannot \
Storage type '\(Storage.self)' of bit width '\(storageBitWidth)' cannot \
represent value '\(self)' of bit width '\(Self.bitWidth)'
""")
#endif
Expand Down

0 comments on commit 1f84beb

Please sign in to comment.