My Project
Loading...
Searching...
No Matches
GlibMemory.h
1/*
2 * Copyright (C) 2017 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License version 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Pete Woods <pete.woods@canonical.com>
17 * Michi Henning <michi.henning@canonical.com>
18 * James Henstridge <james.henstridge@canonical.com>
19 */
20
21#ifndef UNITY_UTIL_GLIBMEMORY_H
22#define UNITY_UTIL_GLIBMEMORY_H
23
24#include <memory>
25#include <glib.h>
26
27#include <unity/util/ResourcePtr.h>
28
29namespace unity
30{
31
32namespace util
33{
34
35namespace internal
36{
37
38template<typename T> struct GlibDeleter;
39template<typename T> using GlibSPtr = std::shared_ptr<T>;
40template<typename T> using GlibUPtr = std::unique_ptr<T, GlibDeleter<T>>;
41
51template<typename SP>
52class GlibAssigner
53{
54public:
55 typedef typename SP::element_type ElementType;
56
57 GlibAssigner(SP& smart_ptr) noexcept :
58 smart_ptr_(smart_ptr)
59 {
60 }
61
62 GlibAssigner(const GlibAssigner& other) = delete;
63
64 GlibAssigner(GlibAssigner&& other) noexcept:
65 ptr_(other.ptr_), smart_ptr_(other.smart_ptr_)
66 {
67 other.ptr_ = nullptr;
68 }
69
70 ~GlibAssigner() noexcept
71 {
72 smart_ptr_ = SP(ptr_, GlibDeleter<ElementType>());
73 }
74
75 GlibAssigner& operator=(const GlibAssigner& other) = delete;
76
77 operator ElementType**() noexcept
78 {
79 return &ptr_;
80 }
81
82private:
83 ElementType* ptr_ = nullptr;
84
85 SP& smart_ptr_;
86};
87
88struct GSourceUnsubscriber
89{
90 void operator()(guint tag) noexcept
91 {
92 if (tag != 0)
93 {
94 g_source_remove(tag);
95 }
96 }
97};
98
99}
100
101#define UNITY_UTIL_DEFINE_GLIB_SMART_POINTERS(TypeName, func) \
102using TypeName##Deleter = internal::GlibDeleter<TypeName>; \
103using TypeName##SPtr = internal::GlibSPtr<TypeName>; \
104using TypeName##UPtr = internal::GlibUPtr<TypeName>; \
105namespace internal \
106{ \
107template<> struct GlibDeleter<TypeName> \
108{ \
109 void operator()(TypeName* ptr) noexcept \
110 { \
111 if (ptr) \
112 { \
113 ::func(ptr); \
114 } \
115 } \
116}; \
117}
118
127template<typename T>
128inline internal::GlibSPtr<T> share_glib(T* ptr) noexcept
129{
130 return internal::GlibSPtr<T>(ptr, internal::GlibDeleter<T>());
131}
132
141template<typename T>
142inline internal::GlibUPtr<T> unique_glib(T* ptr) noexcept
143{
144 return internal::GlibUPtr<T>(ptr, internal::GlibDeleter<T>());
145}
146
166template<typename SP>
167inline internal::GlibAssigner<SP> assign_glib(SP& smart_ptr) noexcept
168{
169 return internal::GlibAssigner<SP>(smart_ptr);
170}
171
172using GSourceManager = ResourcePtr<guint, internal::GSourceUnsubscriber>;
173
182inline GSourceManager g_source_manager(guint id)
183{
184 return GSourceManager(id, internal::GSourceUnsubscriber());
185}
186
190#pragma push_macro("G_DEFINE_AUTOPTR_CLEANUP_FUNC")
191#undef G_DEFINE_AUTOPTR_CLEANUP_FUNC
192#define G_DEFINE_AUTOPTR_CLEANUP_FUNC(TypeName, func) UNITY_UTIL_DEFINE_GLIB_SMART_POINTERS(TypeName, func)
193
194#pragma push_macro("G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC")
195#undef G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC
196#define G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(TypeName, func)
197
198#pragma push_macro("G_DEFINE_AUTO_CLEANUP_FREE_FUNC")
199#undef G_DEFINE_AUTO_CLEANUP_FREE_FUNC
200#define G_DEFINE_AUTO_CLEANUP_FREE_FUNC(TypeName, func, none)
201
202#define __GLIB_H_INSIDE__
203#include <glib/glib-autocleanups.h>
204#undef __GLIB_H_INSIDE__
205
206#pragma pop_macro("G_DEFINE_AUTOPTR_CLEANUP_FUNC")
207#pragma pop_macro("G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC")
208#pragma pop_macro("G_DEFINE_AUTO_CLEANUP_FREE_FUNC")
209
213#if GLIB_CHECK_VERSION(2, 57, 2)
214typedef GRefStringSPtr gcharSPtr;
215typedef GRefStringUPtr gcharUPtr;
216#else
217UNITY_UTIL_DEFINE_GLIB_SMART_POINTERS(gchar, g_free)
218#endif
219typedef gchar* gcharv;
220UNITY_UTIL_DEFINE_GLIB_SMART_POINTERS(gcharv, g_strfreev)
221
222} // namespace until
223
224} // namespace unity
225
226#endif
Top-level namespace for all things Unity-related.
Definition Version.h:38