Pioneer
SmartPtr.h
Go to the documentation of this file.
1 // Copyright © 2008-2023 Pioneer Developers. See AUTHORS.txt for details
2 // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt
3 
4 #ifndef _SMARTPTR_H
5 #define _SMARTPTR_H
6 
7 #include <cassert>
8 #include <cstddef> // for ptrdiff_t
9 #include <cstdlib> // for free()
10 
11 #ifdef __GNUC__
12 #define WARN_UNUSED_RESULT(ret, decl) ret decl __attribute__((warn_unused_result))
13 #else
14 #define WARN_UNUSED_RESULT(ret, decl) ret decl
15 #endif
16 
17 template <typename Derived, typename T>
18 class SmartPtrBase {
20  typedef T *this_type::*safe_bool;
21 
22 public:
23  // copy & swap idiom
24  // see http://stackoverflow.com/questions/3279543/what-is-the-copy-and-swap-idiom
25  void Reset(T *p = 0) { Derived(p).Swap(*static_cast<Derived *>(this)); }
26 
27  T &operator*() const
28  {
29  assert(m_ptr);
30  return *m_ptr;
31  }
32  T *operator->() const
33  {
34  assert(m_ptr);
35  return m_ptr;
36  }
37  T *Get() const { return m_ptr; }
38  bool Valid() const { return (m_ptr != 0); }
39 
40  // safe bool idiom; see http://www.artima.com/cppsource/safebool.html
41  operator safe_bool() const { return (m_ptr == 0) ? 0 : &this_type::m_ptr; }
42  bool operator!() const { return (m_ptr == 0); }
43 
44  friend void swap(this_type &a, this_type &b) { a.Swap(b); }
45 
46  void Swap(this_type &b)
47  {
48  T *p = m_ptr;
49  m_ptr = b.m_ptr;
50  b.m_ptr = p;
51  }
52 
53  // comparisons directly with T* have to be defined here, because
54  // if comparing with literal 0 (null pointer), the compiler can't
55  // deduce the second pointer type for the more general templated
56  // comparisons that are written to work on any <T1,T2> pair
57  friend bool operator==(const this_type &a, const T *b) { return (a.Get() == b); }
58  friend bool operator!=(const this_type &a, const T *b) { return (a.Get() != b); }
59  friend bool operator<(const this_type &a, const T *b) { return (a.Get() < b); }
60  friend bool operator<=(const this_type &a, const T *b) { return (a.Get() <= b); }
61  friend bool operator>(const this_type &a, const T *b) { return (a.Get() > b); }
62  friend bool operator>=(const this_type &a, const T *b) { return (a.Get() >= b); }
63 
64  friend bool operator==(const T *a, const this_type &b) { return (a == b.Get()); }
65  friend bool operator!=(const T *a, const this_type &b) { return (a != b.Get()); }
66  friend bool operator<(const T *a, const this_type &b) { return (a < b.Get()); }
67  friend bool operator<=(const T *a, const this_type &b) { return (a <= b.Get()); }
68  friend bool operator>(const T *a, const this_type &b) { return (a > b.Get()); }
69  friend bool operator>=(const T *a, const this_type &b) { return (a >= b.Get()); }
70 
71 protected:
73  m_ptr(0) {}
74  explicit SmartPtrBase(T *p) :
75  m_ptr(p) {}
76 
77  // Release() doesn't make sense for all smart pointer types
78  // (e.g., RefCountedPtr can't Release, it can only Reset)
79  WARN_UNUSED_RESULT(T *, Release())
80  {
81  T *p = m_ptr;
82  m_ptr = 0;
83  return p;
84  }
85 
86  T *m_ptr;
87 };
88 
89 #define DEF_SMARTPTR_COMPARISON(op) \
90  template <typename D1, typename T1, typename D2, typename T2> \
91  inline bool operator op(const SmartPtrBase<D1, T1> &a, const SmartPtrBase<D2, T2> &b) \
92  { \
93  return (a.Get() op b.Get()); \
94  } \
95  template <typename D, typename T1, typename T2> \
96  inline bool operator op(const SmartPtrBase<D, T1> &a, const T2 *b) \
97  { \
98  return (a.Get() op b); \
99  } \
100  template <typename D, typename T1, typename T2> \
101  inline bool operator op(const T1 *a, const SmartPtrBase<D, T2> &b) \
102  { \
103  return (a op b.Get()); \
104  }
111 #undef DEF_SMARTPTR_COMPARISON
112 
113 // a deleter type for use with std::unique_ptr
114 struct FreeDeleter {
115  void operator()(void *p) { std::free(p); }
116 };
117 
118 #endif
#define WARN_UNUSED_RESULT(ret, decl)
Definition: SmartPtr.h:14
#define DEF_SMARTPTR_COMPARISON(op)
Definition: SmartPtr.h:89
Definition: SmartPtr.h:18
m_ptr
Definition: SmartPtr.h:82
friend bool operator==(const this_type &a, const T *b)
Definition: SmartPtr.h:57
bool Valid() const
Definition: SmartPtr.h:38
return p
Definition: SmartPtr.h:83
friend void swap(this_type &a, this_type &b)
Definition: SmartPtr.h:44
SmartPtrBase()
Definition: SmartPtr.h:72
T * operator->() const
Definition: SmartPtr.h:32
friend bool operator==(const T *a, const this_type &b)
Definition: SmartPtr.h:64
T * Get() const
Definition: SmartPtr.h:37
friend bool operator<(const this_type &a, const T *b)
Definition: SmartPtr.h:59
friend bool operator>(const this_type &a, const T *b)
Definition: SmartPtr.h:61
friend bool operator<=(const this_type &a, const T *b)
Definition: SmartPtr.h:60
T & operator*() const
Definition: SmartPtr.h:27
friend bool operator>=(const this_type &a, const T *b)
Definition: SmartPtr.h:62
SmartPtrBase(T *p)
Definition: SmartPtr.h:74
friend bool operator!=(const T *a, const this_type &b)
Definition: SmartPtr.h:65
friend bool operator>(const T *a, const this_type &b)
Definition: SmartPtr.h:68
bool operator!() const
Definition: SmartPtr.h:42
void Reset(T *p=0)
Definition: SmartPtr.h:25
friend bool operator<(const T *a, const this_type &b)
Definition: SmartPtr.h:66
friend bool operator<=(const T *a, const this_type &b)
Definition: SmartPtr.h:67
friend bool operator>=(const T *a, const this_type &b)
Definition: SmartPtr.h:69
T * m_ptr
Definition: SmartPtr.h:86
friend bool operator!=(const this_type &a, const T *b)
Definition: SmartPtr.h:58
void Swap(this_type &b)
Definition: SmartPtr.h:46
Definition: SmartPtr.h:114
void operator()(void *p)
Definition: SmartPtr.h:115