FastUIDraw
reference_counted.hpp
Go to the documentation of this file.
1 /*!
2  * \file reference_counted.hpp
3  * \brief file reference_counted.hpp
4  *
5  * Copyright 2016 by Intel.
6  *
7  * Contact: kevin.rogovin@gmail.com
8  *
9  * This Source Code Form is subject to the
10  * terms of the Mozilla Public License, v. 2.0.
11  * If a copy of the MPL was not distributed with
12  * this file, You can obtain one at
13  * http://mozilla.org/MPL/2.0/.
14  *
15  * \author Kevin Rogovin <kevin.rogovin@gmail.com>
16  *
17  */
18 
19 
20 #ifndef FASTUIDRAW_REFERENCE_COUNTED_HPP
21 #define FASTUIDRAW_REFERENCE_COUNTED_HPP
22 
23 
24 #include <fastuidraw/util/util.hpp>
26 
29 
30 /*!
31  * All functionality of FastUIDraw is in the namespace fastuidraw.
32  */
33 namespace fastuidraw
34 {
35 /*!\addtogroup Utility
36  * @{
37  */
38 
39  /*!
40  * \brief
41  * A wrapper over a pointer to implement reference counting.
42  *
43  * The class T must implement the static methods
44  * - T::add_reference(const T*)
45  * - T::remove_reference(const T*)
46  *
47  * where T::add_reference() increment the reference count and
48  * T::remove_reference() decrements the reference count and will
49  * delete the object.
50  *
51  * See also reference_counted_base and reference_counted.
52  */
53  template<typename T>
55  {
56  private:
57  typedef void (reference_counted_ptr::*unspecified_bool_type)(void) const;
58 
59  void
60  fake_function(void) const
61  {}
62 
63  public:
64  /*!
65  * Ctor, inits the reference_counted_ptr as
66  * equivalent to nullptr.
67  */
69  m_p(nullptr)
70  {}
71 
72  /*!
73  * Ctor, initialize from a T*. If passed non-nullptr,
74  * then the reference counter is incremented
75  * (via T::add_reference()).
76  * \param p pointer value from which to initialize
77  */
79  m_p(p)
80  {
81  if (m_p)
82  {
83  T::add_reference(m_p);
84  }
85  }
86 
87  /*!
88  * Copy ctor.
89  * \param obj value from which to initialize
90  */
92  m_p(obj.get())
93  {
94  if (m_p)
95  {
96  T::add_reference(m_p);
97  }
98  }
99 
100  /*!
101  * Ctor from a reference_counted_ptr<U> where U* is
102  * implicitely convertible to a T*.
103  * \tparam U type where U* is implicitely convertible to a T*.
104  * \param obj value from which to initialize
105  */
106  template<typename U>
108  m_p(obj.get())
109  {
110  if (m_p)
111  {
112  T::add_reference(m_p);
113  }
114  }
115 
116  /*!
117  * Move ctor.
118  * \param obj object from which to take.
119  */
121  m_p(obj.m_p)
122  {
123  obj.m_p = nullptr;
124  }
125 
126  /*!
127  * Dtor, if pointer is non-nullptr, then reference is decremented
128  * (via T::remove_reference()).
129  */
131  {
132  if (m_p)
133  {
134  T::remove_reference(m_p);
135  }
136  }
137 
138  /*!
139  * Assignment operator
140  * \param rhs value from which to assign
141  */
144  {
145  reference_counted_ptr temp(rhs);
146  temp.swap(*this);
147  return *this;
148  }
149 
150  /*!
151  * Assignment operator from a T*.
152  * \param rhs value from which to assign
153  */
155  operator=(T *rhs)
156  {
157  reference_counted_ptr temp(rhs);
158  temp.swap(*this);
159  return *this;
160  }
161 
162  /*!
163  * Move assignment operator
164  * \param rhs value from which to assign
165  */
168  {
169  if (m_p)
170  {
171  T::remove_reference(m_p);
172  }
173  m_p = rhs.m_p;
174  rhs.m_p = nullptr;
175  return *this;
176  }
177 
178  /*!
179  * Assignment operator from a reference_counted_ptr<U>
180  * where U* is implicitely convertible to a T*.
181  * \tparam U type where U* is implicitely convertible to a T*.
182  * \param rhs value from which to assign
183  */
184  template<typename U>
187  {
188  reference_counted_ptr temp(rhs);
189  temp.swap(*this);
190  return *this;
191  }
192 
193  /*!
194  * Returns the underlying pointer
195  */
196  T*
197  get(void) const
198  {
199  return m_p;
200  }
201 
202  /*!
203  * Overload of dererefence operator. Under debug build,
204  * assers if pointer is nullptr.
205  */
206  T&
207  operator*(void) const
208  {
209  FASTUIDRAWassert(m_p);
210  return *m_p;
211  }
212 
213  /*!
214  * Overload of operator. Under debug build,
215  * assers if pointer is nullptr.
216  */
217  T*
218  operator->(void) const
219  {
220  FASTUIDRAWassert(m_p);
221  return m_p;
222  }
223 
224  /*!
225  * Performs swap without needing to increment or
226  * decrement the reference counter.
227  * \param rhs object with which to swap
228  */
229  void
231  {
232  T *temp;
233  temp = rhs.m_p;
234  rhs.m_p = m_p;
235  m_p = temp;
236  }
237 
238  /*!
239  * Allows one to legally write:
240  * \code
241  * reference_counted_ptr<T> p;
242  *
243  * if (p)
244  * {
245  * // i.e. p.get() is not nullptr
246  * }
247  *
248  * if (!p)
249  * {
250  * // i.e. p.get() is nullptr
251  * }
252  * \endcode
253  */
254  operator unspecified_bool_type() const
255  {
256  return m_p ? &reference_counted_ptr::fake_function : 0;
257  }
258 
259  /*!
260  * Equality comparison operator to a pointer value.
261  * \param rhs value with which to compare against
262  */
263  template<typename U>
264  bool
265  operator==(U *rhs) const
266  {
267  return m_p == rhs;
268  }
269 
270  /*!
271  * Equality comparison operator to a
272  * reference_counted_ptr value.
273  * \tparam U type where U* is implicitely comparable to a T*.
274  * \param rhs value with which to compare against
275  */
276  template<typename U>
277  bool
279  {
280  return m_p == rhs.get();
281  }
282 
283  /*!
284  * Inequality comparison operator to a pointer value.
285  * \tparam U type where U* is implicitely comparable to a T*.
286  * \param rhs value with which to compare against
287  */
288  template<typename U>
289  bool
290  operator!=(U *rhs) const
291  {
292  return m_p != rhs;
293  }
294 
295  /*!
296  * Inequality comparison operator to
297  * a reference_counted_ptr value.
298  * \tparam U type where U* is implicitely comparable to a T*.
299  * \param rhs value with which to compare against
300  */
301  template<typename U>
302  bool
304  {
305  return m_p != rhs.get();
306  }
307 
308  /*!
309  * Comparison operator for sorting.
310  * \param rhs value with which to compare against
311  */
312  bool
314  {
315  return get() < rhs.get();
316  }
317 
318  /*!
319  * Clears the reference_counted_ptr object,
320  * equivalent to
321  * \code
322  * operator=(reference_counted_ptr());
323  * \endcode
324  */
325  void
326  clear(void)
327  {
328  if (m_p)
329  {
330  T::remove_reference(m_p);
331  m_p = nullptr;
332  }
333  }
334  /*!
335  * Perform static cast to down cast (uses static_cast internally).
336  * \tparam U type to which to cast
337  */
338  template<typename U>
340  static_cast_ptr(void) const
341  {
342  return static_cast<U*>(get());
343  }
344 
345  /*!
346  * Perform const cast to cast (uses const_cast internally).
347  * \tparam U type to which to cast
348  */
349  template<typename U>
351  const_cast_ptr(void) const
352  {
353  return const_cast<U*>(get());
354  }
355 
356  /*!
357  * Perform dynamic cast to down cast (uses dynamic_cast internally).
358  * \tparam U type to which to cast
359  */
360  template<typename U>
362  dynamic_cast_ptr(void) const
363  {
364  return dynamic_cast<U*>(get());
365  }
366 
367  private:
368  T *m_p;
369  };
370 
371  /*!
372  * Equality comparison operator
373  * \param lhs left hand side of operator
374  * \param rhs right hand side of operator
375  */
376  template<typename T, typename S>
377  inline
378  bool
379  operator==(T *lhs,
380  const reference_counted_ptr<S> &rhs)
381  {
382  return lhs == rhs.get();
383  }
384 
385  /*!
386  * Inequality comparison operator
387  * \param lhs left hand side of operator
388  * \param rhs right hand side of operator
389  */
390  template<typename T, typename S>
391  inline
392  bool
393  operator!=(T *lhs,
394  const reference_counted_ptr<S> &rhs)
395  {
396  return lhs != rhs.get();
397  }
398 
399  /*!
400  * swap() routine, equivalent to
401  * \code
402  * lhs.swap(rhs);
403  * \endcode
404  * \param lhs object to swap
405  * \param rhs object to swap
406  */
407  template<typename T>
408  inline
409  void
412  {
413  lhs.swap(rhs);
414  }
415 
416  /*!
417  * \brief
418  * Base class to use for reference counted objects,
419  * for using reference_counted_ptr. See also \ref reference_counted.
420  * Object deletion (when the reference count goes to zero) is performed
421  * via \ref FASTUIDRAWdelete. As a consequence of using \ref
422  * FASTUIDRAWdelete, objects must be created with \ref FASTUIDRAWnew.
423  *
424  * \tparam T object type that is reference counted
425  * \tparam Counter object type to perform reference counting.
426  *
427  * The type Counter must expose the methods:
428  * - void add_reference() to increment the counter
429  * - bool remove_reference() to decrement the counter and return true
430  * if the counter is zero after the decrement operation.
431  */
432  template<typename T, typename Counter>
434  {
435  public:
436  /*!
437  * Empty ctor.
438  */
440  {}
441 
442  virtual
444  {}
445 
446  /*!
447  * Adds a reference count to an object.
448  * \param p pointer to object to which to add reference count.
449  */
450  static
451  void
453  {
454  FASTUIDRAWassert(p);
455  p->m_counter.add_reference();
456  }
457 
458  /*!
459  * Removes a reference count to an object, if the reference
460  * count is 0, then deletes the object with \ref FASTUIDRAWdelete.
461  * \param p pointer to object from which to remove reference count.
462  */
463  static
464  void
466  {
467  FASTUIDRAWassert(p);
468  if (p->m_counter.remove_reference())
469  {
471  q = const_cast<reference_counted_base<T, Counter>*>(p);
472  FASTUIDRAWdelete(q);
473  }
474  }
475  private:
476  mutable Counter m_counter;
477  };
478 
479  /*!
480  * \brief
481  * Defines default reference counting base classes.
482  *
483  * See also reference_counted_base and reference_counted_ptr.
484  */
485  template<typename T>
487  {
488  public:
489  /*!
490  * \brief
491  * Typedef to reference counting which is NOT thread safe
492  */
494 
495  /*!
496  * \brief
497  * Typedef to reference counting which is thread safe by atomically
498  * adding and removing reference
499  */
501  };
502 
503  /*!
504  * \brief
505  * A common base class to use for resources that need to be saved opaquely
506  */
508  public reference_counted<resource_base>::concurrent
509  {
510  public:
511  virtual
512  ~resource_base()
513  {}
514  };
515 /*! @} */
516 
517 } //namespace fastuidraw
518 
519 #endif
bool operator!=(const reference_counted_ptr< U > &rhs) const
file fastuidraw_memory.hpp
reference_counted_base< T, reference_count_atomic > concurrent
Typedef to reference counting which is thread safe by atomically adding and removing reference...
Base class to use for reference counted objects, for using reference_counted_ptr. See also reference_...
reference_counted_ptr< U > static_cast_ptr(void) const
reference_counted_ptr(reference_counted_ptr &&obj)
all classes and functions of FastUIDraw are in the namespace fastuidraw.
Definition: colorstop.hpp:28
reference_counted_ptr< U > const_cast_ptr(void) const
static void add_reference(const reference_counted_base< T, Counter > *p)
A wrapper over a pointer to implement reference counting.
void swap(reference_counted_ptr &rhs)
bool operator<(const reference_counted_ptr &rhs) const
reference_counted_ptr< U > dynamic_cast_ptr(void) const
static void remove_reference(const reference_counted_base< T, Counter > *p)
file reference_count_atomic.hpp
file util.hpp
reference_counted_ptr(const reference_counted_ptr &obj)
reference_counted_ptr & operator=(const reference_counted_ptr &rhs)
reference_counted_base< T, reference_count_non_concurrent > non_concurrent
Typedef to reference counting which is NOT thread safe.
file reference_count_non_concurrent.hpp
reference_counted_ptr(const reference_counted_ptr< U > &obj)
reference_counted_ptr & operator=(T *rhs)
reference_counted_ptr & operator=(const reference_counted_ptr< U > &rhs)
A common base class to use for resources that need to be saved opaquely.
Defines default reference counting base classes.
#define FASTUIDRAWdelete(ptr)
reference_counted_ptr & operator=(reference_counted_ptr &&rhs)
Class for which copy ctor and assignment operator are private functions.
Definition: util.hpp:505
#define FASTUIDRAWassert(X)
Definition: util.hpp:99
bool operator==(const reference_counted_ptr< U > &rhs) const