BeeeOn Gateway  v2020.3.1-2-g6f737dc
Platform to interconnect the IoT world
GlibPtr.h
1 #pragma once
2 
3 #include <glib.h>
4 #include <gio/gio.h>
5 
6 #include <utility>
7 
8 #include <Poco/Exception.h>
9 
10 #include "bluetooth/GlibPtr.h"
11 
12 namespace BeeeOn {
13 
14 static inline gpointer g_object_ref_copy(gconstpointer src, gpointer)
15 {
16  return ::g_object_ref(const_cast<gpointer>(src));
17 }
18 
25 template <typename T>
26 class GlibPtr {
27 public:
28  GlibPtr();
29  GlibPtr(T* ptr);
30  GlibPtr(const GlibPtr& ptr);
31  GlibPtr(GlibPtr&& ptr);
32  ~GlibPtr();
33 
34  GlibPtr& operator =(T* ptr);
35  GlibPtr& operator =(const GlibPtr& ptr);
36  GlibPtr& operator =(GlibPtr&& ptr);
37  T* operator ->();
38  const T* operator ->() const;
39  T& operator *();
40  const T& operator *() const;
41  T* raw();
42  const T* raw() const;
43 
48  T** operator &();
49 
53  const T** operator &() const;
54  bool operator !() const;
55  bool isNull() const;
56 
57 protected:
58  void release();
59  void assign(T* ptr);
60 
61 private:
62  T* m_ptr;
63 };
64 
65 template <typename T>
67  m_ptr(nullptr)
68 {
69 }
70 
71 template <typename T>
72 GlibPtr<T>::GlibPtr(T* ptr):
73  m_ptr(ptr)
74 {
75 }
76 
77 template <typename T>
78 GlibPtr<T>::GlibPtr(const GlibPtr& ptr):
79  m_ptr(nullptr)
80 {
81  assign(ptr.m_ptr);
82 }
83 
84 
85 template <typename T>
86 GlibPtr<T>::GlibPtr(GlibPtr&& ptr):
87  m_ptr(nullptr)
88 {
89  std::swap(m_ptr, ptr.m_ptr);
90 }
91 
92 template <typename T>
93 GlibPtr<T>::~GlibPtr()
94 {
95  release();
96 }
97 
98 template <typename T>
99 GlibPtr<T>& GlibPtr<T>::operator =(T* ptr)
100 {
101  return (*this = GlibPtr<T>{ptr});
102 }
103 
104 template <typename T>
105 GlibPtr<T>& GlibPtr<T>::operator =(const GlibPtr& ptr)
106 {
107  if (ptr.m_ptr != m_ptr)
108  assign(ptr.m_ptr);
109 
110  return *this;
111 }
112 
113 template <typename T>
114 GlibPtr<T>& GlibPtr<T>::operator =(GlibPtr&& ptr)
115 {
116  std::swap(m_ptr, ptr.m_ptr);
117  return *this;
118 }
119 
120 template <typename T>
121 T* GlibPtr<T>::operator ->()
122 {
123  if (isNull())
124  throw Poco::NullPointerException(
125  "GlibPtr operator ->");
126 
127  return m_ptr;
128 }
129 
130 template <typename T>
131 const T* GlibPtr<T>::operator ->() const
132 {
133  if (isNull())
134  throw Poco::NullPointerException(
135  "GlibPtr const operator ->");
136 
137  return m_ptr;
138 }
139 
140 template <typename T>
141 T& GlibPtr<T>::operator *()
142 {
143  if (isNull())
144  throw Poco::NullPointerException(
145  "GlibPtr operator *");
146 
147  return *m_ptr;
148 }
149 
150 template <typename T>
151 const T& GlibPtr<T>::operator *() const
152 {
153  if (isNull())
154  throw Poco::NullPointerException(
155  "GlibPtr const operator *");
156 
157  return *m_ptr;
158 }
159 
160 template <typename T>
161 T* GlibPtr<T>::raw()
162 {
163  if (isNull())
164  throw Poco::NullPointerException(
165  "GlibPtr method raw");
166 
167  return m_ptr;
168 }
169 
170 template <typename T>
171 const T* GlibPtr<T>::raw() const
172 {
173  if (isNull())
174  throw Poco::NullPointerException(
175  "GlibPtr method const raw");
176 
177  return m_ptr;
178 }
179 
180 template <typename T>
182 {
183  if (isNull())
184  return &m_ptr;
185 
186  throw Poco::IllegalStateException(
187  "cannot dereference non-const non-null GlibPtr");
188 }
189 
190 template <typename T>
191 const T** GlibPtr<T>::operator &() const
192 {
193  return &m_ptr;
194 }
195 
196 template <typename T>
197 bool GlibPtr<T>::operator !() const
198 {
199  return isNull();
200 }
201 
202 template <typename T>
203 bool GlibPtr<T>::isNull() const
204 {
205  return m_ptr == nullptr;
206 }
207 
208 template <typename GO>
209 inline void GlibPtr<GO>::release()
210 {
211  g_clear_object(&m_ptr);
212 }
213 
214 template <typename GO>
215 inline void GlibPtr<GO>::assign(GO* ptr)
216 {
217  release();
218  if (ptr != nullptr)
219  m_ptr = reinterpret_cast<GO*>(::g_object_ref(ptr));
220 }
221 
222 template <>
223 inline void GlibPtr<GMainLoop>::release()
224 {
225  if (!isNull()) {
226  ::g_main_loop_unref(m_ptr);
227  m_ptr = nullptr;
228  }
229 }
230 
231 template <>
232 inline void GlibPtr<GMainLoop>::assign(GMainLoop* ptr)
233 {
234  release();
235  if (ptr != nullptr)
236  m_ptr = ::g_main_loop_ref(ptr);
237 }
238 
239 template <>
240 inline void GlibPtr<GError>::release()
241 {
242  ::g_clear_error(&m_ptr);
243 }
244 
245 template <>
246 inline void GlibPtr<GError>::assign(GError* ptr)
247 {
248  release();
249  if (ptr != nullptr)
250  m_ptr = ::g_error_copy(ptr);
251 }
252 
253 template <>
254 inline void GlibPtr<GList>::release()
255 {
256  if (!isNull()) {
257  ::g_list_free_full(m_ptr, g_object_unref);
258  m_ptr = nullptr;
259  }
260 }
261 
262 template <>
263 inline void GlibPtr<GList>::assign(GList* ptr)
264 {
265  release();
266  if (ptr != nullptr)
267  m_ptr = ::g_list_copy_deep(ptr, g_object_ref_copy, nullptr);
268 }
269 
270 template <>
271 inline void GlibPtr<GVariant>::release()
272 {
273  if (!isNull()) {
274  ::g_variant_unref(m_ptr);
275  m_ptr = nullptr;
276  }
277 }
278 
279 template <>
280 inline void GlibPtr<GVariant>::assign(GVariant* ptr)
281 {
282  release();
283  if (ptr != nullptr)
284  m_ptr = ::g_variant_ref(ptr);
285 }
286 
287 
288 }
The class is used to store the references to objects from the GLib library. It is also responsible fo...
Definition: GlibPtr.h:26
T ** operator&()
Returns reference of the m_ptr attribute.
Definition: GlibPtr.h:181