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_2_BADPARAMETER))); 00094 p = NULL; 00095 } 00096 00097 /// \brief 00098 /// Constructs a FdoPtr around the given object. 00099 /// 00100 /// \param lp 00101 /// Input the object to wrap. 00102 /// 00103 /// \return 00104 /// Returns a FdoPtr 00105 /// 00106 /// \note 00107 /// This constructor just attaches the object to this FdoPtr. It does 00108 /// not add a reference on the object. 00109 FdoPtr(T* lp) throw() 00110 { 00111 p = lp; 00112 } 00113 00114 /// \brief 00115 /// FdoPtr copy constructor. Wraps a new FdoPtr around the object 00116 /// referenced by lp. 00117 /// 00118 /// \param lp 00119 /// Input the FdoPtr to copy from. 00120 /// 00121 /// \return 00122 /// Returns a FdoPtr 00123 /// 00124 /// \note 00125 /// This operator adds a reference on the object. 00126 FdoPtr(const FdoPtr<T>& lp) throw() 00127 { 00128 p = lp.p; 00129 if (p != NULL) 00130 p->AddRef(); 00131 } 00132 00133 /// \brief 00134 /// FdoPtr destructor. If this FdoPtr points to an object 00135 /// then the object is released. 00136 /// 00137 ~FdoPtr() throw() 00138 { 00139 if (p) 00140 p->Release(); 00141 } 00142 00143 /// \brief 00144 /// FdoPtr object extractor 00145 /// 00146 /// \return 00147 /// Returns a pointer to the object referenced by this FdoPtr. 00148 /// 00149 operator T*() const throw() 00150 { 00151 return p; 00152 } 00153 00154 /// \brief 00155 /// FdoPtr object extractor 00156 /// 00157 /// \return 00158 /// Returns the object referenced by this FdoPtr. 00159 /// 00160 #ifdef _WIN32 00161 T& operator*() const throw(...) 00162 #else 00163 T& operator*() const throw(FdoException) 00164 #endif 00165 { 00166 if (p==NULL) 00167 throw FdoException::Create(FdoException::NLSGetMessage(FDO_NLSID(FDO_2_BADPARAMETER))); 00168 return *p; 00169 } 00170 00171 /// \brief 00172 /// FdoPtr object extractor 00173 /// 00174 /// \return 00175 /// Returns a double pointer to the object referenced by this FdoPtr. 00176 /// 00177 #ifdef _WIN32 00178 T** operator&() throw(...) 00179 #else 00180 T** operator&() throw(FdoException) 00181 #endif 00182 { 00183 return &p; 00184 } 00185 00186 #ifdef _WIN32 00187 _NoAddRefReleaseOnFdoPtr<T>* operator->() const throw(...) 00188 #else 00189 _NoAddRefReleaseOnFdoPtr<T>* operator->() const throw(FdoException) 00190 #endif 00191 { 00192 if (p==NULL) 00193 throw FdoException::Create(FdoException::NLSGetMessage(FDO_NLSID(FDO_2_BADPARAMETER))); 00194 return (_NoAddRefReleaseOnFdoPtr<T>*)p; 00195 } 00196 00197 /// \brief 00198 /// Is Null operator 00199 /// 00200 /// \return 00201 /// Returns true if this FdoPtr points to NULL. 00202 /// 00203 bool operator!() const throw() 00204 { 00205 return (p == NULL); 00206 } 00207 00208 /// \brief 00209 /// Less than operator 00210 /// 00211 /// \param lp 00212 /// Input the object to compare 00213 /// 00214 /// \return 00215 /// Returns true if this FdoPtr points to an object whose 00216 /// address is less than the address of the given object. 00217 /// 00218 bool operator<(T* pT) const throw() 00219 { 00220 return p < pT; 00221 } 00222 00223 /// \brief 00224 /// Equals operator 00225 /// 00226 /// \param lp 00227 /// Input the object to compare 00228 /// 00229 /// \return 00230 /// Returns true if this FdoPtr points to the given object. 00231 /// 00232 bool operator==(T* pT) const throw() 00233 { 00234 return p == pT; 00235 } 00236 00237 /// \brief 00238 /// Assignment operator. Wraps the given object in this 00239 /// FdoPtr. 00240 /// 00241 /// \param lp 00242 /// Input the object to assign to this FdoPtr. 00243 /// 00244 /// \return 00245 /// Returns lp 00246 /// 00247 /// \note 00248 /// This operator just attaches the object to this FdoPtr. It does 00249 /// not add a reference on the object. 00250 T* operator=(T* lp) throw() 00251 { 00252 FDO_SAFE_RELEASE(p); 00253 p = lp; 00254 return p; 00255 } 00256 00257 /// \brief 00258 /// Assignment operator for matching smart-pointer types. Assign the given FdoPtr's object to 00259 /// this FdoPtr. 00260 /// 00261 /// \param lp 00262 /// Input the FdoPtr whose object is assigned to this FdoPtr. 00263 /// 00264 /// \return 00265 /// Returns the object. 00266 /// 00267 /// \note 00268 /// This operator adds a reference on the object and releases the object 00269 /// previously referenced by this FdoPtr. 00270 T* operator=(const FdoPtr<T>& lp) throw() 00271 { 00272 return static_cast<T*>(FdoPtrAssign<T>(&p, lp)); 00273 } 00274 00275 00276 /// \brief 00277 /// Assignment operator for unmatched smart-pointer types. Assign the given FdoPtr's object to 00278 /// this FdoPtr. 00279 /// 00280 /// \param lp 00281 /// Input the FdoPtr whose object is assigned to this FdoPtr. 00282 /// 00283 /// \return 00284 /// Returns the object. 00285 /// 00286 /// \note 00287 /// This operator adds a reference on the object and releases the object 00288 /// previously referenced by this FdoPtr. 00289 template<class U> 00290 T* operator=(const FdoPtr<U>& lp) throw() 00291 { 00292 return static_cast<T*>(FdoPtrAssign<T>(&p, lp)); 00293 } 00294 00295 /// \cond DOXYGEN-IGNORE 00296 /// Release the object and set to NULL 00297 void Release() throw() 00298 { 00299 T* pTemp = p; 00300 if (pTemp) 00301 { 00302 p = NULL; 00303 pTemp->Release(); 00304 } 00305 } 00306 /// \endcond 00307 00308 /// \brief 00309 /// Attaches the given object to this FdoPtr. It does 00310 /// not add a reference on the object. However, the object 00311 /// previously referenced by this FdoPtr is released. 00312 /// 00313 /// \param p2 00314 /// Input the object to attach. 00315 /// 00316 void Attach(T* p2) throw() 00317 { 00318 if (p) 00319 p->Release(); 00320 p = p2; 00321 } 00322 00323 /// \brief 00324 /// Detaches this FdoPtr's object from this FdoPtr. It does 00325 /// not release the object. 00326 /// 00327 /// \return 00328 /// Returns the object that was detached. 00329 /// 00330 T* Detach() throw() 00331 { 00332 T* pt = p; 00333 p = NULL; 00334 return pt; 00335 } 00336 00337 /// \brief 00338 /// Copies this FdoPtr's object to a double pointer. A reference 00339 /// is added to the object. 00340 /// 00341 /// \param ppT 00342 /// Input the double pointer. 00343 /// 00344 /// \return 00345 /// Returns true if the object as copied, false if it could 00346 /// not be copied (double pointer is null). 00347 /// 00348 bool CopyTo(T** ppT) throw() 00349 { 00350 if (ppT == NULL) 00351 return false; 00352 *ppT = p; 00353 if (p) 00354 p->AddRef(); 00355 return true; 00356 } 00357 00358 T* p; 00359 }; 00360 #endif 00361 00362
Comments or suggestions? Send us feedback. |