Mercurial > hg > pub > prymula > com
comparison DPF-Prymula-audioplugins/dpf/distrho/extra/ScopedPointer.hpp @ 3:84e66ea83026
DPF-Prymula-audioplugins-0.231015-2
author | prymula <prymula76@outlook.com> |
---|---|
date | Mon, 16 Oct 2023 21:53:34 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
2:cf2cb71d31dd | 3:84e66ea83026 |
---|---|
1 /* | |
2 * DISTRHO Plugin Framework (DPF) | |
3 * Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com> | |
4 * | |
5 * Permission to use, copy, modify, and/or distribute this software for any purpose with | |
6 * or without fee is hereby granted, provided that the above copyright notice and this | |
7 * permission notice appear in all copies. | |
8 * | |
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD | |
10 * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN | |
11 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL | |
12 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER | |
13 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | |
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
15 */ | |
16 | |
17 #ifndef DISTRHO_SCOPED_POINTER_HPP_INCLUDED | |
18 #define DISTRHO_SCOPED_POINTER_HPP_INCLUDED | |
19 | |
20 #include "../DistrhoUtils.hpp" | |
21 | |
22 #include <algorithm> | |
23 | |
24 START_NAMESPACE_DISTRHO | |
25 | |
26 // ----------------------------------------------------------------------- | |
27 // The following code was based from juce-core ScopedPointer class | |
28 | |
29 /** | |
30 Copyright (C) 2013 Raw Material Software Ltd. | |
31 | |
32 Permission is granted to use this software under the terms of the ISC license | |
33 http://www.isc.org/downloads/software-support-policy/isc-license/ | |
34 | |
35 Permission to use, copy, modify, and/or distribute this software for any | |
36 purpose with or without fee is hereby granted, provided that the above | |
37 copyright notice and this permission notice appear in all copies. | |
38 | |
39 THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH REGARD | |
40 TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND | |
41 FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, | |
42 OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF | |
43 USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER | |
44 TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE | |
45 OF THIS SOFTWARE. | |
46 */ | |
47 | |
48 //============================================================================== | |
49 /** | |
50 This class holds a pointer which is automatically deleted when this object goes | |
51 out of scope. | |
52 | |
53 Once a pointer has been passed to a ScopedPointer, it will make sure that the pointer | |
54 gets deleted when the ScopedPointer is deleted. Using the ScopedPointer on the stack or | |
55 as member variables is a good way to use RAII to avoid accidentally leaking dynamically | |
56 created objects. | |
57 | |
58 A ScopedPointer can be used in pretty much the same way that you'd use a normal pointer | |
59 to an object. If you use the assignment operator to assign a different object to a | |
60 ScopedPointer, the old one will be automatically deleted. | |
61 | |
62 A const ScopedPointer is guaranteed not to lose ownership of its object or change the | |
63 object to which it points during its lifetime. This means that making a copy of a const | |
64 ScopedPointer is impossible, as that would involve the new copy taking ownership from the | |
65 old one. | |
66 | |
67 If you need to get a pointer out of a ScopedPointer without it being deleted, you | |
68 can use the release() method. | |
69 | |
70 Something to note is the main difference between this class and the std::auto_ptr class, | |
71 which is that ScopedPointer provides a cast-to-object operator, wheras std::auto_ptr | |
72 requires that you always call get() to retrieve the pointer. The advantages of providing | |
73 the cast is that you don't need to call get(), so can use the ScopedPointer in pretty much | |
74 exactly the same way as a raw pointer. The disadvantage is that the compiler is free to | |
75 use the cast in unexpected and sometimes dangerous ways - in particular, it becomes difficult | |
76 to return a ScopedPointer as the result of a function. To avoid this causing errors, | |
77 ScopedPointer contains an overloaded constructor that should cause a syntax error in these | |
78 circumstances, but it does mean that instead of returning a ScopedPointer from a function, | |
79 you'd need to return a raw pointer (or use a std::auto_ptr instead). | |
80 */ | |
81 template<class ObjectType> | |
82 class ScopedPointer | |
83 { | |
84 public: | |
85 //============================================================================== | |
86 /** Creates a ScopedPointer containing a null pointer. */ | |
87 ScopedPointer() noexcept | |
88 : object(nullptr) {} | |
89 | |
90 /** Creates a ScopedPointer that owns the specified object. */ | |
91 ScopedPointer(ObjectType* const objectToTakePossessionOf) noexcept | |
92 : object(objectToTakePossessionOf) {} | |
93 | |
94 /** Creates a ScopedPointer that takes its pointer from another ScopedPointer. | |
95 | |
96 Because a pointer can only belong to one ScopedPointer, this transfers | |
97 the pointer from the other object to this one, and the other object is reset to | |
98 be a null pointer. | |
99 */ | |
100 ScopedPointer(ScopedPointer& objectToTransferFrom) noexcept | |
101 : object(objectToTransferFrom.object) | |
102 { | |
103 objectToTransferFrom.object = nullptr; | |
104 } | |
105 | |
106 /** Destructor. | |
107 This will delete the object that this ScopedPointer currently refers to. | |
108 */ | |
109 ~ScopedPointer() | |
110 { | |
111 delete object; | |
112 } | |
113 | |
114 /** Changes this ScopedPointer to point to a new object. | |
115 | |
116 Because a pointer can only belong to one ScopedPointer, this transfers | |
117 the pointer from the other object to this one, and the other object is reset to | |
118 be a null pointer. | |
119 | |
120 If this ScopedPointer already points to an object, that object | |
121 will first be deleted. | |
122 */ | |
123 ScopedPointer& operator=(ScopedPointer& objectToTransferFrom) | |
124 { | |
125 if (this != objectToTransferFrom.getAddress()) | |
126 { | |
127 // Two ScopedPointers should never be able to refer to the same object - if | |
128 // this happens, you must have done something dodgy! | |
129 DISTRHO_SAFE_ASSERT_RETURN(object == nullptr || object != objectToTransferFrom.object, *this); | |
130 | |
131 ObjectType* const oldObject = object; | |
132 object = objectToTransferFrom.object; | |
133 objectToTransferFrom.object = nullptr; | |
134 delete oldObject; | |
135 } | |
136 | |
137 return *this; | |
138 } | |
139 | |
140 /** Changes this ScopedPointer to point to a new object. | |
141 | |
142 If this ScopedPointer already points to an object, that object | |
143 will first be deleted. | |
144 | |
145 The pointer that you pass in may be a nullptr. | |
146 */ | |
147 ScopedPointer& operator=(ObjectType* const newObjectToTakePossessionOf) | |
148 { | |
149 if (object != newObjectToTakePossessionOf) | |
150 { | |
151 ObjectType* const oldObject = object; | |
152 object = newObjectToTakePossessionOf; | |
153 delete oldObject; | |
154 } | |
155 | |
156 return *this; | |
157 } | |
158 | |
159 //============================================================================== | |
160 /** Returns the object that this ScopedPointer refers to. */ | |
161 operator ObjectType*() const noexcept { return object; } | |
162 | |
163 /** Returns the object that this ScopedPointer refers to. */ | |
164 ObjectType* get() const noexcept { return object; } | |
165 | |
166 /** Returns the object that this ScopedPointer refers to. */ | |
167 ObjectType& getObject() const noexcept { return *object; } | |
168 | |
169 /** Returns the object that this ScopedPointer refers to. */ | |
170 ObjectType& operator*() const noexcept { return *object; } | |
171 | |
172 /** Lets you access methods and properties of the object that this ScopedPointer refers to. */ | |
173 ObjectType* operator->() const noexcept { return object; } | |
174 | |
175 //============================================================================== | |
176 /** Removes the current object from this ScopedPointer without deleting it. | |
177 This will return the current object, and set the ScopedPointer to a null pointer. | |
178 */ | |
179 ObjectType* release() noexcept { ObjectType* const o = object; object = nullptr; return o; } | |
180 | |
181 //============================================================================== | |
182 /** Swaps this object with that of another ScopedPointer. | |
183 The two objects simply exchange their pointers. | |
184 */ | |
185 void swapWith(ScopedPointer<ObjectType>& other) noexcept | |
186 { | |
187 // Two ScopedPointers should never be able to refer to the same object - if | |
188 // this happens, you must have done something dodgy! | |
189 DISTRHO_SAFE_ASSERT_RETURN(object != other.object || this == other.getAddress() || object == nullptr,); | |
190 | |
191 std::swap(object, other.object); | |
192 } | |
193 | |
194 private: | |
195 //============================================================================== | |
196 ObjectType* object; | |
197 | |
198 // (Required as an alternative to the overloaded & operator). | |
199 const ScopedPointer* getAddress() const noexcept { return this; } | |
200 | |
201 #ifndef _MSC_VER // (MSVC can't deal with multiple copy constructors) | |
202 /* The copy constructors are private to stop people accidentally copying a const ScopedPointer | |
203 (the compiler would let you do so by implicitly casting the source to its raw object pointer). | |
204 | |
205 A side effect of this is that in a compiler that doesn't support C++11, you may hit an | |
206 error when you write something like this: | |
207 | |
208 ScopedPointer<MyClass> m = new MyClass(); // Compile error: copy constructor is private. | |
209 | |
210 Even though the compiler would normally ignore the assignment here, it can't do so when the | |
211 copy constructor is private. It's very easy to fix though - just write it like this: | |
212 | |
213 ScopedPointer<MyClass> m (new MyClass()); // Compiles OK | |
214 | |
215 It's probably best to use the latter form when writing your object declarations anyway, as | |
216 this is a better representation of the code that you actually want the compiler to produce. | |
217 */ | |
218 # ifdef DISTRHO_PROPER_CPP11_SUPPORT | |
219 ScopedPointer(const ScopedPointer&) = delete; | |
220 ScopedPointer& operator=(const ScopedPointer&) = delete; | |
221 # else | |
222 ScopedPointer(const ScopedPointer&); | |
223 ScopedPointer& operator=(const ScopedPointer&); | |
224 # endif | |
225 #endif | |
226 }; | |
227 | |
228 //============================================================================== | |
229 /** Compares a ScopedPointer with another pointer. | |
230 This can be handy for checking whether this is a null pointer. | |
231 */ | |
232 template<class ObjectType> | |
233 bool operator==(const ScopedPointer<ObjectType>& pointer1, ObjectType* const pointer2) noexcept | |
234 { | |
235 return static_cast<ObjectType*>(pointer1) == pointer2; | |
236 } | |
237 | |
238 /** Compares a ScopedPointer with another pointer. | |
239 This can be handy for checking whether this is a null pointer. | |
240 */ | |
241 template<class ObjectType> | |
242 bool operator!=(const ScopedPointer<ObjectType>& pointer1, ObjectType* const pointer2) noexcept | |
243 { | |
244 return static_cast<ObjectType*>(pointer1) != pointer2; | |
245 } | |
246 | |
247 // ----------------------------------------------------------------------- | |
248 | |
249 END_NAMESPACE_DISTRHO | |
250 | |
251 #endif // DISTRHO_SCOPED_POINTER_HPP_INCLUDED |