ヨーキョクデイ

いろいろ雑食

ベクタの(ポインタ|参照)のベクタ

まず C++STL

#include <vector>
#include <iostream>

int main(){
    std::vector<int> u, v;
    std::vector<std::vector<int>*> m;

    m.push_back(&u);
    m.push_back(&v);

    for(int i = 0; i < 5; i++){
        u.push_back(i);
        v.push_back(-3 * i);
    }
    u[4] = 100;
    v[2] *= -1;

    for(std::vector<std::vector<int>*>::iterator mit = m.begin();
            mit != m.end(); ++mit){
        for(std::vector<int>::iterator it = (*mit)->begin();
                it != (*mit)->end(); ++it){
            std::cout << *it << std::endl;
        }
    }

    return 0;
}

STL のコンテナには参照型を格納できないという噂なのでポインタを使った。
これに相当するものを D 言語 で。Tango 0.99.7 と DMD 1.033 を使用。tango.util.collection.ArraySeq 版から。

import tango.util.collection.ArraySeq;
import tango.io.Stdout;

int main(){
    auto u = new ArraySeq!(int);
    auto v = new ArraySeq!(int);
    auto m = new ArraySeq!(ArraySeq!(int));

    m.append(u);
    m.append(v);

    for(int i; i < 5; i++){
        u.append(i);
        v.append(-3 * i);
    }
    u[4] = 100;        // opIndexAssign は使える
    v[2] = -1 * v[2];  // opIndexMulAssign したいのにッ

    foreach(e; m){
         foreach(f; e){
            Stdout(f).newline;
        }
    }

    return 0;
}

tango.util.collection.ArraySeq.ArraySeq はクラスであり、D ではクラスは参照型である。
tango.util.container.more.Vector は実にアレ。

import tango.util.container.more.Vector;
import tango.io.Stdout;

int main(){
    Vector!(int, 5) u, v;
    Vector!(Vector!(int, 5)*, 2) m;

    m.add(&u);
    m ~= &v;  // alias add opCatAssign; されている

    for(int i; i < 5; i++){
        u.add(i);
        v.add(-3 * i);
    }
    u[4] = 100;        // opIndexAssign は使える
    v[2] = -1 * v[2];  // opIndexMulAssign したいのにッ

    foreach(e; m.slice){
        foreach(f; (*e)[]){  // alias slice opSlice; されている
            Stdout(f).newline;
        }
    }

    return 0;
}

tango.util.container.more.Vector.Vector は構造体で、構造体は値型なので Vector のポインタを Vector に格納。固定長なのは個性としても、イテレータというか Vector#opApplyLIFO 的で、つまり最近追加したものから古いものへと順に出てくる。よくあるものとは逆順。かといって Vector#opApplyReverse が実装されているわけでもない。そのため、Vector#slice で配列にして foreach しなければならない。opApplyReverseArraySeq でも使えないけど。この辺の自由度は STL 最強か。
それはさておき、これら 3 つの出力結果はいずれも次のようになるはず。

0
1
2
3
100
0
-3
6
-9
-12

結論としては、D に opIndex*Assign が欲しいのとイテレータ周辺を改良してほしいということ。