SST/macro
refcount_ptr.h
Go to the documentation of this file.
1 #ifndef sprockit_refcount_ptr_h
2 #define sprockit_refcount_ptr_h
3 
4 #include <cstdio>
5 #include <sprockit/spkt_config.h>
6 
7 #if SPKT_ATOMIC_REFCOUNT
8 #define ref_increment(refcount) __atomic_add_fetch(&refcount, 1, __ATOMIC_SEQ_CST)
9 #define ref_decrement_return(refcount) __atomic_add_fetch(&refcount, -1, __ATOMIC_SEQ_CST)
10 inline int fetch_and_add( int * variable, int value) {
11  asm volatile("lock; xaddl %%eax, %2;"
12  :"=a" (value) //Output
13  :"a" (value), "m" (*variable) //Input
14  :"memory");
15  return value;
16 }
17 #else
18 #define ref_increment(refcount) ++refcount
19 #define ref_decrement_return(refcount) --refcount
20 #endif
21 
22 namespace sprockit {
23 
24 template <class T>
25 class refcount_ptr {
26  template <class U> friend class refcount_ptr;
27  private:
28  T* ptr;
29 
30  template <class U>
31  void decref(U* ptr){
32  if (ptr){
33  if (ref_decrement_return(ptr->references) == 0)
34  delete ptr;
35  }
36  }
37 
38  template <class U>
39  void incref(U* ptr){
40  if (ptr) ref_increment(ptr->references);
41  }
42 
43  public:
44  refcount_ptr() : ptr(0) {
45  }
46 
47  template <class U>
48  refcount_ptr(const refcount_ptr<U>& rhs) : ptr(rhs.ptr) {
49  incref(ptr);
50  }
51 
52  refcount_ptr(const refcount_ptr& rhs) : ptr(rhs.ptr) {
53  incref(ptr);
54  }
55 
56  refcount_ptr(T* rhs) : ptr(rhs) {
57  incref(ptr);
58  }
59 
61  decref(ptr);
62  }
63 
64  T*
65  get() const {
66  return ptr;
67  }
68 
69  template <class U>
72  incref(rhs.ptr);
73  decref(ptr);
74  ptr = rhs.ptr;
75  return *this;
76  }
77 
79  operator=(const refcount_ptr& rhs){
80  incref(rhs.ptr);
81  decref(ptr);
82  ptr = rhs.ptr;
83  return *this;
84  }
85 
87  operator=(T* rhs){
88  incref(rhs);
89  decref(ptr);
90  ptr = rhs;
91  return *this;
92  }
93 
94  operator bool() const {
95  return bool(ptr);
96  }
97 
98  T*
99  operator->() const {
100  return ptr;
101  }
102 
103  bool
104  null() const {
105  return ptr == 0;
106  }
107 };
108 
109 }
110 
111 #if __cplusplus > 199711L
112 
113 namespace std {
114  template <class T> struct hash<sprockit::refcount_ptr<T> > {
115  size_t
116  operator()(const sprockit::refcount_ptr<T>& ptr) const {
117  return hash<void*>()(ptr.get());
118  }
119  };
120 }
121 
122 #endif
123 
124 #endif
T * operator->() const
Definition: refcount_ptr.h:99
#define ref_decrement_return(refcount)
Definition: refcount_ptr.h:19
refcount_ptr< T > & operator=(const refcount_ptr< U > &rhs)
Definition: refcount_ptr.h:71
refcount_ptr< T > & operator=(T *rhs)
Definition: refcount_ptr.h:87
refcount_ptr(const refcount_ptr< U > &rhs)
Definition: refcount_ptr.h:48
refcount_ptr(const refcount_ptr &rhs)
Definition: refcount_ptr.h:52
refcount_ptr< T > & operator=(const refcount_ptr &rhs)
Definition: refcount_ptr.h:79
#define ref_increment(refcount)
Definition: refcount_ptr.h:18