utils.h

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2008 by Kutumov Alexey                                  *
00003  *   ru.pixel@gmail.com                                                    *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  *                                                                         *
00010  *   This program is distributed in the hope that it will be useful,       *
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00013  *   GNU General Public License for more details.                          *
00014  *                                                                         *
00015  *   You should have received a copy of the GNU General Public License     *
00016  *   along with this program; if not, write to the                         *
00017  *   Free Software Foundation, Inc.,                                       *
00018  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
00019  ***************************************************************************/
00020 
00033 #ifndef __utils__header__
00034 #define __utils__header__
00035 
00036 #include "gpucalc/std_headers.h"
00037 
00038 namespace gpucalc
00039 {
00047  template <int num> struct Int2Type
00048  {
00049   enum
00050   {
00051    number = num
00052   };
00053  };
00054 
00055 
00056  template <class T> class SharedPtr
00057  {
00058   public:
00059 
00063    SharedPtr(): mPointer(0), mUseCount(0)
00064    {
00065    }
00066 
00067 
00071    template <class Y> explicit SharedPtr(Y * Pointer): mPointer(Pointer), mUseCount(new unsigned int(1))
00072    {
00073    }
00074 
00075 
00076    SharedPtr(const SharedPtr & r): mPointer(0), mUseCount(0)
00077    {
00078     mPointer = r.mPointer;
00079     mUseCount = r.mUseCount;
00080     if (mUseCount)
00081     {
00082      ++(*mUseCount);
00083     }
00084    }
00085 
00086 
00087    SharedPtr & operator = (const SharedPtr & r)
00088    {
00089     if (mPointer == r.mPointer)
00090     {
00091      return * this;
00092     }
00093     // Swap current data into a local copy
00094     // this ensures we deal with rhs and this being dependent
00095     SharedPtr<T> tmp(r);
00096     swap(tmp);
00097     return * this;
00098    }
00099 
00100 
00101    template <class Y> SharedPtr(const SharedPtr<Y> & r): mPointer(0), mUseCount(0)
00102    {
00103     mPointer = r.getPointer();
00104     mUseCount = r.useCountPointer();
00105     // Handle zero pointer gracefully to manage STL containers
00106     if (mUseCount)
00107     {
00108      ++(*mUseCount);
00109     }
00110    }
00111 
00112 
00113    template <class Y> SharedPtr & operator = (const SharedPtr<Y> & r)
00114    {
00115     if (mPointer == r.mPointer)
00116     {
00117      return * this;
00118     }
00119     // Swap current data into a local copy
00120     // this ensures we deal with rhs and this being dependent
00121     SharedPtr<T> tmp(r);
00122     swap(tmp);
00123     return * this;
00124    }
00125 
00126 
00127    virtual ~SharedPtr()
00128    {
00129     release();
00130    }
00131 
00132 
00133    inline T & operator * () const
00134    {
00135     assert(mPointer);
00136     return * mPointer;
00137    }
00138 
00139 
00140    inline T * operator -> () const
00141    {
00142     assert(mPointer);
00143     return mPointer;
00144    }
00145 
00146 
00147    inline T * get() const
00148    {
00149     return mPointer;
00150    }
00151 
00152 
00156    void bind(T * Pointer)
00157    {
00158     assert(!mPointer && !mUseCount);
00159     mUseCount = new unsigned int (1);
00160     mPointer = Pointer;
00161    }
00162 
00163 
00164    inline bool unique() const
00165    {
00166     assert(mUseCount);
00167     return * mUseCount == 1;
00168    }
00169 
00170 
00171    inline unsigned int useCount() const
00172    {
00173     assert(mUseCount);
00174     return * mUseCount;
00175    }
00176 
00177 
00178    inline unsigned int * useCountPointer() const
00179    {
00180     return mUseCount;
00181    }
00182 
00183 
00184    inline T * getPointer() const
00185    {
00186     return mPointer;
00187    }
00188 
00189 
00190    inline bool isNull() const
00191    {
00192     return mPointer == 0;
00193    }
00194 
00195 
00196    inline void setNull()
00197    {
00198     if (mPointer)
00199     {
00200      release();
00201      mPointer = 0;
00202      mUseCount = 0;
00203     }
00204    }
00205 
00206 
00207   protected:
00208 
00209    T * mPointer;
00210 
00211    unsigned int * mUseCount;
00212 
00213 
00214    inline void release()
00215    {
00216     bool destroyThis = false;
00217     if (mUseCount)
00218     {
00219      if (--(*mUseCount) == 0)
00220      {
00221       destroyThis = true;
00222      }
00223     }
00224     if (destroyThis)
00225     {
00226      destroy();
00227     }
00228    }
00229 
00230 
00231    virtual void destroy()
00232    {
00233     // IF YOU GET A CRASH HERE, YOU FORGOT TO FREE UP POINTERS
00234     // BEFORE SHUTTING gpucalc DOWN
00235     // Use setNull() before shutdown or make sure your pointer goes
00236     // out of scope before gpucalc shuts down to avoid this.
00237     delete mPointer;
00238     delete mUseCount;
00239    }
00240 
00241 
00242    virtual void swap(SharedPtr<T> & other)
00243    {
00244     std::swap(mPointer, other.mPointer);
00245     std::swap(mUseCount, other.mUseCount);
00246    }
00247  };
00248 
00249 
00250  template <class T, class U> inline bool operator == (SharedPtr<T> const & a, SharedPtr<U> const & b)
00251  {
00252   return a.get() == b.get();
00253  }
00254 
00255 
00256  template <class T, class U> inline bool operator != (SharedPtr<T> const & a, SharedPtr<U> const & b)
00257  {
00258   return a.get() != b.get();
00259  }
00260 
00261 
00262  template <class T, class U> inline bool operator < (SharedPtr<T> const & a, SharedPtr<U> const & b)
00263  {
00264   return std::less<const void *>()(a.get(), b.get());
00265  }
00266 }
00267 
00268 
00269 #endif

Generated on Thu Mar 5 22:36:42 2009 for gpucalc by  doxygen 1.5.6