LCOV - code coverage report
Current view: top level - DCPS - RcHandle_T.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 120 124 96.8 %
Date: 2023-04-30 01:32:43 Functions: 615 8612 7.1 %

          Line data    Source code
       1             : /*
       2             :  * Distributed under the OpenDDS License.
       3             :  * See: http://www.opendds.org/license.html
       4             :  */
       5             : 
       6             : #ifndef OPENDDS_DCPS_RCHANDLE_T_H
       7             : #define OPENDDS_DCPS_RCHANDLE_T_H
       8             : 
       9             : #include "dds/Versioned_Namespace.h"
      10             : #include "Definitions.h"
      11             : #include "unique_ptr.h"
      12             : 
      13             : OPENDDS_BEGIN_VERSIONED_NAMESPACE_DECL
      14             : 
      15             : namespace OpenDDS {
      16             : namespace DCPS {
      17             : 
      18             : struct inc_count {};
      19             : struct keep_count {};
      20             : 
      21             : /// Templated Reference counted handle to a pointer.
      22             : /// A non-DDS specific helper class.
      23             : template <typename T>
      24             : class RcHandle {
      25             : public:
      26         669 :   RcHandle()
      27         669 :     : ptr_(0)
      28             :   {
      29         669 :   }
      30             : 
      31        3282 :   RcHandle(T* p, keep_count)
      32        3282 :     : ptr_(p)
      33             :   {
      34        3282 :   }
      35             : 
      36             :   template <typename U>
      37           1 :   RcHandle(unique_ptr<U> p)
      38           1 :     : ptr_(p.release())
      39             :   {
      40           1 :   }
      41             : 
      42        2114 :   RcHandle(T* p, inc_count)
      43        2114 :     : ptr_(p)
      44             :   {
      45        2114 :     this->bump_up();
      46        2114 :   }
      47             : 
      48             :   template <typename U>
      49        2247 :   RcHandle(const RcHandle<U>& other)
      50        2247 :     : ptr_(other.in())
      51             :   {
      52        2247 :     this->bump_up();
      53        2247 :   }
      54             : 
      55        2293 :   RcHandle(const RcHandle& b)
      56        2293 :     : ptr_(b.ptr_)
      57             :   {
      58        2293 :     this->bump_up();
      59        2293 :   }
      60             : 
      61       10606 :   ~RcHandle()
      62             :   {
      63       10606 :     this->bump_down();
      64       10606 :   }
      65             : 
      66          32 :   void reset()
      67             :   {
      68          32 :     RcHandle tmp;
      69          32 :     swap(tmp);
      70          32 :   }
      71             : 
      72             :   template <typename U>
      73           3 :   void reset(T* p, U counting_strategy)
      74             :   {
      75           3 :     RcHandle tmp(p, counting_strategy);
      76           3 :     swap(tmp);
      77           3 :   }
      78             : 
      79         228 :   RcHandle& operator=(const RcHandle& b)
      80             :   {
      81         228 :     RcHandle tmp(b);
      82         228 :     swap(tmp);
      83         228 :     return *this;
      84         228 :   }
      85             : 
      86             :   template <class U>
      87          19 :   RcHandle& operator=(const RcHandle<U>& b)
      88             :   {
      89          19 :     RcHandle<T> tmp(b);
      90          19 :     swap(tmp);
      91          19 :     return *this;
      92          19 :   }
      93             : 
      94             :   template <typename U>
      95           1 :   RcHandle& operator=(unique_ptr<U> b)
      96             :   {
      97           1 :     RcHandle<T> tmp(b.release(), keep_count());
      98           1 :     swap(tmp);
      99           2 :     return *this;
     100           1 :   }
     101             : 
     102         328 :   void swap(RcHandle& rhs)
     103             :   {
     104         328 :     T* t = this->ptr_;
     105         328 :     this->ptr_ = rhs.ptr_;
     106         328 :     rhs.ptr_ = t;
     107         328 :   }
     108             : 
     109       10391 :   T* operator->() const
     110             :   {
     111       10391 :     OPENDDS_ASSERT(ptr_);
     112       10391 :     return this->ptr_;
     113             :   }
     114             : 
     115        2247 :   T& operator*() const
     116             :   {
     117        2247 :     OPENDDS_ASSERT(ptr_);
     118        2247 :     return *this->ptr_;
     119             :   }
     120             : 
     121          23 :   bool is_nil() const
     122             :   {
     123          23 :     return this->ptr_ == 0;
     124             :   }
     125             : 
     126        7563 :   T* in() const
     127             :   {
     128        7563 :     return this->ptr_;
     129             :   }
     130             : 
     131          23 :   T* get() const
     132             :   {
     133          23 :     return this->ptr_;
     134             :   }
     135             : 
     136           1 :   T*& inout()
     137             :   {
     138           1 :     return this->ptr_;
     139             :   }
     140             : 
     141           1 :   T*& out()
     142             :   {
     143           1 :     this->bump_down();
     144           1 :     return this->ptr_;
     145             :   }
     146             : 
     147           1 :   T* _retn()
     148             :   {
     149           1 :     T* retval = this->ptr_;
     150           1 :     this->ptr_ = 0;
     151           1 :     return retval;
     152             :   }
     153             : 
     154        4637 :   operator bool() const
     155             :   {
     156        4637 :     return in() != 0;
     157             :   }
     158             : 
     159           6 :   bool operator==(const RcHandle& rhs) const
     160             :   {
     161           6 :     return in() == rhs.in();
     162             :   }
     163             : 
     164           1 :   bool operator!=(const RcHandle& rhs) const
     165             :   {
     166           1 :     return in() != rhs.in();
     167             :   }
     168             : 
     169           1 :   bool operator < (const RcHandle& rhs) const
     170             :   {
     171           1 :     return in() < rhs.in();
     172             :   }
     173             : 
     174             : private:
     175        6654 :   void bump_up()
     176             :   {
     177        6654 :     if (ptr_ != 0) {
     178        6651 :       ptr_->_add_ref();
     179             :     }
     180        6654 :   }
     181             : 
     182       10607 :   void bump_down()
     183             :   {
     184       10607 :     if (ptr_ != 0) {
     185        9934 :       ptr_->_remove_ref();
     186        9934 :       ptr_ = 0;
     187             :     }
     188       10607 :   }
     189             : 
     190             :   /// The actual "unsmart" pointer to the T object.
     191             :   T* ptr_;
     192             : };
     193             : 
     194             : 
     195             : template <typename T>
     196           1 : void swap(RcHandle<T>& lhs, RcHandle<T>& rhs)
     197             : {
     198           1 :   lhs.swap(rhs);
     199           1 : }
     200             : 
     201             : template <typename T, typename U>
     202          17 : RcHandle<T> static_rchandle_cast(const RcHandle<U>& h)
     203             : {
     204          17 :   return RcHandle<T>(static_cast<T*>(h.in()), inc_count());
     205             : }
     206             : 
     207             : template <typename T, typename U>
     208           1 : RcHandle<T> const_rchandle_cast(const RcHandle<U>& h)
     209             : {
     210           1 :   return RcHandle<T>(const_cast<T*>(h.in()), inc_count());
     211             : }
     212             : 
     213             : template <typename T, typename U>
     214           1 : RcHandle<T> dynamic_rchandle_cast(const RcHandle<U>& h)
     215             : {
     216           1 :   return RcHandle<T>(dynamic_cast<T*>(h.in()), inc_count());
     217             : }
     218             : 
     219             : 
     220             : template< class T >
     221             : class reference_wrapper{
     222             : public:
     223             :   // types
     224             :   typedef T type;
     225             : 
     226             :   // construct/copy/destroy
     227           5 :   reference_wrapper(T& ref): _ptr(&ref) {}
     228             :   // access
     229             :   operator T& () const { return *_ptr; }
     230           5 :   T& get() const { return *_ptr; }
     231             : 
     232             : private:
     233             :   T* _ptr;
     234             : };
     235             : 
     236             : template <typename T>
     237           5 : reference_wrapper<T> ref(T& r)
     238             : {
     239           5 :   return reference_wrapper<T>(r);
     240             : }
     241             : 
     242             : template <typename T>
     243        3261 : T const& unwrap_reference(T const& t)
     244             : {
     245        3261 :   return t;
     246             : }
     247             : 
     248             : template <typename T>
     249           5 : T& unwrap_reference(reference_wrapper<T> const& t)
     250             : {
     251           5 :   return t.get();
     252             : }
     253             : 
     254             : 
     255             : template <typename T>
     256         315 : RcHandle<T> make_rch()
     257             : {
     258         315 :   return RcHandle<T>(new T(), keep_count());
     259             : }
     260             : 
     261             : template <typename T, typename U>
     262         168 : RcHandle<T> make_rch(U const& u)
     263             : {
     264         168 :   return RcHandle<T>(new T(unwrap_reference(u)), keep_count());
     265             : }
     266             : 
     267             : template <typename T, typename U0, typename U1>
     268          28 : RcHandle<T> make_rch(U0 const& u0, U1 const& u1)
     269             : {
     270          28 :   return RcHandle<T>(new T(unwrap_reference(u0), unwrap_reference(u1)), keep_count());
     271             : }
     272             : 
     273             : template <typename T, typename U0, typename U1, typename U2>
     274          14 : RcHandle<T> make_rch(U0 const& u0, U1 const& u1, U2 const& u2)
     275             : {
     276          14 :   return RcHandle<T>(new T(unwrap_reference(u0), unwrap_reference(u1), unwrap_reference(u2)), keep_count());
     277             : }
     278             : 
     279             : template <typename T, typename U0, typename U1, typename U2, typename U3>
     280           0 : RcHandle<T> make_rch(U0 const& u0, U1 const& u1, U2 const& u2, U3 const& u3)
     281             : {
     282           0 :   return RcHandle<T>(new T(unwrap_reference(u0), unwrap_reference(u1), unwrap_reference(u2), unwrap_reference(u3)), keep_count());
     283             : }
     284             : 
     285             : template <typename T, typename U0, typename U1, typename U2, typename U3, typename U4>
     286         600 : RcHandle<T> make_rch(U0 const& u0, U1 const& u1, U2 const& u2, U3 const& u3, U4 const& u4)
     287             : {
     288         600 :   return RcHandle<T>(new T(unwrap_reference(u0), unwrap_reference(u1), unwrap_reference(u2), unwrap_reference(u3), unwrap_reference(u4)), keep_count());
     289             : }
     290             : 
     291             : template <typename T, typename U0, typename U1, typename U2, typename U3, typename U4, typename U5>
     292             : RcHandle<T> make_rch(U0 const& u0, U1 const& u1, U2 const& u2, U3 const& u3, U4 const& u4, U5 const& u5)
     293             : {
     294             :   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());
     295             : }
     296             : 
     297             : template <typename T, typename U0, typename U1, typename U2, typename U3, typename U4, typename U5, typename U6>
     298             : 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)
     299             : {
     300             :   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());
     301             : }
     302             : 
     303             : template <typename T, typename U0, typename U1, typename U2, typename U3, typename U4, typename U5, typename U6, typename U7>
     304           0 : 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)
     305             : {
     306           0 :   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());
     307             : }
     308             : 
     309             : template<typename T>
     310        2092 : RcHandle<T> rchandle_from(T* pointer)
     311             : {
     312        2092 :   OPENDDS_ASSERT(pointer == 0 || pointer->ref_count() > 0);
     313        2092 :   return RcHandle<T>(pointer, inc_count());
     314             : }
     315             : 
     316             : 
     317             : } // namespace DCPS
     318             : } // namespace OpenDDS
     319             : 
     320             : OPENDDS_END_VERSIONED_NAMESPACE_DECL
     321             : 
     322             : #endif  /* OPENDDS_RCHANDLE_T_H */

Generated by: LCOV version 1.16