Swift3 の OptionSet でビット演算する

  • 1
    いいね
  • 3
    コメント

動機

参考:OptionSetTypeでビット演算ができるようにする
http://qiita.com/su_k/items/967509c6096ea6b6685d

こちらを参考にして実装してたコードが Swift3 でめんどくさいことになってたのでなおした

がんばったコード

OptionSetExtension.swift
func & <T: OptionSet>(lhs: T, rhs: T) -> T where T.RawValue : BitwiseOperations {
    return T(rawValue: lhs.rawValue & rhs.rawValue)
}

func | <T: OptionSet>(lhs: T, rhs: T) -> T where T.RawValue : BitwiseOperations {
    return T(rawValue: lhs.rawValue | rhs.rawValue)
}

func ^ <T: OptionSet>(lhs: T, rhs: T) -> T where T.RawValue : BitwiseOperations {
    return T(rawValue: lhs.rawValue ^ rhs.rawValue)
}

func &= <T: OptionSet>(lhs: inout T, rhs: T) where T.RawValue : BitwiseOperations {
    lhs = lhs & rhs
}

func |= <T: OptionSet>(lhs: inout T, rhs: T) where T.RawValue : BitwiseOperations {
    lhs = lhs | rhs
}

func ^= <T: OptionSet>(lhs: inout T, rhs: T) where T.RawValue : BitwiseOperations {
    lhs = lhs ^ rhs
}

prefix func ~ <T: OptionSet>(type: T) -> T where T.RawValue: BitwiseOperations {
    return T(rawValue: ~type.rawValue)
}

func > <T: OptionSet>(lhs: T, rhs: T.RawValue) -> Bool where T.RawValue: Integer {
    return lhs.rawValue > rhs
}

func > <T: OptionSet>(lhs: T.RawValue, rhs: T) -> Bool where T.RawValue: Integer {
    return lhs > rhs.rawValue
}

func >= <T: OptionSet>(lhs: T, rhs: T.RawValue) -> Bool where T.RawValue: Integer {
    return lhs.rawValue >= rhs
}

func >= <T: OptionSet>(lhs: T.RawValue, rhs: T) -> Bool where T.RawValue: Integer {
    return lhs >= rhs.rawValue
}

func < <T: OptionSet>(lhs: T.RawValue, rhs: T) -> Bool where T.RawValue: Integer {
    return  lhs < rhs.rawValue
}

func < <T: OptionSet>(lhs: T, rhs: T.RawValue) -> Bool where T.RawValue: Integer {
    return  lhs.rawValue < rhs
}

func <= <T: OptionSet>(lhs: T.RawValue, rhs: T) -> Bool where T.RawValue: Integer {
    return  lhs <= rhs.rawValue
}

func <= <T: OptionSet>(lhs: T, rhs: T.RawValue) -> Bool where T.RawValue: Integer {
    return  lhs.rawValue <= rhs
}

func == <T: OptionSet>(lhs: T, rhs: T.RawValue) -> Bool where T.RawValue: Integer {
    return  lhs.rawValue == rhs
}

func == <T: OptionSet>(lhs: T.RawValue, rhs: T) -> Bool where T.RawValue: Integer {
    return  lhs == rhs.rawValue
}

prefix func ! <T: OptionSet>(type: T) -> Bool where T.RawValue: Integer {
    return type.rawValue <= 0
}

てきとうにテスト

ViewController.swift

override function viewDidLoad() {
    var masks: UIInterfaceOrientationMask = .portrait | .landscapeLeft | .landscapeRight    // .allButUpsideDown

    print((masks | .portrait)           == .allButUpsideDown)
    print((masks | .portraitUpsideDown) == .all)

    print((masks & .portrait)           == .portrait)
    print((masks & .portraitUpsideDown) == [])

    print(masks ^ .portrait             == .landscape)
    print(masks ^ .portraitUpsideDown   == .all)

    masks |= .portraitUpsideDown
    print(masks == .all)

    masks &= .portraitUpsideDown
    print(masks == .portraitUpsideDown)

    masks = .all & ~.portraitUpsideDown
    print(masks == .allButUpsideDown)

    print(masks ^= .portrait)
    print(masks == .landscape)
}

全部 true 表示されてるから大丈夫 たぶん

てきとうな備考

  • OptionSetExtension.swift って書いたけど、別に Extension じゃない
    でも他に思いつかない
  • ObjC の時 None,Unknown とかって書いてた部分が
    Swift だと [] になってるの、簡単だけどわかりづらい
    • HogeOptionSet(rawValue: 0) == [] だけどやり始めのころはわからん
  • Swift2 の時に .Landscape とか書いてたのに、
    Swift3 で .landscape になってるのなんで