プリプロセッサ

自分は、携帯JAVAでゲームを作る際には、Imageを配列で持ちます。
しかし、実際にゲームを作ろうと思っても、画像が用意されていないことはしばしばあります。
なので、仮想イメージとして、

#define g_title         0
#define g_card(n)       (1+n)
#define g_chara(n)      (g_card(g_card_max)+n)
#define g_number(n)     (g_number(g_chara_max)+n)

#define g_card_max      (54)
#define g_chara_max     (6)
#define g_number_max    (10)

こんな感じで持っておいて、描画をする際に、これを実際のImage配列のインデックスに変換します。

public int getIndex(int r){
    int n = -1;
    if(r == g_title){
        n = 0;
    }else if(g_card(0)<=r && r<g_card(g_card_max)){
        n = 7 + (r - g_card(0));
    }else if(g_chara(0)<=r && r<g_chara(g_chara_max)){
        n = 1 + (r - g_chara(0));
    }else if(g_number(0)<=r && r<g_number(g_number_max)){
        n = 70 + (r - g_number(0));
    }
    return n;
}

しかし、これだと、大変見た目が悪い!と思って、これを整理するためにプリプロセッサを駆使してみました。

public int getIndex(int r){
    int n=-1;

#define ef              else if
#define _same(a)        (r == (a))
#define _range(a,b)     ((a)<=r && r<(b))
#define same(a)         ef(_same(a))
#define range(a)        ef(_range(a(0),(a(0)+a##_max)))
#define diff(a)         (r-(a(0)))

    if(_same(g_title)){
        n = 0;
    }range(g_card){
        n = 7 + diff(g_card);
    }range(g_chara){
        n = 1 + diff(g_chara);
    }range(g_number){
        n = 70 + diff(g_number);
    }

#undef diff
#undef range
#undef same
#undef _range
#undef _same
#undef ef

    return n;
}

ええ、明らかにやりすぎですね(^^;


まあ、これはどうでもいいんですよ。
ここまでやったんだから、ということで、最初のdefine定義も同じように綺麗にしてやろうとした訳なんですよ。

#define g_rmax(a)           (a(0)+a##_max)
#define g_smax(a)           ((a)+1)

#define g_title             0
#define g_card(n)           (g_smax(g_title)+n)
#define g_chara(n)          (g_rmax(g_card)+n)
#define g_number(n)         (g_rmax(g_chara)+n)

#define g_card_max          (54)
#define g_chara_max         (6)
#define g_number_max        (10)

これ、コンパイルが通らないんです。
なんか、g_numberのg_rmaxをプリプロセッサで展開すると、その中身にg_chara(0)が入っていて、これが展開されると、またg_rmaxが入っているのですが、これが上手く展開されないんですよ。
プリプロセッサって案外しょぼいということに気が付いた瞬間でした(;つД`)
いや、まあ、それだけなんですけどね(;´Д`)