FDO API Reference | Feature Data Objects |
00001 #ifndef _FDOPTR_H_ 00002 #define _FDOPTR_H_ 00003 // 00004 00005 // 00006 // Copyright (C) 2004-2006 Autodesk, Inc. 00007 // 00008 // This library is free software; you can redistribute it and/or 00009 // modify it under the terms of version 2.1 of the GNU Lesser 00010 // General Public License as published by the Free Software Foundation. 00011 // 00012 // This library is distributed in the hope that it will be useful, 00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 // Lesser General Public License for more details. 00016 // 00017 // You should have received a copy of the GNU Lesser General Public 00018 // License along with this library; if not, write to the Free Software 00019 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00020 // 00021 00022 #ifdef _WIN32 00023 #pragma once 00024 #endif 00025 00026 /// \brief 00027 /// This class ensures T implements AddRef() and Release() and also ensures 00028 /// you cannot call it through the FdoPtr. 00029 template <class T> 00030 class _NoAddRefReleaseOnFdoPtr : public T 00031 { 00032 private: 00033 virtual FdoInt32 AddRef() = 0; 00034 virtual FdoInt32 Release() = 0; 00035 }; 00036 00037 template <class T> 00038 #ifdef _WIN32 00039 inline __declspec(nothrow) T* __stdcall FdoPtrAssign(T** pp, T* lp) 00040 #else 00041 inline T* FdoPtrAssign(T** pp, T* lp) 00042 #endif 00043 { 00044 if (lp != NULL) 00045 lp->AddRef(); 00046 if (*pp) 00047 (*pp)->Release(); 00048 *pp = lp; 00049 return lp; 00050 } 00051 00052 /// \brief 00053 /// FdoPtr is smart pointer to FDO objects. It automatically 00054 /// handles the memory management for these objects. In particular it handles 00055 /// the adding and releasing of references on the objects, and their deletion 00056 /// when the last reference is released. 00057 /// 00058 /// When the FdoPtr goes out of scope, the FDO object that it references 00059 /// is released. 00060 template <class T> 00061 class FdoPtr 00062 { 00063 public: 00064 typedef T _PtrClass; 00065 00066 /// \brief 00067 /// Constructs a FdoPtr that initially points to NULL. 00068 /// 00069 /// \return 00070 /// Returns a FdoPtr 00071 /// 00072 FdoPtr() throw() 00073 { 00074 p = NULL; 00075 } 00076 00077 /// \brief 00078 /// Constructs a FdoPtr that initially points to NULL. 00079 /// 00080 /// \param nNull 00081 /// Input always 0 00082 /// 00083 /// \return 00084 /// Returns a FdoPtr 00085 /// 00086 #ifdef _WIN32 00087 FdoPtr(FdoInt32 nNull) throw(...) 00088 #else 00089 FdoPtr(FdoInt32 nNull) throw( FdoException *) 00090 #endif 00091 { 00092 if (nNull != 0) 00093 throw FdoException::Create(FdoException::NLSGetMessage(FDO_NLSID(FDO_1_INVALID_INPUT_ON_CLASS_CREATION), 00094 L"FdoPtr", 00095 L"nNull")); 00096 00097 p = NULL; 00098 } 00099 00100 /// \brief 00101 /// Constructs a FdoPtr around the given object. 00102 /// 00103 /// \param lp 00104 /// Input the object to wrap. 00105 /// 00106 /// \return 00107 /// Returns a FdoPtr 00108 /// 00109 /// \note 00110 /// This constructor just attaches the object to this FdoPtr. It does 00111 /// not add a reference on the object. 00112 FdoPtr(T* lp) throw() 00113 { 00114 p = lp; 00115 } 00116 00117 /// \brief 00118 /// FdoPtr copy constructor. Wraps a new FdoPtr around the object 00119 /// referenced by lp. 00120 /// 00121 /// \param lp 00122 /// Input the FdoPtr to copy from. 00123 /// 00124 /// \return 00125 /// Returns a FdoPtr 00126 /// 00127 /// \note 00128 /// This operator adds a reference on the object. 00129 FdoPtr(const FdoPtr<T>& lp) throw() 00130 { 00131 p = lp.p; 00132 if (p != NULL) 00133 p->AddRef(); 00134 } 00135 00136 /// \brief 00137 /// FdoPtr destructor. If this FdoPtr points to an object 00138 /// then the object is released. 00139 /// 00140 ~FdoPtr() throw() 00141 { 00142 if (p) 00143 p->Release(); 00144 } 00145 00146 /// \brief 00147 /// FdoPtr object extractor 00148 /// 00149 /// \return 00150 /// Returns a pointer to the object referenced by this FdoPtr. 00151 /// 00152 operator T*() const throw() 00153 { 00154 return p; 00155 } 00156 00157 /// \brief 00158 /// FdoPtr object extractor 00159 /// 00160 /// \return 00161 /// Returns the object referenced by this FdoPtr. 00162 /// 00163 #ifdef _WIN32 00164 T& operator*() const throw(...) 00165 #else 00166 T& operator*() const throw(FdoException *) 00167 #endif 00168 { 00169 if (p==NULL) 00170 throw FdoException::Create(FdoException::NLSGetMessage(FDO_NLSID(FDO_1_INVALID_INPUT_ON_CLASS_FUNCTION), 00171 L"FdoPtr::operator*", 00172 L"p")); 00173 return *p; 00174 } 00175 00176 /// \brief 00177 /// FdoPtr object extractor 00178 /// 00179 /// \return 00180 /// Returns a double pointer to the object referenced by this FdoPtr. 00181 /// 00182 #ifdef _WIN32 00183 T** operator&() throw(...) 00184 #else 00185 T** operator&() throw(FdoException *) 00186 #endif 00187 { 00188 return &p; 00189 } 00190 00191 #ifdef _WIN32 00192 _NoAddRefReleaseOnFdoPtr<T>* operator->() const throw(...) 00193 #else 00194 _NoAddRefReleaseOnFdoPtr<T>* operator->() const throw(FdoException *) 00195 #endif 00196 { 00197 if (p==NULL) 00198 throw FdoException::Create(FdoException::NLSGetMessage(FDO_NLSID(FDO_1_INVALID_INPUT_ON_CLASS_FUNCTION), 00199 L"FdoPtr::operator->", 00200 L"p")); 00201 return (_NoAddRefReleaseOnFdoPtr<T>*)p; 00202 } 00203 00204 /// \brief 00205 /// Is Null operator 00206 /// 00207 /// \return 00208 /// Returns true if this FdoPtr points to NULL. 00209 /// 00210 bool operator!() const throw() 00211 { 00212 return (p == NULL); 00213 } 00214 00215 /// \brief 00216 /// Less than operator 00217 /// 00218 /// \param pT 00219 /// Input the object to compare 00220 /// 00221 /// \return 00222 /// Returns true if this FdoPtr points to an object whose 00223 /// address is less than the address of the given object. 00224 /// 00225 bool operator<(T* pT) const throw() 00226 { 00227 return p < pT; 00228 } 00229 00230 /// \brief 00231 /// Equals operator 00232 /// 00233 /// \param pT 00234 /// Input the object to compare 00235 /// 00236 /// \return 00237 /// Returns true if this FdoPtr points to the given object. 00238 /// 00239 bool operator==(T* pT) const throw() 00240 { 00241 return p == pT; 00242 } 00243 00244 /// \brief 00245 /// Assignment operator. Wraps the given object in this 00246 /// FdoPtr. 00247 /// 00248 /// \param lp 00249 /// Input the object to assign to this FdoPtr. 00250 /// 00251 /// \return 00252 /// Returns lp 00253 /// 00254 /// \note 00255 /// This operator just attaches the object to this FdoPtr. It does 00256 /// not add a reference on the object. 00257 T* operator=(T* lp) throw() 00258 { 00259 FDO_SAFE_RELEASE(p); 00260 p = lp; 00261 return p; 00262 } 00263 00264 /// \brief 00265 /// Assignment operator for matching smart-pointer types. Assign the given FdoPtr's object to 00266 /// this FdoPtr. 00267 /// 00268 /// \param lp 00269 /// Input the FdoPtr whose object is assigned to this FdoPtr. 00270 /// 00271 /// \return 00272 /// Returns the object. 00273 /// 00274 /// \note 00275 /// This operator adds a reference on the object and releases the object 00276 /// previously referenced by this FdoPtr. 00277 T* operator=(const FdoPtr<T>& lp) throw() 00278 { 00279 return static_cast<T*>(FdoPtrAssign<T>(&p, lp)); 00280 } 00281 00282 00283 /// \brief 00284 /// Assignment operator for unmatched smart-pointer types. Assign the given FdoPtr's object to 00285 /// this FdoPtr. 00286 /// 00287 /// \param lp 00288 /// Input the FdoPtr whose object is assigned to this FdoPtr. 00289 /// 00290 /// \return 00291 /// Returns the object. 00292 /// 00293 /// \note 00294 /// This operator adds a reference on the object and releases the object 00295 /// previously referenced by this FdoPtr. 00296 template<class U> 00297 T* operator=(const FdoPtr<U>& lp) throw() 00298 { 00299 return static_cast<T*>(FdoPtrAssign<T>(&p, lp)); 00300 } 00301 00302 /// \cond DOXYGEN-IGNORE 00303 00304 /// Release the object and set to NULL 00305 void Release() throw() 00306 { 00307 T* pTemp = p; 00308 if (pTemp) 00309 { 00310 p = NULL; 00311 pTemp->Release(); 00312 } 00313 } 00314 /// \endcond 00315 00316 /// \brief 00317 /// Attaches the given object to this FdoPtr. It does 00318 /// not add a reference on the object. However, the object 00319 /// previously referenced by this FdoPtr is released. 00320 /// 00321 /// \param p2 00322 /// Input the object to attach. 00323 /// 00324 void Attach(T* p2) throw() 00325 { 00326 if (p) 00327 p->Release(); 00328 p = p2; 00329 } 00330 00331 /// \brief 00332 /// Detaches this FdoPtr's object from this FdoPtr. It does 00333 /// not release the object. 00334 /// 00335 /// \return 00336 /// Returns the object that was detached. 00337 /// 00338 T* Detach() throw() 00339 { 00340 T* pt = p; 00341 p = NULL; 00342 return pt; 00343 } 00344 00345 /// \brief 00346 /// Copies this FdoPtr's object to a double pointer. A reference 00347 /// is added to the object. 00348 /// 00349 /// \param ppT 00350 /// Input the double pointer. 00351 /// 00352 /// \return 00353 /// Returns true if the object as copied, false if it could 00354 /// not be copied (double pointer is null). 00355 /// 00356 bool CopyTo(T** ppT) throw() 00357 { 00358 if (ppT == NULL) 00359 return false; 00360 *ppT = p; 00361 if (p) 00362 p->AddRef(); 00363 return true; 00364 } 00365 00366 T* p; 00367 }; 00368 #endif 00369 00370
Comments or suggestions? Send us feedback. |