protocolにextensionが書けるって素敵

個人的にGLSLやOpenCLなんかのswizzeringが好きで、オレオレのベクタ型にはそれっぽいのを必ず用意してたりします。
SwiftはずーっとTLの狼狽を眺めてばかりでやり過ごしてたのですが、このswizzeringを一番そっくりに使えそうなのに気づいてすこし格闘してました。最悪の場合、type毎に、別の言語でソースコード生成してしまおうかとボンヤリしてたら、ふっと、「もしかして?」みたいな感じで、protocolにextensionを書いてみたところ、ばっちり動いてくれました。
Swift情報に疎く、ほぼSwift初心者なので、ネットに頼らず自力で発見できたことが嬉しくて、記録として残そうと思った次第です。

CGPointだけだと過剰ですな。でも、3要素や4要素あるベクタが複数あるとき、あるいは色々試したいとき、これからは楽できそう。

protocol Component2Swizzering {
    typealias ItemType
    typealias Component2Type
    var x: ItemType { get set }
    var y: ItemType { get set }
    func C2_INIT( x x: ItemType, y: ItemType ) -> Component2Type
    func X_C2( c : Component2Type ) -> ItemType
    func Y_C2( c : Component2Type ) -> ItemType
}
extension Component2Swizzering {

    var xy : Component2Type {
        get { return C2_INIT( x: x, y: y ) }
        set(p) { x = X_C2(p); y = Y_C2(p) }
    }

    var yx : Component2Type {
        get { return C2_INIT( x: y, y: x ) }
        set(p) { x = Y_C2(p); y = X_C2(p) }
    }

    var xx : Component2Type {
        get { return C2_INIT( x: x, y: x ) }
    }

    var yy : Component2Type {
        get { return C2_INIT( x: y, y: y ) }
    }
    
}
extension CGPoint : Component2Swizzering{

    typealias Component2Type = CGPoint

    func C2_INIT(x x:ItemType,y:ItemType) -> Component2Type {
        return CGPoint( x: x, y: y )
    }

    func X_C2(c : Component2Type ) -> ItemType {
        return c.x
    }

    func Y_C2(c : Component2Type ) -> ItemType {
        return c.y
    }

}
var point : CGPoint = CGPointMake(10, 20) // point変数に(10.0,20.0)が入ってる
print( point.yz ) // だけど(20.0,10.0) と表示される