RcHandle_T.h

Go to the documentation of this file.
00001 /*
00002  * Distributed under the OpenDDS License.
00003  * See: http://www.opendds.org/license.html
00004  */
00005 
00006 #ifndef OPENDDS_RCHANDLE_T_H
00007 #define OPENDDS_RCHANDLE_T_H
00008 
00009 #include "dds/Versioned_Namespace.h"
00010 #include <cassert>
00011 #include "unique_ptr.h"
00012 
00013 OPENDDS_BEGIN_VERSIONED_NAMESPACE_DECL
00014 
00015 namespace OpenDDS {
00016 namespace DCPS {
00017 
00018 struct inc_count {};
00019 struct keep_count {};
00020 
00021 /// Templated Reference counted handle to a pointer.
00022 /// A non-DDS specific helper class.
00023 template <typename T>
00024 class RcHandle {
00025 public:
00026 
00027   RcHandle()
00028     : ptr_(0)
00029   {}
00030 
00031   RcHandle(T* p, keep_count)
00032     : ptr_(p)
00033   {
00034   }
00035 
00036   template <typename U>
00037   RcHandle(unique_ptr<U> p)
00038     : ptr_(p.release())
00039   {
00040   }
00041 
00042 
00043   RcHandle(T* p, inc_count)
00044     : ptr_(p)
00045   {
00046     this->bump_up();
00047   }
00048 
00049   template <typename U>
00050   RcHandle(const RcHandle<U>& other)
00051     : ptr_(other.in())
00052   {
00053     this->bump_up();
00054   }
00055 
00056   RcHandle(const RcHandle& b)
00057     : ptr_(b.ptr_)
00058   {
00059     this->bump_up();
00060   }
00061 
00062   ~RcHandle()
00063   {
00064     this->bump_down();
00065   }
00066 
00067   void reset()
00068   {
00069     RcHandle tmp;
00070     swap(tmp);
00071   }
00072 
00073   template <typename U>
00074   void reset(T* p, U counting_strategy)
00075   {
00076     RcHandle tmp(p, counting_strategy);
00077     swap(tmp);
00078   }
00079 
00080   RcHandle& operator=(const RcHandle& b)
00081   {
00082     RcHandle tmp(b);
00083     swap(tmp);
00084     return *this;
00085   }
00086 
00087   template <class U>
00088   RcHandle& operator=(const RcHandle<U>& b)
00089   {
00090     RcHandle<T> tmp(b);
00091     swap(tmp);
00092     return *this;
00093   }
00094 
00095   template <typename U>
00096   RcHandle& operator=(unique_ptr<U> b)
00097   {
00098     RcHandle<T> tmp(b.release(), keep_count());
00099     swap(tmp);
00100     return *this;
00101   }
00102 
00103   void swap(RcHandle& rhs)
00104   {
00105     T* t = this->ptr_;
00106     this->ptr_ = rhs.ptr_;
00107     rhs.ptr_ = t;
00108   }
00109 
00110   T* operator->() const
00111   {
00112     return this->ptr_;
00113   }
00114 
00115   T& operator*() const
00116   {
00117     return *this->ptr_;
00118   }
00119 
00120   bool is_nil() const
00121   {
00122     return this->ptr_ == 0;
00123   }
00124 
00125   T* in() const
00126   {
00127     return this->ptr_;
00128   }
00129 
00130   T* get() const
00131   {
00132     return this->ptr_;
00133   }
00134 
00135   T*& inout()
00136   {
00137     return this->ptr_;
00138   }
00139 
00140   T*& out()
00141   {
00142     this->bump_down();
00143     return this->ptr_;
00144   }
00145 
00146   T* _retn()
00147   {
00148     T* retval = this->ptr_;
00149     this->ptr_ = 0;
00150     return retval;
00151   }
00152 
00153 
00154   operator bool() const
00155   {
00156     return in() != 0;
00157   }
00158 
00159   bool operator==(const RcHandle& rhs) const
00160   {
00161     return in() == rhs.in();
00162   }
00163 
00164   bool operator!=(const RcHandle& rhs) const
00165   {
00166     return in() != rhs.in();
00167   }
00168 
00169   bool operator < (const RcHandle& rhs) const
00170   {
00171     return in() < rhs.in();
00172   }
00173 
00174 private:
00175 
00176   void bump_up()
00177   {
00178     if (this->ptr_ != 0) {
00179       this->ptr_->_add_ref();
00180     }
00181   }
00182 
00183   void bump_down()
00184   {
00185     if (this->ptr_ != 0) {
00186       this->ptr_->_remove_ref();
00187       this->ptr_ = 0;
00188     }
00189   }
00190 
00191   /// The actual "unsmart" pointer to the T object.
00192   T* ptr_;
00193 };
00194 
00195 
00196 template <typename T>
00197 void swap(RcHandle<T>& lhs, RcHandle<T>& rhs)
00198 {
00199   lhs.swap(rhs);
00200 }
00201 
00202 template <typename T, typename U>
00203 RcHandle<T> static_rchandle_cast(const RcHandle<U>& h)
00204 {
00205   return RcHandle<T>(static_cast<T*>(h.in()), inc_count());
00206 }
00207 
00208 template <typename T, typename U>
00209 RcHandle<T> const_rchandle_cast(const RcHandle<U>& h)
00210 {
00211   return RcHandle<T>(const_cast<T*>(h.in()), inc_count());
00212 }
00213 
00214 template <typename T, typename U>
00215 RcHandle<T> dynamic_rchandle_cast(const RcHandle<U>& h)
00216 {
00217   return RcHandle<T>(dynamic_cast<T*>(h.in()), inc_count());
00218 }
00219 
00220 
00221 template< class T >
00222 class reference_wrapper{
00223 public:
00224   // types
00225   typedef T type;
00226 
00227   // construct/copy/destroy
00228   reference_wrapper(T& ref): _ptr(&ref) {}
00229   // access
00230   operator T& () const { return *_ptr; }
00231   T& get() const { return *_ptr; }
00232 
00233 private:
00234   T* _ptr;
00235 };
00236 
00237 template <typename T>
00238 reference_wrapper<T> ref(T& r)
00239 {
00240   return reference_wrapper<T>(r);
00241 }
00242 
00243 template <typename T>
00244 T const& unwrap_reference(T const& t)
00245 {
00246   return t;
00247 }
00248 
00249 template <typename T>
00250 T& unwrap_reference(reference_wrapper<T> const& t)
00251 {
00252   return t.get();
00253 }
00254 
00255 
00256 template <typename T>
00257 RcHandle<T> make_rch()
00258 {
00259   return RcHandle<T>(new T(), keep_count());
00260 }
00261 
00262 template <typename T, typename U>
00263 RcHandle<T> make_rch(U const& u)
00264 {
00265   return RcHandle<T>(new T(unwrap_reference(u)), keep_count());
00266 }
00267 
00268 template <typename T, typename U0, typename U1>
00269 RcHandle<T> make_rch(U0 const& u0, U1 const& u1)
00270 {
00271   return RcHandle<T>(new T(unwrap_reference(u0), unwrap_reference(u1)), keep_count());
00272 }
00273 
00274 template <typename T, typename U0, typename U1, typename U2>
00275 RcHandle<T> make_rch(U0 const& u0, U1 const& u1, U2 const& u2)
00276 {
00277   return RcHandle<T>(new T(unwrap_reference(u0), unwrap_reference(u1), unwrap_reference(u2)), keep_count());
00278 }
00279 
00280 template <typename T, typename U0, typename U1, typename U2, typename U3>
00281 RcHandle<T> make_rch(U0 const& u0, U1 const& u1, U2 const& u2, U3 const& u3)
00282 {
00283   return RcHandle<T>(new T(unwrap_reference(u0), unwrap_reference(u1), unwrap_reference(u2), unwrap_reference(u3)), keep_count());
00284 }
00285 
00286 template <typename T, typename U0, typename U1, typename U2, typename U3, typename U4>
00287 RcHandle<T> make_rch(U0 const& u0, U1 const& u1, U2 const& u2, U3 const& u3, U4 const& u4)
00288 {
00289   return RcHandle<T>(new T(unwrap_reference(u0), unwrap_reference(u1), unwrap_reference(u2), unwrap_reference(u3), unwrap_reference(u4)), keep_count());
00290 }
00291 
00292 template <typename T, typename U0, typename U1, typename U2, typename U3, typename U4, typename U5>
00293 RcHandle<T> make_rch(U0 const& u0, U1 const& u1, U2 const& u2, U3 const& u3, U4 const& u4, U5 const& u5)
00294 {
00295   return RcHandle<T>(new T(unwrap_reference(u0), unwrap_reference(u1), unwrap_reference(u2), unwrap_reference(u3), unwrap_reference(u4), unwrap_reference(u5)), keep_count());
00296 }
00297 
00298 template <typename T, typename U0, typename U1, typename U2, typename U3, typename U4, typename U5, typename U6>
00299 RcHandle<T> make_rch(U0 const& u0, U1 const& u1, U2 const& u2, U3 const& u3, U4 const& u4, U5 const& u5, U6 const& u6)
00300 {
00301   return RcHandle<T>(new T(unwrap_reference(u0), unwrap_reference(u1), unwrap_reference(u2), unwrap_reference(u3), unwrap_reference(u4), unwrap_reference(u5), unwrap_reference(u6)), keep_count());
00302 }
00303 
00304 template <typename T, typename U0, typename U1, typename U2, typename U3, typename U4, typename U5, typename U6, typename U7>
00305 RcHandle<T> make_rch(U0 const& u0, U1 const& u1, U2 const& u2, U3 const& u3, U4 const& u4, U5 const& u5, U6 const& u6, U7 const& u7)
00306 {
00307   return RcHandle<T>(new T(unwrap_reference(u0), unwrap_reference(u1), unwrap_reference(u2), unwrap_reference(u3), unwrap_reference(u4), unwrap_reference(u5), unwrap_reference(u6), unwrap_reference(u7)), keep_count());
00308 }
00309 
00310 template<typename T>
00311 RcHandle<T> rchandle_from(T* pointer)
00312 {
00313 #ifndef OPENDDS_SAFETY_PROFILE
00314   assert(pointer == 0 || pointer->ref_count() > 0);
00315 #endif
00316   return RcHandle<T>(pointer, inc_count());
00317 }
00318 
00319 
00320 } // namespace DCPS
00321 } // namespace OpenDDS
00322 
00323 OPENDDS_END_VERSIONED_NAMESPACE_DECL
00324 
00325 #endif  /* OPENDDS_RCHANDLE_T_H */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 10 Aug 2018 for OpenDDS by  doxygen 1.6.1