DynamicTypeMacros.hxx

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2001-2004 MUSIC TECHNOLOGY GROUP (MTG)
00003  *                         UNIVERSITAT POMPEU FABRA
00004  *
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  *
00020  */
00021 
00022 
00023 #include "Assert.hxx"
00024 #include "TypeInfoStd.hxx"
00025 #include "StaticBool.hxx"
00026 #include <typeinfo>
00027 
00029 // Reimplementation using chained template methods
00030 // These macros expand functions in the concrete (derived) class of DynamicType.
00031 //
00032 // Related macros: 
00033 // * DYNAMIC_TYPE
00034 // * DYNAMIC_TYPE_USING_INTERFACE
00035 // * DYN_ATTRIBUTE
00036 // * DYN_CONTAINER_ATTRIBUTE
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         template <unsigned int NAttrib, typename Visitor> \
00127         void VisitChainedAttr (AttributePosition<NAttrib>*a, Visitor & visitor) { \
00128                 CheckAttribute ((AttributePosition<NAttrib>::InboundsCheck*)NULL, \
00129                                 (AttributePosition<NAttrib>*)NULL); \
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         /*inline TYPE* Get##NAME##Vector(unsigned n) { return Get_##TYPE##Vector(n); }*/ \
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 
Generated by  doxygen 1.6.3