1/*
2 * Copyright (C) 2014 Igalia S.L.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public License
15 * along with this library; see the file COPYING.LIB. If not, write to
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 *
19 */
20
21#ifndef GUniquePtr_h
22#define GUniquePtr_h
23
24#if USE(GLIB)
25
26#include <gio/gio.h>
27#include <wtf/Noncopyable.h>
28
29namespace WTF {
30
31template<typename T>
32struct GPtrDeleter {
33 void operator()(T* ptr) const { g_free(ptr); }
34};
35
36template<typename T>
37using GUniquePtr = std::unique_ptr<T, GPtrDeleter<T>>;
38
39#define FOR_EACH_GLIB_DELETER(macro) \
40 macro(GError, g_error_free) \
41 macro(GList, g_list_free) \
42 macro(GSList, g_slist_free) \
43 macro(GPatternSpec, g_pattern_spec_free) \
44 macro(GDir, g_dir_close) \
45 macro(GTimer, g_timer_destroy) \
46 macro(GKeyFile, g_key_file_free) \
47 macro(char*, g_strfreev) \
48 macro(GVariantIter, g_variant_iter_free)
49
50#define WTF_DEFINE_GPTR_DELETER(typeName, deleterFunc) \
51 template<> struct GPtrDeleter<typeName> \
52 { \
53 void operator() (typeName* ptr) const \
54 { \
55 deleterFunc(ptr); \
56 } \
57 };
58
59FOR_EACH_GLIB_DELETER(WTF_DEFINE_GPTR_DELETER)
60#undef FOR_EACH_GLIB_DELETER
61
62template <typename T> class GUniqueOutPtr {
63 WTF_MAKE_NONCOPYABLE(GUniqueOutPtr);
64public:
65 GUniqueOutPtr()
66 : m_ptr(nullptr)
67 {
68 }
69
70 ~GUniqueOutPtr()
71 {
72 reset();
73 }
74
75 T*& outPtr()
76 {
77 reset();
78 return m_ptr;
79 }
80
81 GUniquePtr<T> release()
82 {
83 GUniquePtr<T> ptr(m_ptr);
84 m_ptr = nullptr;
85 return ptr;
86 }
87
88 T& operator*() const
89 {
90 ASSERT(m_ptr);
91 return *m_ptr;
92 }
93
94 T* operator->() const
95 {
96 ASSERT(m_ptr);
97 return m_ptr;
98 }
99
100 T* get() const { return m_ptr; }
101
102 bool operator!() const { return !m_ptr; }
103
104 // This conversion operator allows implicit conversion to bool but not to other integer types.
105 typedef T* GUniqueOutPtr::*UnspecifiedBoolType;
106 operator UnspecifiedBoolType() const { return m_ptr ? &GUniqueOutPtr::m_ptr : 0; }
107
108private:
109 void reset()
110 {
111 if (m_ptr) {
112 GUniquePtr<T> deletePtr(m_ptr);
113 m_ptr = nullptr;
114 }
115 }
116
117 T* m_ptr;
118};
119
120} // namespace WTF
121
122using WTF::GUniquePtr;
123using WTF::GUniqueOutPtr;
124
125#endif // USE(GLIB)
126
127#endif // GUniquePtr_h
128
129