5faebf497b920b61d445f82c86d20a46f08d2b18
[libcds.git] / cds / gc / details / retired_ptr.h
1 //$$CDS-header$$
2
3 #ifndef CDSLIB_GC_DETAILS_RETIRED_PTR_H
4 #define CDSLIB_GC_DETAILS_RETIRED_PTR_H
5
6 #include <cds/details/defs.h>
7 #include <cds/details/static_functor.h>
8
9 //@cond
10 namespace cds { namespace gc {
11     /// Common implementation details for any GC
12     namespace details {
13
14         /// Pointer to function to free (destruct and deallocate) retired pointer of specific type
15         typedef void (* free_retired_ptr_func )( void * );
16
17         /// Retired pointer
18         /**
19             Pointer to an object that is ready to delete.
20         */
21         struct retired_ptr {
22             /// Pointer type
23             typedef void *          pointer;
24
25             union {
26                 pointer                 m_p;        ///< retired pointer
27                 uintptr_t               m_n;
28             };
29             free_retired_ptr_func   m_funcFree; ///< pointer to the destructor function
30
31             /// Comparison of two retired pointers
32             static bool less( const retired_ptr& p1, const retired_ptr& p2 ) CDS_NOEXCEPT
33             {
34                 return p1.m_p < p2.m_p;
35             }
36
37             /// Default ctor initializes pointer to \p nullptr
38             retired_ptr() CDS_NOEXCEPT
39                 : m_p( nullptr )
40                 , m_funcFree( nullptr )
41             {}
42
43             /// Ctor
44             retired_ptr( pointer p, free_retired_ptr_func func ) CDS_NOEXCEPT
45                 : m_p( p )
46                 , m_funcFree( func )
47             {}
48
49             /// Typecasting ctor
50             template <typename T>
51             retired_ptr( T * p, void (* pFreeFunc)(T *)) CDS_NOEXCEPT
52                 : m_p( reinterpret_cast<pointer>(p))
53                 , m_funcFree( reinterpret_cast< free_retired_ptr_func >( pFreeFunc ))
54             {}
55
56             /// Assignment operator
57             retired_ptr& operator =( retired_ptr const& s) CDS_NOEXCEPT
58             {
59                 m_p = s.m_p;
60                 m_funcFree = s.m_funcFree;
61                 return *this;
62             }
63
64             /// Invokes destructor function for the pointer
65             void free()
66             {
67                 assert( m_funcFree );
68                 assert( m_p );
69                 m_funcFree( m_p );
70
71                 CDS_STRICT_DO( m_p = nullptr );
72                 CDS_STRICT_DO( m_funcFree = nullptr );
73             }
74         };
75
76         static inline bool operator <( const retired_ptr& p1, const retired_ptr& p2 ) CDS_NOEXCEPT
77         {
78             return retired_ptr::less( p1, p2 );
79         }
80
81         static inline bool operator ==( const retired_ptr& p1, const retired_ptr& p2 ) CDS_NOEXCEPT
82         {
83             return p1.m_p == p2.m_p;
84         }
85
86         static inline bool operator !=( const retired_ptr& p1, const retired_ptr& p2 ) CDS_NOEXCEPT
87         {
88             return !(p1 == p2);
89         }
90     }  // namespace details
91
92     template <typename Func, typename T>
93     static inline cds::gc::details::retired_ptr make_retired_ptr( T * p )
94     {
95         return cds::gc::details::retired_ptr( p, cds::details::static_functor<Func, T>::call );
96     }
97
98 }}   // namespace cds::gc
99 //@endcond
100
101 #endif // #ifndef CDSLIB_GC_DETAILS_RETIRED_PTR_H