OptionSetTypeでビット演算ができるようにする

## Swift1.2 → 2.0での変化
Swift1.2 → 2.0で**RawOptionSetType**が**OptionSetType**に移り変わり、書き方が変わったのはご存知かと思います。

このOptionSetへの移行でよく記事として見かける**UIUserNotificationType**を例に出すと、、

```swift:1.2まで
let notificationTypes: UIUserNotificationType = .Alert | .Badge | .Sound
```

```swift:2.0移行
let notificationTypes = UIUserNotificationType([.Alert, .Badge, .Sound])
// .Alert | .Badge | .Sound の書き方は×
```

こんな感じで、<b> | </b>を使わずに表現する形に移りました。1.2→2.0の移行をした時は大変でしたね :sweat_drops: 
書き方が変わった以外にも、OptionSetTypeを1.2の時よりも定義しやすくなったのも大きな変化かと思います。

人によっては、2.0移行での書き方 (`[.Alert, .Badge, .Sound]`)、`SomeType.A.union(.B)`のが好き！って人もいると思いますが......


<b> & , | , ^ , ~ </b> 使いたくないですか！？

基本的に**UIUserNotificationType**とかみたいにセットするだけ程度なら不要かもしれないですが、
**自分でOptionSetType作って、フラグ管理する場合なんかは、**

```swift
let type = SomeType.A
let other = SomeType.B
var newType = type.union(other) // ビット演算子の | と同等のことをする関数
newType.unionInPlace(.C)
newType.remove(.C)
```

ってやるよりは、

```swift
let type = SomeType.A
let other = SomeType.B
var newType = type | other
newType |= .C
newType &= ~.C
```

ってやった方が短くなるしスマートな気がします。
自分は`C,C++`に慣れ親しんできたので、*union*を使うよりこっちの書き方のが好きだしわかりやすいです。

ということで...使えるようにしましょう！

## CustomOperatorを実装する :bulb:
##### 環境

- Xcode 7.1.1 (Swift 2.1.1)<br>おそらくSwift2.0移行なら大丈夫です。

以下のように、それぞれ必要な演算子を定義していきます。

```swift:CustomOperators
func & <T: OptionSetType where T.RawValue: BitwiseOperationsType>(lhs: T, rhs: T) -> T {
    return T(rawValue: lhs.rawValue & rhs.rawValue)
}

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

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

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

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

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

prefix func ~ <T: OptionSetType where T.RawValue: BitwiseOperationsType>(type: T) -> T {
    return T(rawValue: ~type.rawValue)
}
```

これで、<b> & , &= , | , |= , ^ , ^= , ~ , </b> が使えるようになります :blush: 
それぞれの演算子はもともとビット演算子として用意されているので、オーバーロードという形となります。

**ポイント**は、`OptionSetType`の*rawValue*が**BitwiseOperationsTypeに適合する**という条件を加えることで、
`lhs`と`rhs`の*rawValue*でビット演算をおこなえるようになり、演算を行った結果を*rawValue*として渡して新たな`OptionSetType`を返しています。

ということで、冒頭で出してた例で再現すると、

```swift
let h = UIUserNotificationType([.Alert, .Badge, .Sound])
let g: UIUserNotificationType = .Alert | .Badge | .Sound // OK!!!!
// let g = UIUserNotificationType.Alert | .Badge | .Sound // これもOK。
//一番最初のTypeに型を書けばあとのTypeに対して型推論が働くらしい。
print(h == g) // true、2つとも同値であることが確認できた!!
```

**~(チルダ)** も実装したので、こんなこともできます :muscle: 
あくまでも例なので、実用的かどうかは一旦置いておきます。

