#include <iostream>
#include <string>
enum class SimpleType {
ST_INVALID, ST_INT64, ST_UINT64, ST_DOUBLE, ST_STRING
};
#define SIMPLE_TYPE_MACRO(MY_MACRO, ...) \
MY_MACRO(SimpleType::ST_INT64, int64_t, ##__VA_ARGS__); \
MY_MACRO(SimpleType::ST_UINT64, uint64_t, ##__VA_ARGS__); \
MY_MACRO(SimpleType::ST_DOUBLE, double, ##__VA_ARGS__); \
MY_MACRO(SimpleType::ST_STRING, std::string, ##__VA_ARGS__)
template<SimpleType stype>
struct SimpleType2BuiltinType {
struct InvalidType {};
typedef InvalidType BuiltinType;
};
#define SimpleType2BuiltinTypeTraits(stype, btype, ...) \
template<> \
struct SimpleType2BuiltinType<stype> { \
typedef btype BuiltinType; \
}
SIMPLE_TYPE_MACRO(SimpleType2BuiltinTypeTraits);
#undef SimpleType2BuiltinTypeTraits
class Object {
public:
Object(SimpleType stype)
: type_(stype) {}
~Object() {}
public:
virtual SimpleType type() const {
return type_;
}
virtual void type(SimpleType stype) {
type_ = stype;
}
private:
SimpleType type_;
};
template<class T>
class BasicType : public Object {
public:
BasicType(SimpleType stype)
: Object(stype) {}
~BasicType() {}
public:
virtual void value(const T& value) {
value_ = value;
}
virtual const T& value() const {
return value_;
}
private:
T value_;
};
typedef BasicType<std::string> String;
int main(int argc, char *argv[]) {
std::string v("foo");
String foo(SimpleType::ST_STRING);
foo.value(v);
Object* object = &foo;
switch (object->type()) {
#define GET_VALUE(stype, ...) \
case stype: { \
typedef SimpleType2BuiltinType<stype>::BuiltinType Type; \
BasicType<Type>* typed = static_cast<BasicType<Type>*>(object); \
const Type& v = typed->value(); \
std::cout << v << std::endl; \
break; \
}
SIMPLE_TYPE_MACRO(GET_VALUE, object);
#undef GET_VALUE
default:
break;
}
return 0;
}