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 
00028 // Reimplementation using chained template methods
00029 // These macros expand functions in the concrete (derived) class of DynamicType.
00030 //
00031 // Related macros: 
00032 // * DYNAMIC_TYPE
00033 // * DYNAMIC_TYPE_USING_INTERFACE
00034 // * DYN_ATTRIBUTE
00035 // * DYN_CONTAINER_ATTRIBUTE
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         template <unsigned int NAttrib, typename Visitor> \
00126         void VisitChainedAttr (AttributePosition<NAttrib>*a, Visitor & visitor) { \
00127                 CheckAttribute ((AttributePosition<NAttrib>::InboundsCheck*)NULL, \
00128                                 (AttributePosition<NAttrib>*)NULL); \
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         /*inline TYPE* Get##NAME##Vector(unsigned n) { return Get_##TYPE##Vector(n); }*/ \
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 

Generated on Tue Aug 12 22:33:42 2008 for CLAM by  doxygen 1.5.5