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 void AddRef() = 0; 00034 virtual void 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 lp 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 lp 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 /// Release the object and set to NULL 00304 void Release() throw() 00305 { 00306 T* pTemp = p; 00307 if (pTemp) 00308 { 00309 p = NULL; 00310 pTemp->Release(); 00311 } 00312 } 00313 /// \endcond 00314 00315 /// \brief 00316 /// Attaches the given object to this FdoPtr. It does 00317 /// not add a reference on the object. However, the object 00318 /// previously referenced by this FdoPtr is released. 00319 /// 00320 /// \param p2 00321 /// Input the object to attach. 00322 /// 00323 void Attach(T* p2) throw() 00324 { 00325 if (p) 00326 p->Release(); 00327 p = p2; 00328 } 00329 00330 /// \brief 00331 /// Detaches this FdoPtr's object from this FdoPtr. It does 00332 /// not release the object. 00333 /// 00334 /// \return 00335 /// Returns the object that was detached. 00336 /// 00337 T* Detach() throw() 00338 { 00339 T* pt = p; 00340 p = NULL; 00341 return pt; 00342 } 00343 00344 /// \brief 00345 /// Copies this FdoPtr's object to a double pointer. A reference 00346 /// is added to the object. 00347 /// 00348 /// \param ppT 00349 /// Input the double pointer. 00350 /// 00351 /// \return 00352 /// Returns true if the object as copied, false if it could 00353 /// not be copied (double pointer is null). 00354 /// 00355 bool CopyTo(T** ppT) throw() 00356 { 00357 if (ppT == NULL) 00358 return false; 00359 *ppT = p; 00360 if (p) 00361 p->AddRef(); 00362 return true; 00363 } 00364 00365 T* p; 00366 }; 00367 #endif 00368 00369
Comments or suggestions? Send us feedback. |