- Main Page
- Related Pages
- Modules
- Classes
- Files

# 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

Please send us your comment about this page