unique_ptr.h

Go to the documentation of this file.
00001 #ifndef UNIQUE_PTR_H_18C6F30C
00002 #define UNIQUE_PTR_H_18C6F30C
00003 
00004 #if !defined (ACE_LACKS_PRAGMA_ONCE)
00005 # pragma once
00006 #endif /* ACE_LACKS_PRAGMA_ONCE */
00007 
00008 
00009 #include "dds/Versioned_Namespace.h"
00010 
00011 #include "ace/config-lite.h"
00012 
00013 #ifdef ACE_HAS_CPP11
00014 #define HAS_STD_UNIQUE_PTR
00015 #endif
00016 
00017 #ifdef HAS_STD_UNIQUE_PTR
00018 #include <memory>
00019 #else
00020 #include "ace/Atomic_Op.h"
00021 #include "ace/Synch_Traits.h"
00022 #include <cassert>
00023 #  ifdef ACE_HAS_CPP11
00024 #    include <utility>
00025 #  else
00026 #    include <algorithm>
00027 #  endif
00028 #endif
00029 
00030 OPENDDS_BEGIN_VERSIONED_NAMESPACE_DECL
00031 
00032 namespace OpenDDS {
00033 namespace DCPS {
00034 
00035 #ifdef HAS_STD_UNIQUE_PTR
00036 
00037 using std::move;
00038 using std::unique_ptr;
00039 
00040 template <typename T>
00041 using container_supported_unique_ptr = std::unique_ptr<T>;
00042 
00043 template <typename T>
00044 struct EnableContainerSupportedUniquePtr {};
00045 
00046 #else //HAS_STD_UNIQUE_PTR
00047 
00048 template <typename T>
00049 class rv : public T {
00050   rv();
00051   ~rv();
00052   rv(const rv &);
00053   void operator=(const rv&);
00054 };
00055 
00056 template <typename T>
00057 struct default_deleter
00058 {
00059   void operator()(T* ptr) const
00060   {
00061     delete ptr;
00062   }
00063 };
00064 
00065 template <typename T, typename Deleter = default_deleter<T> >
00066 class unique_ptr {
00067 public:
00068   typedef T element_type;
00069   typedef Deleter deleter_type;
00070 
00071   explicit unique_ptr(T* p = 0) // never throws
00072     : ptr_(p)
00073   {}
00074 
00075 #ifndef __SUNPRO_CC
00076   typedef rv<unique_ptr>& rv_reference;
00077 #else
00078   typedef unique_ptr& rv_reference;
00079 #endif
00080 
00081   unique_ptr(rv_reference other)
00082     : ptr_(other.release())
00083   {}
00084 
00085   ~unique_ptr() // never throws
00086   {
00087     Deleter()(ptr_);
00088   }
00089 
00090   unique_ptr& operator=(rv<unique_ptr>& other)
00091   {
00092     reset(other.release());
00093     return *this;
00094   }
00095 
00096   void reset(T* p = 0) // never throws
00097   {
00098     Deleter()(ptr_);
00099     ptr_ = p;
00100   }
00101 
00102   T* release()
00103   {
00104     T* p = ptr_;
00105     ptr_ = 0;
00106     return p;
00107   }
00108 
00109   T& operator*() const // never throws
00110   {
00111     return *get();
00112   }
00113 
00114   T* operator->() const // never throws
00115   {
00116     return get();
00117   }
00118 
00119   T* get() const // never throws
00120   {
00121     return ptr_;
00122   }
00123 
00124   operator bool() const // never throws
00125   {
00126     return get() != 0;
00127   }
00128 
00129   void swap(unique_ptr& b) // never throws
00130   {
00131     std::swap(ptr_, b.ptr_);
00132   }
00133 
00134 private:
00135   unique_ptr(const unique_ptr&);
00136   unique_ptr& operator=(const unique_ptr&);
00137 
00138   T* ptr_;
00139 };
00140 
00141 template <typename T>
00142 typename T::rv_reference move(T& p)
00143 {
00144   return static_cast<typename T::rv_reference>(p);
00145 }
00146 
00147 
00148 template <typename T, typename Deleter>
00149 void swap(unique_ptr<T, Deleter>& a, unique_ptr<T, Deleter>& b) // never throws
00150 {
00151   return a.swap(b);
00152 }
00153 
00154 template <typename T>
00155 class container_supported_unique_ptr
00156 {
00157 public:
00158 
00159   container_supported_unique_ptr()
00160     : ptr_(0)
00161   {}
00162 
00163   explicit container_supported_unique_ptr(T* p)
00164     : ptr_(p)
00165   {
00166   }
00167 
00168   template <typename U>
00169   container_supported_unique_ptr(unique_ptr<U> p)
00170     : ptr_(p.release())
00171   {
00172   }
00173 
00174   template <typename U>
00175   container_supported_unique_ptr(const container_supported_unique_ptr<U>& other)
00176     : ptr_(other.get())
00177   {
00178     this->bump_up();
00179   }
00180 
00181   container_supported_unique_ptr(const container_supported_unique_ptr& b)
00182     : ptr_(b.ptr_)
00183   {
00184     this->bump_up();
00185   }
00186 
00187   ~container_supported_unique_ptr()
00188   {
00189     this->bump_down();
00190   }
00191 
00192   template <typename U>
00193   void reset(U* p)
00194   {
00195     container_supported_unique_ptr tmp(p);
00196     swap(tmp);
00197   }
00198 
00199   void reset(T* p=0)
00200   {
00201     container_supported_unique_ptr tmp(p);
00202     swap(tmp);
00203   }
00204 
00205   container_supported_unique_ptr& operator=(const container_supported_unique_ptr& b)
00206   {
00207     container_supported_unique_ptr tmp(b);
00208     swap(tmp);
00209     return *this;
00210   }
00211 
00212   template <class U>
00213   container_supported_unique_ptr& operator=(const container_supported_unique_ptr<U>& b)
00214   {
00215     container_supported_unique_ptr<T> tmp(b);
00216     swap(tmp);
00217     return *this;
00218   }
00219 
00220   template <typename U>
00221   container_supported_unique_ptr& operator=(unique_ptr<U> b)
00222   {
00223     container_supported_unique_ptr<T> tmp(b.release());
00224     swap(tmp);
00225     return *this;
00226   }
00227 
00228   void swap(container_supported_unique_ptr& rhs)
00229   {
00230     T* t = this->ptr_;
00231     this->ptr_ = rhs.ptr_;
00232     rhs.ptr_ = t;
00233   }
00234 
00235   T* operator->() const
00236   {
00237     return this->ptr_;
00238   }
00239 
00240   T& operator*() const
00241   {
00242     return *this->ptr_;
00243   }
00244 
00245   T* get() const
00246   {
00247     return this->ptr_;
00248   }
00249 
00250   T* release()
00251   {
00252     T* retval = this->ptr_;
00253     this->ptr_ = 0;
00254     return retval;
00255   }
00256 
00257   operator bool() const
00258   {
00259     return get() != 0;
00260   }
00261 
00262   bool operator==(const container_supported_unique_ptr& rhs) const
00263   {
00264     return get() == rhs.get();
00265   }
00266 
00267   bool operator!=(const container_supported_unique_ptr& rhs) const
00268   {
00269     return get() != rhs.get();
00270   }
00271 
00272   bool operator < (const container_supported_unique_ptr& rhs) const
00273   {
00274     return get() < rhs.get();
00275   }
00276 
00277 private:
00278 
00279   void bump_up()
00280   {
00281     if (this->ptr_ != 0) {
00282       this->ptr_->_add_ref();
00283     }
00284   }
00285 
00286   void bump_down()
00287   {
00288     if (this->ptr_ != 0) {
00289       this->ptr_->_remove_ref();
00290       this->ptr_ = 0;
00291     }
00292   }
00293 
00294   /// The actual "unsmart" pointer to the T object.
00295   T* ptr_;
00296 };
00297 
00298 template <typename T>
00299 void swap(container_supported_unique_ptr<T>& lhs, container_supported_unique_ptr<T>& rhs)
00300 {
00301   lhs.swap(rhs);
00302 }
00303 
00304 template <typename T>
00305 class EnableContainerSupportedUniquePtr {
00306 protected:
00307   EnableContainerSupportedUniquePtr()
00308     : ref_count_(1)
00309   {
00310   }
00311 private:
00312   template <typename U>
00313   friend class container_supported_unique_ptr;
00314 
00315   template <typename U>
00316   friend typename unique_ptr<U>::rv_reference move(container_supported_unique_ptr<U>& ptr);
00317 
00318   void _add_ref() {
00319     ++this->ref_count_;
00320   }
00321 
00322   void _remove_ref(){
00323     const long new_count = --this->ref_count_;
00324 
00325     if (new_count == 0) {
00326       delete static_cast<T*>(this);
00327     }
00328   }
00329   long ref_count() const { return ref_count_.value(); }
00330   ACE_Atomic_Op<ACE_SYNCH_MUTEX, long> ref_count_;
00331 };
00332 
00333 template <typename T>
00334 typename unique_ptr<T>::rv_reference move(container_supported_unique_ptr<T>& ptr)
00335 {
00336 # ifndef OPENDDS_SAFETY_PROFILE
00337   assert(ptr->ref_count() == 1);
00338 # endif
00339   return reinterpret_cast<typename unique_ptr<T>::rv_reference>(ptr);
00340 }
00341 
00342 #endif
00343 } // namespace DCPS
00344 } // namespace OpenDDS
00345 
00346 OPENDDS_END_VERSIONED_NAMESPACE_DECL
00347 #endif /* end of include guard: UNIQUE_PTR_H_18C6F30C */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 10 Aug 2018 for OpenDDS by  doxygen 1.6.1