LoginSignup
2

More than 5 years have passed since last update.

Swift3 の OptionSet でビット演算する

Posted at

動機

参考: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 になってるのなんで

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2