CLAM-Development
1.1
|
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