|
CLAM-Development
1.3
|
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
1.7.6.1