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