OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2012 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2012 The WebRTC Project Authors. All rights reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 // Borrowed from Chromium's src/base/memory/scoped_ptr.h. | 11 // This entire file is deprecated, and will be removed in XXXX 2016. Use |
12 | 12 // std::unique_ptr instead! |
13 // Scopers help you manage ownership of a pointer, helping you easily manage a | |
14 // pointer within a scope, and automatically destroying the pointer at the end | |
15 // of a scope. There are two main classes you will use, which correspond to the | |
16 // operators new/delete and new[]/delete[]. | |
17 // | |
18 // Example usage (scoped_ptr<T>): | |
19 // { | |
20 // scoped_ptr<Foo> foo(new Foo("wee")); | |
21 // } // foo goes out of scope, releasing the pointer with it. | |
22 // | |
23 // { | |
24 // scoped_ptr<Foo> foo; // No pointer managed. | |
25 // foo.reset(new Foo("wee")); // Now a pointer is managed. | |
26 // foo.reset(new Foo("wee2")); // Foo("wee") was destroyed. | |
27 // foo.reset(new Foo("wee3")); // Foo("wee2") was destroyed. | |
28 // foo->Method(); // Foo::Method() called. | |
29 // foo.get()->Method(); // Foo::Method() called. | |
30 // SomeFunc(foo.release()); // SomeFunc takes ownership, foo no longer | |
31 // // manages a pointer. | |
32 // foo.reset(new Foo("wee4")); // foo manages a pointer again. | |
33 // foo.reset(); // Foo("wee4") destroyed, foo no longer | |
34 // // manages a pointer. | |
35 // } // foo wasn't managing a pointer, so nothing was destroyed. | |
36 // | |
37 // Example usage (scoped_ptr<T[]>): | |
38 // { | |
39 // scoped_ptr<Foo[]> foo(new Foo[100]); | |
40 // foo.get()->Method(); // Foo::Method on the 0th element. | |
41 // foo[10].Method(); // Foo::Method on the 10th element. | |
42 // } | |
43 // | |
44 // These scopers also implement part of the functionality of C++11 unique_ptr | |
45 // in that they are "movable but not copyable." You can use the scopers in the | |
46 // parameter and return types of functions to signify ownership transfer in to | |
47 // and out of a function. When calling a function that has a scoper as the | |
48 // argument type, it must be called with the result of calling std::move on an | |
49 // analogous scoper, or another function that generates a temporary; passing by | |
50 // copy will NOT work. Here is an example using scoped_ptr: | |
51 // | |
52 // void TakesOwnership(scoped_ptr<Foo> arg) { | |
53 // // Do something with arg | |
54 // } | |
55 // scoped_ptr<Foo> CreateFoo() { | |
56 // // No need for calling std::move because we are constructing a temporary | |
57 // // for the return value. | |
58 // return scoped_ptr<Foo>(new Foo("new")); | |
59 // } | |
60 // scoped_ptr<Foo> PassThru(scoped_ptr<Foo> arg) { | |
61 // return std::move(arg); | |
62 // } | |
63 // | |
64 // { | |
65 // scoped_ptr<Foo> ptr(new Foo("yay")); // ptr manages Foo("yay"). | |
66 // TakesOwnership(std::move(ptr)); // ptr no longer owns Foo("yay"). | |
67 // scoped_ptr<Foo> ptr2 = CreateFoo(); // ptr2 owns the return Foo. | |
68 // scoped_ptr<Foo> ptr3 = // ptr3 now owns what was in ptr2. | |
69 // PassThru(std::move(ptr2)); // ptr2 is correspondingly nullptr. | |
70 // } | |
71 // | |
72 // Notice that if you do not call std::move when returning from PassThru(), or | |
73 // when invoking TakesOwnership(), the code will not compile because scopers | |
74 // are not copyable; they only implement move semantics which require calling | |
75 // std::move to signify a destructive transfer of state. CreateFoo() is | |
76 // different though because we are constructing a temporary on the return line | |
77 // and thus can avoid needing to call std::move. | |
78 | 13 |
79 #ifndef WEBRTC_BASE_SCOPED_PTR_H__ | 14 #ifndef WEBRTC_BASE_SCOPED_PTR_H__ |
80 #define WEBRTC_BASE_SCOPED_PTR_H__ | 15 #define WEBRTC_BASE_SCOPED_PTR_H__ |
81 | 16 |
82 // This is an implementation designed to match the anticipated future TR2 | 17 // All these #includes are left to maximize backwards compatibility. |
83 // implementation of the scoped_ptr class. | |
84 | 18 |
85 #include <assert.h> | 19 #include <assert.h> |
86 #include <stddef.h> | 20 #include <stddef.h> |
87 #include <stdlib.h> | 21 #include <stdlib.h> |
88 | 22 |
89 #include <algorithm> // For std::swap(). | 23 #include <algorithm> |
90 #include <cstddef> | 24 #include <cstddef> |
91 #include <memory> | 25 #include <memory> |
92 | 26 |
93 #include "webrtc/base/constructormagic.h" | 27 #include "webrtc/base/constructormagic.h" |
94 #include "webrtc/base/template_util.h" | 28 #include "webrtc/base/template_util.h" |
95 #include "webrtc/typedefs.h" | 29 #include "webrtc/typedefs.h" |
96 | 30 |
97 namespace rtc { | 31 namespace rtc { |
98 | 32 |
99 // Function object which deletes its parameter, which must be a pointer. | 33 template <typename T, typename Deleter = std::default_delete<T>> |
100 // If C is an array type, invokes 'delete[]' on the parameter; otherwise, | 34 using scoped_ptr = std::unique_ptr<T, Deleter>; |
101 // invokes 'delete'. The default deleter for scoped_ptr<T>. | |
102 template <class T> | |
103 struct DefaultDeleter { | |
104 DefaultDeleter() {} | |
105 template <typename U> DefaultDeleter(const DefaultDeleter<U>& other) { | |
106 // IMPLEMENTATION NOTE: C++11 20.7.1.1.2p2 only provides this constructor | |
107 // if U* is implicitly convertible to T* and U is not an array type. | |
108 // | |
109 // Correct implementation should use SFINAE to disable this | |
110 // constructor. However, since there are no other 1-argument constructors, | |
111 // using a static_assert based on is_convertible<> and requiring | |
112 // complete types is simpler and will cause compile failures for equivalent | |
113 // misuses. | |
114 // | |
115 // Note, the is_convertible<U*, T*> check also ensures that U is not an | |
116 // array. T is guaranteed to be a non-array, so any U* where U is an array | |
117 // cannot convert to T*. | |
118 enum { T_must_be_complete = sizeof(T) }; | |
119 enum { U_must_be_complete = sizeof(U) }; | |
120 static_assert(rtc::is_convertible<U*, T*>::value, | |
121 "U* must implicitly convert to T*"); | |
122 } | |
123 inline void operator()(T* ptr) const { | |
124 enum { type_must_be_complete = sizeof(T) }; | |
125 delete ptr; | |
126 } | |
127 }; | |
128 | 35 |
129 // Specialization of DefaultDeleter for array types. | 36 // These used to convert between rtc::scoped_ptr and std::unique_ptr. Now they |
130 template <class T> | 37 // are no-ops. |
131 struct DefaultDeleter<T[]> { | |
132 inline void operator()(T* ptr) const { | |
133 enum { type_must_be_complete = sizeof(T) }; | |
134 delete[] ptr; | |
135 } | |
136 | |
137 private: | |
138 // Disable this operator for any U != T because it is undefined to execute | |
139 // an array delete when the static type of the array mismatches the dynamic | |
140 // type. | |
141 // | |
142 // References: | |
143 // C++98 [expr.delete]p3 | |
144 // http://cplusplus.github.com/LWG/lwg-defects.html#938 | |
145 template <typename U> void operator()(U* array) const; | |
146 }; | |
147 | |
148 template <class T, int n> | |
149 struct DefaultDeleter<T[n]> { | |
150 // Never allow someone to declare something like scoped_ptr<int[10]>. | |
151 static_assert(sizeof(T) == -1, "do not use array with size as type"); | |
152 }; | |
153 | |
154 // Function object which invokes 'free' on its parameter, which must be | |
155 // a pointer. Can be used to store malloc-allocated pointers in scoped_ptr: | |
156 // | |
157 // scoped_ptr<int, rtc::FreeDeleter> foo_ptr( | |
158 // static_cast<int*>(malloc(sizeof(int)))); | |
159 struct FreeDeleter { | |
160 inline void operator()(void* ptr) const { | |
161 free(ptr); | |
162 } | |
163 }; | |
164 | |
165 namespace internal { | |
166 | |
167 template <typename T> | 38 template <typename T> |
168 struct ShouldAbortOnSelfReset { | 39 std::unique_ptr<T> ScopedToUnique(std::unique_ptr<T> up) { |
169 template <typename U> | 40 return up; |
170 static rtc::internal::NoType Test(const typename U::AllowSelfReset*); | |
171 | |
172 template <typename U> | |
173 static rtc::internal::YesType Test(...); | |
174 | |
175 static const bool value = | |
176 sizeof(Test<T>(0)) == sizeof(rtc::internal::YesType); | |
177 }; | |
178 | |
179 // Minimal implementation of the core logic of scoped_ptr, suitable for | |
180 // reuse in both scoped_ptr and its specializations. | |
181 template <class T, class D> | |
182 class scoped_ptr_impl { | |
183 public: | |
184 explicit scoped_ptr_impl(T* p) : data_(p) {} | |
185 | |
186 // Initializer for deleters that have data parameters. | |
187 scoped_ptr_impl(T* p, const D& d) : data_(p, d) {} | |
188 | |
189 // Templated constructor that destructively takes the value from another | |
190 // scoped_ptr_impl. | |
191 template <typename U, typename V> | |
192 scoped_ptr_impl(scoped_ptr_impl<U, V>* other) | |
193 : data_(other->release(), other->get_deleter()) { | |
194 // We do not support move-only deleters. We could modify our move | |
195 // emulation to have rtc::subtle::move() and rtc::subtle::forward() | |
196 // functions that are imperfect emulations of their C++11 equivalents, | |
197 // but until there's a requirement, just assume deleters are copyable. | |
198 } | |
199 | |
200 template <typename U, typename V> | |
201 void TakeState(scoped_ptr_impl<U, V>* other) { | |
202 // See comment in templated constructor above regarding lack of support | |
203 // for move-only deleters. | |
204 reset(other->release()); | |
205 get_deleter() = other->get_deleter(); | |
206 } | |
207 | |
208 ~scoped_ptr_impl() { | |
209 if (data_.ptr != nullptr) { | |
210 // Not using get_deleter() saves one function call in non-optimized | |
211 // builds. | |
212 static_cast<D&>(data_)(data_.ptr); | |
213 } | |
214 } | |
215 | |
216 void reset(T* p) { | |
217 // This is a self-reset, which is no longer allowed for default deleters: | |
218 // https://crbug.com/162971 | |
219 assert(!ShouldAbortOnSelfReset<D>::value || p == nullptr || p != data_.ptr); | |
220 | |
221 // Note that running data_.ptr = p can lead to undefined behavior if | |
222 // get_deleter()(get()) deletes this. In order to prevent this, reset() | |
223 // should update the stored pointer before deleting its old value. | |
224 // | |
225 // However, changing reset() to use that behavior may cause current code to | |
226 // break in unexpected ways. If the destruction of the owned object | |
227 // dereferences the scoped_ptr when it is destroyed by a call to reset(), | |
228 // then it will incorrectly dispatch calls to |p| rather than the original | |
229 // value of |data_.ptr|. | |
230 // | |
231 // During the transition period, set the stored pointer to nullptr while | |
232 // deleting the object. Eventually, this safety check will be removed to | |
233 // prevent the scenario initially described from occurring and | |
234 // http://crbug.com/176091 can be closed. | |
235 T* old = data_.ptr; | |
236 data_.ptr = nullptr; | |
237 if (old != nullptr) | |
238 static_cast<D&>(data_)(old); | |
239 data_.ptr = p; | |
240 } | |
241 | |
242 T* get() const { return data_.ptr; } | |
243 | |
244 D& get_deleter() { return data_; } | |
245 const D& get_deleter() const { return data_; } | |
246 | |
247 void swap(scoped_ptr_impl& p2) { | |
248 // Standard swap idiom: 'using std::swap' ensures that std::swap is | |
249 // present in the overload set, but we call swap unqualified so that | |
250 // any more-specific overloads can be used, if available. | |
251 using std::swap; | |
252 swap(static_cast<D&>(data_), static_cast<D&>(p2.data_)); | |
253 swap(data_.ptr, p2.data_.ptr); | |
254 } | |
255 | |
256 T* release() { | |
257 T* old_ptr = data_.ptr; | |
258 data_.ptr = nullptr; | |
259 return old_ptr; | |
260 } | |
261 | |
262 T** accept() { | |
263 reset(nullptr); | |
264 return &(data_.ptr); | |
265 } | |
266 | |
267 T** use() { | |
268 return &(data_.ptr); | |
269 } | |
270 | |
271 private: | |
272 // Needed to allow type-converting constructor. | |
273 template <typename U, typename V> friend class scoped_ptr_impl; | |
274 | |
275 // Use the empty base class optimization to allow us to have a D | |
276 // member, while avoiding any space overhead for it when D is an | |
277 // empty class. See e.g. http://www.cantrip.org/emptyopt.html for a good | |
278 // discussion of this technique. | |
279 struct Data : public D { | |
280 explicit Data(T* ptr_in) : ptr(ptr_in) {} | |
281 Data(T* ptr_in, const D& other) : D(other), ptr(ptr_in) {} | |
282 T* ptr; | |
283 }; | |
284 | |
285 Data data_; | |
286 | |
287 RTC_DISALLOW_COPY_AND_ASSIGN(scoped_ptr_impl); | |
288 }; | |
289 | |
290 } // namespace internal | |
291 | |
292 // A scoped_ptr<T> is like a T*, except that the destructor of scoped_ptr<T> | |
293 // automatically deletes the pointer it holds (if any). | |
294 // That is, scoped_ptr<T> owns the T object that it points to. | |
295 // Like a T*, a scoped_ptr<T> may hold either nullptr or a pointer to a T | |
296 // object. Also like T*, scoped_ptr<T> is thread-compatible, and once you | |
297 // dereference it, you get the thread safety guarantees of T. | |
298 // | |
299 // The size of scoped_ptr is small. On most compilers, when using the | |
300 // DefaultDeleter, sizeof(scoped_ptr<T>) == sizeof(T*). Custom deleters will | |
301 // increase the size proportional to whatever state they need to have. See | |
302 // comments inside scoped_ptr_impl<> for details. | |
303 // | |
304 // Current implementation targets having a strict subset of C++11's | |
305 // unique_ptr<> features. Known deficiencies include not supporting move-only | |
306 // deleters, function pointers as deleters, and deleters with reference | |
307 // types. | |
308 template <class T, class D = rtc::DefaultDeleter<T> > | |
309 class scoped_ptr { | |
310 | |
311 // TODO(ajm): If we ever import RefCountedBase, this check needs to be | |
312 // enabled. | |
313 //static_assert(rtc::internal::IsNotRefCounted<T>::value, | |
314 // "T is refcounted type and needs scoped refptr"); | |
315 | |
316 public: | |
317 // The element and deleter types. | |
318 typedef T element_type; | |
319 typedef D deleter_type; | |
320 | |
321 // Constructor. Defaults to initializing with nullptr. | |
322 scoped_ptr() : impl_(nullptr) {} | |
323 | |
324 // Constructor. Takes ownership of p. | |
325 explicit scoped_ptr(element_type* p) : impl_(p) {} | |
326 | |
327 // Constructor. Allows initialization of a stateful deleter. | |
328 scoped_ptr(element_type* p, const D& d) : impl_(p, d) {} | |
329 | |
330 // Constructor. Allows construction from a nullptr. | |
331 scoped_ptr(std::nullptr_t) : impl_(nullptr) {} | |
332 | |
333 // Constructor. Allows construction from a scoped_ptr rvalue for a | |
334 // convertible type and deleter. | |
335 // | |
336 // IMPLEMENTATION NOTE: C++11 unique_ptr<> keeps this constructor distinct | |
337 // from the normal move constructor. By C++11 20.7.1.2.1.21, this constructor | |
338 // has different post-conditions if D is a reference type. Since this | |
339 // implementation does not support deleters with reference type, | |
340 // we do not need a separate move constructor allowing us to avoid one | |
341 // use of SFINAE. You only need to care about this if you modify the | |
342 // implementation of scoped_ptr. | |
343 template <typename U, typename V> | |
344 scoped_ptr(scoped_ptr<U, V>&& other) | |
345 : impl_(&other.impl_) { | |
346 static_assert(!rtc::is_array<U>::value, "U cannot be an array"); | |
347 } | |
348 | |
349 // operator=. Allows assignment from a scoped_ptr rvalue for a convertible | |
350 // type and deleter. | |
351 // | |
352 // IMPLEMENTATION NOTE: C++11 unique_ptr<> keeps this operator= distinct from | |
353 // the normal move assignment operator. By C++11 20.7.1.2.3.4, this templated | |
354 // form has different requirements on for move-only Deleters. Since this | |
355 // implementation does not support move-only Deleters, we do not need a | |
356 // separate move assignment operator allowing us to avoid one use of SFINAE. | |
357 // You only need to care about this if you modify the implementation of | |
358 // scoped_ptr. | |
359 template <typename U, typename V> | |
360 scoped_ptr& operator=(scoped_ptr<U, V>&& rhs) { | |
361 static_assert(!rtc::is_array<U>::value, "U cannot be an array"); | |
362 impl_.TakeState(&rhs.impl_); | |
363 return *this; | |
364 } | |
365 | |
366 // operator=. Allows assignment from a nullptr. Deletes the currently owned | |
367 // object, if any. | |
368 scoped_ptr& operator=(std::nullptr_t) { | |
369 reset(); | |
370 return *this; | |
371 } | |
372 | |
373 // Deleted copy constructor and copy assignment, to make the type move-only. | |
374 scoped_ptr(const scoped_ptr& other) = delete; | |
375 scoped_ptr& operator=(const scoped_ptr& other) = delete; | |
376 | |
377 // Reset. Deletes the currently owned object, if any. | |
378 // Then takes ownership of a new object, if given. | |
379 void reset(element_type* p = nullptr) { impl_.reset(p); } | |
380 | |
381 // Accessors to get the owned object. | |
382 // operator* and operator-> will assert() if there is no current object. | |
383 element_type& operator*() const { | |
384 assert(impl_.get() != nullptr); | |
385 return *impl_.get(); | |
386 } | |
387 element_type* operator->() const { | |
388 assert(impl_.get() != nullptr); | |
389 return impl_.get(); | |
390 } | |
391 element_type* get() const { return impl_.get(); } | |
392 | |
393 // Access to the deleter. | |
394 deleter_type& get_deleter() { return impl_.get_deleter(); } | |
395 const deleter_type& get_deleter() const { return impl_.get_deleter(); } | |
396 | |
397 // Allow scoped_ptr<element_type> to be used in boolean expressions, but not | |
398 // implicitly convertible to a real bool (which is dangerous). | |
399 // | |
400 // Note that this trick is only safe when the == and != operators | |
401 // are declared explicitly, as otherwise "scoped_ptr1 == | |
402 // scoped_ptr2" will compile but do the wrong thing (i.e., convert | |
403 // to Testable and then do the comparison). | |
404 private: | |
405 typedef rtc::internal::scoped_ptr_impl<element_type, deleter_type> | |
406 scoped_ptr::*Testable; | |
407 | |
408 public: | |
409 operator Testable() const { | |
410 return impl_.get() ? &scoped_ptr::impl_ : nullptr; | |
411 } | |
412 | |
413 // Comparison operators. | |
414 // These return whether two scoped_ptr refer to the same object, not just to | |
415 // two different but equal objects. | |
416 bool operator==(const element_type* p) const { return impl_.get() == p; } | |
417 bool operator!=(const element_type* p) const { return impl_.get() != p; } | |
418 | |
419 // Swap two scoped pointers. | |
420 void swap(scoped_ptr& p2) { | |
421 impl_.swap(p2.impl_); | |
422 } | |
423 | |
424 // Release a pointer. | |
425 // The return value is the current pointer held by this object. If this object | |
426 // holds a nullptr, the return value is nullptr. After this operation, this | |
427 // object will hold a nullptr, and will not own the object any more. | |
428 element_type* release() WARN_UNUSED_RESULT { | |
429 return impl_.release(); | |
430 } | |
431 | |
432 // Delete the currently held pointer and return a pointer | |
433 // to allow overwriting of the current pointer address. | |
434 element_type** accept() WARN_UNUSED_RESULT { | |
435 return impl_.accept(); | |
436 } | |
437 | |
438 // Return a pointer to the current pointer address. | |
439 element_type** use() WARN_UNUSED_RESULT { | |
440 return impl_.use(); | |
441 } | |
442 | |
443 private: | |
444 // Needed to reach into |impl_| in the constructor. | |
445 template <typename U, typename V> friend class scoped_ptr; | |
446 rtc::internal::scoped_ptr_impl<element_type, deleter_type> impl_; | |
447 | |
448 // Forbidden for API compatibility with std::unique_ptr. | |
449 explicit scoped_ptr(int disallow_construction_from_null); | |
450 | |
451 // Forbid comparison of scoped_ptr types. If U != T, it totally | |
452 // doesn't make sense, and if U == T, it still doesn't make sense | |
453 // because you should never have the same object owned by two different | |
454 // scoped_ptrs. | |
455 template <class U> bool operator==(scoped_ptr<U> const& p2) const; | |
456 template <class U> bool operator!=(scoped_ptr<U> const& p2) const; | |
457 }; | |
458 | |
459 template <class T, class D> | |
460 class scoped_ptr<T[], D> { | |
461 public: | |
462 // The element and deleter types. | |
463 typedef T element_type; | |
464 typedef D deleter_type; | |
465 | |
466 // Constructor. Defaults to initializing with nullptr. | |
467 scoped_ptr() : impl_(nullptr) {} | |
468 | |
469 // Constructor. Stores the given array. Note that the argument's type | |
470 // must exactly match T*. In particular: | |
471 // - it cannot be a pointer to a type derived from T, because it is | |
472 // inherently unsafe in the general case to access an array through a | |
473 // pointer whose dynamic type does not match its static type (eg., if | |
474 // T and the derived types had different sizes access would be | |
475 // incorrectly calculated). Deletion is also always undefined | |
476 // (C++98 [expr.delete]p3). If you're doing this, fix your code. | |
477 // - it cannot be const-qualified differently from T per unique_ptr spec | |
478 // (http://cplusplus.github.com/LWG/lwg-active.html#2118). Users wanting | |
479 // to work around this may use implicit_cast<const T*>(). | |
480 // However, because of the first bullet in this comment, users MUST | |
481 // NOT use implicit_cast<Base*>() to upcast the static type of the array. | |
482 explicit scoped_ptr(element_type* array) : impl_(array) {} | |
483 | |
484 // Constructor. Allows construction from a nullptr. | |
485 scoped_ptr(std::nullptr_t) : impl_(nullptr) {} | |
486 | |
487 // Constructor. Allows construction from a scoped_ptr rvalue. | |
488 scoped_ptr(scoped_ptr&& other) : impl_(&other.impl_) {} | |
489 | |
490 // operator=. Allows assignment from a scoped_ptr rvalue. | |
491 scoped_ptr& operator=(scoped_ptr&& rhs) { | |
492 impl_.TakeState(&rhs.impl_); | |
493 return *this; | |
494 } | |
495 | |
496 // operator=. Allows assignment from a nullptr. Deletes the currently owned | |
497 // array, if any. | |
498 scoped_ptr& operator=(std::nullptr_t) { | |
499 reset(); | |
500 return *this; | |
501 } | |
502 | |
503 // Deleted copy constructor and copy assignment, to make the type move-only. | |
504 scoped_ptr(const scoped_ptr& other) = delete; | |
505 scoped_ptr& operator=(const scoped_ptr& other) = delete; | |
506 | |
507 // Reset. Deletes the currently owned array, if any. | |
508 // Then takes ownership of a new object, if given. | |
509 void reset(element_type* array = nullptr) { impl_.reset(array); } | |
510 | |
511 // Accessors to get the owned array. | |
512 element_type& operator[](size_t i) const { | |
513 assert(impl_.get() != nullptr); | |
514 return impl_.get()[i]; | |
515 } | |
516 element_type* get() const { return impl_.get(); } | |
517 | |
518 // Access to the deleter. | |
519 deleter_type& get_deleter() { return impl_.get_deleter(); } | |
520 const deleter_type& get_deleter() const { return impl_.get_deleter(); } | |
521 | |
522 // Allow scoped_ptr<element_type> to be used in boolean expressions, but not | |
523 // implicitly convertible to a real bool (which is dangerous). | |
524 private: | |
525 typedef rtc::internal::scoped_ptr_impl<element_type, deleter_type> | |
526 scoped_ptr::*Testable; | |
527 | |
528 public: | |
529 operator Testable() const { | |
530 return impl_.get() ? &scoped_ptr::impl_ : nullptr; | |
531 } | |
532 | |
533 // Comparison operators. | |
534 // These return whether two scoped_ptr refer to the same object, not just to | |
535 // two different but equal objects. | |
536 bool operator==(element_type* array) const { return impl_.get() == array; } | |
537 bool operator!=(element_type* array) const { return impl_.get() != array; } | |
538 | |
539 // Swap two scoped pointers. | |
540 void swap(scoped_ptr& p2) { | |
541 impl_.swap(p2.impl_); | |
542 } | |
543 | |
544 // Release a pointer. | |
545 // The return value is the current pointer held by this object. If this object | |
546 // holds a nullptr, the return value is nullptr. After this operation, this | |
547 // object will hold a nullptr, and will not own the object any more. | |
548 element_type* release() WARN_UNUSED_RESULT { | |
549 return impl_.release(); | |
550 } | |
551 | |
552 // Delete the currently held pointer and return a pointer | |
553 // to allow overwriting of the current pointer address. | |
554 element_type** accept() WARN_UNUSED_RESULT { | |
555 return impl_.accept(); | |
556 } | |
557 | |
558 // Return a pointer to the current pointer address. | |
559 element_type** use() WARN_UNUSED_RESULT { | |
560 return impl_.use(); | |
561 } | |
562 | |
563 private: | |
564 // Force element_type to be a complete type. | |
565 enum { type_must_be_complete = sizeof(element_type) }; | |
566 | |
567 // Actually hold the data. | |
568 rtc::internal::scoped_ptr_impl<element_type, deleter_type> impl_; | |
569 | |
570 // Disable initialization from any type other than element_type*, by | |
571 // providing a constructor that matches such an initialization, but is | |
572 // private and has no definition. This is disabled because it is not safe to | |
573 // call delete[] on an array whose static type does not match its dynamic | |
574 // type. | |
575 template <typename U> explicit scoped_ptr(U* array); | |
576 explicit scoped_ptr(int disallow_construction_from_null); | |
577 | |
578 // Disable reset() from any type other than element_type*, for the same | |
579 // reasons as the constructor above. | |
580 template <typename U> void reset(U* array); | |
581 void reset(int disallow_reset_from_null); | |
582 | |
583 // Forbid comparison of scoped_ptr types. If U != T, it totally | |
584 // doesn't make sense, and if U == T, it still doesn't make sense | |
585 // because you should never have the same object owned by two different | |
586 // scoped_ptrs. | |
587 template <class U> bool operator==(scoped_ptr<U> const& p2) const; | |
588 template <class U> bool operator!=(scoped_ptr<U> const& p2) const; | |
589 }; | |
590 | |
591 template <class T, class D> | |
592 void swap(rtc::scoped_ptr<T, D>& p1, rtc::scoped_ptr<T, D>& p2) { | |
593 p1.swap(p2); | |
594 } | |
595 | |
596 // Convert between the most common kinds of scoped_ptr and unique_ptr. | |
597 template <typename T> | |
598 std::unique_ptr<T> ScopedToUnique(scoped_ptr<T> sp) { | |
599 return std::unique_ptr<T>(sp.release()); | |
600 } | 41 } |
601 template <typename T> | 42 template <typename T> |
602 scoped_ptr<T> UniqueToScoped(std::unique_ptr<T> up) { | 43 std::unique_ptr<T> UniqueToScoped(std::unique_ptr<T> up) { |
603 return scoped_ptr<T>(up.release()); | 44 return up; |
604 } | 45 } |
605 | 46 |
606 } // namespace rtc | 47 } // namespace rtc |
607 | 48 |
608 template <class T, class D> | |
609 bool operator==(T* p1, const rtc::scoped_ptr<T, D>& p2) { | |
610 return p1 == p2.get(); | |
611 } | |
612 | |
613 template <class T, class D> | |
614 bool operator!=(T* p1, const rtc::scoped_ptr<T, D>& p2) { | |
615 return p1 != p2.get(); | |
616 } | |
617 | |
618 // A function to convert T* into scoped_ptr<T> | |
619 // Doing e.g. make_scoped_ptr(new FooBarBaz<type>(arg)) is a shorter notation | |
620 // for scoped_ptr<FooBarBaz<type> >(new FooBarBaz<type>(arg)) | |
621 template <typename T> | |
622 rtc::scoped_ptr<T> rtc_make_scoped_ptr(T* ptr) { | |
623 return rtc::scoped_ptr<T>(ptr); | |
624 } | |
625 | |
626 #endif // #ifndef WEBRTC_BASE_SCOPED_PTR_H__ | 49 #endif // #ifndef WEBRTC_BASE_SCOPED_PTR_H__ |
OLD | NEW |