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
48#define WTF_DEFINE_GPTR_DELETER(typeName, deleterFunc) \
49    template<> struct GPtrDeleter<typeName> \
50    { \
51        void operator() (typeName* ptr) const \
52        { \
53            if (ptr) \
54                deleterFunc(ptr); \
55        } \
56    };
57
58FOR_EACH_GLIB_DELETER(WTF_DEFINE_GPTR_DELETER)
59#undef FOR_EACH_GLIB_DELETER
60
61template <typename T> class GUniqueOutPtr {
62    WTF_MAKE_NONCOPYABLE(GUniqueOutPtr);
63public:
64    GUniqueOutPtr()
65        : m_ptr(nullptr)
66    {
67    }
68
69    ~GUniqueOutPtr()
70    {
71        reset();
72    }
73
74    T*& outPtr()
75    {
76        reset();
77        return m_ptr;
78    }
79
80    GUniquePtr<T> release()
81    {
82        GUniquePtr<T> ptr(m_ptr);
83        m_ptr = nullptr;
84        return ptr;
85    }
86
87    T& operator*() const
88    {
89        ASSERT(m_ptr);
90        return *m_ptr;
91    }
92
93    T* operator->() const
94    {
95        ASSERT(m_ptr);
96        return m_ptr;
97    }
98
99    T* get() const { return m_ptr; }
100
101    bool operator!() const { return !m_ptr; }
102
103    // This conversion operator allows implicit conversion to bool but not to other integer types.
104    typedef T* GUniqueOutPtr::*UnspecifiedBoolType;
105    operator UnspecifiedBoolType() const { return m_ptr ? &GUniqueOutPtr::m_ptr : 0; }
106
107private:
108    void reset()
109    {
110        if (m_ptr) {
111            GUniquePtr<T> deletePtr(m_ptr);
112            m_ptr = nullptr;
113        }
114    }
115
116    T* m_ptr;
117};
118
119} // namespace WTF
120
121using WTF::GUniquePtr;
122using WTF::GUniqueOutPtr;
123
124#endif // USE(GLIB)
125
126#endif // GUniquePtr_h
127
128