typesystem.h
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #if !defined(INCLUDED_TYPESYSTEM_H)
00023 #define INCLUDED_TYPESYSTEM_H
00024
00025 #include <list>
00026 #include "generic/callback.h"
00027 #include "generic/static.h"
00028
00029 class InitialiserList
00030 {
00031 typedef std::list<Callback> Initialisers;
00032 Initialisers m_initialisers;
00033 mutable bool m_initialised;
00034 public:
00035 InitialiserList () :
00036 m_initialised(false)
00037 {
00038 }
00039 void addInitialiser (const Callback& callback)
00040 {
00041 m_initialisers.push_back(callback);
00042 }
00043 void initialise () const
00044 {
00045 if (!m_initialised) {
00046 m_initialised = true;
00047
00048 for (Initialisers::const_iterator i = m_initialisers.begin(); i != m_initialisers.end(); ++i) {
00049 (*i)();
00050 }
00051 }
00052 }
00053 };
00054
00055
00056
00057 class TypeSystemInitialiser: public InitialiserList
00058 {
00059 };
00060
00061 typedef SmartStatic<TypeSystemInitialiser> StaticTypeSystemInitialiser;
00062
00063 class TypeSystemRef: public StaticTypeSystemInitialiser
00064 {
00065 public:
00066 TypeSystemRef ()
00067 {
00068 StaticTypeSystemInitialiser::instance().initialise();
00069 }
00070 };
00071
00072 typedef std::size_t TypeId;
00073 typedef void*(*TypeCast) (void*);
00074
00075 template<std::size_t SIZE>
00076 class TypeCastTable
00077 {
00078 TypeCast m_casts[SIZE];
00079 public:
00080 TypeCastTable ()
00081 {
00082 std::uninitialized_fill(m_casts, m_casts + SIZE, TypeCast(0));
00083 }
00084 void install (TypeId typeId, TypeCast typeCast)
00085 {
00086 m_casts[typeId] = typeCast;
00087 }
00088 void* cast (TypeId typeId, void* p)
00089 {
00090 TypeCast typeCast = m_casts[typeId];
00091 if (typeCast != 0) {
00092 return typeCast(p);
00093 }
00094 return 0;
00095 }
00096 };
00097
00098 template<typename Type, typename Cast>
00099 class CastInstaller
00100 {
00101 public:
00102 static void install (TypeCastTable<Type::SIZE>& table)
00103 {
00104 table.install(Type::getTypeId(), Cast::cast);
00105 }
00106 };
00107
00108 template<typename Type>
00109 class IdentityCast
00110 {
00111 public:
00112 static void* cast (void* p)
00113 {
00114 return p;
00115 }
00116 };
00117
00118 template<typename Type, typename Base>
00119 class StaticCast
00120 {
00121 public:
00122 static void* cast (void* p)
00123 {
00124 return static_cast<Base*> (reinterpret_cast<Type*> (p));
00125 }
00126 };
00127
00128 template<typename Type>
00129 class NullType
00130 {
00131 };
00132
00133 template<typename Type, typename Contained>
00134 class ContainedCast
00135 {
00136 public:
00137 static void* cast (void* p)
00138 {
00139 return &reinterpret_cast<Type*> (p)->get(NullType<Contained> ());
00140 }
00141 };
00142
00143 #endif