00001 ///////////////////////////////////////////////////////////////////////////////////////// 00002 /// \file classapi.h 00003 /// \brief Header file that defines templatized utility functions used to implement 00004 /// the private data management inside the atomic classes 00005 /// 00006 /// Functions to: 00007 /// - set the private data 00008 /// - retrieve the private data 00009 /// - deallocate the private data 00010 /// 00011 /// Each utility function comes in 2 flavors: 00012 /// - for the SPARK::TObject instance as accessed from an instance callback 00013 /// - for the SPARK::TInverse instance as accessed from a static callback 00014 /// 00015 /// Also, the DeleteData() functions are parameterized with a delete policy type that 00016 /// lets you implement the deletion task. We have provided two such policy classes: 00017 /// - SPARK::delete_policy 00018 /// - SPARK::delete_array_policy 00019 /// 00020 ///////////////////////////////////////////////////////////////////////////////////////// 00021 /// 00022 /// \author Dimitri Curtil 00023 /// \version %SPARK 2.0 00024 /// \date April 16, 2003 00025 /// 00026 ///////////////////////////////////////////////////////////////////////////////////////// 00027 /// \attention 00028 /// PORTIONS COPYRIGHT (C) 2003 AYRES SOWELL ASSOCIATES, INC. \n 00029 /// PORTIONS COPYRIGHT (C) 2003 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA . 00030 /// PENDING APPROVAL BY THE US DEPARTMENT OF ENERGY. ALL RIGHTS RESERVED. 00031 /// 00032 ///////////////////////////////////////////////////////////////////////////////////////// 00033 00034 00035 #if !defined(__CLASSAPI_H__) 00036 #define __CLASSAPI_H__ 00037 00038 00039 #include "compat.h" 00040 00041 00042 ///////////////////////////////////////////////////////////////////////////////////////// 00043 /// \namespace SPARK::AtomicClass 00044 /// \brief Definition of the atomic class API library used to manage the private data 00045 /// from the callbacks asociated with each SPARK::TObject and SPARK::TInverse 00046 /// instances. 00047 ///////////////////////////////////////////////////////////////////////////////////////// 00048 00049 namespace SPARK { 00050 00051 // Forward declaration 00052 class TObject; 00053 class TInverse; 00054 00055 00056 /// \struct delete_policy 00057 /// \brief Policy class used to delete non-array data types using delete operator 00058 /// 00059 /// \note The static method apply() does not throw any exceptions. 00060 struct delete_policy { 00061 template<typename DataType> 00062 static bool apply(DataType* data) SPARK_NOT_THROWING 00063 { 00064 try { 00065 delete data; 00066 } 00067 catch(...) { 00068 return false; 00069 } 00070 return true; 00071 } 00072 }; 00073 00074 00075 /// \struct delete_array_policy 00076 /// \brief Policy class used to delete array data types using delete [] operator 00077 /// 00078 /// \note The static method apply() does not throw any exceptions. 00079 struct delete_array_policy { 00080 template<typename DataType> 00081 static bool apply(DataType* data) SPARK_NOT_THROWING 00082 { 00083 try { 00084 delete [] data; 00085 } 00086 catch(...) { 00087 return false; 00088 } 00089 return true; 00090 } 00091 }; 00092 00093 00094 /// \struct deleter 00095 /// \brief Helper class that implements either delete_policy or delete_array_policy 00096 /// depending on the compile-time value of the non-type parameter IsArray 00097 /// 00098 /// The delete policy is used in the SPARK::AtomicClass::DeleteData() API function. 00099 /// Also see macro #DELETE_DATA in file spark.h for usage of the deleter<> struct. 00100 template<bool IsArray> 00101 struct deleter 00102 {}; 00103 00104 template<> // IsArray = false 00105 struct deleter<false> : public delete_policy 00106 {}; 00107 00108 template<> // IsArray = true 00109 struct deleter<true> : public delete_array_policy 00110 {}; 00111 00112 00113 00114 00115 namespace AtomicClass { 00116 00117 /// \brief Sets pointer to private data in TObject instance 00118 /// 00119 /// \param object Address of the TObject instance (use THIS macro from within the callback body) 00120 /// \param data Address of the private data to be stored within the TObject instance 00121 template<typename DataType> 00122 void SetData(TObject* object, DataType* data) 00123 { 00124 object->SetData( data ); 00125 } 00126 00127 00128 /// \brief Sets pointer to static private data in TInverse instance 00129 /// 00130 /// \param inverse Address of the TInverse instance (use THIS macro from within the static callback body) 00131 /// \param staticData Address of the static private data to be stored within the TInverse instance 00132 template<typename StaticDataType> 00133 void SetData(TInverse* inverse, StaticDataType* staticData) 00134 { 00135 inverse->SetStaticData( staticData ); 00136 } 00137 00138 00139 /// \brief Returns address of private data of type \c DataType attached to the \c TObject instance 00140 /// 00141 /// \return Pointer to private data as DataType* 00142 /// \param object (use THIS macro from within the callback body) 00143 template<typename DataType> 00144 DataType* GetData(TObject* object) 00145 { 00146 return static_cast<DataType*>( object->GetData() ); 00147 } 00148 00149 00150 /// \brief Returns address of static private data of type \c StaticDataType attached to the \c TInverse instance 00151 /// 00152 /// \return Pointer to static private data as StaticDataType* 00153 /// \param inverse (use THIS macro from within the static callback body) 00154 template<typename StaticDataType> 00155 StaticDataType* GetData(TInverse* inverse) 00156 { 00157 return static_cast<StaticDataType*>( inverse->GetStaticData() ); 00158 } 00159 00160 00161 /// \brief Deallocates private data of type \c DataType attached to a TObject instance 00162 /// 00163 /// \param object Address of the TObject instance (use THIS macro from within the callback body) 00164 /// \param dummy1 Never specify this parameter. It is used as a workaround for a bug in MSVC++ 00165 /// \param dummy2 Never specify this parameter. It is used as a workaround for a bug in MSVC++ 00166 /// 00167 /// \pre DeletePolicyType must define a static method named apply() that performs the deletion task. 00168 /// Possible policy candidates are: SPARK::delete_policy and SPARK::delete_array_policy 00169 /// \post Private data is deallocated and pointer in TObject instance is reset to 0 00170 /// 00171 // \bug MSVC++ does not overload normal functions depending on explicit argument specifications 00172 // (see Microsoft KB Article 240871). The workaround consists in adding a dummy parameter 00173 // with proper default value. 00174 template<typename DataType, typename DeletePolicyType> 00175 bool DeleteData(TObject* object, DataType* dummy1 = 0, DeletePolicyType* dummy2 = 0) 00176 { 00177 // Cast void* to private data type 00178 // \bug MSVC++ does not recognize template type from return type. It is therefore explictly specified. 00179 DataType* Data = SPARK::AtomicClass::GetData<DataType>( object ); 00180 00181 // Release allocated memory 00182 bool Deleted = DeletePolicyType::apply( Data ); 00183 00184 // Reset NULL pointer to private data 00185 // \bug MSVC++ cannot deduce template type of argument. It is therefore explictly specified. 00186 SPARK::AtomicClass::SetData<DataType>( object, 0 ); 00187 00188 return Deleted; 00189 } 00190 00191 00192 /// \brief Deallocates private data of type \c StaticDataType attached to a TInverse instance 00193 /// 00194 /// \param inverse Address of the TInverse instance (use THIS macro from within the static callback body) 00195 /// \param dummy1 Never specify this parameter. It is used as a workaround for a bug in MSVC++ 00196 /// \param dummy2 Never specify this parameter. It is used as a workaround for a bug in MSVC++ 00197 /// 00198 /// \pre DeletePolicyType must define a static method named apply() that performs the deletion task. 00199 /// Possible policy candidates are: SPARK::delete_policy and SPARK::delete_array_policy 00200 /// \post Private data is deallocated and pointer in TInverse instance is reset to 0 00201 /// 00202 // \bug MSVC++ does not overload normal functions depending on explicit argument specifications 00203 // (see Microsoft KB Article 240871). The workaround consists in adding a dummy parameter 00204 // with proper default value. 00205 template<typename StaticDataType, typename DeletePolicyType> 00206 bool DeleteData(TInverse* inverse, StaticDataType* dummy1 = 0, DeletePolicyType* dummy2 = 0) 00207 { 00208 // Cast void* to private data type 00209 // \bug MS VC++ does not recognize template type from return type. It is therefore explictly specified. 00210 StaticDataType* StaticData = SPARK::AtomicClass::GetData<StaticDataType>( inverse ); 00211 00212 // Release allocated memory 00213 bool Deleted = DeletePolicyType::apply( StaticData ); 00214 00215 // Reset NULL pointer to private data 00216 // \bug MSVC++ cannot deduce template type of argument. It is therefore explictly specified. 00217 SPARK::AtomicClass::SetData<StaticDataType>( inverse, 0 ); 00218 00219 return Deleted; 00220 } 00221 00222 00223 }; }; // namespace SPARK::AtomicClass 00224 ///////////////////////////////////////////////////////////////////////////////////////// 00225 00226 00227 #endif //__CLASSAPI_H__ 00228 00229