'Problems to conform enum:int32 BinaryInteger
I want to have an Int32 enum which I can combine logically. This is my code but Xcode syas that it doesn't conform the BinaryInteger protocol:
enum AppState : Int32, CaseIterable, BinaryInteger, Numeric {
typealias Words = Int32.Type;
typealias IntegerLiteralType = Int32.Type
typealias Magnitude = Int32.Type;
static func & (lhs: AppState, rhs: AppState) -> AppState {
return (lhs.rawValue & rhs.rawValue) as! AppState;
}
static func | (lhs: AppState, rhs: AppState) -> AppState {
return (lhs.rawValue | rhs.rawValue) as! AppState;
}
static func + (lhs: AppState, rhs: AppState) -> AppState {
return (lhs.rawValue + rhs.rawValue) as! AppState;
}
static func - (lhs: AppState, rhs: AppState) -> AppState {
return (lhs.rawValue - rhs.rawValue) as! AppState;
}
case APP_UNINITIALIZED = 0;
case APP_PREFERENCES = 1;
case APP_INSULIN_FAVORITES = 2;
case APP_FOODS = 4;
case APP_CONFIGURATIONS = 8;
case APP_FULL_INITIALIZED = 16;
}
var state : AppState;
state = AppState.APP_PREFERENCES & AppState.APP_FOODS;
Solution 1:[1]
You have several issues here:
Code like
(lhs.rawValue | rhs.rawValue) as! AppStatewill always fail, because(lhs.rawValue | rhs.rawValue)will always be of typeInt32, which is not related toAppState. You're looking forAppState(rawValue: lhs.rawValue | rhs.rawValue), which itself will always fail, because there's no valueAppStatevalue whose raw value is (for example) 3 (0b01 | 0b10 == 0b11 == 3).You're trying to conform to
BinaryInteger, but you're nowhere near close to fulfilling all of its requirements, likebitWidth: Int,trailingZeroBitCount: Int,var words: Words, all the relevant initializers, etc.Your conformance to
Numericis also incomplete. You need to implementvar magnitude: Self.Magnitude,*and*=, etc.Numericalso refinesAdditiveArithmetic, so you'd need unary+, binary+, unary-and binary-.AdditiveArithmeticalso refines fromEquatable, so you need==.None of this actually matters though, because you don't actually want to conform to BinaryInteger, it's totally off-track from what you're trying to achieve.
What you're looking for is an OptionSet:
struct AppState: OptionSet {
let rawValue: Int32
static let preferences = AppState(rawValue: 1 << 0)
static let insulinFavorites = AppState(rawValue: 1 << 1)
static let foods = AppState(rawValue: 1 << 2)
static let configurations = AppState(rawValue: 1 << 3)
static let uninitialized: AppState = []
static let fullyInitialized: AppState = [.preferences, .insulinFavorites, .foods, .configurations]
}
let state: AppState = [.preferences, .foods]
OptionSet gives a Set-like API for manipulating bit fields like this, abstracting the underlying bitwise operations necessary to manipulate these values.
Some other ideas to consider:
- If space isn’t an issue (and at this scale, it probably isn’t), then a struct full of booleans might be preferable.
- If your states get more complex, and not all combinations of bits are valid, then it might be better to use an enumeration to model every single possible case (combination of bits), with a state machine that transitions between these valid states. That way, invalid states would never be possible (there wouldn’t be an enumeration to represent them)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
