"Fossies" - the Fresh Open Source Software Archive

Member "regexxer-0.10/src/sharedptr.h" (6 Oct 2011, 6397 Bytes) of package /linux/privat/old/regexxer-0.10.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "sharedptr.h" see the Fossies "Dox" file reference documentation.

    1 /*
    2  * Copyright (c) 2002-2007  Daniel Elstner  <daniel.kitta@gmail.com>
    3  *
    4  * This file is part of regexxer.
    5  *
    6  * regexxer is free software; you can redistribute it and/or modify
    7  * it under the terms of the GNU General Public License as published by
    8  * the Free Software Foundation; either version 2 of the License, or
    9  * (at your option) any later version.
   10  *
   11  * regexxer is distributed in the hope that it will be useful,
   12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   14  * GNU General Public License for more details.
   15  *
   16  * You should have received a copy of the GNU General Public License
   17  * along with regexxer; if not, write to the Free Software Foundation,
   18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
   19  */
   20 
   21 #ifndef REGEXXER_SHAREDPTR_H_INCLUDED
   22 #define REGEXXER_SHAREDPTR_H_INCLUDED
   23 
   24 #include <algorithm>
   25 
   26 namespace Util
   27 {
   28 
   29 template <class> class SharedPtr;
   30 
   31 /*
   32  * Common base class of objects managed by SharedPtr<>.
   33  */
   34 class SharedObject
   35 {
   36 protected:
   37   inline SharedObject(); // initial reference count is 0
   38   inline ~SharedObject();
   39 
   40 private:
   41   mutable long refcount_;
   42 
   43   // noncopyable
   44   SharedObject(const SharedObject&);
   45   SharedObject& operator=(const SharedObject&);
   46 
   47   template <class> friend class SharedPtr;
   48 };
   49 
   50 /*
   51  * Intrusive smart pointer implementation.  It requires the managed types
   52  * to be derived from class SharedObject, in order to do reference counting
   53  * as efficient as possible.
   54  *
   55  * The intrusive approach also simplifies the implementation, particularly
   56  * with regards to exception safety.  A non-intrusive smart pointer like
   57  * boost::shared_ptr<> would have to allocate memory to hold the reference
   58  * count -- this is tricky not only because of the 'new' which could throw,
   59  * but it also complicates the implementation of the cast templates like
   60  * shared_dynamic_cast<> etc.
   61  *
   62  * The cast template functions use the same syntax as in boost:
   63  *
   64  *     shared_static_cast<T>        returns static_cast<T*>(pointer)
   65  *     shared_dynamic_cast<T>       returns dynamic_cast<T*>(pointer)
   66  *     shared_polymorphic_cast<T>   returns &dynamic_cast<T&>(*pointer)
   67  *
   68  * I didn't implement shared_polymorphic_downcast<T> because it seems to be
   69  * just a debug check for those who don't want to ship with debugging enabled.
   70  * This would be silly IMHO, considering that the dynamic_cast<> overhead is
   71  * negligible in a GUI application like regexxer.
   72  *
   73  * About operator const void*() const:
   74  *
   75  * This operator fulfills the same task operator bool() would, but safer.
   76  * A SharedPtr<> will never be implicitely converted to an integer type,
   77  * which is particularly important in the context of overload resolution.
   78  * An additional advantage is that operator const void*() gets us equality
   79  * and non-equality tests for free.
   80  *
   81  * Note that boost is using an operator that converts to a PMF (pointer to
   82  * member function) for this purpose.  However, I consider this solution
   83  * to be somewhat over the top.
   84  */
   85 template <class T>
   86 class SharedPtr
   87 {
   88 public:
   89   inline SharedPtr();
   90   inline ~SharedPtr();
   91 
   92   explicit inline SharedPtr(T* ptr); // obtains reference
   93 
   94   inline SharedPtr(const SharedPtr<T>& other);
   95   inline SharedPtr<T>& operator=(const SharedPtr<T>& other);
   96 
   97   template <class U> inline SharedPtr(const SharedPtr<U>& other);
   98   template <class U> inline SharedPtr<T>& operator=(const SharedPtr<U>& other);
   99 
  100   inline void swap(SharedPtr<T>& other);
  101 
  102   inline void reset(T* ptr = 0); // obtains reference
  103   inline T*   get() const;
  104 
  105   inline T* operator->() const;
  106   inline T& operator*()  const;
  107 
  108   inline operator const void*() const;
  109 
  110 private:
  111   T* ptr_;
  112 };
  113 
  114 /*
  115  * Explicitely forbid the usage of a generic SharedPtr<SharedObject>
  116  * because class SharedObject doesn't have a virtual destructor.
  117  */
  118 template <> class SharedPtr<SharedObject> {};
  119 template <> class SharedPtr<const SharedObject> {};
  120 
  121 inline
  122 SharedObject::SharedObject()
  123 :
  124   refcount_ (0)
  125 {}
  126 
  127 inline
  128 SharedObject::~SharedObject()
  129 {}
  130 
  131 template <class T> inline
  132 SharedPtr<T>::SharedPtr()
  133 :
  134   ptr_ (0)
  135 {}
  136 
  137 template <class T> inline
  138 SharedPtr<T>::~SharedPtr()
  139 {
  140   if (ptr_ && --ptr_->refcount_ <= 0)
  141     delete ptr_;
  142 }
  143 
  144 template <class T> inline
  145 SharedPtr<T>::SharedPtr(T* ptr)
  146 :
  147   ptr_ (ptr)
  148 {
  149   if (ptr_)
  150     ++ptr_->refcount_;
  151 }
  152 
  153 /*
  154  * Note that reset() and get() are defined here and not in declaration order
  155  * on purpose -- defining them before their first use is required with some
  156  * compilers for for maximum inlining.
  157  */
  158 template <class T> inline
  159 void SharedPtr<T>::swap(SharedPtr<T>& other)
  160 {
  161   std::swap(ptr_, other.ptr_);
  162 }
  163 
  164 template <class T> inline
  165 void SharedPtr<T>::reset(T* ptr)
  166 {
  167   // Note that SharedPtr<>::reset() obtains a reference.
  168   SharedPtr<T> temp (ptr);
  169   std::swap(ptr_, temp.ptr_);
  170 }
  171 
  172 template <class T> inline
  173 T* SharedPtr<T>::get() const
  174 {
  175   return ptr_;
  176 }
  177 
  178 template <class T> inline
  179 SharedPtr<T>::SharedPtr(const SharedPtr<T>& other)
  180 :
  181   ptr_ (other.ptr_)
  182 {
  183   if (ptr_)
  184     ++ptr_->refcount_;
  185 }
  186 
  187 template <class T> inline
  188 SharedPtr<T>& SharedPtr<T>::operator=(const SharedPtr<T>& other)
  189 {
  190   this->reset(other.ptr_);
  191   return *this;
  192 }
  193 
  194 template <class T>
  195   template <class U>
  196 inline
  197 SharedPtr<T>::SharedPtr(const SharedPtr<U>& other)
  198 :
  199   ptr_ (other.get())
  200 {
  201   if (ptr_)
  202     ++ptr_->refcount_;
  203 }
  204 
  205 template <class T>
  206   template <class U>
  207 inline
  208 SharedPtr<T>& SharedPtr<T>::operator=(const SharedPtr<U>& other)
  209 {
  210   this->reset(other.get());
  211   return *this;
  212 }
  213 
  214 template <class T> inline
  215 T* SharedPtr<T>::operator->() const
  216 {
  217   return ptr_;
  218 }
  219 
  220 template <class T> inline
  221 T& SharedPtr<T>::operator*() const
  222 {
  223   return *ptr_;
  224 }
  225 
  226 template <class T> inline
  227 SharedPtr<T>::operator const void*() const
  228 {
  229   return ptr_;
  230 }
  231 
  232 template <class T> inline
  233 void swap(SharedPtr<T>& a, SharedPtr<T>& b)
  234 {
  235   a.swap(b);
  236 }
  237 
  238 template <class T, class U> inline
  239 SharedPtr<T> shared_static_cast(const SharedPtr<U>& other)
  240 {
  241   return SharedPtr<T>(static_cast<T*>(other.get()));
  242 }
  243 
  244 template <class T, class U> inline
  245 SharedPtr<T> shared_dynamic_cast(const SharedPtr<U>& other)
  246 {
  247   return SharedPtr<T>(dynamic_cast<T*>(other.get()));
  248 }
  249 
  250 template <class T, class U> inline
  251 SharedPtr<T> shared_polymorphic_cast(const SharedPtr<U>& other)
  252 {
  253   return SharedPtr<T>(&dynamic_cast<T&>(*other)); // may throw std::bad_cast
  254 }
  255 
  256 } // namespace Util
  257 
  258 #endif /* REGEXXER_SHAREDPTR_H_INCLUDED */