KOTET'S PERSONAL BLOG

#dlang binary.h in D

Created: , Last modified:
#dlang #tech

C言語にはなぜか二進数リテラルがないため、そういうことをしたい場合自分で何とかする必要がある。 D言語には普通に二進数リテラルがあるが、同じことをするコードを書いてTemplate Mixinの練習をすることにした。 与えられた型の表現できる範囲の二進数リテラルを生成する。

mixin template binary(T)
{
mixin(() {
import std.conv : to;
import std.range : chain, only, iota;
import std.string : rightJustify, format;
string result = "";
foreach (n; iota(0, T.max).chain(T.max.only))
{
size_t maxlen = format("%b", T.max).length;
string representation = format("%b", n);
foreach (minWidth; representation.length .. maxlen + 1)
{
result ~= "enum " ~ T.stringof ~ " B" ~ rightJustify(representation,
minWidth, '0') ~ " = " ~ to!string(n) ~ ";";
}
}
return result;
}());
}
unittest
{
mixin binary!(ubyte);
}
view raw binary.d hosted with ❤ by GitHub

どんなコードが生成されているか見てみる。

$ dmd binary.d -unittest -main -vcg-ast

binary.d.cg

全体はこちらubyteで表現できるすべての値の8文字以下の二進数表現を網羅している。 コードの文字列を生成して、1つのmixinに渡している。

mixin template binary(T)
{
    foreach(...){
        mixin(...);
    }
}

上のようにmixinforeachで回したいところだが、それをするためのstatic foreachはまだ Preliminary Review Round 1 なのでのんびり待とう。

追記: static foreachが使えるようになった!