00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "Assert.hxx"
00024 #include "TypeInfoStd.hxx"
00025 #include "StaticBool.hxx"
00026 #include <typeinfo>
00027
00029
00030
00031
00032
00033
00034
00035
00036
00038
00039
00040 #define __COMMON_DYNAMIC_TYPE(CLASS_NAME,N) \
00041 public: \
00042 virtual const char* GetClassName() const { \
00043 return #CLASS_NAME; \
00044 }\
00045 enum { eNumAttr= N }; \
00046 CLAM::DynamicType& GetDynamicTypeCopy(const bool shareData=false, const bool deep=false) const\
00047 { \
00048 return *new CLASS_NAME(*this, shareData, deep); \
00049 }\
00050 protected: \
00051 void MandatoryInit()\
00052 {\
00053 static bool staticTableInitialized = false;\
00054 static TAttr staticTypeDescTable[N+1];\
00055 typeDescTable = staticTypeDescTable;\
00056 if(!staticTableInitialized)\
00057 {\
00058 staticTableInitialized=true;\
00059 InformAll();\
00060 }else \
00061 {\
00062 maxAttrSize = N ? (typeDescTable[N-1].offset+typeDescTable[N-1].size) : 0;\
00063 }\
00064 } \
00065 public: \
00066 \
00067 const std::type_info & GetTypeId(unsigned n) const \
00068 { \
00069 return GetChainedTypeId((AttributePosition<0>*)NULL,n); \
00070 } \
00071 \
00072 template <typename Visitor> \
00073 void VisitAll (Visitor & visitor) { \
00074 VisitChainedAttr((AttributePosition<0>*)NULL, visitor); \
00075 } \
00076 \
00077 void RemoveAll () { \
00078 RemoveChainedAttr((AttributePosition<0>*)NULL); \
00079 } \
00080 \
00081 void AddAll () { \
00082 AddChainedAttr((AttributePosition<0>*)NULL); \
00083 } \
00084 private: \
00085 \
00086 void InformAll () { \
00087 InformChainedAttr((AttributePosition<0>*)NULL); \
00088 DynamicType::InformAll(); \
00089 } \
00090 protected: \
00091 \
00092 virtual void StoreDynAttributes(CLAM::Storage & s) const { \
00093 StoreChainedAttr((AttributePosition<0>*)NULL,s); \
00094 } \
00095 \
00096 virtual void LoadDynAttributes(CLAM::Storage & s) { \
00097 AddAll(); \
00098 UpdateData(); \
00099 LoadChainedAttr((AttributePosition<0>*)NULL,s); \
00100 UpdateData(); \
00101 } \
00102 private: \
00103 template <unsigned int NAttrib> \
00104 class AttributePosition : public CLAM::DynamicType::AttributePositionBase<NAttrib> { \
00105 public: \
00106 typedef StaticBool<!(NAttrib>=N)> InboundsCheck; \
00107 }; \
00108 \
00111 template <unsigned int NAttrib> \
00112 void CheckAttribute (StaticFalse*inRange,AttributePosition<NAttrib>*a) { \
00113 AttributePosition<(NAttrib)-1>* previous; \
00114 previous->CompilationError_AttributePositionOutOfBounds(); \
00115 }\
00116 \
00120 template <unsigned int NAttrib> \
00121 void CheckAttribute (StaticTrue*inRange,AttributePosition<NAttrib>*a) { \
00122 a->CompilationError_AttributeNotDefined(); \
00123 }\
00124 \
00125
00126
00127
00128
00129
00130 \
00131 \
00132 template <unsigned int NAttrib> \
00133 void RemoveChainedAttr (AttributePosition<NAttrib>*a) { \
00134 typedef typename AttributePosition<NAttrib>::InboundsCheck InboundsCheck; \
00135 CheckAttribute ((InboundsCheck*)NULL, \
00136 (AttributePosition<NAttrib>*)NULL); \
00137 }\
00138 \
00139 template <unsigned int NAttrib> \
00140 void AddChainedAttr (AttributePosition<NAttrib>*a) { \
00141 typedef typename AttributePosition<NAttrib>::InboundsCheck InboundsCheck; \
00142 CheckAttribute ((InboundsCheck*)NULL, \
00143 (AttributePosition<NAttrib>*)NULL); \
00144 }\
00145 \
00146 template <unsigned int NAttrib> \
00147 void InformChainedAttr (AttributePosition<NAttrib>*a) { \
00148 typedef typename AttributePosition<NAttrib>::InboundsCheck InboundsCheck; \
00149 CheckAttribute ((InboundsCheck*)NULL, \
00150 (AttributePosition<NAttrib>*)NULL); \
00151 }\
00152 \
00153 template <unsigned int NAttrib> \
00154 void StoreChainedAttr (AttributePosition<NAttrib>*a,CLAM::Storage & s) const { \
00155 typedef typename AttributePosition<NAttrib>::InboundsCheck InboundsCheck; \
00156 CheckAttribute ((InboundsCheck*)NULL, \
00157 (AttributePosition<NAttrib>*)NULL); \
00158 }\
00159 \
00160 template <unsigned int NAttrib> \
00161 void LoadChainedAttr (AttributePosition<NAttrib>*a,CLAM::Storage & s) { \
00162 typedef typename AttributePosition<NAttrib>::InboundsCheck InboundsCheck; \
00163 CheckAttribute ((InboundsCheck*)NULL, \
00164 (AttributePosition<NAttrib>*)NULL); \
00165 }\
00166 private: \
00167 \
00168 template <typename Visitor> \
00169 void VisitChainedAttr (AttributePosition<N>*, Visitor & visitor) { \
00170 } \
00171 \
00172 void RemoveChainedAttr (AttributePosition<N>*) { \
00173 } \
00174 \
00175 void AddChainedAttr (AttributePosition<N>*) { \
00176 } \
00177 \
00178 void InformChainedAttr (AttributePosition<N>*) { \
00179 } \
00180 \
00181 void StoreChainedAttr (AttributePosition<N>*pos, CLAM::Storage &s) const { \
00182 } \
00183 \
00184 void LoadChainedAttr (AttributePosition<N>*pos, CLAM::Storage &s) { \
00185 } \
00186 \
00187 const std::type_info & GetChainedTypeId(AttributePosition<N>*pos, unsigned n) const \
00188 { \
00189 return typeid(void); \
00190 } \
00191
00192
00193
00194 #define DYNAMIC_TYPE(CLASS_NAME, N)\
00195 public: \
00196 CLASS_NAME() : CLAM::DynamicType(N)\
00197 {\
00198 MandatoryInit(); \
00199 DefaultInit();\
00200 }\
00201 CLASS_NAME(const CLASS_NAME& prototype, const bool shareData=false, const bool deep=true)\
00202 : CLAM::DynamicType(prototype, shareData, deep) { \
00203 CopyInit(prototype);\
00204 }\
00205 __COMMON_DYNAMIC_TYPE(CLASS_NAME,N); \
00206
00207
00208 #define DYNAMIC_TYPE_USING_INTERFACE(CLASS_NAME, N, INTERFACE_NAME)\
00209 public: \
00210 CLASS_NAME() : INTERFACE_NAME(N)\
00211 {\
00212 MandatoryInit(); \
00213 DefaultInit();\
00214 }\
00215 CLASS_NAME(const CLASS_NAME& prototype, const bool shareData=false, const bool deep=true)\
00216 : INTERFACE_NAME(prototype, shareData, deep) { \
00217 CopyInit(prototype); \
00218 }\
00219 __COMMON_DYNAMIC_TYPE(CLASS_NAME,N); \
00220
00221
00222 #define __COMMON_DYN_ATTRIBUTE(N,ACCESS,TYPE,NAME) \
00223 private: \
00224 static void* _new_##NAME(void* p)\
00225 {\
00226 return static_cast<void*> (new(p) TYPE());\
00227 }\
00228 \
00229 static void* _new_##NAME(void* pos, void* orig)\
00230 {\
00231 TYPE* typed = static_cast< TYPE*>(orig);\
00232 return static_cast<void*>( new(pos) TYPE(*typed) );\
00233 }\
00234 \
00235 static void _destructor_##NAME(void* p)\
00236 {\
00237 typedef TYPE __Ty;\
00238 static_cast<__Ty*>(p)->~__Ty();\
00239 }\
00240 \
00241 \
00242 struct {} CLAM_compile_time_error_Duplicated_Attribute_Index_##N;\
00243 \
00244 ACCESS: \
00245 inline TYPE& Get##NAME() const {\
00246 CLAM_DEBUG_ASSERT((N<numAttr), \
00247 "There are more registered Attributes than the number " \
00248 "defined in the DYNAMIC_TYPE macro.");\
00249 CLAM_ASSERT(ExistAttr(N),\
00250 "You are trying to access attribute " #NAME \
00251 " that is not Added or not Updated.");\
00252 CLAM_DEBUG_ASSERT(data, \
00253 "No data allocated for the accessed dynamic type:" #NAME );\
00254 void *p=data + dynamicTable[N].offs;\
00255 return *static_cast<TYPE*>(p); \
00256 }\
00257 \
00258 \
00259 inline void Set##NAME(TYPE const & arg) {\
00260 CLAM_DEBUG_ASSERT((N<numAttr), \
00261 "There are more registered Attributes than the number " \
00262 "defined in the DYNAMIC_TYPE macro.");\
00263 CLAM_ASSERT(ExistAttr(N),\
00264 "You are trying to access attribute " #NAME \
00265 " that is not Added or not Updated.");\
00266 CLAM_DEBUG_ASSERT(data, \
00267 "No data allocated for the accessed dynamic type." #NAME );\
00268 void* orig = (void*)(&arg);\
00269 char* pos = data+dynamicTable[N].offs;\
00270 _destructor_##NAME(pos);\
00271 _new_##NAME(pos, orig);\
00272 }\
00273 inline void Add##NAME() {\
00274 AddAttr_(N, sizeof(TYPE));\
00275 }\
00276 template <typename Visitor> \
00277 inline void Visit##NAME(Visitor & visitor) { \
00278 if (Has##NAME()) \
00279 visitor.Accept(#NAME,Get##NAME()); \
00280 }\
00281 inline void Remove##NAME() { \
00282 RemoveAttr_(N); \
00283 }\
00284 inline bool Has##NAME() const { \
00285 return ExistAttr(N); \
00286 } \
00287 private: \
00288 inline void Inform##NAME() {\
00289 InformTypedAttr_(N, #NAME, sizeof(TYPE), #TYPE, false, _new_##NAME, _new_##NAME, _destructor_##NAME, (TYPE*)0);\
00290 }\
00291 static inline int GetSize##NAME() { return sizeof(TYPE); } \
00292 static inline const char* GetType##NAME() { return #TYPE; } \
00293 static inline int GetId##NAME() { return N;}\
00294 public: \
00295 \
00296 private: \
00297 template <typename Visitor> \
00298 void VisitChainedAttr(AttributePosition<N>*, Visitor & visitor) { \
00299 Visit##NAME(visitor); \
00300 VisitChainedAttr((AttributePosition<(N)+1>*)NULL, visitor); \
00301 } \
00302 void RemoveChainedAttr(AttributePosition<N>*) { \
00303 Remove##NAME(); \
00304 RemoveChainedAttr((AttributePosition<(N)+1>*)NULL); \
00305 } \
00306 void AddChainedAttr(AttributePosition<N>*) { \
00307 Add##NAME(); \
00308 AddChainedAttr((AttributePosition<(N)+1>*)NULL); \
00309 } \
00310 void InformChainedAttr(AttributePosition<N>*) { \
00311 Inform##NAME(); \
00312 InformChainedAttr((AttributePosition<(N)+1>*)NULL); \
00313 } \
00314 void StoreChainedAttr(AttributePosition<N>*, CLAM::Storage & s) const { \
00315 Store##NAME(s); \
00316 StoreChainedAttr((AttributePosition<(N)+1>*)NULL,s); \
00317 } \
00318 void LoadChainedAttr(AttributePosition<N>*, CLAM::Storage & s) { \
00319 Load##NAME(s); \
00320 LoadChainedAttr((AttributePosition<(N)+1>*)NULL,s); \
00321 } \
00322 const std::type_info & GetChainedTypeId(AttributePosition<N>*, unsigned n) const { \
00323 if (n==N) return typeid(TYPE); \
00324 return GetChainedTypeId((AttributePosition<(N)+1>*)NULL,n); \
00325 } \
00326
00327
00328 #define DYN_ATTRIBUTE(N,ACCESS,TYPE,NAME) \
00329 __COMMON_DYN_ATTRIBUTE(N,ACCESS,TYPE,NAME) \
00330 protected: \
00331 void Store##NAME(CLAM::Storage & s) const { \
00332 if (Has##NAME()) { \
00333 StoreAttribute((CLAM::TypeInfo<TYPE >::StorableAsLeaf*)NULL, s, Get##NAME(), #NAME); \
00334 } \
00335 } \
00336 bool Load##NAME(CLAM::Storage & s) { \
00337 TYPE obj; \
00338 if (!LoadAttribute((CLAM::TypeInfo<TYPE >::StorableAsLeaf*)NULL, s, obj, #NAME)) { \
00339 Remove##NAME(); \
00340 return false; \
00341 } \
00342 Set##NAME(obj); \
00343 return true; \
00344 } \
00345 ACCESS: \
00346
00347
00348 #define DYN_CONTAINER_ATTRIBUTE(N,ACCESS,TYPE,NAME,ENAME) \
00349 __COMMON_DYN_ATTRIBUTE(N,ACCESS,TYPE,NAME) \
00350 protected: \
00351 void Store##NAME(CLAM::Storage & s) const { \
00352 if (Has##NAME()) { \
00353 StoreIterableAttribute(s, Get##NAME(), #NAME, #ENAME); \
00354 } \
00355 } \
00356 bool Load##NAME(CLAM::Storage & s) { \
00357 Add##NAME(); \
00358 UpdateData(); \
00359 if (! LoadIterableAttribute(s, Get##NAME(), #NAME, #ENAME)) { \
00360 Remove##NAME(); \
00361 return false; \
00362 } \
00363 return true; \
00364 } \
00365 ACCESS: \
00366
00367
00368