```swift:上記の演算子を定義して、Playgroundに貼り付ければすぐ実行できます！
import UIKit
import Foundation
import XCPlayground

let corners = UIRectCorner.AllCorners & ~.TopLeft // 下の行と同じ意味になる
//let corners = UIRectCorner.TopRight | .BottomLeft | .BottomRight
let view = UIView(frame: CGRectMake(0, 0, 100, 100))
view.backgroundColor = UIColor.redColor()
view.clipsToBounds = true
let path = UIBezierPath(
    roundedRect: view.bounds,
    byRoundingCorners: corners,
    cornerRadii: CGSizeMake(50.0, 50.0)
)
let layer = CAShapeLayer()
layer.frame = view.bounds
layer.path = path.CGPath
view.layer.mask = layer
XCPlaygroundPage.currentPage.liveView = view // 左上以外が角丸のviewが描画される
```

` A & ~B `で、AからBのビットを除いた結果を返すことができます。
ビット演算については、以下が参考になるかと思います。

- [ビット演算(Wikipedia)](https://ja.wikipedia.org/wiki/ビット演算)
- [ビット演算を理解してフラグを使いこなす](http://yas-hummingbird.blogspot.jp/2009/02/c_11.html)

あとはおこのみで、OptionSetTypeと、OptionSetTypeのRawValueと同じ型の数値と大小比較できる比較演算子を定義して、以下の処理ができるようにするといいかもしれないですね :smirk: 

```swift:typeがセットされているか調べる
var type = UIRectCorner.TopRight | .BottomLeft
if (type & .TopRight) > 0 { //typeがセットされているか調べる
//if (type & .TopRight).rawValue > 0 { ">"を実装しなければ、こうするのが正解
    print("TopRight is Set!!")
}
```

これでだいぶ、CやC++の時のような扱い方ができるようになったかと思います！では！

## あとがき(Swiftのソースを覗いてみる) :pushpin: 

当初は、

```swift:最初に書いたもの
func | <T: OptionSetType>(lhs: T, rhs: T) -> T {
    return lhs.union(rhs) //ただのラッパー程度の実装
}
...
```

のように定義していたのですが、実際に**union ( | ), intersect ( & ), exclusiveOr ( ^ )**とかをどうやって組んでいるだろうということで本家([swift/stdlib/public/core/OptionSet.swift](https://github.com/apple/swift/blob/master/stdlib/public/core/OptionSet.swift))を :mag: 見にいったら、

```swift:OptionalSet.swiftでの実装から抜粋
extension OptionSetType {
  /// Returns the set of elements contained in `self`, in `other`, or in
  /// both `self` and `other`.
  @warn_unused_result
  public func union(other: Self) -> Self {
    var r: Self = Self(rawValue: self.rawValue)
    r.unionInPlace(other)
    return r
  }
...
}

extension OptionSetType where RawValue : BitwiseOperationsType {
  /// Create an empty instance.
  ///
  /// - Equivalent to `[] as Self`
  public init() {
    self.init(rawValue: .allZeros)
  }

  /// Insert all elements of `other` into `self`.
  ///
  /// - Equivalent to replacing `self` with `self.union(other)`.
  /// - Postcondition: `self.isSupersetOf(other)`
  public mutating func unionInPlace(other: Self) {
    self = Self(rawValue: self.rawValue | other.rawValue)
  }
  
  /// Remove all elements of `self` that are not also present in
  /// `other`.
  ///
  /// - Equivalent to replacing `self` with `self.intersect(other)`
  /// - Postcondition: `self.isSubsetOf(other)`
  public mutating func intersectInPlace(other: Self) {
    self = Self(rawValue: self.rawValue & other.rawValue)
  }
  
  /// Replace `self` with a set containing all elements contained in
  /// either `self` or `other`, but not both.
  ///
  /// - Equivalent to replacing `self` with `self.exclusiveOr(other)`
  public mutating func exclusiveOrInPlace(other: Self) {
    self = Self(rawValue: self.rawValue ^ other.rawValue)
  }
}

```


って書いてあるのを見つけて、intersectとかを書いてたら結果として処理が深くなっちゃうしなって思って、参考にしたのが今の形となります。

----
意外に、使える絵文字色々あるんですね :notes: