読者です 読者をやめる 読者になる 読者になる

【D言語】__LINE__と__FILE__の挙動が修正される

D言語

前回は、LINEFILEの挙動を修正するPull Requestについてでしたが、

http://codelogy.org/?p=960

最近、そのPull RequestがMergeされ、LINEFILEの挙動が修正されました!


LINEFILEの挙動が修正されると、例えば


import std.conv : to;
import std.stdio : writeln;

// 同じ内容で、structとclassを両方定義する
string defBoth(size_t line = __LINE__, string file = __FILE__)(string name, string def)
{
    return "struct S" ~ name ~ "{" ~ def ~ "}"
           // 行数を合わせるために#lineを使う
           "#line " ~ line.to!string() ~ " \""~ file ~ "\"\n"
           "class C" ~ name ~ "{" ~ def ~ "}";
}

mixin (defBoth("Point", q{
    int x, y;

    this(int x, int y)
    {
        this.x = x;
        this.y = y;
        __LINE__.writeln();
    }
}));

void main()
{
    SPoint p1 = SPoint(1, 2);
    CPoint p2 = new CPoint(3, 4);
}

今までは、上のdefBothのようなことを実現するために、文字列mixinを使わざるを得ませんでした。今回の修正で、普通のテンプレートの引数のデフォルト値として使われたLINEFILEが、インスタンス化された場所の値になるようになったので、


import std.conv : to;
import std.stdio : writeln;

static assert(__VERSION__ >= 2064);

// 同じ内容で、structとclassを両方定義する
mixin template defBoth(string name, string def, size_t line = __LINE__, string file = __FILE__)
{
    mixin (defBothImpl(name, def, line, file));
}

string defBothImpl(string name, string def, size_t line, string file)
{
    return "#line " ~ line.to!string() ~ " \""~ file ~ "\"\n"
           "struct S" ~ name ~ "{" ~ def ~ "}"
           "#line " ~ line.to!string() ~ " \""~ file ~ "\"\n"
           "class C" ~ name ~ "{" ~ def ~ "}";
}

mixin defBoth!("Point", q{
    int x, y;

    this(int x, int y)
    {
        this.x = x;
        this.y = y;
        __LINE__.writeln();
    }
});

void main()
{
    SPoint p1 = SPoint(1, 2);
    CPoint p2 = new CPoint(3, 4);
}

このように、template mixinを使うことができます。書かなくてはいけないカッコが1組減るので、見やすくなっています。 便利ですね。

担当:美馬(ctpgもtemplate mixinのインターフェースを提供する予定)