Swiftの2次元配列をCの2次元配列に変換する

```
$ swift --version
Apple Swift version 4.0 (swiftlang-900.0.63.10 clang-900.0.36)
Target: x86_64-apple-macosx10.9
```

Swift は C言語の関数を簡単に呼び出せて便利です。 Cでポインタを受けている関数に、Swiftの `Array<T>` を渡したりもできるので、配列の受け渡しも簡単です。

これは関数呼び出し部分において、 `Array<T>` が `UnsafePointer<T>` に暗黙キャストされるという仕組みで実現されています。

しかし、これが2次元配列となるとうまくいきません。 Cで2次元配列を受ける場合、ダブルポインタが使用されます。例えばCで 

```c
void f0(const int * const * p);
```

と定義されている関数は、 Swift から見ると、

```swift
func f0(_ p: UnsafePointer<UnsafePointer<CInt>?>!)
```

と解釈されます。これに対して、 Swift 側に `let arr: Array<Array<CInt>>` があったとして、下記はうまく動きません。

```swift
let arr: Array<Array<CInt>> = [ [0, 1, 2], [3, 4, 5] ]
f0(arr) // コンパイルエラー
```

なぜなら、 `Array<Array<CInt>>` をポインタへ暗黙変換して得られるのは、 

```swift
UnsafePointer<Array<CInt>>
``` 

であって、 

```swift
UnsafePointer<UnsafePointer<CInt>?>
```

ではないからです。

そこで、 `Array<T>` から `UnsafePointer<T>` を取り出す変換を調べると、 

```swift
func withUnsafeBufferPointer<R>(_ body: (UnsafeBufferPointer<Array.Element>) throws -> R) rethrows -> R
```

が見つかります。これを使って以下のようなコードを書きたくなるかもしれません。これは、 **コンパイルは通るけどやってはいけません。**

```swift
let arr: Array<Array<CInt>> = [ [0, 1, 2], [3, 4, 5] ]
let bufPtrArr: Array<UnsafeBufferPointer<CInt>> = arr.map {
    return $0.withUnsafeBufferPointer { $0 }
}
let ptrArr: Array<UnsafePointer<CInt>?> = bufPtrArr.map { $0.baseAddress }
f0(ptrArr)
```

なぜなら、 `withUnsafeBufferPointer` メソッドの引数のクロージャに渡されるポインタは、このメソッドの実行中しか使用してはいけないからです。

配列を1つずつポインタに変換しなければならないのに、そのポインタは `withUnsafeBufferPointer` の期間中しか使えないので、再帰呼び出しの使い所です。
ある配列を `withUnsafeBufferPointer` で変換したら、そのメソッドの内部で、さらに次の配列を変換するようにして、ポインタの配列を構築していく手順です。

この再帰処理は何度も書くのはつらいので、再利用するために `Array` の拡張メソッドにするとして、 `Array<Array<T>>` から `Array<UnsafeBufferPointer<T>>` を得るメソッド `withUnsafeBufferPointerArray` を作りました。

```swift
extension Array {
    public func withUnsafeBufferPointerArray<T, R>(_ body: (Array<UnsafeBufferPointer<T>>) -> R) -> R
        where Element == Array<T>
    {
        var buffers = Array<UnsafeBufferPointer<T>>()
        var result: R?
        
        func recurse(body: (Array<UnsafeBufferPointer<T>>) -> R)
        {
            let i = buffers.count
            guard i < self.count else {
                result = body(buffers)
                return
            }
            self[i].withUnsafeBufferPointer { (buf: UnsafeBufferPointer<T>) in
                buffers.append(buf)
                recurse(body: body)
            }
        }
        
        recurse(body: body)
        
        return result!
    }
}
```

関数内関数を使うとこの手の状態操作と再帰呼び出しを組み合わせた処理が書きやすくて良いですね。返り値のコピーが要素数の数だけ繰り返されるのが嫌なので `Optional` と `!` を使っています。

さて、これを使うと以下のようにして `f0` の呼び出しができます。

```swift
let arr: Array<Array<CInt>> = [ [0, 1, 2], [3, 4, 5] ]
arr.withUnsafeBufferPointerArray { (bufPtrArr: Array<UnsafeBufferPointer<CInt>>) in
    let ptrArr: Array<UnsafePointer<CInt>?> = bufPtrArr.map { $0.baseAddress }
    f0(ptrArr)
}
```

実用例としては、 OpenGLESの 

```c
void glShaderSource(
	GLuint shader,
	GLsizei count,
	const GLchar * const *string,
	const GLint *length);
```

の呼び出しに使用すると

```swift
    public static func shaderSource(_ id: GLuint,
                                    _ strings: Array<Array<GLchar>>)
    {
        strings.withUnsafeBufferPointerArray { (buffers: Array<UnsafeBufferPointer<GLchar>>) in
            glShaderSource(id,
                           GLsizei(buffers.count),
                           buffers.map { $0.baseAddress },
                           buffers.map { GLint($0.count) })
        }
    }
```

という感じです。 `count` 引数、 `string` 引数、 `length` 引数が、どれも `buffers` から簡単に構築できていて良い感じですね。