It's possible but tricky to get enumeration's discriminator.
// MARK: DO NOT USE THIS CODE
// use with enums only
func discriminator<Enum>(_ e: Enum) -> Int {
withUnsafeBytes(of: e) { p in
let n = p.count
let tag = p.load(fromByteOffset: n - 1, as: UInt8.self)
let first = p.load(fromByteOffset: 0, as: UInt8.self)
return tag == 7 ? 1000 + Int(first) : Int(tag)
}
}
let examples: [TestEnum] = [
.caseWithoutAssociatedValues,
.bar2(value: 0),
.baz(val: 0, ""),
.baz(val: 0, bal: ("", ty: 0)),
.caseWithAssociatedValues(0, "", 0),
.caseWithOptionalFunc(func: nil),
.caseWithFuncOptionalReturn({ _, _ in 0 }),
.caseWithOptionalFuncOptionalReturn(nil)
]
for (i, e) in examples.enumerated() {
print("examples[\(i)],", terminator: " ")
print("discr =", discriminator(e), terminator: ", ")
print("val =", e)
}
outputs:
examples[0], discr = 1000, val = caseWithoutAssociatedValues
examples[1], discr = 0, val = bar2(value: 0)
examples[2], discr = 1, val = baz(val: 0, "")
examples[3], discr = 2, val = baz(val: 0, bal: ("", ty: 0.0))
examples[4], discr = 3, val = caseWithAssociatedValues(0, "", 0.0)
examples[5], discr = 4, val = caseWithOptionalFunc(func: nil)
examples[6], discr = 5, val = caseWithFuncOptionalReturn((Function))
examples[7], discr = 6, val = caseWithOptionalFuncOptionalReturn(nil)