added iOS source code
[wl-app.git] / iOS / Pods / Realm / include / core / realm / impl / destroy_guard.hpp
1 /*************************************************************************
2  *
3  * Copyright 2016 Realm Inc.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  **************************************************************************/
18
19 #ifndef REALM_IMPL_DESTROY_GUARD_HPP
20 #define REALM_IMPL_DESTROY_GUARD_HPP
21
22 #include <realm/util/features.h>
23 #include <realm/array.hpp>
24
25 namespace realm {
26 namespace _impl {
27
28
29 /// Calls `ptr->destroy()` if the guarded pointer (`ptr`) is not null
30 /// when the guard is destroyed. For arrays (`T` = `Array`) this means
31 /// that the array is destroyed in a shallow fashion. See
32 /// `DeepArrayDestroyGuard` for an alternative.
33 template <class T>
34 class DestroyGuard {
35 public:
36     DestroyGuard() noexcept;
37
38     DestroyGuard(T*) noexcept;
39
40     ~DestroyGuard() noexcept;
41
42     // Default implementations of copy/assign can trigger multiple destructions
43     DestroyGuard(const DestroyGuard&) = delete;
44     DestroyGuard& operator=(const DestroyGuard&) = delete;
45
46     void reset(T*) noexcept;
47
48     T* get() const noexcept;
49
50     T* release() noexcept;
51
52 private:
53     T* m_ptr;
54 };
55
56 using ShallowArrayDestroyGuard = DestroyGuard<Array>;
57
58
59 /// Calls `ptr->destroy_deep()` if the guarded Array pointer (`ptr`)
60 /// is not null when the guard is destroyed.
61 class DeepArrayDestroyGuard {
62 public:
63     DeepArrayDestroyGuard() noexcept;
64
65     DeepArrayDestroyGuard(Array*) noexcept;
66
67     ~DeepArrayDestroyGuard() noexcept;
68
69     // Default implementations of copy/assign can trigger multiple destructions
70     DeepArrayDestroyGuard(const DeepArrayDestroyGuard&) = delete;
71     DeepArrayDestroyGuard& operator=(const DeepArrayDestroyGuard&) = delete;
72
73     void reset(Array*) noexcept;
74
75     Array* get() const noexcept;
76
77     Array* release() noexcept;
78
79 private:
80     Array* m_ptr;
81 };
82
83
84 /// Calls `Array::destroy_deep(ref, alloc)` if the guarded 'ref'
85 /// (`ref`) is not zero when the guard is destroyed.
86 class DeepArrayRefDestroyGuard {
87 public:
88     DeepArrayRefDestroyGuard(Allocator&) noexcept;
89
90     DeepArrayRefDestroyGuard(ref_type, Allocator&) noexcept;
91
92     ~DeepArrayRefDestroyGuard() noexcept;
93
94     // Default implementations of copy/assign can trigger multiple destructions
95     DeepArrayRefDestroyGuard(const DeepArrayRefDestroyGuard&) = delete;
96     DeepArrayRefDestroyGuard& operator=(const DeepArrayRefDestroyGuard&) = delete;
97
98     void reset(ref_type) noexcept;
99
100     ref_type get() const noexcept;
101
102     ref_type release() noexcept;
103
104 private:
105     ref_type m_ref;
106     Allocator& m_alloc;
107 };
108
109
110 // Implementation:
111
112 // DestroyGuard<T>
113
114 template <class T>
115 inline DestroyGuard<T>::DestroyGuard() noexcept
116     : m_ptr(nullptr)
117 {
118 }
119
120 template <class T>
121 inline DestroyGuard<T>::DestroyGuard(T* ptr) noexcept
122     : m_ptr(ptr)
123 {
124 }
125
126 template <class T>
127 inline DestroyGuard<T>::~DestroyGuard() noexcept
128 {
129     if (m_ptr)
130         m_ptr->destroy();
131 }
132
133 template <class T>
134 inline void DestroyGuard<T>::reset(T* ptr) noexcept
135 {
136     if (m_ptr)
137         m_ptr->destroy();
138     m_ptr = ptr;
139 }
140
141 template <class T>
142 inline T* DestroyGuard<T>::get() const noexcept
143 {
144     return m_ptr;
145 }
146
147 template <class T>
148 inline T* DestroyGuard<T>::release() noexcept
149 {
150     T* ptr = m_ptr;
151     m_ptr = nullptr;
152     return ptr;
153 }
154
155
156 // DeepArrayDestroyGuard
157
158 inline DeepArrayDestroyGuard::DeepArrayDestroyGuard() noexcept
159     : m_ptr(nullptr)
160 {
161 }
162
163 inline DeepArrayDestroyGuard::DeepArrayDestroyGuard(Array* ptr) noexcept
164     : m_ptr(ptr)
165 {
166 }
167
168 inline DeepArrayDestroyGuard::~DeepArrayDestroyGuard() noexcept
169 {
170     if (m_ptr)
171         m_ptr->destroy_deep();
172 }
173
174 inline void DeepArrayDestroyGuard::reset(Array* ptr) noexcept
175 {
176     if (m_ptr)
177         m_ptr->destroy_deep();
178     m_ptr = ptr;
179 }
180
181 inline Array* DeepArrayDestroyGuard::get() const noexcept
182 {
183     return m_ptr;
184 }
185
186 inline Array* DeepArrayDestroyGuard::release() noexcept
187 {
188     Array* ptr = m_ptr;
189     m_ptr = nullptr;
190     return ptr;
191 }
192
193
194 // DeepArrayRefDestroyGuard
195
196 inline DeepArrayRefDestroyGuard::DeepArrayRefDestroyGuard(Allocator& alloc) noexcept
197     : m_ref(0)
198     , m_alloc(alloc)
199 {
200 }
201
202 inline DeepArrayRefDestroyGuard::DeepArrayRefDestroyGuard(ref_type ref, Allocator& alloc) noexcept
203     : m_ref(ref)
204     , m_alloc(alloc)
205 {
206 }
207
208 inline DeepArrayRefDestroyGuard::~DeepArrayRefDestroyGuard() noexcept
209 {
210     if (m_ref)
211         Array::destroy_deep(m_ref, m_alloc);
212 }
213
214 inline void DeepArrayRefDestroyGuard::reset(ref_type ref) noexcept
215 {
216     if (m_ref)
217         Array::destroy_deep(m_ref, m_alloc);
218     m_ref = ref;
219 }
220
221 inline ref_type DeepArrayRefDestroyGuard::get() const noexcept
222 {
223     return m_ref;
224 }
225
226 inline ref_type DeepArrayRefDestroyGuard::release() noexcept
227 {
228     ref_type ref = m_ref;
229     m_ref = 0;
230     return ref;
231 }
232
233
234 } // namespace _impl
235 } // namespace realm
236
237 #endif // REALM_IMPL_DESTROY_GUARD_HPP