foobar2000 SDK  2015-08-03
ref_counter.h
Go to the documentation of this file.
1 #ifdef _MSC_VER
2 #include <intrin.h>
3 #endif
4 
5 namespace pfc {
6  class counter {
7  public:
8  typedef long t_val;
9 
10  counter(t_val p_val = 0) : m_val(p_val) {}
11  long operator++() throw() {return inc();}
12  long operator--() throw() {return dec();}
13  long operator++(int) throw() {return inc()-1;}
14  long operator--(int) throw() {return dec()+1;}
15  operator t_val() const throw() {return m_val;}
16  private:
17  t_val inc() {
18 #ifdef _MSC_VER
19  return _InterlockedIncrement(&m_val);
20 #else
21  return __sync_add_and_fetch(&m_val, 1);
22 #endif
23  }
24  t_val dec() {
25 #ifdef _MSC_VER
26  return _InterlockedDecrement(&m_val);
27 #else
28  return __sync_sub_and_fetch(&m_val, 1);
29 #endif
30  }
31 
32  volatile t_val m_val;
33  };
34 
36 
37  class NOVTABLE refcounted_object_root
38  {
39  public:
40  void refcount_add_ref() throw() {++m_counter;}
41  void refcount_release() throw() {if (--m_counter == 0) delete this;}
42  void _refcount_release_temporary() throw() {--m_counter;}//for internal use only!
43  protected:
46  private:
47  refcounter m_counter;
48  };
49 
50  template<typename T>
52  private:
54  public:
55  inline refcounted_object_ptr_t() throw() : m_ptr(NULL) {}
56  inline refcounted_object_ptr_t(T* p_ptr) throw() : m_ptr(NULL) {copy(p_ptr);}
57  inline refcounted_object_ptr_t(const t_self & p_source) throw() : m_ptr(NULL) {copy(p_source);}
58  inline refcounted_object_ptr_t(t_self && p_source) throw() { m_ptr = p_source.m_ptr; p_source.m_ptr = NULL; }
59 
60  template<typename t_source>
61  inline refcounted_object_ptr_t(t_source * p_ptr) throw() : m_ptr(NULL) {copy(p_ptr);}
62 
63  template<typename t_source>
64  inline refcounted_object_ptr_t(const refcounted_object_ptr_t<t_source> & p_source) throw() : m_ptr(NULL) {copy(p_source);}
65 
66  inline ~refcounted_object_ptr_t() throw() {if (m_ptr != NULL) m_ptr->refcount_release();}
67 
68  template<typename t_source>
69  inline void copy(t_source * p_ptr) throw() {
70  T* torel = pfc::replace_t(m_ptr,pfc::safe_ptr_cast<T>(p_ptr));
71  if (m_ptr != NULL) m_ptr->refcount_add_ref();
72  if (torel != NULL) torel->refcount_release();
73 
74  }
75 
76  template<typename t_source>
77  inline void copy(const refcounted_object_ptr_t<t_source> & p_source) throw() {copy(p_source.get_ptr());}
78 
79 
80  inline const t_self & operator=(const t_self & p_source) throw() {copy(p_source); return *this;}
81  inline const t_self & operator=(t_self && p_source) throw() {attach(p_source.detach()); return *this;}
82  inline const t_self & operator=(T * p_ptr) throw() {copy(p_ptr); return *this;}
83 
84  template<typename t_source> inline t_self & operator=(const refcounted_object_ptr_t<t_source> & p_source) throw() {copy(p_source); return *this;}
85  template<typename t_source> inline t_self & operator=(t_source * p_ptr) throw() {copy(p_ptr); return *this;}
86 
87  inline void release() throw() {
88  T * temp = pfc::replace_t(m_ptr,(T*)NULL);
89  if (temp != NULL) temp->refcount_release();
90  }
91 
92 
93  inline T& operator*() const throw() {return *m_ptr;}
94 
95  inline T* operator->() const throw() {PFC_ASSERT(m_ptr != NULL);return m_ptr;}
96 
97  inline T* get_ptr() const throw() {return m_ptr;}
98 
99  inline bool is_valid() const throw() {return m_ptr != NULL;}
100  inline bool is_empty() const throw() {return m_ptr == NULL;}
101 
102  inline bool operator==(const t_self & p_item) const throw() {return m_ptr == p_item.get_ptr();}
103  inline bool operator!=(const t_self & p_item) const throw() {return m_ptr != p_item.get_ptr();}
104  inline bool operator>(const t_self & p_item) const throw() {return m_ptr > p_item.get_ptr();}
105  inline bool operator<(const t_self & p_item) const throw() {return m_ptr < p_item.get_ptr();}
106 
107 
108  inline T* _duplicate_ptr() const throw()//should not be used ! temporary !
109  {
110  if (m_ptr) m_ptr->refcount_add_ref();
111  return m_ptr;
112  }
113 
114  inline T* detach() throw() {//should not be used ! temporary !
115  T* ret = m_ptr;
116  m_ptr = 0;
117  return ret;
118  }
119 
120  inline void attach(T * p_ptr) throw() {//should not be used ! temporary !
121  release();
122  m_ptr = p_ptr;
123  }
124  inline t_self & operator<<(t_self & p_source) throw() {attach(p_source.detach());return *this;}
125  inline t_self & operator>>(t_self & p_dest) throw() {p_dest.attach(detach());return *this;}
126  private:
128  };
129 
130  template<typename T>
132  public:
133  enum { realloc_safe = true, constructor_may_fail = false};
134  };
135 
136 };
long operator++()
Definition: ref_counter.h:11
bool operator>(const t_self &p_item) const
Definition: ref_counter.h:104
counter refcounter
Definition: ref_counter.h:35
t_self & operator=(t_source *p_ptr)
Definition: ref_counter.h:85
bool operator<(const t_self &p_item) const
Definition: ref_counter.h:105
bool operator==(const t_self &p_item) const
Definition: ref_counter.h:102
t_self & operator>>(t_self &p_dest)
Definition: ref_counter.h:125
void copy(const refcounted_object_ptr_t< t_source > &p_source)
Definition: ref_counter.h:77
t_type replace_t(t_type &p_var, const t_newval &p_newval)
Definition: primitives.h:682
const t_self & operator=(t_self &&p_source)
Definition: ref_counter.h:81
t_self & operator=(const refcounted_object_ptr_t< t_source > &p_source)
Definition: ref_counter.h:84
const t_self & operator=(const t_self &p_source)
Definition: ref_counter.h:80
long operator--()
Definition: ref_counter.h:12
refcounted_object_ptr_t(const refcounted_object_ptr_t< t_source > &p_source)
Definition: ref_counter.h:64
long operator++(int)
Definition: ref_counter.h:13
t_self & operator<<(t_self &p_source)
Definition: ref_counter.h:124
long operator--(int)
Definition: ref_counter.h:14
t_val dec()
Definition: ref_counter.h:24
bool operator!=(const t_self &p_item) const
Definition: ref_counter.h:103
t_val inc()
Definition: ref_counter.h:17
refcounted_object_ptr_t< T > t_self
Definition: ref_counter.h:53
volatile t_val m_val
Definition: ref_counter.h:32
counter(t_val p_val=0)
Definition: ref_counter.h:10
void copy(t_source *p_ptr)
Definition: ref_counter.h:69
refcounted_object_ptr_t(t_source *p_ptr)
Definition: ref_counter.h:61
This is free and unencumbered software released into the public domain Anyone is free to copy
Definition: pfc-license.txt:3
const t_self & operator=(T *p_ptr)
Definition: ref_counter.h:82
refcounted_object_ptr_t(t_self &&p_source)
Definition: ref_counter.h:58
refcounted_object_ptr_t(const t_self &p_source)
Definition: ref_counter.h:57