SharedPtr.h
Go to the documentation of this file.
00001 //
00002 // SharedPtr.h
00003 //
00004 // $Id: //poco/1.3/Foundation/include/Poco/SharedPtr.h#7 $
00005 //
00006 // Library: Foundation
00007 // Package: Core
00008 // Module:  SharedPtr
00009 //
00010 // Definition of the SharedPtr template class.
00011 //
00012 // Copyright (c) 2005-2008, Applied Informatics Software Engineering GmbH.
00013 // and Contributors.
00014 //
00015 // Permission is hereby granted, free of charge, to any person or organization
00016 // obtaining a copy of the software and accompanying documentation covered by
00017 // this license (the "Software") to use, reproduce, display, distribute,
00018 // execute, and transmit the Software, and to prepare derivative works of the
00019 // Software, and to permit third-parties to whom the Software is furnished to
00020 // do so, all subject to the following:
00021 // 
00022 // The copyright notices in the Software and this entire statement, including
00023 // the above license grant, this restriction and the following disclaimer,
00024 // must be included in all copies of the Software, in whole or in part, and
00025 // all derivative works of the Software, unless such copies or derivative
00026 // works are solely in the form of machine-executable object code generated by
00027 // a source language processor.
00028 // 
00029 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00030 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00031 // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
00032 // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
00033 // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
00034 // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
00035 // DEALINGS IN THE SOFTWARE.
00036 //
00037 
00038 
00039 #ifndef Foundation_SharedPtr_INCLUDED
00040 #define Foundation_SharedPtr_INCLUDED
00041 
00042 
00043 #include "Poco/Foundation.h"
00044 #include "Poco/Exception.h"
00045 #include "Poco/AtomicCounter.h"
00046 #include <algorithm>
00047 
00048 
00049 namespace Poco {
00050 
00051 
00052 class ReferenceCounter
00054 {
00055 public:
00056         ReferenceCounter(): _cnt(1)
00057         {
00058         }
00059 
00060         void duplicate()
00061         {
00062                 ++_cnt;
00063         }
00064 
00065         int release()
00066         {
00067                 return --_cnt;
00068         }
00069         
00070         int referenceCount() const
00071         {
00072                 return _cnt.value();
00073         }
00074 
00075 private:
00076         AtomicCounter _cnt;
00077 };
00078 
00079 
00080 template <class C>
00081 class ReleasePolicy
00084 {
00085 public:
00086         static void release(C* pObj)
00089         {
00090                 delete pObj;
00091         }
00092 };
00093 
00094 
00095 template <class C, class RC = ReferenceCounter, class RP = ReleasePolicy<C> >
00096 class SharedPtr
00122 {
00123 public:
00124         SharedPtr(): _pCounter(new RC), _ptr(0)
00125         {
00126         }
00127 
00128         SharedPtr(C* ptr): _pCounter(new RC), _ptr(ptr)
00129         {
00130         }
00131 
00132         template <class Other, class OtherRP> 
00133         SharedPtr(const SharedPtr<Other, RC, OtherRP>& ptr): _pCounter(ptr._pCounter), _ptr(const_cast<Other*>(ptr.get()))
00134         {
00135                 _pCounter->duplicate();
00136         }
00137 
00138         SharedPtr(const SharedPtr& ptr): _pCounter(ptr._pCounter), _ptr(ptr._ptr)
00139         {
00140                 _pCounter->duplicate();
00141         }
00142 
00143         ~SharedPtr()
00144         {
00145                 release();
00146         }
00147 
00148         SharedPtr& assign(C* ptr)
00149         {
00150                 if (get() != ptr)
00151                 {
00152                         RC* pTmp = new RC;
00153                         release();
00154                         _pCounter = pTmp;
00155                         _ptr = ptr;
00156                 }
00157                 return *this;
00158         }
00159         
00160         SharedPtr& assign(const SharedPtr& ptr)
00161         {
00162                 if (&ptr != this)
00163                 {
00164                         SharedPtr tmp(ptr);
00165                         swap(tmp);
00166                 }
00167                 return *this;
00168         }
00169         
00170         template <class Other, class OtherRP>
00171         SharedPtr& assign(const SharedPtr<Other, RC, OtherRP>& ptr)
00172         {
00173                 if (ptr.get() != _ptr)
00174                 {
00175                         SharedPtr tmp(ptr);
00176                         swap(tmp);
00177                 }
00178                 return *this;
00179         }
00180 
00181         SharedPtr& operator = (C* ptr)
00182         {
00183                 return assign(ptr);
00184         }
00185 
00186         SharedPtr& operator = (const SharedPtr& ptr)
00187         {
00188                 return assign(ptr);
00189         }
00190 
00191         template <class Other, class OtherRP>
00192         SharedPtr& operator = (const SharedPtr<Other, RC, OtherRP>& ptr)
00193         {
00194                 return assign<Other>(ptr);
00195         }
00196 
00197         void swap(SharedPtr& ptr)
00198         {
00199                 std::swap(_ptr, ptr._ptr);
00200                 std::swap(_pCounter, ptr._pCounter);
00201         }
00202 
00203         template <class Other> 
00204         SharedPtr<Other, RC, RP> cast() const
00211         {
00212                 Other* pOther = dynamic_cast<Other*>(_ptr);
00213                 if (pOther)
00214                         return SharedPtr<Other, RC, RP>(_pCounter, pOther);
00215                 return SharedPtr<Other, RC, RP>();
00216         }
00217 
00218         template <class Other> 
00219         SharedPtr<Other, RC, RP> unsafeCast() const
00225         {
00226                 Other* pOther = static_cast<Other*>(_ptr);
00227                 return SharedPtr<Other, RC, RP>(_pCounter, pOther);
00228         }
00229 
00230         C* operator -> ()
00231         {
00232                 return deref();
00233         }
00234 
00235         const C* operator -> () const
00236         {
00237                 return deref();
00238         }
00239 
00240         C& operator * ()
00241         {
00242                 return *deref();
00243         }
00244 
00245         const C& operator * () const
00246         {
00247                 return *deref();
00248         }
00249 
00250         C* get()
00251         {
00252                 return _ptr;
00253         }
00254 
00255         const C* get() const
00256         {
00257                 return _ptr;
00258         }
00259 
00260         operator C* ()
00261         {
00262                 return _ptr;
00263         }
00264         
00265         operator const C* () const
00266         {
00267                 return _ptr;
00268         }
00269 
00270         bool operator ! () const
00271         {
00272                 return _ptr == 0;
00273         }
00274 
00275         bool isNull() const
00276         {
00277                 return _ptr == 0;
00278         }
00279 
00280         bool operator == (const SharedPtr& ptr) const
00281         {
00282                 return get() == ptr.get();
00283         }
00284 
00285         bool operator == (const C* ptr) const
00286         {
00287                 return get() == ptr;
00288         }
00289 
00290         bool operator == (C* ptr) const
00291         {
00292                 return get() == ptr;
00293         }
00294 
00295         bool operator != (const SharedPtr& ptr) const
00296         {
00297                 return get() != ptr.get();
00298         }
00299 
00300         bool operator != (const C* ptr) const
00301         {
00302                 return get() != ptr;
00303         }
00304 
00305         bool operator != (C* ptr) const
00306         {
00307                 return get() != ptr;
00308         }
00309 
00310         bool operator < (const SharedPtr& ptr) const
00311         {
00312                 return get() < ptr.get();
00313         }
00314 
00315         bool operator < (const C* ptr) const
00316         {
00317                 return get() < ptr;
00318         }
00319 
00320         bool operator < (C* ptr) const
00321         {
00322                 return get() < ptr;
00323         }
00324 
00325         bool operator <= (const SharedPtr& ptr) const
00326         {
00327                 return get() <= ptr.get();
00328         }
00329 
00330         bool operator <= (const C* ptr) const
00331         {
00332                 return get() <= ptr;
00333         }
00334 
00335         bool operator <= (C* ptr) const
00336         {
00337                 return get() <= ptr;
00338         }
00339 
00340         bool operator > (const SharedPtr& ptr) const
00341         {
00342                 return get() > ptr.get();
00343         }
00344 
00345         bool operator > (const C* ptr) const
00346         {
00347                 return get() > ptr;
00348         }
00349 
00350         bool operator > (C* ptr) const
00351         {
00352                 return get() > ptr;
00353         }
00354 
00355         bool operator >= (const SharedPtr& ptr) const
00356         {
00357                 return get() >= ptr.get();
00358         }
00359 
00360         bool operator >= (const C* ptr) const
00361         {
00362                 return get() >= ptr;
00363         }
00364 
00365         bool operator >= (C* ptr) const
00366         {
00367                 return get() >= ptr;
00368         }
00369         
00370         int referenceCount() const
00371         {
00372                 return _pCounter->referenceCount();
00373         }
00374 
00375 private:
00376         C* deref() const
00377         {
00378                 if (!_ptr)
00379                         throw NullPointerException();
00380 
00381                 return _ptr;
00382         }
00383 
00384         void release()
00385         {
00386                 poco_assert_dbg (_pCounter);
00387                 int i = _pCounter->release();
00388                 if (i == 0)
00389                 {
00390                         RP::release(_ptr);
00391                         _ptr = 0;
00392 
00393                         delete _pCounter;
00394                         _pCounter = 0;
00395                 }
00396         }
00397 
00398         SharedPtr(RC* pCounter, C* ptr): _pCounter(pCounter), _ptr(ptr)
00400         {
00401                 poco_assert_dbg (_pCounter);
00402                 _pCounter->duplicate();
00403         }
00404 
00405 private:
00406         RC* _pCounter;
00407         C*  _ptr;
00408 
00409         template <class OtherC, class OtherRC, class OtherRP> friend class SharedPtr;
00410 };
00411 
00412 
00413 template <class C, class RC, class RP>
00414 inline void swap(SharedPtr<C, RC, RP>& p1, SharedPtr<C, RC, RP>& p2)
00415 {
00416         p1.swap(p2);
00417 }
00418 
00419 
00420 } // namespace Poco
00421 
00422 
00423 #endif // Foundation_SharedPtr_INCLUDED


pluginlib
Author(s): Tully Foote and Eitan Marder-Eppstein
autogenerated on Sat Dec 28 2013 17:20:19