FDO API Reference Feature Data Objects

Ptr.h

Go to the documentation of this file.
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.