1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
|
/* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */
/*
* creg - Code compoment registration system
* Type matching using class templates (only class template support partial specialization)
*/
#ifndef _TYPE_DEDUCTION_H
#define _TYPE_DEDUCTION_H
// Undefined types return 0
template<typename T>
struct DeduceType {
boost::shared_ptr<IType> Get() { return boost::shared_ptr<IType>(IType::CreateObjInstanceType(T::StaticClass())); }
};
template<typename T>
struct IsBasicType {
enum {Yes=0, No=1};
};
// Support for a number of fundamental types
#define CREG_SUPPORT_BASIC_TYPE(T, typeID) \
template<> struct DeduceType<T> { \
boost::shared_ptr<IType> Get() { return IType::CreateBasicType(typeID); } \
}; \
template<> struct IsBasicType<T> { \
enum {Yes=1, No=0 }; \
};
CREG_SUPPORT_BASIC_TYPE(int, crInt)
CREG_SUPPORT_BASIC_TYPE(unsigned int, crUInt)
CREG_SUPPORT_BASIC_TYPE(short, crShort)
CREG_SUPPORT_BASIC_TYPE(unsigned short, crUShort)
CREG_SUPPORT_BASIC_TYPE(char, crChar)
CREG_SUPPORT_BASIC_TYPE(unsigned char, crUChar)
CREG_SUPPORT_BASIC_TYPE(long, crInt) // Long is assumed to be an int (4 bytes)
CREG_SUPPORT_BASIC_TYPE(unsigned long, crUInt)
CREG_SUPPORT_BASIC_TYPE(float, crFloat)
CREG_SUPPORT_BASIC_TYPE(double, crDouble)
CREG_SUPPORT_BASIC_TYPE(bool, crBool)
#if defined(SYNCDEBUG) || defined(SYNCCHECK)
CREG_SUPPORT_BASIC_TYPE(SyncedSint, crSyncedSint)
CREG_SUPPORT_BASIC_TYPE(SyncedUint, crSyncedUint)
CREG_SUPPORT_BASIC_TYPE(SyncedSshort, crSyncedSshort)
CREG_SUPPORT_BASIC_TYPE(SyncedUshort, crSyncedUshort)
CREG_SUPPORT_BASIC_TYPE(SyncedSchar, crSyncedSchar)
CREG_SUPPORT_BASIC_TYPE(SyncedUchar, crSyncedUchar)
CREG_SUPPORT_BASIC_TYPE(SyncedSlong, crSyncedSint) // Long is assumed to be an int (4 bytes)
CREG_SUPPORT_BASIC_TYPE(SyncedUlong, crSyncedUint)
CREG_SUPPORT_BASIC_TYPE(SyncedFloat, crSyncedFloat)
CREG_SUPPORT_BASIC_TYPE(SyncedDouble, crSyncedDouble)
CREG_SUPPORT_BASIC_TYPE(SyncedBool, crSyncedBool)
#endif
template<typename T>
class ObjectPointerType : public IType
{
public:
ObjectPointerType() { objectClass = T::StaticClass(); }
void Serialize(ISerializer *s, void *instance) {
void **ptr = (void**)instance;
if (s->IsWriting())
s->SerializeObjectPtr(ptr, *ptr ? ((T*)*ptr)->GetClass() : 0);
else s->SerializeObjectPtr(ptr, objectClass);
}
std::string GetName() { return objectClass->name + "*"; }
Class* objectClass;
};
// Pointer type
template<typename T>
struct DeduceType<T*> {
boost::shared_ptr<IType> Get() { return boost::shared_ptr<IType>(new ObjectPointerType<T>()); }
};
// Reference type, handled as a pointer
template<typename T>
struct DeduceType<T&> {
boost::shared_ptr<IType> Get() { return boost::shared_ptr<IType>(new ObjectPointerType<T>()); }
};
// Static array type
template<typename T, size_t ArraySize>
struct DeduceType<T[ArraySize]> {
boost::shared_ptr<IType> Get() {
DeduceType<T> subtype;
return boost::shared_ptr<IType>(new StaticArrayType<T, ArraySize>(subtype.Get()));
}
};
// Vector type (vector<T>)
template<typename T>
struct DeduceType<std::vector<T> > {
boost::shared_ptr<IType> Get() {
DeduceType<T> elemtype;
return boost::shared_ptr<IType>(new DynamicArrayType<std::vector<T> >(elemtype.Get()));
}
};
// String type
template<> struct DeduceType<std::string > {
boost::shared_ptr<IType> Get() { return IType::CreateStringType(); }
};
// GetType allows to use parameter type deduction to get the template argument for DeduceType
template<typename T>
boost::shared_ptr<IType> GetType(T& var) {
DeduceType<T> deduce;
return deduce.Get();
}
#endif // _TYPE_DEDUCTION_H
|