Swiftでタイプそのものを引数にとる関数を実装してみる．


バイナリファイルから整数値を取り出すようなことがある場合，バイト配列を整数に変換する関数を用意しておくと便利です．このときの関数は`getInt32()`や`getUInt64()`などと整数のタイプごとに別個に実装するかと思います．実装の中身はほとんど同じであるにも関わらずです．
そこで，綺麗に実装を一つにまとめられないものだろうかと思い，ジェネリクスを使って試してみました．個人的にはなかなか面白い作業だったと思うので，ここにログしておきます．
　

今回，仕立てた関数`getInteger`はこのように使います．

```swift
let getInt16 = getInteger(type: Int16.self)
let getUInt32 = getInteger(type: UInt32.self)

var v = getInt16(bytes: someByteArray)
var w = getUInt32(bytes: someByteArray)

```
整数タイプを指定するとそれ用の関数が返ってきます．あとは，バイト配列を放り込めばお望みの整数が出力されるという寸法です．
(タイプ自身を表すのに`.self`を付けないといけないのがイマイチな感じはしますね...)

　
ところで，今回もextensionしまくるわけですが，'The Swift Programmig Language'の[Access Control](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/AccessControl.html)の最後の方をみると，protocolやextensionもアクセスコントロールの対象にできるとあります．
組み込みタイプを"魔改造"しすぎても`private`を`protocol`や`extension`に付けておけば，波及をソースファイル内に封じ込めることができるという．これ，すごく便利そうですね．魔改造ファンにはもってこいの機能です．最終的に仕上がった関数なりクラスなりを`public`か`internal`にしておけばよいというわけです．
　


さて本題です．
`getInteger`を実装するには，まず，次のような単純な関数が動くような仕込みが必要になります．

```swift
func foo<T>(x: Int8, y: T) -> T {
    return T(x) << y
}
```
ここで，タイプ`T`は`Int32`など整数タイプのどれかのつもりです．
しかし，コンパイラ様は2点ほど文句つけてきます．

- タイプ`T`はイニシャライザを持ってないよ．
- タイプ`T`に適用できるシフト演算子はないよ．

なるほど．ないのであれば，新たに仕込みましょう．
組み込みの整数タイプ(Int8など全10種)を調べてみると，全て共通して各整数タイプ用のイニシャライザを持っていますが，なんらかのプロトコルで強制されているわけではありません．プロトコル`Initializable`をでっち上げて強制してしまいしましょう．

```swift
protocol Initializable {
    init(_ v: Int8)
    init(_ v: UInt8)
	//... ...          全部で10個のinit
	init(_ v: UInt)
}

extension Int8: Initializable {}
//... 他の9種もextension
```
コンパイラはこの空っぽのextensionでも文句はつけません．すでに全`init`が実装されてるからですね．
そして関数`foo`を

```swift
func foo<T: Initializable>(x: Int8, y: T) -> T {...}
```
と記述し直し，「`T`はプロトコル`Initializable`を満たすタイプである」との制約を付けると，1点目のエラーは解消します．
　
2点目ですが，タイプ`T`用の`<<`の実装は少々汚くなります．次のような簡略版でお茶を濁しておくこともできますが... (タイプ`T`は`IntegerType`に制約しておく必要があります．)

```swift
func <<<T: IntegerType>(lhs: T, rhs: T) -> T {
    var n = lhs
    for _ in 0 ..< rhs {
        n = n &* 2  // overflow? dont' care
    }
    return n
}
```
こんなループでぐるぐるなシフト演算は使いたくないですね．

　
真面目に`<<`を実装するには，タイプ`T`を実際の本当のタイプ，例えば`Int16`に変換してやる必要がありそうです．そうしないと組み込み済の`<<`を利用できないので．
整数の具体的なタイプはサイズと符号の有無で特定できそうです．サイズは`sizeof(T)`で取れますが，組み込み整数タイプは符号の有無を取れるプロパティ／メソッドを持ってないので新たにプロトコル`SignCheckable`を作って各タイプにextensionしてしまいます．オブジェクトではなくタイプに問い合わせるので`static`なプロパティにしてます（整数タイプは`class`でなく`struct`）．

```swift
protocol SignCheckable {
    class var isSignedType: Bool {get}
}

extension Int16: SignCheckable  {
    static var isSignedType: Bool {return true}
}
// ... その他のタイプもextension
```

次に必要なのは，具象タイプへの'init'の追加かファクトリメソッドです．
実は，`init`の実装でも`T`の実際のタイプを特定しないとダメで，そうなると，`<<`関数の中でもタイプを特定し，そこから`init`の中でも再び特定しと少々バカらしいので`init`はやめておきましょう．ファクトリにしておきましょう．これもプロトコル`Creatable`を作ってextensionです．

