blob: 4a4b01879d68e20c6bed1b665ae8de50b868e099 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
|
#ifndef GRAEHL__SHARED__INTRUSIVE_REFCOUNT_HPP
#define GRAEHL__SHARED__INTRUSIVE_REFCOUNT_HPP
#include <boost/intrusive_ptr.hpp>
#include <boost/noncopyable.hpp>
#include <boost/detail/atomic_count.hpp>
#include <cassert>
/** usage:
struct mine : public boost::instrusive_refcount<mine> {};
boost::intrusive_ptr<mine> p(new mine());
*/
namespace boost {
// note: the free functions need to be in boost namespace, OR namespace of involved type. this is the only way to do it.
template <class T>
class intrusive_refcount;
template <class T>
class atomic_intrusive_refcount;
template<class T>
void intrusive_ptr_add_ref(intrusive_refcount<T>* ptr)
{
++(ptr->refs);
}
template<class T>
void intrusive_ptr_release(intrusive_refcount<T>* ptr)
{
if (!--(ptr->refs)) delete static_cast<T*>(ptr);
}
//WARNING: only 2^32 (unsigned) refs allowed. hope that's ok :)
template<class T>
class intrusive_refcount : boost::noncopyable
{
protected:
// typedef intrusive_refcount<T> pointed_type;
friend void intrusive_ptr_add_ref<T>(intrusive_refcount<T>* ptr);
friend void intrusive_ptr_release<T>(intrusive_refcount<T>* ptr);
// friend class intrusive_ptr<T>;
intrusive_refcount(): refs(0) {}
~intrusive_refcount() { assert(refs==0); }
private:
unsigned refs;
};
template<class T>
void intrusive_ptr_add_ref(atomic_intrusive_refcount<T>* ptr)
{
++(ptr->refs);
}
template<class T>
void intrusive_ptr_release(atomic_intrusive_refcount<T>* ptr)
{
if(!--(ptr->refs)) delete static_cast<T*>(ptr);
}
template<class T>
class atomic_intrusive_refcount : boost::noncopyable
{
protected:
friend void intrusive_ptr_add_ref<T>(atomic_intrusive_refcount<T>* ptr);
friend void intrusive_ptr_release<T>(atomic_intrusive_refcount<T>* ptr);
atomic_intrusive_refcount(): refs(0) {}
~atomic_intrusive_refcount() { assert(refs==0); }
private:
boost::detail::atomic_count refs;
};
}
#endif
|