std.typecons.Tupleが使えない。

D言語(v2.012)のstd.typecons.Tupleがだめ過ぎる。


ええと、std.typecons.Tupleってのは簡単に言うとboost::tupleみたいなもんです。
ところが、こいつには問題があって、むちゃくちゃ大雑把に実装を説明すると

struct Tuple(type){//説明のために1要素限定のTuple
	mixin(type.stringof ~ " _0;\n");
}

こんな感じに文字列mixinを使って変数を宣言しています。
が、type.stringofというのが呼び出されるのはstd.typecons.Tupleの中なので
std.typecons以外のモジュールで定義された型に触れません。
つまり

import std.typecons;
struct Hoge{}
Tuple!(Hoge) Huga;//Error: std.typeconsの中ではHogeは定義されていない

みたいな宣言を行うことが出来ません。
正直、この制限が鬱陶しかったので適当に修正加えてみました。


tupleImpl全書き換え

private template tupleImpl(uint index){}
private template tupleImpl(uint index,type,string name,T...){
    mixin tupleImpl!(index,type,T);
    mixin("alias _" ~ ToString!(index) ~ " " ~ name ~ ";\n");
}
private template tupleImpl(uint index,type,T...)
{
    enum string indexStr = ToString!(index);
    enum string decl = "type _"~indexStr~";"
        ~"\ntemplate field(int i : "~indexStr~") { alias _"~indexStr
        ~" field; }\n";
    mixin(decl);
    mixin tupleImpl!(index + 1, T);
}

struct Tuple直後のmixin(tupleImpl!(0, T).result);を変更

    mixin tupleImpl!(0, T);

なんかライブラリ周りで不満な点があったら、
自分の使うphobosだけ適当に修正加えてその場凌ぎをしてしまう癖が。

phobosは色々微妙なんだけど、Tangoとかは使う気が沸かないんだよなぁ

this(this)と~thisは死ねば良いと思うよ

D言語の新バージョンで遊んでみた。

struct S{}
struct T{~this(){}}
struct U{this(this){}}
struct V{V opAssign(V x){return*this;} ~this(){}}
void main(){
	S a;a=a=a;//OK
	T b;b=b=b;//NG
	U c;c=c=c;//NG
	V d;d=d=d;//OK
}

~this()かthis(this)が定義すると、
なんと勝手にopAssignも定義しやがるんですが、そいつの帰り値の型がポインタです。
だから、b=bの式の型はT*になるとか、わけがわからん。
ただ、自分でopAssignも定義すれば大丈夫になるからまぁマシか。

個人的には構造体のデストラクタは嬉しいんだけどね。

よくわからんけど通らない(win dmd v2.011)

とりあえず最小限のえらー発生コード

void main(){
	int[string]x=["AA":0];
	cast(void)x["AA"];
}

連想配列リテラルなんて普段使わんから、
自分が悪いのかコンパイラ(+ライブラリ)が悪いのかよくわからん。
とりあえずは急場を凌ぐために

void main(){
	int[string]x=["AA":0];
	foreach(k,v;x)x[k]=v;
	cast(void)x["AA"];
}

とかやって誤魔化してるけど。
TODO:v2.050くらいまでに直らなかったら後で調べる。

std.algorithm.mapが使えねー

久しぶりにD言語の愚痴を。
とりあえずstd.algorithm.mapがイマイチ。
なにが使えないかってmapの返す型です。

Ranges[0] map(string fun,Ranges...)(Ranges rs);

具体的にはこれ書こうとしてエラー出るのが嫌

map!(toInt)(words);//文字列の配列を数値の配列に変換

これは引数がstringだから、
戻り値もstring
にしないと駄目なので通らない(dmd v2.011)


ようするに(A->A)->[A]->[A]じゃなくて(A->B)->[A]->[B]が欲しい


というわけでphobosを適当書き換え。
やったことは非常に簡単。
map関数の戻り値の型を以下のように書き換えればOK。

- Ranges[0] map(string fun, Ranges...)(Ranges rs)
+ typeof(unaryFun!(fun)(Ranges[0][0]))[] map(string fun, Ranges...)(Ranges rs)
- Ranges[0] map(alias fun, Ranges...)(Ranges rs)
+ typeof(fun(Ranges[0][0]))[] map(alias fun, Ranges...)(Ranges rs)

PKU3406

今日もodzさんのところから問題ゲット(id:odz:20080113)。
ただ、他の人と比べてメモリの使用量がすんごい事になってる。
ううむ、なんか、実装に大分差がありそうだなー。
問題がだるい大きさなのでコードサイズの削減がかなーり適当です。
たぶん、普通にまだ削れる気がする。

続きを読む