Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conform integer types to BitFieldProjectable #129

Merged
merged 2 commits into from
Oct 7, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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