00001
00002
00003
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
00022
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
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
00225 typedef T type;
00226
00227
00228 reference_wrapper(T& ref): _ptr(&ref) {}
00229
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 }
00321 }
00322
00323 OPENDDS_END_VERSIONED_NAMESPACE_DECL
00324
00325 #endif