MemoryUtils.hpp

Go to the documentation of this file.
00001 #pragma ident "$Id: MemoryUtils.hpp 2937 2011-10-23 19:23:33Z yanweignss $"
00002 
00008 #ifndef GPSTK_MEMORYUTILS_HPP
00009 #define GPSTK_MEMORYUTILS_HPP
00010 
00011 //============================================================================
00012 //
00013 //  This file is part of GPSTk, the GPS Toolkit.
00014 //
00015 //  The GPSTk is free software; you can redistribute it and/or modify
00016 //  it under the terms of the GNU Lesser General Public License as published
00017 //  by the Free Software Foundation; either version 2.1 of the License, or
00018 //  any later version.
00019 //
00020 //  The GPSTk is distributed in the hope that it will be useful,
00021 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00022 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00023 //  GNU Lesser General Public License for more details.
00024 //
00025 //  You should have received a copy of the GNU Lesser General Public
00026 //  License along with GPSTk; if not, write to the Free Software Foundation,
00027 //  Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00028 //
00029 //  Wei Yan - Chinese Academy of Sciences . 2011
00030 //
00031 //============================================================================
00032 
00033 #include <list>
00034 #include <algorithm>
00035 #include <cassert>
00036 
00037 namespace gpstk
00038 {
00039 
00040       //
00041       // ReleasePolicy classes
00042       //
00043       // Here are two classes for simple type or class and it's array.
00044       // For the complicate one, you should define you customize 'ReleasePolicy' 
00045       // in the similar way.
00046       //
00047 
00049    template <class C>
00050    class ReleasePolicy
00051    {
00052    public:
00053       static void release(C* pObj) { delete pObj; }
00054    };
00055 
00057    template <class C>
00058    class ReleaseArrayPolicy
00059    {
00060    public:
00061       static void release(C* pObj) { delete [] pObj; }
00062    };
00063 
00065    template <class C>
00066    class ReleaseCustomizePolicy
00067    {
00068    public:
00069       static void release(C* pObj) { if(pObj) pObj->release(); }
00070    };
00071 
00072    // End of ReleasePolicy classes
00073 
00075    template < class C, class RP = ReleasePolicy<C> >
00076    class AutoReleasePool
00077    {
00078    public:
00079       AutoReleasePool()
00080       { }
00081 
00082       ~AutoReleasePool()
00083       { release();}
00084 
00085       void add(C* pObject)
00086       { if (pObject) _list.push_back(pObject); }
00087 
00088       void release()
00089       {
00090          while (!_list.empty())
00091          {
00092             RP::release(_list.front());
00093             _list.pop_front();
00094          }
00095       }
00096 
00097    protected:
00098 
00099       std::list<C*> _list;
00100 
00101    };
00102 
00103 
00104    class ReferenceCounter
00105    {
00106    public:
00107       ReferenceCounter(): counter(1)
00108       { }
00109 
00110       void duplicate()
00111       { ++counter; }
00112 
00113       int release()
00114       { return (--counter <= 0) ? 0 : counter; }
00115 
00116       int referenceCount() const
00117       { return counter; }
00118 
00119    private:
00120       long counter;
00121    };
00122 
00148    template <class C, class RP = ReleasePolicy<C>, class RC = ReferenceCounter >
00149    class AutoPtr
00150    {
00151    public:
00152       AutoPtr(): _pCounter(new RC), _ptr(0)
00153       {}
00154 
00155       AutoPtr(C* ptr): _pCounter(new RC), _ptr(ptr)
00156       {}
00157 
00158       template <class Other, class OtherRP> 
00159       AutoPtr(const AutoPtr<Other, RC, OtherRP>& ptr)
00160          : _pCounter(ptr._pCounter), _ptr(const_cast<Other*>(ptr.get()))
00161       { _pCounter->duplicate(); }
00162 
00163       AutoPtr(const AutoPtr& ptr)
00164          : _pCounter(ptr._pCounter), _ptr(ptr._ptr)
00165       { _pCounter->duplicate(); }
00166 
00167       ~AutoPtr()
00168       { release(); }
00169 
00170       AutoPtr& assign(C* ptr)
00171       {
00172          if (get() != ptr)
00173          {
00174             RC* pTmp = new RC;
00175             release();
00176             _pCounter = pTmp;
00177             _ptr = ptr;
00178          }
00179          return *this;
00180       }
00181 
00182       AutoPtr& assign(const AutoPtr& ptr)
00183       {
00184          if (&ptr != this)
00185          {
00186             AutoPtr tmp(ptr);
00187             swap(tmp);
00188          }
00189          return *this;
00190       }
00191 
00192       template <class Other, class OtherRP>
00193       AutoPtr& assign(const AutoPtr<Other, RC, OtherRP>& ptr)
00194       {
00195          if (ptr.get() != _ptr)
00196          {
00197             AutoPtr tmp(ptr);
00198             swap(tmp);
00199          }
00200          return *this;
00201       }
00202 
00203       AutoPtr& operator = (C* ptr)
00204       { return assign(ptr); }
00205 
00206       AutoPtr& operator = (const AutoPtr& ptr)
00207       { return assign(ptr); }
00208 
00209       template <class Other, class OtherRP>
00210       AutoPtr& operator = (const AutoPtr<Other, RC, OtherRP>& ptr)
00211       { return assign<Other>(ptr); }
00212 
00213       void swap(AutoPtr& ptr)
00214       {
00215          std::swap(_ptr, ptr._ptr);
00216          std::swap(_pCounter, ptr._pCounter);
00217       }
00218 
00219       template <class Other> 
00220       AutoPtr<Other, RC, RP> cast() const
00221       {
00222          Other* pOther = dynamic_cast<Other*>(_ptr);
00223          if (pOther)
00224             return AutoPtr<Other, RC, RP>(_pCounter, pOther);
00225          return AutoPtr<Other, RC, RP>();
00226       }
00227 
00228       template <class Other> 
00229       AutoPtr<Other, RC, RP> unsafeCast() const
00230       {
00231          Other* pOther = static_cast<Other*>(_ptr);
00232          return AutoPtr<Other, RC, RP>(_pCounter, pOther);
00233       }
00234 
00235       C* operator -> ()
00236       { return deref(); }
00237 
00238       const C* operator -> () const
00239       { return deref(); }
00240 
00241       C& operator * ()
00242       { return *deref(); }
00243 
00244       const C& operator * () const
00245       { return *deref(); }
00246 
00247       C* get()
00248       { return _ptr; }
00249 
00250       const C* get() const
00251       { return _ptr; }
00252 
00253       operator C* ()
00254       { return _ptr; }
00255 
00256       operator const C* () const
00257       { return _ptr; }
00258 
00259       bool operator ! () const
00260       { return _ptr == 0; }
00261 
00262       bool isNull() const
00263       { return _ptr == 0; }
00264 
00265       bool operator == (const AutoPtr& ptr) const
00266       { return get() == ptr.get(); }
00267 
00268       bool operator == (const C* ptr) const
00269       { return get() == ptr; }
00270 
00271       bool operator == (C* ptr) const
00272       { return get() == ptr; }
00273 
00274       bool operator != (const AutoPtr& ptr) const
00275       { return get() != ptr.get(); }
00276 
00277       bool operator != (const C* ptr) const
00278       { return get() != ptr; }
00279 
00280       bool operator != (C* ptr) const
00281       { return get() != ptr; }
00282 
00283       bool operator < (const AutoPtr& ptr) const
00284       { return get() < ptr.get(); }
00285 
00286       bool operator < (const C* ptr) const
00287       { return get() < ptr; }
00288 
00289       bool operator < (C* ptr) const
00290       { return get() < ptr; }
00291 
00292       bool operator <= (const AutoPtr& ptr) const
00293       { return get() <= ptr.get(); }
00294 
00295       bool operator <= (const C* ptr) const
00296       { return get() <= ptr; }
00297 
00298       bool operator <= (C* ptr) const
00299       { return get() <= ptr; }
00300 
00301       bool operator > (const AutoPtr& ptr) const
00302       { return get() > ptr.get(); }
00303 
00304       bool operator > (const C* ptr) const
00305       { return get() > ptr; }
00306 
00307       bool operator > (C* ptr) const
00308       { return get() > ptr; }
00309 
00310       bool operator >= (const AutoPtr& ptr) const
00311       { return get() >= ptr.get(); }
00312 
00313       bool operator >= (const C* ptr) const
00314       { return get() >= ptr; }
00315 
00316       bool operator >= (C* ptr) const
00317       { return get() >= ptr; }
00318 
00319       int referenceCount() const
00320       { return _pCounter->referenceCount(); }
00321 
00322    private:
00323       C* deref() const
00324       {
00325          if (!_ptr) GPSTK_THROW(NullPointerException("Try access a pointer.")); 
00326 
00327          return _ptr;
00328       }
00329 
00330       void release()
00331       {
00332          int i = _pCounter->release();
00333          if (i == 0)
00334          {
00335             RP::release(_ptr);
00336             _ptr = 0;
00337 
00338             delete _pCounter;
00339             _pCounter = 0;
00340          }
00341       }
00342 
00343       AutoPtr(RC* pCounter, C* ptr): _pCounter(pCounter), _ptr(ptr)
00344       {
00345          _pCounter->duplicate();
00346       }
00347 
00348    private:
00349       RC* _pCounter;
00350       C*  _ptr;
00351 
00352       template <class OtherC, class OtherRC, class OtherRP> friend class AutoPtr;
00353    };
00354 
00355 
00356    template <class C, class RC, class RP>
00357    inline void swap(AutoPtr<C, RC, RP>& p1, AutoPtr<C, RC, RP>& p2)
00358    {
00359       p1.swap(p2);
00360    }
00361 
00362 
00363    template <class T>
00364    class Buffer
00365    {
00366    public:
00367       Buffer(std::size_t size):_size(size),_ptr(new T[size]){}
00368 
00369       ~Buffer(){ if(_ptr) delete [] _ptr;}
00370 
00371       std::size_t size() const {return _size;}
00372 
00373       T* begin() { return _ptr; }
00374 
00375       const T* begin() const{return _ptr;}
00376 
00377       T* end(){return _ptr + _size;}
00378 
00379       const T* end() const { return _ptr + _size;}
00380 
00381       T& operator [] (std::size_t index)
00382       {
00383          if(index<0 || index>=_size)
00384          {
00385             GPSTK_THROW(Exception("The input index is out of range."));
00386          }
00387          
00388          return _ptr[index];
00389       }
00390 
00391       const T& operator [] (std::size_t index) const
00392       {
00393          if(index<0 || index>=_size)
00394          {
00395             GPSTK_THROW(Exception("The input index is out of range."));
00396          }
00397 
00398          return _ptr[index];
00399       }
00400 
00401    private:
00402       Buffer();
00403       Buffer(const Buffer&);
00404       Buffer& operator = (const Buffer&);
00405 
00406       std::size_t _size;
00407       T* _ptr;
00408    }; // End of class 'Buffer'
00409 
00410 
00411 }   // End of namespace gpstk
00412 
00413 
00414 #endif  //GPSTK_MEMORYUTILS_HPP
00415 

Generated on Tue May 22 03:30:59 2012 for GPS ToolKit Software Library by  doxygen 1.3.9.1