smart_ptr.h
Go to the documentation of this file.
00001 /*
00002  * Copyright 2006-2008 The FLWOR Foundation.
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  * 
00008  * http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 #ifndef ZORBA_SMARTPTR_API_H
00018 #define ZORBA_SMARTPTR_API_H
00019 
00020 #include <zorba/config.h>
00021 
00022 namespace zorba {
00023 
00024 class ZORBA_DLL_PUBLIC SmartObject
00025 {
00026 protected:
00027   mutable unsigned int  theRefCount;
00028 
00029 public:
00030   SmartObject() : theRefCount(0) { }
00031 
00032   SmartObject(const SmartObject&) : theRefCount(0) { }
00033 
00034   virtual ~SmartObject();
00035 
00036   virtual void free();
00037 
00038   long getRefCount() const { return theRefCount; }
00039 
00040   void addReference() const { ++theRefCount; }
00041 
00042   void removeReference () {
00043     if (--theRefCount == 0) 
00044       free();
00045   }
00046 
00047   SmartObject& operator=(const SmartObject&) { return *this; }
00048 }; /* class SmartObject */
00049 
00050 template<class T>
00051 class SmartPtr 
00052 {
00053 protected:
00054   T  *p;
00055 
00056   void init() {
00057     if (p != 0) p->addReference();
00058   }
00059 
00060   template <class otherT> SmartPtr& 
00061   assign (const SmartPtr<otherT>& rhs) {
00062     if (p != rhs.get())
00063     {
00064       if (p) p->removeReference();
00065       p = static_cast<T*>(rhs.get());
00066       init();
00067     }
00068     return *this;
00069   }
00070 
00071 public:
00072   SmartPtr(T* realPtr = 0) : p(realPtr) {
00073     init(); 
00074   }
00075 
00076   SmartPtr(SmartPtr const& rhs) : p(rhs.get()) {
00077     init();
00078   }
00079 
00080   ~SmartPtr() {
00081     if (p)
00082       p->removeReference();
00083     p = 0;
00084   }
00085 
00086   bool isNull () const        { return p == 0; }
00087 
00088   T* get() const             { return p; }
00089 
00090   operator T* ()              { return get(); }
00091   operator const T * () const { return get(); }
00092 
00093   T* operator->() const       { return p; } 
00094   T& operator*() const        { return *p; } 
00095 
00096   bool operator==(SmartPtr const& h) const  { return p == h.p; }
00097   bool operator!=(SmartPtr const& h) const  { return p != h.p; }
00098   bool operator==(T const* pp) const        { return p == pp; } 
00099   bool operator!=(T const* pp) const        { return p != pp; }
00100   bool operator<(const SmartPtr& h) const   { return p < h.p; }
00101 
00102   SmartPtr& operator=(SmartPtr const& rhs) {
00103     return assign (rhs);
00104   }
00105 
00106   template <class otherT> SmartPtr& operator=(SmartPtr<otherT> const& rhs) {
00107     return assign (rhs);
00108   }
00109 
00110 }; // SmartPtr
00111 
00112 } // namespace zorba
00113 #endif /* ZORBA_SMARTPTR_API_H */
00114 /* vim:set et sw=2 ts=2: */
blog comments powered by Disqus