まだまだ改良の余地がありますが暫定的なものとして公開します。
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 件のコメント:
コメントを投稿