MythTV master
quicksp.h
Go to the documentation of this file.
1#ifndef QUICKSP_H_
2#define QUICKSP_H_
3
4#include "mythmetaexp.h"
5
6struct NoLock
7{
8 void lock() {}
9 void unlock() {}
10};
11
12// TODO: implement for threads
13// If implemented for threads move the instance pointer to simple_ref_ptr
14// so simple access isn't synchronized.
16{
17 void lock() {}
18
19 void unlock() {}
20};
21
22// TODO: Get a real reference counted smart pointer in libmyth
23template <typename T, class Locker = NoLock>
25{
26 public:
27 simple_ref_ptr() : m_ref(nullptr)
28 {
29 }
30
32 : m_ref(new ref(ptr))
33 {
34 }
35
36 simple_ref_ptr(const simple_ref_ptr &rhs) : m_ref(nullptr)
37 {
38 *this = rhs;
39 }
40
42 {
43 unref();
44 }
45
46 // The first two lines of this function are the clang-tidy
47 // recommended solution to make a function properly handle
48 // self-assignment. No idea why clang-tidy doesn't recognize
49 // this, unless it has something to do with templates?
50 //
51 // NOLINTNEXTLINE(bugprone-unhandled-self-assignment,cert-oop54-cpp)
53 {
54 if (this == &rhs)
55 return *this;
56 rhs.m_ref->inc();
57 unref();
58 m_ref = rhs.m_ref;
59
60 return *this;
61 }
62
63 T *operator->() const
64 {
65 return get();
66 }
67
68 T &operator*() const
69 {
70 return *get();
71 }
72
73 T *get() const
74 {
75 if (m_ref) return m_ref->get();
76
77 return nullptr;
78 }
79
80 void reset(T *ptr)
81 {
82 unref();
83 m_ref = new ref(ptr);
84 }
85
86 using fake_bool = T *(simple_ref_ptr<T>::*)() const;
87
88 operator fake_bool() const
89 {
90 return m_ref == nullptr ? nullptr : &simple_ref_ptr<T>::get;
91 }
92
93 bool operator!() const
94 {
95 return m_ref == nullptr;
96 }
97
98 private:
99 class ref : public Locker
100 {
101 public:
102 explicit ref(T *ptr) : m_type(ptr) {}
103
105 {
106 delete m_type;
107 }
108
109 unsigned int inc()
110 {
111 this->lock();
112 ++m_count;
113 this->unlock();
114 return m_count;
115 }
116
117 unsigned int dec()
118 {
119 this->lock();
120 --m_count;
121 this->unlock();
122 return m_count;
123 }
124
125 T *get()
126 {
127 return m_type;
128 }
129
130 T *get() const
131 {
132 return m_type;
133 }
134
135 private:
136 unsigned int m_count {1};
138 };
139
140 void unref()
141 {
142 if (m_ref && m_ref->dec() <= 0)
143 {
144 delete m_ref;
145 m_ref = nullptr;
146 }
147 }
148
149 private:
151};
152
153template <typename T>
155{
156 return lhs.get() == rhs.get();
157}
158
159template <typename T>
161{
162 return lhs.get() != rhs.get();
163}
164
165#endif // QUICKSP_H_
unsigned int m_count
Definition: quicksp.h:136
T * get() const
Definition: quicksp.h:130
unsigned int inc()
Definition: quicksp.h:109
unsigned int dec()
Definition: quicksp.h:117
bool operator!() const
Definition: quicksp.h:93
T * operator->() const
Definition: quicksp.h:63
T & operator*() const
Definition: quicksp.h:68
simple_ref_ptr & operator=(const simple_ref_ptr &rhs)
Definition: quicksp.h:52
simple_ref_ptr()
Definition: quicksp.h:27
simple_ref_ptr(const simple_ref_ptr &rhs)
Definition: quicksp.h:36
~simple_ref_ptr()
Definition: quicksp.h:41
void unref()
Definition: quicksp.h:140
T * get() const
Definition: quicksp.h:73
void reset(T *ptr)
Definition: quicksp.h:80
simple_ref_ptr(T *ptr)
Definition: quicksp.h:31
ref * m_ref
Definition: quicksp.h:150
T *(simple_ref_ptr< T >::*)() const fake_bool
Definition: quicksp.h:86
bool operator==(const simple_ref_ptr< T > &lhs, const simple_ref_ptr< T > &rhs)
Definition: quicksp.h:154
bool operator!=(const simple_ref_ptr< T > &lhs, const simple_ref_ptr< T > &rhs)
Definition: quicksp.h:160
Definition: quicksp.h:7
void unlock()
Definition: quicksp.h:9
void lock()
Definition: quicksp.h:8
void unlock()
Definition: quicksp.h:19
void lock()
Definition: quicksp.h:17