Skip to content

Instantly share code, notes, and snippets.

@erica
Last active February 19, 2019 23:10

Revisions

  1. erica revised this gist Jul 12, 2015. 1 changed file with 2 additions and 1 deletion.
    3 changes: 2 additions & 1 deletion counting.swift
    Original file line number Diff line number Diff line change
    @@ -18,7 +18,8 @@ extension EnumConvertible where Self:Hashable {
    static public func countMembers() -> Int {
    // Cannot add storage to protocol at this time, so this gets computed each call
    let byteCount = sizeof(self)
    if byteCount < 1 || byteCount > 2 {fatalError("Unable to process enumeration")}
    if byteCount == 0 {return 1}
    if byteCount > 2 {fatalError("Unable to process enumeration")}
    let singleByte = byteCount == 1
    let minValue = singleByte ? 2 : 257
    let maxValue = singleByte ? 2 << 8 : 2 << 16
  2. erica revised this gist Jul 12, 2015. 1 changed file with 12 additions and 11 deletions.
    23 changes: 12 additions & 11 deletions counting.swift
    Original file line number Diff line number Diff line change
    @@ -16,12 +16,13 @@ extension EnumConvertible where Self:Hashable {
    }

    static public func countMembers() -> Int {
    if sizeof(self) == 0 {return 1} // throw up hands
    if sizeof(self) > 2 {fatalError("too many enumeration cases.")}
    let singleByte = sizeof(self) == 1
    let min = singleByte ? 2 : 257
    let max = singleByte ? 2 << 8 : 2 << 16
    for hashIndex in min..<max {
    // Cannot add storage to protocol at this time, so this gets computed each call
    let byteCount = sizeof(self)
    if byteCount < 1 || byteCount > 2 {fatalError("Unable to process enumeration")}
    let singleByte = byteCount == 1
    let minValue = singleByte ? 2 : 257
    let maxValue = singleByte ? 2 << 8 : 2 << 16
    for hashIndex in minValue..<maxValue {
    switch singleByte {
    case true:
    if unsafeBitCast(UInt8(hashIndex), self).hashValue == 0 {
    @@ -33,23 +34,23 @@ extension EnumConvertible where Self:Hashable {
    }
    }
    }
    return max
    return maxValue
    }

    static public func members() -> [Self] {
    var enumMembers = [Self]()
    var enumerationMembers = [Self]()
    let singleByte = sizeof(self) == 1
    for index in 0..<Self.countMembers() {
    switch singleByte {
    case true:
    let member = unsafeBitCast(UInt8(index), self)
    enumMembers.append(member)
    enumerationMembers.append(member)
    case false:
    let member = unsafeBitCast(UInt16(index), self)
    enumMembers.append(member)
    enumerationMembers.append(member)
    }
    }
    return enumMembers
    return enumerationMembers
    }

    public init?(hashValue hash: Int) {
  3. erica revised this gist Jul 12, 2015. 1 changed file with 40 additions and 40 deletions.
    80 changes: 40 additions & 40 deletions counting.swift
    Original file line number Diff line number Diff line change
    @@ -1,43 +1,8 @@
    import Cocoa

    // Note: use of enumeration var in generic is instadeath
    // Note: use of static var in generic is not yet supported

    func EnumerationMemberCount<EnumType:Hashable>(eType : EnumType.Type) -> Int {
    if sizeof(eType) == 0 {return 1} // throw up hands
    if sizeof(eType) > 2 {fatalError("too many enumeration cases.")}
    let singleByte = sizeof(eType) == 1
    let min = singleByte ? 2 : 257
    let max = singleByte ? 2 << 8 : 2 << 16
    for hashIndex in min..<max {
    switch singleByte {
    case true:
    if unsafeBitCast(UInt8(hashIndex), eType).hashValue == 0 {
    return hashIndex
    }
    case false:
    if unsafeBitCast(UInt16(hashIndex), eType).hashValue == 0 {
    return hashIndex
    }
    }
    }
    return max
    }

    func EnumerationMembers<EnumType:Hashable>(eType:EnumType.Type) -> [EnumType] {
    var enumMembers = [EnumType]()
    let singleByte = sizeof(eType) == 1
    for index in 0..<EnumerationMemberCount(EnumType) {
    switch singleByte {
    case true:
    let member = unsafeBitCast(UInt8(index), EnumType.self)
    enumMembers.append(member)
    case false:
    let member = unsafeBitCast(UInt16(index), EnumType.self)
    enumMembers.append(member)
    }
    }
    return enumMembers
    }

    public protocol EnumConvertible: Hashable {
    init?(hashValue hash: Int)
    static func countMembers() -> Int
    @@ -50,8 +15,42 @@ extension EnumConvertible where Self:Hashable {
    return member
    }

    static public func countMembers() -> Int {return EnumerationMemberCount(Self)}
    static public func members() -> [Self] {return EnumerationMembers(Self)}
    static public func countMembers() -> Int {
    if sizeof(self) == 0 {return 1} // throw up hands
    if sizeof(self) > 2 {fatalError("too many enumeration cases.")}
    let singleByte = sizeof(self) == 1
    let min = singleByte ? 2 : 257
    let max = singleByte ? 2 << 8 : 2 << 16
    for hashIndex in min..<max {
    switch singleByte {
    case true:
    if unsafeBitCast(UInt8(hashIndex), self).hashValue == 0 {
    return hashIndex
    }
    case false:
    if unsafeBitCast(UInt16(hashIndex), self).hashValue == 0 {
    return hashIndex
    }
    }
    }
    return max
    }

    static public func members() -> [Self] {
    var enumMembers = [Self]()
    let singleByte = sizeof(self) == 1
    for index in 0..<Self.countMembers() {
    switch singleByte {
    case true:
    let member = unsafeBitCast(UInt8(index), self)
    enumMembers.append(member)
    case false:
    let member = unsafeBitCast(UInt16(index), self)
    enumMembers.append(member)
    }
    }
    return enumMembers
    }

    public init?(hashValue hash: Int) {
    if hash >= Self.countMembers() {return nil}
    @@ -72,4 +71,5 @@ print(Quark.members())
    Quark(hashValue: 2)!.rawValue
    Foo(hashValue: 0)!.rawValue
    Foo(hashValue: 23)
    Foo(hashValue: 0)
    Foo(hashValue: 0)

  4. erica revised this gist Jul 12, 2015. 1 changed file with 9 additions and 12 deletions.
    21 changes: 9 additions & 12 deletions counting.swift
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,6 @@
    // Note: use of enumeration var in generic is instadeath
    // Note: use of static var in generic is not yet supported

    func EnumerationMemberCount<EnumType:Hashable>(eType : EnumType.Type) -> Int {
    if sizeof(eType) == 0 {return 1} // throw up hands
    if sizeof(eType) > 2 {fatalError("too many enumeration cases.")}
    @@ -36,7 +39,7 @@ func EnumerationMembers<EnumType:Hashable>(eType:EnumType.Type) -> [EnumType] {
    }

    public protocol EnumConvertible: Hashable {
    init?(fromHash hash: Int)
    init?(hashValue hash: Int)
    static func countMembers() -> Int
    static func members() -> [Self]
    }
    @@ -50,19 +53,13 @@ extension EnumConvertible where Self:Hashable {
    static public func countMembers() -> Int {return EnumerationMemberCount(Self)}
    static public func members() -> [Self] {return EnumerationMembers(Self)}

    public init?(fromHash hash: Int) {
    public init?(hashValue hash: Int) {
    if hash >= Self.countMembers() {return nil}
    self = Self.fromHash(hashValue: hash)
    }
    }

    enum Planets : Int, EnumConvertible {case Mercury, Venus, Earth, Mars, Jupiter, Saturn, Neptune, Uranus, Pluto}
    Planets.fromHash(hashValue: 0)
    EnumerationMemberCount(Planets)
    EnumerationMembers(Planets)
    Planets.countMembers()
    Planets.members()

    enum Foo : Int, EnumConvertible {case i = 1, j = 5, k = 9}
    enum Coin : EnumConvertible {case Heads, Tails}
    enum Quark: String, EnumConvertible {case Up, Down, Top, Bottom, Strange, Charmed}
    @@ -72,7 +69,7 @@ print(Foo.members())
    print(Coin.members())
    print(Quark.members())

    Quark.fromHash(hashValue: 2).rawValue
    Foo.fromHash(hashValue: 0).rawValue
    Foo(fromHash: 23)
    Foo(fromHash: 0)
    Quark(hashValue: 2)!.rawValue
    Foo(hashValue: 0)!.rawValue
    Foo(hashValue: 23)
    Foo(hashValue: 0)
  5. erica revised this gist Jul 12, 2015. 1 changed file with 43 additions and 11 deletions.
    54 changes: 43 additions & 11 deletions counting.swift
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    func enumCount<EnumType:Hashable>(eType : EnumType.Type) -> Int {
    func EnumerationMemberCount<EnumType:Hashable>(eType : EnumType.Type) -> Int {
    if sizeof(eType) == 0 {return 1} // throw up hands
    if sizeof(eType) > 2 {fatalError("too many enumeration cases.")}
    let singleByte = sizeof(eType) == 1
    @@ -19,10 +19,10 @@ func enumCount<EnumType:Hashable>(eType : EnumType.Type) -> Int {
    return max
    }

    func members<EnumType:Hashable>(eType:EnumType.Type) -> [EnumType] {
    func EnumerationMembers<EnumType:Hashable>(eType:EnumType.Type) -> [EnumType] {
    var enumMembers = [EnumType]()
    let singleByte = sizeof(eType) == 1
    for index in 0..<enumCount(EnumType) {
    for index in 0..<EnumerationMemberCount(EnumType) {
    switch singleByte {
    case true:
    let member = unsafeBitCast(UInt8(index), EnumType.self)
    @@ -35,12 +35,44 @@ func members<EnumType:Hashable>(eType:EnumType.Type) -> [EnumType] {
    return enumMembers
    }

    enum Planets : Int {case Mercury, Venus, Earth, Mars, Jupiter, Saturn, Neptune, Uranus, Pluto}
    enum Foo : Int {case i = 1, j = 5, k = 9}
    enum Coin {case Heads, Tails}
    enum Quark: String {case Up, Down, Top, Bottom, Strange, Charmed}
    public protocol EnumConvertible: Hashable {
    init?(fromHash hash: Int)
    static func countMembers() -> Int
    static func members() -> [Self]
    }

    extension EnumConvertible where Self:Hashable {
    internal static func fromHash(hashValue index: Int) -> Self {
    let member = unsafeBitCast(UInt8(index), Self.self)
    return member
    }

    static public func countMembers() -> Int {return EnumerationMemberCount(Self)}
    static public func members() -> [Self] {return EnumerationMembers(Self)}

    public init?(fromHash hash: Int) {
    if hash >= Self.countMembers() {return nil}
    self = Self.fromHash(hashValue: hash)
    }
    }

    enum Planets : Int, EnumConvertible {case Mercury, Venus, Earth, Mars, Jupiter, Saturn, Neptune, Uranus, Pluto}
    Planets.fromHash(hashValue: 0)
    EnumerationMemberCount(Planets)
    EnumerationMembers(Planets)
    Planets.countMembers()
    Planets.members()

    enum Foo : Int, EnumConvertible {case i = 1, j = 5, k = 9}
    enum Coin : EnumConvertible {case Heads, Tails}
    enum Quark: String, EnumConvertible {case Up, Down, Top, Bottom, Strange, Charmed}

    print(Planets.members())
    print(Foo.members())
    print(Coin.members())
    print(Quark.members())

    print(members(Planets))
    print(members(Foo))
    print(members(Coin))
    print(members(Quark))
    Quark.fromHash(hashValue: 2).rawValue
    Foo.fromHash(hashValue: 0).rawValue
    Foo(fromHash: 23)
    Foo(fromHash: 0)
  6. erica revised this gist Jul 11, 2015. 1 changed file with 28 additions and 21 deletions.
    49 changes: 28 additions & 21 deletions counting.swift
    Original file line number Diff line number Diff line change
    @@ -1,31 +1,38 @@
    import Cocoa

    func enumCount<EnumType:Hashable>(eType : EnumType.Type) -> Int {
    if sizeof(eType) == 0 {return 1}
    if sizeof(eType) == 1 {
    // min case is 2
    for hashIndex in (2..<(2 << 8) {
    if sizeof(eType) == 0 {return 1} // throw up hands
    if sizeof(eType) > 2 {fatalError("too many enumeration cases.")}
    let singleByte = sizeof(eType) == 1
    let min = singleByte ? 2 : 257
    let max = singleByte ? 2 << 8 : 2 << 16
    for hashIndex in min..<max {
    switch singleByte {
    case true:
    if unsafeBitCast(UInt8(hashIndex), eType).hashValue == 0 {
    return hashIndex}
    return hashIndex
    }
    case false:
    if unsafeBitCast(UInt16(hashIndex), eType).hashValue == 0 {
    return hashIndex
    }
    }
    return 2 << 8
    }
    if sizeof(eType) > 2 {return -1}
    // min case is 257
    for hashIndex in ((2 << 8) + 1)..<(2 << 16) {
    if unsafeBitCast(UInt8(hashIndex), eType).hashValue == 0 {
    return hashIndex}
    }
    return 2 << 16
    return max
    }

    func members<EnumType:Hashable>(eType:EnumType.Type) -> [EnumType] {
    var m = [EnumType]()
    for i in 0..<enumCount(EnumType) {
    let j = unsafeBitCast(UInt8(i), EnumType.self)
    m.append(j)
    var enumMembers = [EnumType]()
    let singleByte = sizeof(eType) == 1
    for index in 0..<enumCount(EnumType) {
    switch singleByte {
    case true:
    let member = unsafeBitCast(UInt8(index), EnumType.self)
    enumMembers.append(member)
    case false:
    let member = unsafeBitCast(UInt16(index), EnumType.self)
    enumMembers.append(member)
    }
    }
    return m
    return enumMembers
    }

    enum Planets : Int {case Mercury, Venus, Earth, Mars, Jupiter, Saturn, Neptune, Uranus, Pluto}
    @@ -36,4 +43,4 @@ enum Quark: String {case Up, Down, Top, Bottom, Strange, Charmed}
    print(members(Planets))
    print(members(Foo))
    print(members(Coin))
    print(members(Quark))
    print(members(Quark))
  7. erica revised this gist Jul 11, 2015. 1 changed file with 3 additions and 1 deletion.
    4 changes: 3 additions & 1 deletion counting.swift
    Original file line number Diff line number Diff line change
    @@ -3,13 +3,15 @@ import Cocoa
    func enumCount<EnumType:Hashable>(eType : EnumType.Type) -> Int {
    if sizeof(eType) == 0 {return 1}
    if sizeof(eType) == 1 {
    for hashIndex in 2..<(2 << 8) {
    // min case is 2
    for hashIndex in (2..<(2 << 8) {
    if unsafeBitCast(UInt8(hashIndex), eType).hashValue == 0 {
    return hashIndex}
    }
    return 2 << 8
    }
    if sizeof(eType) > 2 {return -1}
    // min case is 257
    for hashIndex in ((2 << 8) + 1)..<(2 << 16) {
    if unsafeBitCast(UInt8(hashIndex), eType).hashValue == 0 {
    return hashIndex}
  8. erica created this gist Jul 11, 2015.
    37 changes: 37 additions & 0 deletions counting.swift
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,37 @@
    import Cocoa

    func enumCount<EnumType:Hashable>(eType : EnumType.Type) -> Int {
    if sizeof(eType) == 0 {return 1}
    if sizeof(eType) == 1 {
    for hashIndex in 2..<(2 << 8) {
    if unsafeBitCast(UInt8(hashIndex), eType).hashValue == 0 {
    return hashIndex}
    }
    return 2 << 8
    }
    if sizeof(eType) > 2 {return -1}
    for hashIndex in ((2 << 8) + 1)..<(2 << 16) {
    if unsafeBitCast(UInt8(hashIndex), eType).hashValue == 0 {
    return hashIndex}
    }
    return 2 << 16
    }

    func members<EnumType:Hashable>(eType:EnumType.Type) -> [EnumType] {
    var m = [EnumType]()
    for i in 0..<enumCount(EnumType) {
    let j = unsafeBitCast(UInt8(i), EnumType.self)
    m.append(j)
    }
    return m
    }

    enum Planets : Int {case Mercury, Venus, Earth, Mars, Jupiter, Saturn, Neptune, Uranus, Pluto}
    enum Foo : Int {case i = 1, j = 5, k = 9}
    enum Coin {case Heads, Tails}
    enum Quark: String {case Up, Down, Top, Bottom, Strange, Charmed}

    print(members(Planets))
    print(members(Foo))
    print(members(Coin))
    print(members(Quark))