```swift
protocol Creatable {
    class func createFrom<T>(v: T) -> Self
}

extension Int16: Creatable {
    static func createFrom<T>(v: T) -> Int16 {
        return Int16(v as Int16)
    }
}
// ... 他のタイプもextension
```
プロトコル内では自分自身のタイプを`Self`で表現するようです．createFromメソッド内で`v as Int16`とやっていますが，必ずこのキャストは成功します．なぜなら，今回の使い方(`<<`演算子用)では`v`の実際のタイプは`Int16`だからです．他の整数タイプでも同様です．なんだか回りくどいですね．自分自身でダブルディスパッチみたいになってます．しかし，こうやらないと`T`から`Int16`への変換ができないんですよね．もっと簡単な方法があるかもしれませんが思いつきません．

これでやっと`<<`関数（演算子）を定義できます．以下のようになります．プロトコルがいくつもあると`T`への制約がだらだらと長くなってしまうので．上で作ったプロトコルをまとめて新たにプロトコル`MyIntegerType`を作ってます．

```swift
private func <<<T: MyIntegerType>(lhs: T, rhs: T) -> T {
    switch (T.isSignedType, sizeof(T)) {
	//...
    case (true, 2):
        let (m, n) = (T.createFrom(lhs) as Int16,
                      T.createFrom(rhs) as Int16)
        return T(m << n)
	//...
    case (false, 4):
        let (m, n) = (T.createFrom(lhs) as UInt32,
                      T.createFrom(rhs) as UInt32)
        return T(m << n)
    default:
        // error...
    }
}
```
`switch`使って符号の有無とサイズのパターンを網羅します．各`case`内でタイプ`T`を，マッチする整数の具象タイプに変換します．ここでも`as Int16`などが必要になります．コンパイル時には`createFrom`からの戻り値タイプが分からないんです．そして，その具象タイプ用の組み込み`<<`演算子を使ってシフト演算します．いや〜，汚いですね．なんかいい方法はないものでしょうか？
汚いのはともかく，なんとかタイプ`T`用の`<<`関数が実装できたので，上の方で定義した関数`foo`も`T: MyIntegerType`という制約を付ければコンパイラも真っ当な関数として扱ってくれるようになります．

----
　
　
以上で，お膳立ては整いました．やっと`getInteger`関数を定義できます．といっても，大したものじゃありません．基本的にシフトと論理和だけが仕事ですから．

```swift
func getInteger<T where T: IntegerType, T: MyIntegerType>
(# type: T.Type)(bytes: [Int8]) -> T
{
    let (shift, indices) = {(t: T.Type) -> (T, [T]) in
        switch sizeof(t) {
        case 1: return ( 0, [0])
        case 2: return ( 8, [0,1])
        case 4: return (24, [0,1,2,3])
        case 8: return (56, [0,1,2,3,4,5,6,7])
        default:
            return (0, []) // error...
        }
    }(type)

    if shift == 0 {
        return type.isSignedType ? bytes[0] as T : UInt8(bitPattern: bytes[0]) as T
    }

    let b = bytes.map(indices) {
        (s: Int8, t: T) -> T in
        let v = T(Int16(s) & 0xff)
        return  v << (shift - t * 8)
    }
    return b.reduce(0) {$0 | $1}
}
```
`getInteger`は後の使い勝手を考えカリー化して定義しています．最初の引数に整数のタイプを指定．タイプを表す識別子は`T.Type`となるようですね．2番目の引数は整数を切り出す元となるバイト列です．
関数の中身は，シフトする量と，直後の`map`関数で使うインデックス用の配列を生成します．個人的好みで，`let`とクロージャ定義&即起動をやってます（使ってみたかった）．タプルのパターンマッチで複数変数を一遍に初期化できるのは気持ちいいです．
`map`関数は，[map関数の引数を増やしてしまおう](http://qiita.com/satoshia/items/26b062c021363df0555b)とだいたい同じノリのものです．なんで`map`に拘るかといえば，`map`&`reduce`でズバッといきたいからでした．
`map`でシフト演算してバイトの位置を定めてから`reduce`で一気に論理和をという，関数型の典型パターン．
あとは，

```swift
let getInt32 = getInteger(Int32.self)
let getUInt64 = getInteger(UInt64.self)
...
```
などと`getInteger`をタイプで部分適用した定数を並べて目的達成です．
ちなみに全部ビッグエンディアンになってます．

　
正直，ここまで面倒なお膳立てが必要になるとは思いもしませんでしたが，Swiftのジェネリクスの勉強にもなったし良しとしましょう．性能が気になるところですが，Swiftが正式リリースされるまではパフォーマンス計測はしないでおこうと思います．
組み込みタイプの魔改造が終わった後は安全のために一つのファイルに切り出してプロトコル等は`private`にしておいたほうが良いでしょうね．