...ing logging 4.0

はてなブログに移行しました。D言語の話とかいろいろ。

「以下について教えてあげよう♪」(2)

import std.stdio;
import std.algorithm;
import std.range;
import std.string;

char f(char x)
{
	if ( x >= '0' && x <= '9' ) return '9' - x + '0';
	if ( x >= 'A' && x <= 'Z' ) return x - 'A' + 'a';
	return x;
}

template toArray(R) if (isInputRange!(R))
{
	auto toArray(R r)
	{
		ElementType!(R)[] res;
		foreach (e; r)
			res ~= e;
		return res;
	}
}

void main()
{
	string str = "Abc012_59F_#012Gh";
	writeln(str);
	
	string[] ss = split(str, "#");
	auto res = toArray(map!(f)(ss[0])) ~ "#" ~ ss[1];
	
	writeln(res);
}

うーん?

  • import文が多い
  • fがin-placeに書けない(delegateリテラルがmapのテンプレート引数に書けない)
  • mapの結果であるRangeオブジェクトを組み込み配列に自分で変換しなければ"#"以降の文字列と連結できない
    • chainを使うと結果がおかしくなった(文字列なのに数字の列になった).

元のC++コードのようにiteratorベースのコードにした方がスマートに書けるだろうか?
std.iteratorってのがあったはずだけど何ができたっけなぁ.

こんなこといいな できたらいいな

import std.stdio;
import std.algorithm;
import std.range;

void main()
{
	auto res = map!("a * a")(cast(int[])[1,2,3]);
	writeln(res);
}

// Rangeオブジェクトの型が表示できなくなるけど標準にあったらいいな
template writeln(R) if (isInputRange!(R))
{
	void writeln(R r)
	{
		foreach (e; r)
			std.stdio.write(e);
		std.stdio.writeln();
	}
}

でしょ?
(追記:このままじゃダメみたいだ)