2013年3月17日日曜日

C言語でインデクサを実現するm4マクロ

C#のインデクサのようなものをC言語で実現するm4マクロを紹介します。
まだまだ改良の余地がありますが暫定的なものとして公開します。
define(`defObject',`
        setIndexer($2)
        $1 $2=NULL;
        $2=$1Init(shift($@));
');
define(`setIndexer',`define(`$1',
                `if'`else('
                        `$'`#'`,2,'
                        ``$1''`->a['`$'`1'`*'`$'`2'`],
                        ``$1'''
                `)'
        )
');

#include <stdlib.h>

typedef struct{
        int *a;
} testObj;
testObj *testObjInit(void *a,int n){
        struct testObj *result=malloc(sizeof(struct testObj));
        result->a=malloc(sizeof(int)*n);
 return result;
}
int main(void){
        defObject(testObj,objs,1024);    //①
        objs(1,3)+=1;//ここでインデクサのようなアクセスを実現している
 objs->a[2]=2;//普通にアクセスすることも出来る
}
①のdefObjectの第1引数は型名、第2引数は宣言する変数名です。
第3引数以降はtestObjInitに渡すデータです。
defObjectの中で[構造体名]Init関数を呼び出しています。(ここではtestObjInit)
 defObjectの中で呼び出されているsetIndexerマクロがインデクサを実現する機能になります。
setIndexerの中の ``$1''`->a['`$'`1'`*'`$'`2'`], はobjs(1,3)と呼び出されたとき、objs->a[1*3]に置換することを書いています。
 仮にsetIndexerを次のように書いた場合、
define(`setIndexer',`define(`$1',
                `if'`else('
                        `$'`#'`,1,'
                        ``$1''`->a['`$'`1'],
                        ``$1'''
                `)'
        )
');


objs(3)がobjs->a[3]に置換されます.

0 件のコメント:

コメントを投稿