foobar2000 SDK  2015-01-14
rcptr.h
Go to the documentation of this file.
1 namespace pfc {
2 
3  struct _rcptr_null;
4  typedef _rcptr_null* t_rcptr_null;
5 
6  static const t_rcptr_null rcptr_null = NULL;
7 
9  public:
10  long add_ref() throw() {
11  return ++m_counter;
12  }
13  long release() throw() {
14  long ret = --m_counter;
15  if (ret == 0) PFC_ASSERT_NO_EXCEPTION( delete this );
16  return ret;
17  }
18  protected:
19  virtual ~rc_container_base() {}
20  private:
22  };
23 
24  template<typename t_object>
26  public:
28 
29  t_object m_object;
30  };
31 
32  template<typename t_object>
33  class rcptr_t {
34  private:
38  public:
39  rcptr_t(t_rcptr_null) throw() {_clear();}
40  rcptr_t() throw() {_clear();}
41  rcptr_t(const t_self & p_source) throw() {__init(p_source);}
42  t_self const & operator=(const t_self & p_source) throw() {__copy(p_source); return *this;}
43 
44  template<typename t_source>
45  rcptr_t(const rcptr_t<t_source> & p_source) throw() {__init(p_source);}
46  template<typename t_source>
47  const t_self & operator=(const rcptr_t<t_source> & p_source) throw() {__copy(p_source); return *this;}
48 
49  rcptr_t(t_self && p_source) throw() {_move(p_source);}
50  const t_self & operator=(t_self && p_source) throw() {release(); _move(p_source); return *this;}
51 
52  const t_self & operator=(t_rcptr_null) throw() {release(); return *this;}
53 
54 /* template<typename t_object_cast>
55  operator rcptr_t<t_object_cast>() const throw() {
56  rcptr_t<t_object_cast> temp;
57  if (is_valid()) temp.__set_from_cast(this->m_container,this->m_ptr);
58  return temp;
59  }*/
60 
61 
62  template<typename t_other>
63  bool operator==(const rcptr_t<t_other> & p_other) const throw() {
64  return m_container == p_other.__container();
65  }
66 
67  template<typename t_other>
68  bool operator!=(const rcptr_t<t_other> & p_other) const throw() {
69  return m_container != p_other.__container();
70  }
71 
72  void __set_from_cast(t_container * p_container,t_object * p_ptr) throw() {
73  //addref first because in rare cases this is the same pointer as the one we currently own
74  if (p_container != NULL) p_container->add_ref();
75  release();
76  m_container = p_container;
77  m_ptr = p_ptr;
78  }
79 
80  bool is_valid() const throw() {return m_container != NULL;}
81  bool is_empty() const throw() {return m_container == NULL;}
82 
83 
84  ~rcptr_t() throw() {release();}
85 
86  void release() throw() {
87  t_container * temp = m_container;
88  m_ptr = NULL;
89  m_container = NULL;
90  if (temp != NULL) temp->release();
91  }
92 
93 
94  template<typename t_object_cast>
97  if (is_valid()) temp.__set_from_cast(this->m_container,static_cast<t_object_cast*>(this->m_ptr));
98  return temp;
99  }
100 
101  void new_t() {
102  on_new(new t_container_impl());
103  }
104 
105  template<typename t_param1>
106  void new_t(t_param1 const & p_param1) {
107  on_new(new t_container_impl(p_param1));
108  }
109 
110  template<typename t_param1,typename t_param2>
111  void new_t(t_param1 const & p_param1, t_param2 const & p_param2) {
112  on_new(new t_container_impl(p_param1,p_param2));
113  }
114 
115  template<typename t_param1,typename t_param2,typename t_param3>
116  void new_t(t_param1 const & p_param1, t_param2 const & p_param2,t_param3 const & p_param3) {
117  on_new(new t_container_impl(p_param1,p_param2,p_param3));
118  }
119 
120  template<typename t_param1,typename t_param2,typename t_param3,typename t_param4>
121  void new_t(t_param1 const & p_param1, t_param2 const & p_param2,t_param3 const & p_param3,t_param4 const & p_param4) {
122  on_new(new t_container_impl(p_param1,p_param2,p_param3,p_param4));
123  }
124 
125  template<typename t_param1,typename t_param2,typename t_param3,typename t_param4,typename t_param5>
126  void new_t(t_param1 const & p_param1, t_param2 const & p_param2,t_param3 const & p_param3,t_param4 const & p_param4,t_param5 const & p_param5) {
127  on_new(new t_container_impl(p_param1,p_param2,p_param3,p_param4,p_param5));
128  }
129 
130  template<typename t_param1,typename t_param2,typename t_param3,typename t_param4,typename t_param5,typename t_param6>
131  void new_t(t_param1 const & p_param1, t_param2 const & p_param2,t_param3 const & p_param3,t_param4 const & p_param4,t_param5 const & p_param5,t_param6 const & p_param6) {
132  on_new(new t_container_impl(p_param1,p_param2,p_param3,p_param4,p_param5,p_param6));
133  }
134 
135  static t_self g_new_t() {
136  t_self temp;
137  temp.new_t();
138  return temp;
139  }
140 
141  template<typename t_param1>
142  static t_self g_new_t(t_param1 const & p_param1) {
143  t_self temp;
144  temp.new_t(p_param1);
145  return temp;
146  }
147 
148  template<typename t_param1,typename t_param2>
149  static t_self g_new_t(t_param1 const & p_param1,t_param2 const & p_param2) {
150  t_self temp;
151  temp.new_t(p_param1,p_param2);
152  return temp;
153  }
154 
155  template<typename t_param1,typename t_param2,typename t_param3>
156  static t_self g_new_t(t_param1 const & p_param1,t_param2 const & p_param2,t_param3 const & p_param3) {
157  t_self temp;
158  temp.new_t(p_param1,p_param2,p_param3);
159  return temp;
160  }
161 
162  template<typename t_param1,typename t_param2,typename t_param3,typename t_param4>
163  static t_self g_new_t(t_param1 const & p_param1,t_param2 const & p_param2,t_param3 const & p_param3,t_param4 const & p_param4) {
164  t_self temp;
165  temp.new_t(p_param1,p_param2,p_param3,p_param4);
166  return temp;
167  }
168 
169  template<typename t_param1,typename t_param2,typename t_param3,typename t_param4,typename t_param5>
170  static t_self g_new_t(t_param1 const & p_param1,t_param2 const & p_param2,t_param3 const & p_param3,t_param4 const & p_param4,t_param5 const & p_param5) {
171  t_self temp;
172  temp.new_t(p_param1,p_param2,p_param3,p_param4,p_param5);
173  return temp;
174  }
175 
176  t_object & operator*() const throw() {return *this->m_ptr;}
177 
178  t_object * operator->() const throw() {return this->m_ptr;}
179 
180 
181  t_container * __container() const throw() {return m_container;}
182 
183  // FOR INTERNAL USE ONLY
184  void _clear() throw() {m_container = NULL; m_ptr = NULL;}
185  private:
186 
187  template<typename t_source>
188  void __init(const rcptr_t<t_source> & p_source) throw() {
189  m_container = p_source.__container();
190  m_ptr = &*p_source;
191  if (m_container != NULL) m_container->add_ref();
192  }
193  template<typename t_source>
194  void _move(rcptr_t<t_source> & p_source) throw() {
195  m_container = p_source.__container();
196  m_ptr = &*p_source;
197  p_source._clear();
198  }
199  template<typename t_source>
200  void __copy(const rcptr_t<t_source> & p_source) throw() {
201  __set_from_cast(p_source.__container(),&*p_source);
202  }
203  void on_new(t_container_impl * p_container) throw() {
204  this->release();
205  p_container->add_ref();
206  this->m_ptr = &p_container->m_object;
207  this->m_container = p_container;
208  }
209 
210  t_container * m_container;
211  t_object * m_ptr;
212  };
213 
214  template<typename t_object>
216  rcptr_t<t_object> temp;
217  temp.new_t();
218  return temp;
219  }
220 
221  template<typename t_object,typename t_param1>
222  rcptr_t<t_object> rcnew_t(t_param1 const & p_param1) {
223  rcptr_t<t_object> temp;
224  temp.new_t(p_param1);
225  return temp;
226  }
227 
228  template<typename t_object,typename t_param1,typename t_param2>
229  rcptr_t<t_object> rcnew_t(t_param1 const & p_param1,t_param2 const & p_param2) {
230  rcptr_t<t_object> temp;
231  temp.new_t(p_param1,p_param2);
232  return temp;
233  }
234 
235  template<typename t_object,typename t_param1,typename t_param2,typename t_param3>
236  rcptr_t<t_object> rcnew_t(t_param1 const & p_param1,t_param2 const & p_param2,t_param3 const & p_param3) {
237  rcptr_t<t_object> temp;
238  temp.new_t(p_param1,p_param2,p_param3);
239  return temp;
240  }
241 
242  template<typename t_object,typename t_param1,typename t_param2,typename t_param3,typename t_param4>
243  rcptr_t<t_object> rcnew_t(t_param1 const & p_param1,t_param2 const & p_param2,t_param3 const & p_param3,t_param4 const & p_param4) {
244  rcptr_t<t_object> temp;
245  temp.new_t(p_param1,p_param2,p_param3,p_param4);
246  return temp;
247  }
248 
249  template<typename t_object,typename t_param1,typename t_param2,typename t_param3,typename t_param4,typename t_param5>
250  rcptr_t<t_object> rcnew_t(t_param1 const & p_param1,t_param2 const & p_param2,t_param3 const & p_param3,t_param4 const & p_param4,t_param5 const & p_param5) {
251  rcptr_t<t_object> temp;
252  temp.new_t(p_param1,p_param2,p_param3,p_param4,p_param5);
253  return temp;
254  }
255 
256  template<typename t_object,typename t_param1,typename t_param2,typename t_param3,typename t_param4,typename t_param5,typename t_param6>
257  rcptr_t<t_object> rcnew_t(t_param1 const & p_param1,t_param2 const & p_param2,t_param3 const & p_param3,t_param4 const & p_param4,t_param5 const & p_param5,t_param6 const & p_param6) {
258  rcptr_t<t_object> temp;
259  temp.new_t(p_param1,p_param2,p_param3,p_param4,p_param5,p_param6);
260  return temp;
261  }
262 
263  class traits_rcptr : public traits_default {
264  public:
265  enum { realloc_safe = true, constructor_may_fail = false };
266  };
267 
268  template<typename T> class traits_t<rcptr_t<T> > : public traits_rcptr {};
269 }
t_self const & operator=(const t_self &p_source)
Definition: rcptr.h:42
const t_self & operator=(t_self &&p_source)
Definition: rcptr.h:50
const t_self & operator=(const rcptr_t< t_source > &p_source)
Definition: rcptr.h:47
rc_container_base t_container
Definition: rcptr.h:36
void _move(rcptr_t< t_source > &p_source)
Definition: rcptr.h:194
static t_self g_new_t(t_param1 const &p_param1, t_param2 const &p_param2)
Definition: rcptr.h:149
void new_t()
Definition: rcptr.h:101
t_container * __container() const
Definition: rcptr.h:181
rcptr_t(t_rcptr_null)
Definition: rcptr.h:39
bool operator==(const rcptr_t< t_other > &p_other) const
Definition: rcptr.h:63
~rcptr_t()
Definition: rcptr.h:84
t_object * m_ptr
Definition: rcptr.h:211
void new_t(t_param1 const &p_param1, t_param2 const &p_param2, t_param3 const &p_param3, t_param4 const &p_param4, t_param5 const &p_param5, t_param6 const &p_param6)
Definition: rcptr.h:131
void new_t(t_param1 const &p_param1, t_param2 const &p_param2)
Definition: rcptr.h:111
void new_t(t_param1 const &p_param1, t_param2 const &p_param2, t_param3 const &p_param3, t_param4 const &p_param4)
Definition: rcptr.h:121
void new_t(t_param1 const &p_param1, t_param2 const &p_param2, t_param3 const &p_param3)
Definition: rcptr.h:116
refcounter m_counter
Definition: rcptr.h:21
static t_self g_new_t()
Definition: rcptr.h:135
rcptr_t(const t_self &p_source)
Definition: rcptr.h:41
rcptr_t< t_object_cast > static_cast_t() const
Definition: rcptr.h:95
rc_container_t< t_object > t_container_impl
Definition: rcptr.h:37
rcptr_t< t_object > rcnew_t()
Definition: rcptr.h:215
rcptr_t< t_object > t_self
Definition: rcptr.h:35
static t_self g_new_t(t_param1 const &p_param1, t_param2 const &p_param2, t_param3 const &p_param3, t_param4 const &p_param4, t_param5 const &p_param5)
Definition: rcptr.h:170
rcptr_t(const rcptr_t< t_source > &p_source)
Definition: rcptr.h:45
void new_t(t_param1 const &p_param1, t_param2 const &p_param2, t_param3 const &p_param3, t_param4 const &p_param4, t_param5 const &p_param5)
Definition: rcptr.h:126
void __copy(const rcptr_t< t_source > &p_source)
Definition: rcptr.h:200
void on_new(t_container_impl *p_container)
Definition: rcptr.h:203
t_object * operator->() const
Definition: rcptr.h:178
static t_self g_new_t(t_param1 const &p_param1, t_param2 const &p_param2, t_param3 const &p_param3, t_param4 const &p_param4)
Definition: rcptr.h:163
void __init(const rcptr_t< t_source > &p_source)
Definition: rcptr.h:188
void _clear()
Definition: rcptr.h:184
_rcptr_null * t_rcptr_null
Definition: rcptr.h:3
static const t_rcptr_null rcptr_null
Definition: rcptr.h:6
const t_self & operator=(t_rcptr_null)
Definition: rcptr.h:52
TEMPLATE_CONSTRUCTOR_FORWARD_FLOOD(rc_container_t, m_object) t_object m_object
void __set_from_cast(t_container *p_container, t_object *p_ptr)
Definition: rcptr.h:72
virtual ~rc_container_base()
Definition: rcptr.h:19
bool operator!=(const rcptr_t< t_other > &p_other) const
Definition: rcptr.h:68
t_container * m_container
Definition: rcptr.h:210
t_object & operator*() const
Definition: rcptr.h:176
bool is_empty() const
Definition: rcptr.h:81
void release()
Definition: rcptr.h:86
static t_self g_new_t(t_param1 const &p_param1)
Definition: rcptr.h:142
rcptr_t()
Definition: rcptr.h:40
void new_t(t_param1 const &p_param1)
Definition: rcptr.h:106
rcptr_t(t_self &&p_source)
Definition: rcptr.h:49
static t_self g_new_t(t_param1 const &p_param1, t_param2 const &p_param2, t_param3 const &p_param3)
Definition: rcptr.h:156
bool is_valid() const
Definition: rcptr.h:80