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

type2int

コンパイル時点で型を数値化する記述を無理やり作ってみた。VC++2008だとうまくいった。他のコンパイラだとどうかな。。

#include "stdint.h"
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>

#define ref_member(type, member) (&((type*)0)->member)
#define member_sizeof(type, member) sizeof(((type*)0)->member)

typedef struct {
	uint16_t a;
	int16_t b;
} Mugi;

typedef enum {
	Hoge_A,
	Hoge_B,
} Hoge;

typedef struct {
	uint8_t a;
	int32_t b;
	Hoge c;
	Mugi d;
	uint8_t e;
	uint16_t f;
} Setting;

namespace {
#pragma pack(push,1)
template <typename T>
struct TypeInt
{
	static uint8_t dummy;
};
template <typename T>
uint8_t TypeInt<typename T>::dummy = 0;
static const uint8_t* DUMMY = &TypeInt<void>::dummy;
template <typename T>
uint8_t getTypeInt(T* val)
{
	return (uint8_t) ((&TypeInt<T>::dummy) - DUMMY) - 1;
}


static const int types[] = {
	getTypeInt(ref_member(Setting, a)),
	getTypeInt(ref_member(Setting, b)),
	getTypeInt(ref_member(Setting, c)),
	getTypeInt(ref_member(Setting, d)),
	getTypeInt(ref_member(Setting, e)),
	getTypeInt(ref_member(Setting, f)),
};

}

int main(int argc, char* argv[])
{
	for (int i=0; i<_countof(types); ++i) {
		printf("%d\n", types[i]);
	}
	return 0;
}

テンプレートメタプログラミングといえば、GCCだとtypeofがあるみたいだしVC++2010だとdecltypeが使えるみたいなので少し羨ましい。