Custom Type Based on Type Traits
#include <stdint.h>
#include <string>
#include <iostream>
enum class SimpleType {
ST_INVALID,
ST_INT64,
ST_UINT64,
ST_DOUBLE,
ST_STRING
};
template<SimpleType stype>
struct SimpleType2BuiltinType {
struct InvalidType {};
typedef InvalidType BuiltinType;
};
#define SimpleType2BuiltinTypeTraits(stype, btype) \
template<> \
struct SimpleType2BuiltinType<stype> { \
typedef btype BuiltinType; \
}
SimpleType2BuiltinTypeTraits(SimpleType::ST_INT64, int64_t);
SimpleType2BuiltinTypeTraits(SimpleType::ST_UINT64, uint64_t);
SimpleType2BuiltinTypeTraits(SimpleType::ST_DOUBLE, double);
SimpleType2BuiltinTypeTraits(SimpleType::ST_STRING, std::string);
#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<int64_t> Int64;
typedef BasicType<uint64_t> UInt64;
typedef BasicType<double> Double;
typedef BasicType<std::string> String;
#define SIMPLE_VALUE_HELPER(stype, obj) \
case stype: { \
typedef SimpleType2BuiltinType<stype>::BuiltinType Type; \
BasicType<Type>* typed = static_cast<BasicType<Type>*>(obj); \
const Type& v = typed->value(); \
std::cout << v << std::endl; \
break; \
}
#define SIMPLE_TYPE_MACRO_HEPLER(MY_MACRO, obj) \
MY_MACRO(SimpleType::ST_INT64, obj) \
MY_MACRO(SimpleType::ST_UINT64, obj) \
MY_MACRO(SimpleType::ST_DOUBLE, obj) \
MY_MACRO(SimpleType::ST_STRING, obj)
int main(int argc, char *argv[]) {
std::string v("foo");
String foo(SimpleType::ST_STRING);
foo.value(v);
Object* object = &foo;
switch (object->type()) {
SIMPLE_TYPE_MACRO_HEPLER(SIMPLE_VALUE_HELPER, object);
default:
break;
}
return 0;
}