• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright 2012 The WebRTC Project Authors. All rights reserved.
3  *
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
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 // Borrowed from Chromium's src/base/memory/scoped_ptr.h.
12 
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 
79 #ifndef WEBRTC_BASE_SCOPED_PTR_H__
80 #define WEBRTC_BASE_SCOPED_PTR_H__
81 
82 // This is an implementation designed to match the anticipated future TR2
83 // implementation of the scoped_ptr class.
84 
85 #include <assert.h>
86 #include <stddef.h>
87 #include <stdlib.h>
88 
89 #include <algorithm>  // For std::swap().
90 #include <cstddef>
91 
92 #include "webrtc/base/constructormagic.h"
93 #include "webrtc/base/deprecation.h"
94 #include "webrtc/base/template_util.h"
95 #include "webrtc/typedefs.h"
96 
97 namespace rtc {
98 
99 // Function object which deletes its parameter, which must be a pointer.
100 // If C is an array type, invokes 'delete[]' on the parameter; otherwise,
101 // invokes 'delete'. The default deleter for scoped_ptr<T>.
102 template <class T>
103 struct DefaultDeleter {
DefaultDeleterDefaultDeleter104   DefaultDeleter() {}
DefaultDeleterDefaultDeleter105   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   }
operatorDefaultDeleter123   inline void operator()(T* ptr) const {
124     enum { type_must_be_complete = sizeof(T) };
125     delete ptr;
126   }
127 };
128 
129 // Specialization of DefaultDeleter for array types.
130 template <class T>
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>
168 struct ShouldAbortOnSelfReset {
169   template <typename U>
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   // Get an rvalue reference. (sp.Pass() does the same thing as std::move(sp).)
378   // Deprecated; remove in March 2016 (bug 5373).
379   RTC_DEPRECATED scoped_ptr&& Pass() {
380     return std::move(*this);
381   }
382 
383   // Reset.  Deletes the currently owned object, if any.
384   // Then takes ownership of a new object, if given.
385   void reset(element_type* p = nullptr) { impl_.reset(p); }
386 
387   // Accessors to get the owned object.
388   // operator* and operator-> will assert() if there is no current object.
389   element_type& operator*() const {
390     assert(impl_.get() != nullptr);
391     return *impl_.get();
392   }
393   element_type* operator->() const  {
394     assert(impl_.get() != nullptr);
395     return impl_.get();
396   }
397   element_type* get() const { return impl_.get(); }
398 
399   // Access to the deleter.
400   deleter_type& get_deleter() { return impl_.get_deleter(); }
401   const deleter_type& get_deleter() const { return impl_.get_deleter(); }
402 
403   // Allow scoped_ptr<element_type> to be used in boolean expressions, but not
404   // implicitly convertible to a real bool (which is dangerous).
405   //
406   // Note that this trick is only safe when the == and != operators
407   // are declared explicitly, as otherwise "scoped_ptr1 ==
408   // scoped_ptr2" will compile but do the wrong thing (i.e., convert
409   // to Testable and then do the comparison).
410  private:
411   typedef rtc::internal::scoped_ptr_impl<element_type, deleter_type>
412       scoped_ptr::*Testable;
413 
414  public:
415   operator Testable() const {
416     return impl_.get() ? &scoped_ptr::impl_ : nullptr;
417   }
418 
419   // Comparison operators.
420   // These return whether two scoped_ptr refer to the same object, not just to
421   // two different but equal objects.
422   bool operator==(const element_type* p) const { return impl_.get() == p; }
423   bool operator!=(const element_type* p) const { return impl_.get() != p; }
424 
425   // Swap two scoped pointers.
426   void swap(scoped_ptr& p2) {
427     impl_.swap(p2.impl_);
428   }
429 
430   // Release a pointer.
431   // The return value is the current pointer held by this object. If this object
432   // holds a nullptr, the return value is nullptr. After this operation, this
433   // object will hold a nullptr, and will not own the object any more.
434   element_type* release() WARN_UNUSED_RESULT {
435     return impl_.release();
436   }
437 
438   // Delete the currently held pointer and return a pointer
439   // to allow overwriting of the current pointer address.
440   element_type** accept() WARN_UNUSED_RESULT {
441     return impl_.accept();
442   }
443 
444   // Return a pointer to the current pointer address.
445   element_type** use() WARN_UNUSED_RESULT {
446     return impl_.use();
447   }
448 
449  private:
450   // Needed to reach into |impl_| in the constructor.
451   template <typename U, typename V> friend class scoped_ptr;
452   rtc::internal::scoped_ptr_impl<element_type, deleter_type> impl_;
453 
454   // Forbidden for API compatibility with std::unique_ptr.
455   explicit scoped_ptr(int disallow_construction_from_null);
456 
457   // Forbid comparison of scoped_ptr types.  If U != T, it totally
458   // doesn't make sense, and if U == T, it still doesn't make sense
459   // because you should never have the same object owned by two different
460   // scoped_ptrs.
461   template <class U> bool operator==(scoped_ptr<U> const& p2) const;
462   template <class U> bool operator!=(scoped_ptr<U> const& p2) const;
463 };
464 
465 template <class T, class D>
466 class scoped_ptr<T[], D> {
467  public:
468   // The element and deleter types.
469   typedef T element_type;
470   typedef D deleter_type;
471 
472   // Constructor.  Defaults to initializing with nullptr.
473   scoped_ptr() : impl_(nullptr) {}
474 
475   // Constructor. Stores the given array. Note that the argument's type
476   // must exactly match T*. In particular:
477   // - it cannot be a pointer to a type derived from T, because it is
478   //   inherently unsafe in the general case to access an array through a
479   //   pointer whose dynamic type does not match its static type (eg., if
480   //   T and the derived types had different sizes access would be
481   //   incorrectly calculated). Deletion is also always undefined
482   //   (C++98 [expr.delete]p3). If you're doing this, fix your code.
483   // - it cannot be const-qualified differently from T per unique_ptr spec
484   //   (http://cplusplus.github.com/LWG/lwg-active.html#2118). Users wanting
485   //   to work around this may use implicit_cast<const T*>().
486   //   However, because of the first bullet in this comment, users MUST
487   //   NOT use implicit_cast<Base*>() to upcast the static type of the array.
488   explicit scoped_ptr(element_type* array) : impl_(array) {}
489 
490   // Constructor.  Allows construction from a nullptr.
491   scoped_ptr(std::nullptr_t) : impl_(nullptr) {}
492 
493   // Constructor.  Allows construction from a scoped_ptr rvalue.
494   scoped_ptr(scoped_ptr&& other) : impl_(&other.impl_) {}
495 
496   // operator=.  Allows assignment from a scoped_ptr rvalue.
497   scoped_ptr& operator=(scoped_ptr&& rhs) {
498     impl_.TakeState(&rhs.impl_);
499     return *this;
500   }
501 
502   // operator=.  Allows assignment from a nullptr. Deletes the currently owned
503   // array, if any.
504   scoped_ptr& operator=(std::nullptr_t) {
505     reset();
506     return *this;
507   }
508 
509   // Deleted copy constructor and copy assignment, to make the type move-only.
510   scoped_ptr(const scoped_ptr& other) = delete;
511   scoped_ptr& operator=(const scoped_ptr& other) = delete;
512 
513   // Get an rvalue reference. (sp.Pass() does the same thing as std::move(sp).)
514   // Deprecated; remove in March 2016 (bug 5373).
515   RTC_DEPRECATED scoped_ptr&& Pass() {
516     return std::move(*this);
517   }
518 
519   // Reset.  Deletes the currently owned array, if any.
520   // Then takes ownership of a new object, if given.
521   void reset(element_type* array = nullptr) { impl_.reset(array); }
522 
523   // Accessors to get the owned array.
524   element_type& operator[](size_t i) const {
525     assert(impl_.get() != nullptr);
526     return impl_.get()[i];
527   }
528   element_type* get() const { return impl_.get(); }
529 
530   // Access to the deleter.
531   deleter_type& get_deleter() { return impl_.get_deleter(); }
532   const deleter_type& get_deleter() const { return impl_.get_deleter(); }
533 
534   // Allow scoped_ptr<element_type> to be used in boolean expressions, but not
535   // implicitly convertible to a real bool (which is dangerous).
536  private:
537   typedef rtc::internal::scoped_ptr_impl<element_type, deleter_type>
538       scoped_ptr::*Testable;
539 
540  public:
541   operator Testable() const {
542     return impl_.get() ? &scoped_ptr::impl_ : nullptr;
543   }
544 
545   // Comparison operators.
546   // These return whether two scoped_ptr refer to the same object, not just to
547   // two different but equal objects.
548   bool operator==(element_type* array) const { return impl_.get() == array; }
549   bool operator!=(element_type* array) const { return impl_.get() != array; }
550 
551   // Swap two scoped pointers.
552   void swap(scoped_ptr& p2) {
553     impl_.swap(p2.impl_);
554   }
555 
556   // Release a pointer.
557   // The return value is the current pointer held by this object. If this object
558   // holds a nullptr, the return value is nullptr. After this operation, this
559   // object will hold a nullptr, and will not own the object any more.
560   element_type* release() WARN_UNUSED_RESULT {
561     return impl_.release();
562   }
563 
564   // Delete the currently held pointer and return a pointer
565   // to allow overwriting of the current pointer address.
566   element_type** accept() WARN_UNUSED_RESULT {
567     return impl_.accept();
568   }
569 
570   // Return a pointer to the current pointer address.
571   element_type** use() WARN_UNUSED_RESULT {
572     return impl_.use();
573   }
574 
575  private:
576   // Force element_type to be a complete type.
577   enum { type_must_be_complete = sizeof(element_type) };
578 
579   // Actually hold the data.
580   rtc::internal::scoped_ptr_impl<element_type, deleter_type> impl_;
581 
582   // Disable initialization from any type other than element_type*, by
583   // providing a constructor that matches such an initialization, but is
584   // private and has no definition. This is disabled because it is not safe to
585   // call delete[] on an array whose static type does not match its dynamic
586   // type.
587   template <typename U> explicit scoped_ptr(U* array);
588   explicit scoped_ptr(int disallow_construction_from_null);
589 
590   // Disable reset() from any type other than element_type*, for the same
591   // reasons as the constructor above.
592   template <typename U> void reset(U* array);
593   void reset(int disallow_reset_from_null);
594 
595   // Forbid comparison of scoped_ptr types.  If U != T, it totally
596   // doesn't make sense, and if U == T, it still doesn't make sense
597   // because you should never have the same object owned by two different
598   // scoped_ptrs.
599   template <class U> bool operator==(scoped_ptr<U> const& p2) const;
600   template <class U> bool operator!=(scoped_ptr<U> const& p2) const;
601 };
602 
603 template <class T, class D>
604 void swap(rtc::scoped_ptr<T, D>& p1, rtc::scoped_ptr<T, D>& p2) {
605   p1.swap(p2);
606 }
607 
608 }  // namespace rtc
609 
610 template <class T, class D>
611 bool operator==(T* p1, const rtc::scoped_ptr<T, D>& p2) {
612   return p1 == p2.get();
613 }
614 
615 template <class T, class D>
616 bool operator!=(T* p1, const rtc::scoped_ptr<T, D>& p2) {
617   return p1 != p2.get();
618 }
619 
620 // A function to convert T* into scoped_ptr<T>
621 // Doing e.g. make_scoped_ptr(new FooBarBaz<type>(arg)) is a shorter notation
622 // for scoped_ptr<FooBarBaz<type> >(new FooBarBaz<type>(arg))
623 template <typename T>
624 rtc::scoped_ptr<T> rtc_make_scoped_ptr(T* ptr) {
625   return rtc::scoped_ptr<T>(ptr);
626 }
627 
628 #endif  // #ifndef WEBRTC_BASE_SCOPED_PTR_H__
629