21a8fe954c401cac8c230c658ceee68a0c2a2291
[WebKit-https.git] / Source / WTF / wtf / OSObjectPtr.h
1 /*
2  * Copyright (C) 2014-2018 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #pragma once
27
28 #include <os/object.h>
29 #include <wtf/Assertions.h>
30 #include <wtf/StdLibExtras.h>
31
32 namespace WTF {
33
34 template<typename T> class OSObjectPtr;
35 template<typename T> OSObjectPtr<T> adoptOSObject(T);
36
37 template<typename T>
38 static inline void retainOSObject(T ptr)
39 {
40 #if defined(__OBJC__) && __has_feature(objc_arc)
41     UNUSED_PARAM(ptr);
42 #else
43     os_retain(ptr);
44 #endif
45 }
46
47 template<typename T>
48 static inline void releaseOSObject(T ptr)
49 {
50 #if defined(__OBJC__) && __has_feature(objc_arc)
51     UNUSED_PARAM(ptr);
52 #else
53     os_release(ptr);
54 #endif
55 }
56
57 template<typename T> class OSObjectPtr {
58 public:
59     OSObjectPtr()
60         : m_ptr(nullptr)
61     {
62     }
63
64     ~OSObjectPtr()
65     {
66         if (m_ptr)
67             releaseOSObject(m_ptr);
68     }
69
70     T get() const { return m_ptr; }
71
72     explicit operator bool() const { return m_ptr; }
73     bool operator!() const { return !m_ptr; }
74
75     OSObjectPtr(const OSObjectPtr& other)
76         : m_ptr(other.m_ptr)
77     {
78         if (m_ptr)
79             retainOSObject(m_ptr);
80     }
81
82     OSObjectPtr(OSObjectPtr&& other)
83         : m_ptr(other.m_ptr)
84     {
85         other.m_ptr = nullptr;
86     }
87
88     OSObjectPtr(T ptr)
89         : m_ptr(ptr)
90     {
91         if (m_ptr)
92             retainOSObject(m_ptr);
93     }
94
95     OSObjectPtr& operator=(const OSObjectPtr& other)
96     {
97         OSObjectPtr ptr = other;
98         swap(ptr);
99         return *this;
100     }
101
102     OSObjectPtr& operator=(OSObjectPtr&& other)
103     {
104         OSObjectPtr ptr = WTFMove(other);
105         swap(ptr);
106         return *this;
107     }
108
109     OSObjectPtr& operator=(std::nullptr_t)
110     {
111         if (m_ptr)
112             releaseOSObject(m_ptr);
113         m_ptr = nullptr;
114
115         return *this;
116     }
117
118     OSObjectPtr& operator=(T other)
119     {
120         OSObjectPtr ptr = other;
121         swap(ptr);
122         return *this;
123     }
124
125     void swap(OSObjectPtr& other)
126     {
127         std::swap(m_ptr, other.m_ptr);
128     }
129
130     T leakRef() WARN_UNUSED_RETURN
131     {
132         return std::exchange(m_ptr, nullptr);
133     }
134
135     friend OSObjectPtr adoptOSObject<T>(T);
136
137 private:
138     struct AdoptOSObject { };
139     OSObjectPtr(AdoptOSObject, T ptr)
140         : m_ptr(ptr)
141     {
142     }
143
144     T m_ptr;
145 };
146
147 template<typename T> inline OSObjectPtr<T> adoptOSObject(T ptr)
148 {
149     return OSObjectPtr<T>(typename OSObjectPtr<T>::AdoptOSObject { }, ptr);
150 }
151
152 } // namespace WTF
153
154 using WTF::OSObjectPtr;
155 using WTF::adoptOSObject;