swift - How to enumerate an enum with String type? -


enum suit: string {     case spades = "♠"     case hearts = "♥"     case diamonds = "♦"     case clubs = "♣" } 

for example, how can like:

for suit in suit {     // suit     print(suit.rawvalue) } 

resulting example:

♠ ♥ ♦ ♣ 

i made utility function iterateenum() iterating cases arbitrary enum types.

here example usage:

enum suit:string {     case spades = "♠"     case hearts = "♥"     case diamonds = "♦"     case clubs = "♣" }  f in iterateenum(suit) {     println(f.rawvalue) } 

outputs:

♠ ♥ ♦ ♣ 

but, only debug or test purpose: relies on several undocumented current(swift1.1) compiler behaviors. so, use @ own risk :)

here code:

func iterateenum<t: hashable>(_: t.type) -> generatorof<t> {     var cast: (int -> t)!     switch sizeof(t) {     case 0: return generatorof(generatorofone(unsafebitcast((), t.self)))     case 1: cast = { unsafebitcast(uint8(truncatingbitpattern: $0), t.self) }     case 2: cast = { unsafebitcast(uint16(truncatingbitpattern: $0), t.self) }     case 4: cast = { unsafebitcast(uint32(truncatingbitpattern: $0), t.self) }     case 8: cast = { unsafebitcast(uint64($0), t.self) }     default: fatalerror("cannot here")     }      var = 0     return generatorof {         let next = cast(i)         return next.hashvalue == i++ ? next : nil     } } 

the underlying idea is:

  • memory representation of enum - excluding enums associated types - index of cases, when count of cases 2...256, it's identical uint8, when 257...65536, it's uint16 , on. so, can unsafebitcast corresponding unsigned integer types.
  • .hashvalue of enum values same index of case.
  • .hashvalue of enum values bitcasted invalid index 0

added:

revised swift2 , implemented casting ideas @kametrixom's answer

func iterateenum<t: hashable>(_: t.type) -> anygenerator<t> {     var = 0     return anygenerator {         let next = withunsafepointer(&i) { unsafepointer<t>($0).memory }         return next.hashvalue == i++ ? next : nil     } } 

added: revised swift3

func iterateenum<t: hashable>(_: t.type) -> anyiterator<t> {     var = 0     return anyiterator {         let next = withunsafepointer(to: &i) {             $0.withmemoryrebound(to: t.self, capacity: 1) { $0.pointee }         }         if next.hashvalue != { return nil }         += 1         return next     } } 

added: revised swift3.0.1

func iterateenum<t: hashable>(_: t.type) -> anyiterator<t> {     var = 0     return anyiterator {         let next = withunsafebytes(of: &i) { $0.load(as: t.self) }         if next.hashvalue != { return nil }         += 1         return next     } } 

Comments

Popular posts from this blog

commonjs - How to write a typescript definition file for a node module that exports a function? -

openid - Okta: Failed to get authorization code through API call -

ios - Change Storyboard View using Seague -