1f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org/*
2f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *  Copyright 2012 The WebRTC Project Authors. All rights reserved.
3f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *
4f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *  Use of this source code is governed by a BSD-style license
5f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *  that can be found in the LICENSE file in the root of the source
6f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *  tree. An additional intellectual property rights grant can be found
7f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *  in the file PATENTS.  All contributing project authors may
8f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
9f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org */
10f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
1173ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org// Borrowed from Chromium's src/base/memory/scoped_ptr.h.
1273ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org
1373ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org// Scopers help you manage ownership of a pointer, helping you easily manage a
1473ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org// pointer within a scope, and automatically destroying the pointer at the end
1573ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org// of a scope.  There are two main classes you will use, which correspond to the
1673ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org// operators new/delete and new[]/delete[].
17f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org//
18f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// Example usage (scoped_ptr<T>):
19f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org//   {
20f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org//     scoped_ptr<Foo> foo(new Foo("wee"));
21f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org//   }  // foo goes out of scope, releasing the pointer with it.
22f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org//
23f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org//   {
24f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org//     scoped_ptr<Foo> foo;          // No pointer managed.
25f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org//     foo.reset(new Foo("wee"));    // Now a pointer is managed.
26f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org//     foo.reset(new Foo("wee2"));   // Foo("wee") was destroyed.
27f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org//     foo.reset(new Foo("wee3"));   // Foo("wee2") was destroyed.
28f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org//     foo->Method();                // Foo::Method() called.
29f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org//     foo.get()->Method();          // Foo::Method() called.
30f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org//     SomeFunc(foo.release());      // SomeFunc takes ownership, foo no longer
31f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org//                                   // manages a pointer.
32f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org//     foo.reset(new Foo("wee4"));   // foo manages a pointer again.
33f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org//     foo.reset();                  // Foo("wee4") destroyed, foo no longer
34f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org//                                   // manages a pointer.
35f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org//   }  // foo wasn't managing a pointer, so nothing was destroyed.
36f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org//
37f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// Example usage (scoped_ptr<T[]>):
38f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org//   {
39f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org//     scoped_ptr<Foo[]> foo(new Foo[100]);
40f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org//     foo.get()->Method();  // Foo::Method on the 0th element.
41f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org//     foo[10].Method();     // Foo::Method on the 10th element.
42f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org//   }
43f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org//
44f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// These scopers also implement part of the functionality of C++11 unique_ptr
450eb15ed7b806125774bd13fb214aeb403e2c6857kwiberg// in that they are "movable but not copyable." You can use the scopers in the
460eb15ed7b806125774bd13fb214aeb403e2c6857kwiberg// parameter and return types of functions to signify ownership transfer in to
470eb15ed7b806125774bd13fb214aeb403e2c6857kwiberg// and out of a function. When calling a function that has a scoper as the
480eb15ed7b806125774bd13fb214aeb403e2c6857kwiberg// argument type, it must be called with the result of calling std::move on an
490eb15ed7b806125774bd13fb214aeb403e2c6857kwiberg// analogous scoper, or another function that generates a temporary; passing by
500eb15ed7b806125774bd13fb214aeb403e2c6857kwiberg// copy will NOT work. Here is an example using scoped_ptr:
51f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org//
52f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org//   void TakesOwnership(scoped_ptr<Foo> arg) {
53f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org//     // Do something with arg
54f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org//   }
55f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org//   scoped_ptr<Foo> CreateFoo() {
560eb15ed7b806125774bd13fb214aeb403e2c6857kwiberg//     // No need for calling std::move because we are constructing a temporary
57f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org//     // for the return value.
58f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org//     return scoped_ptr<Foo>(new Foo("new"));
59f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org//   }
60f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org//   scoped_ptr<Foo> PassThru(scoped_ptr<Foo> arg) {
610eb15ed7b806125774bd13fb214aeb403e2c6857kwiberg//     return std::move(arg);
62f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org//   }
63f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org//
64f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org//   {
65f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org//     scoped_ptr<Foo> ptr(new Foo("yay"));  // ptr manages Foo("yay").
660eb15ed7b806125774bd13fb214aeb403e2c6857kwiberg//     TakesOwnership(std::move(ptr));       // ptr no longer owns Foo("yay").
67f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org//     scoped_ptr<Foo> ptr2 = CreateFoo();   // ptr2 owns the return Foo.
68f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org//     scoped_ptr<Foo> ptr3 =                // ptr3 now owns what was in ptr2.
690eb15ed7b806125774bd13fb214aeb403e2c6857kwiberg//         PassThru(std::move(ptr2));        // ptr2 is correspondingly nullptr.
70f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org//   }
71f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org//
720eb15ed7b806125774bd13fb214aeb403e2c6857kwiberg// Notice that if you do not call std::move when returning from PassThru(), or
73f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// when invoking TakesOwnership(), the code will not compile because scopers
74f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// are not copyable; they only implement move semantics which require calling
750eb15ed7b806125774bd13fb214aeb403e2c6857kwiberg// std::move to signify a destructive transfer of state. CreateFoo() is
760eb15ed7b806125774bd13fb214aeb403e2c6857kwiberg// different though because we are constructing a temporary on the return line
770eb15ed7b806125774bd13fb214aeb403e2c6857kwiberg// and thus can avoid needing to call std::move.
78f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
79f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#ifndef WEBRTC_BASE_SCOPED_PTR_H__
80f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#define WEBRTC_BASE_SCOPED_PTR_H__
81f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
8273ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org// This is an implementation designed to match the anticipated future TR2
8373ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org// implementation of the scoped_ptr class.
84f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
8573ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org#include <assert.h>
8673ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org#include <stddef.h>
8773ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org#include <stdlib.h>
88f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
8973ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org#include <algorithm>  // For std::swap().
909390f84a4a0ccaca7f3eeec55e3b111158583665kwiberg#include <cstddef>
916f200b5b87d6cd941f19c01f4ca83d91d13ebef0kwiberg@webrtc.org
9273ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org#include "webrtc/base/constructormagic.h"
9336220ae24f8f5d34b660d6c4c91dd4260886dcb9kwiberg#include "webrtc/base/deprecation.h"
9473ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org#include "webrtc/base/template_util.h"
9573ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org#include "webrtc/typedefs.h"
96f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
97f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgnamespace rtc {
98f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
99f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// Function object which deletes its parameter, which must be a pointer.
100f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// If C is an array type, invokes 'delete[]' on the parameter; otherwise,
101f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// invokes 'delete'. The default deleter for scoped_ptr<T>.
102f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgtemplate <class T>
103f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgstruct DefaultDeleter {
104f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  DefaultDeleter() {}
105f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  template <typename U> DefaultDeleter(const DefaultDeleter<U>& other) {
106f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    // IMPLEMENTATION NOTE: C++11 20.7.1.1.2p2 only provides this constructor
107f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    // if U* is implicitly convertible to T* and U is not an array type.
108f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    //
109f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    // Correct implementation should use SFINAE to disable this
110f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    // constructor. However, since there are no other 1-argument constructors,
1112ebfac5649a5e48fbbc501b42a4336ff979c03e6kwiberg@webrtc.org    // using a static_assert based on is_convertible<> and requiring
112f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    // complete types is simpler and will cause compile failures for equivalent
113f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    // misuses.
114f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    //
115f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    // Note, the is_convertible<U*, T*> check also ensures that U is not an
116f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    // array. T is guaranteed to be a non-array, so any U* where U is an array
117f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    // cannot convert to T*.
118f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    enum { T_must_be_complete = sizeof(T) };
119f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    enum { U_must_be_complete = sizeof(U) };
120675d4373f87b2468a334f2ed48bfa4e6946d80f1Chih-Hung Hsieh    static_assert((rtc::is_convertible<U*, T*>::value),
1212ebfac5649a5e48fbbc501b42a4336ff979c03e6kwiberg@webrtc.org                  "U* must implicitly convert to T*");
122f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
123f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  inline void operator()(T* ptr) const {
124f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    enum { type_must_be_complete = sizeof(T) };
125f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    delete ptr;
126f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
127f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org};
128f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
129f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// Specialization of DefaultDeleter for array types.
130f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgtemplate <class T>
131f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgstruct DefaultDeleter<T[]> {
132f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  inline void operator()(T* ptr) const {
133f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    enum { type_must_be_complete = sizeof(T) };
134f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    delete[] ptr;
135f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
136f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
137f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org private:
138f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Disable this operator for any U != T because it is undefined to execute
139f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // an array delete when the static type of the array mismatches the dynamic
140f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // type.
141f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  //
142f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // References:
143f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  //   C++98 [expr.delete]p3
144f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  //   http://cplusplus.github.com/LWG/lwg-defects.html#938
145f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  template <typename U> void operator()(U* array) const;
146f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org};
147f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
148f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgtemplate <class T, int n>
149f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgstruct DefaultDeleter<T[n]> {
150f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Never allow someone to declare something like scoped_ptr<int[10]>.
1512ebfac5649a5e48fbbc501b42a4336ff979c03e6kwiberg@webrtc.org  static_assert(sizeof(T) == -1, "do not use array with size as type");
152f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org};
153f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
154f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// Function object which invokes 'free' on its parameter, which must be
155f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// a pointer. Can be used to store malloc-allocated pointers in scoped_ptr:
156f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org//
157f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// scoped_ptr<int, rtc::FreeDeleter> foo_ptr(
158f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org//     static_cast<int*>(malloc(sizeof(int))));
159f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgstruct FreeDeleter {
160f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  inline void operator()(void* ptr) const {
161f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    free(ptr);
162f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
163f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org};
164f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
165f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgnamespace internal {
166f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
16773ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.orgtemplate <typename T>
16873ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.orgstruct ShouldAbortOnSelfReset {
16973ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org  template <typename U>
17073ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org  static rtc::internal::NoType Test(const typename U::AllowSelfReset*);
17173ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org
17273ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org  template <typename U>
17373ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org  static rtc::internal::YesType Test(...);
17473ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org
17573ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org  static const bool value =
17673ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org      sizeof(Test<T>(0)) == sizeof(rtc::internal::YesType);
17773ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org};
17873ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org
179f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// Minimal implementation of the core logic of scoped_ptr, suitable for
180f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// reuse in both scoped_ptr and its specializations.
181f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgtemplate <class T, class D>
182f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgclass scoped_ptr_impl {
183f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org public:
18473ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org  explicit scoped_ptr_impl(T* p) : data_(p) {}
185f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
186f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Initializer for deleters that have data parameters.
187f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  scoped_ptr_impl(T* p, const D& d) : data_(p, d) {}
188f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
189f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Templated constructor that destructively takes the value from another
190f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // scoped_ptr_impl.
191f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  template <typename U, typename V>
192f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  scoped_ptr_impl(scoped_ptr_impl<U, V>* other)
193f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      : data_(other->release(), other->get_deleter()) {
194f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    // We do not support move-only deleters.  We could modify our move
19573ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org    // emulation to have rtc::subtle::move() and rtc::subtle::forward()
196f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    // functions that are imperfect emulations of their C++11 equivalents,
197f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    // but until there's a requirement, just assume deleters are copyable.
198f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
199f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
200f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  template <typename U, typename V>
201f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  void TakeState(scoped_ptr_impl<U, V>* other) {
202f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    // See comment in templated constructor above regarding lack of support
203f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    // for move-only deleters.
204f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    reset(other->release());
205f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    get_deleter() = other->get_deleter();
206f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
207f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
208f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ~scoped_ptr_impl() {
20973ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org    if (data_.ptr != nullptr) {
210f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      // Not using get_deleter() saves one function call in non-optimized
211f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      // builds.
212f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      static_cast<D&>(data_)(data_.ptr);
213f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    }
214f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
215f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
216f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  void reset(T* p) {
21773ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org    // This is a self-reset, which is no longer allowed for default deleters:
21873ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org    // https://crbug.com/162971
21973ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org    assert(!ShouldAbortOnSelfReset<D>::value || p == nullptr || p != data_.ptr);
220f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
221f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    // Note that running data_.ptr = p can lead to undefined behavior if
22273ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org    // get_deleter()(get()) deletes this. In order to prevent this, reset()
223f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    // should update the stored pointer before deleting its old value.
224f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    //
225f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    // However, changing reset() to use that behavior may cause current code to
226f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    // break in unexpected ways. If the destruction of the owned object
227f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    // dereferences the scoped_ptr when it is destroyed by a call to reset(),
228f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    // then it will incorrectly dispatch calls to |p| rather than the original
229f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    // value of |data_.ptr|.
230f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    //
23173ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org    // During the transition period, set the stored pointer to nullptr while
232f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    // deleting the object. Eventually, this safety check will be removed to
23373ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org    // prevent the scenario initially described from occurring and
234f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    // http://crbug.com/176091 can be closed.
235f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    T* old = data_.ptr;
23673ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org    data_.ptr = nullptr;
23773ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org    if (old != nullptr)
238f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      static_cast<D&>(data_)(old);
239f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    data_.ptr = p;
240f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
241f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
242f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  T* get() const { return data_.ptr; }
243f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
244f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  D& get_deleter() { return data_; }
245f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  const D& get_deleter() const { return data_; }
246f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
247f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  void swap(scoped_ptr_impl& p2) {
248f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    // Standard swap idiom: 'using std::swap' ensures that std::swap is
249f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    // present in the overload set, but we call swap unqualified so that
250f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    // any more-specific overloads can be used, if available.
251f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    using std::swap;
252f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    swap(static_cast<D&>(data_), static_cast<D&>(p2.data_));
253f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    swap(data_.ptr, p2.data_.ptr);
254f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
255f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
256f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  T* release() {
257f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    T* old_ptr = data_.ptr;
25873ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org    data_.ptr = nullptr;
259f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return old_ptr;
260f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
261f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
262f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  T** accept() {
26373ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org    reset(nullptr);
264f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return &(data_.ptr);
265f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
266f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
267f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  T** use() {
268f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return &(data_.ptr);
269f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
270f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
271f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org private:
272f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Needed to allow type-converting constructor.
273f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  template <typename U, typename V> friend class scoped_ptr_impl;
274f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
275f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Use the empty base class optimization to allow us to have a D
276f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // member, while avoiding any space overhead for it when D is an
277f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // empty class.  See e.g. http://www.cantrip.org/emptyopt.html for a good
278f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // discussion of this technique.
279f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  struct Data : public D {
280f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    explicit Data(T* ptr_in) : ptr(ptr_in) {}
281f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    Data(T* ptr_in, const D& other) : D(other), ptr(ptr_in) {}
282f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    T* ptr;
283f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  };
284f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
285f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  Data data_;
286f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
2873c089d751ede283e21e186885eaf705c3257ccd2henrikg  RTC_DISALLOW_COPY_AND_ASSIGN(scoped_ptr_impl);
288f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org};
289f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
290f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}  // namespace internal
291f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
292f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// A scoped_ptr<T> is like a T*, except that the destructor of scoped_ptr<T>
293f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// automatically deletes the pointer it holds (if any).
294f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// That is, scoped_ptr<T> owns the T object that it points to.
29573ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org// Like a T*, a scoped_ptr<T> may hold either nullptr or a pointer to a T
29673ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org// object. Also like T*, scoped_ptr<T> is thread-compatible, and once you
297f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// dereference it, you get the thread safety guarantees of T.
298f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org//
299f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// The size of scoped_ptr is small. On most compilers, when using the
300f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// DefaultDeleter, sizeof(scoped_ptr<T>) == sizeof(T*). Custom deleters will
301f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// increase the size proportional to whatever state they need to have. See
302f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// comments inside scoped_ptr_impl<> for details.
303f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org//
304f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// Current implementation targets having a strict subset of  C++11's
305f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// unique_ptr<> features. Known deficiencies include not supporting move-only
30673ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org// deleters, function pointers as deleters, and deleters with reference
307f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// types.
308f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgtemplate <class T, class D = rtc::DefaultDeleter<T> >
309f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgclass scoped_ptr {
31073ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org
31173ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org  // TODO(ajm): If we ever import RefCountedBase, this check needs to be
31273ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org  // enabled.
31373ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org  //static_assert(rtc::internal::IsNotRefCounted<T>::value,
31473ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org  //              "T is refcounted type and needs scoped refptr");
315f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
316f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org public:
317f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // The element and deleter types.
318f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  typedef T element_type;
319f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  typedef D deleter_type;
320f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
32173ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org  // Constructor.  Defaults to initializing with nullptr.
32273ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org  scoped_ptr() : impl_(nullptr) {}
323f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
324f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Constructor.  Takes ownership of p.
32573ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org  explicit scoped_ptr(element_type* p) : impl_(p) {}
326f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
327f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Constructor.  Allows initialization of a stateful deleter.
32873ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org  scoped_ptr(element_type* p, const D& d) : impl_(p, d) {}
32973ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org
33073ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org  // Constructor.  Allows construction from a nullptr.
3319390f84a4a0ccaca7f3eeec55e3b111158583665kwiberg  scoped_ptr(std::nullptr_t) : impl_(nullptr) {}
332f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
333f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Constructor.  Allows construction from a scoped_ptr rvalue for a
334f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // convertible type and deleter.
335f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  //
336f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // IMPLEMENTATION NOTE: C++11 unique_ptr<> keeps this constructor distinct
337f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // from the normal move constructor. By C++11 20.7.1.2.1.21, this constructor
338f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // has different post-conditions if D is a reference type. Since this
339f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // implementation does not support deleters with reference type,
340f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // we do not need a separate move constructor allowing us to avoid one
341f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // use of SFINAE. You only need to care about this if you modify the
342f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // implementation of scoped_ptr.
343f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  template <typename U, typename V>
34473ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org  scoped_ptr(scoped_ptr<U, V>&& other)
34573ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org      : impl_(&other.impl_) {
3462ebfac5649a5e48fbbc501b42a4336ff979c03e6kwiberg@webrtc.org    static_assert(!rtc::is_array<U>::value, "U cannot be an array");
347f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
348f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
349f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // operator=.  Allows assignment from a scoped_ptr rvalue for a convertible
350f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // type and deleter.
351f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  //
352f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // IMPLEMENTATION NOTE: C++11 unique_ptr<> keeps this operator= distinct from
353f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // the normal move assignment operator. By C++11 20.7.1.2.3.4, this templated
354f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // form has different requirements on for move-only Deleters. Since this
355f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // implementation does not support move-only Deleters, we do not need a
356f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // separate move assignment operator allowing us to avoid one use of SFINAE.
357f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // You only need to care about this if you modify the implementation of
358f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // scoped_ptr.
359f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  template <typename U, typename V>
36073ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org  scoped_ptr& operator=(scoped_ptr<U, V>&& rhs) {
3612ebfac5649a5e48fbbc501b42a4336ff979c03e6kwiberg@webrtc.org    static_assert(!rtc::is_array<U>::value, "U cannot be an array");
362f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    impl_.TakeState(&rhs.impl_);
363f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return *this;
364f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
365f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
36673ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org  // operator=.  Allows assignment from a nullptr. Deletes the currently owned
36773ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org  // object, if any.
3689390f84a4a0ccaca7f3eeec55e3b111158583665kwiberg  scoped_ptr& operator=(std::nullptr_t) {
36973ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org    reset();
37073ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org    return *this;
37173ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org  }
37273ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org
373a8e285d1934f2dc739d8a9f810fb4372d8d782b1Karl Wiberg  // Deleted copy constructor and copy assignment, to make the type move-only.
374a8e285d1934f2dc739d8a9f810fb4372d8d782b1Karl Wiberg  scoped_ptr(const scoped_ptr& other) = delete;
375a8e285d1934f2dc739d8a9f810fb4372d8d782b1Karl Wiberg  scoped_ptr& operator=(const scoped_ptr& other) = delete;
376a8e285d1934f2dc739d8a9f810fb4372d8d782b1Karl Wiberg
377a8e285d1934f2dc739d8a9f810fb4372d8d782b1Karl Wiberg  // Get an rvalue reference. (sp.Pass() does the same thing as std::move(sp).)
37836220ae24f8f5d34b660d6c4c91dd4260886dcb9kwiberg  // Deprecated; remove in March 2016 (bug 5373).
37936220ae24f8f5d34b660d6c4c91dd4260886dcb9kwiberg  RTC_DEPRECATED scoped_ptr&& Pass() {
38036220ae24f8f5d34b660d6c4c91dd4260886dcb9kwiberg    return std::move(*this);
38136220ae24f8f5d34b660d6c4c91dd4260886dcb9kwiberg  }
382a8e285d1934f2dc739d8a9f810fb4372d8d782b1Karl Wiberg
383f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Reset.  Deletes the currently owned object, if any.
384f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Then takes ownership of a new object, if given.
38573ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org  void reset(element_type* p = nullptr) { impl_.reset(p); }
386f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
387f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Accessors to get the owned object.
388f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // operator* and operator-> will assert() if there is no current object.
389f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  element_type& operator*() const {
39073ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org    assert(impl_.get() != nullptr);
391f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return *impl_.get();
392f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
393f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  element_type* operator->() const  {
39473ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org    assert(impl_.get() != nullptr);
395f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return impl_.get();
396f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
397f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  element_type* get() const { return impl_.get(); }
398f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
399f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Access to the deleter.
400f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  deleter_type& get_deleter() { return impl_.get_deleter(); }
401f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  const deleter_type& get_deleter() const { return impl_.get_deleter(); }
402f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
403f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Allow scoped_ptr<element_type> to be used in boolean expressions, but not
404f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // implicitly convertible to a real bool (which is dangerous).
405f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  //
406f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Note that this trick is only safe when the == and != operators
407f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // are declared explicitly, as otherwise "scoped_ptr1 ==
408f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // scoped_ptr2" will compile but do the wrong thing (i.e., convert
409f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // to Testable and then do the comparison).
410f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org private:
411f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  typedef rtc::internal::scoped_ptr_impl<element_type, deleter_type>
412f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      scoped_ptr::*Testable;
413f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
414f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org public:
41573ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org  operator Testable() const {
41673ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org    return impl_.get() ? &scoped_ptr::impl_ : nullptr;
41773ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org  }
418f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
419f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Comparison operators.
420f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // These return whether two scoped_ptr refer to the same object, not just to
421f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // two different but equal objects.
422f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  bool operator==(const element_type* p) const { return impl_.get() == p; }
423f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  bool operator!=(const element_type* p) const { return impl_.get() != p; }
424f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
425f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Swap two scoped pointers.
426f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  void swap(scoped_ptr& p2) {
427f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    impl_.swap(p2.impl_);
428f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
429f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
430f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Release a pointer.
43173ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org  // The return value is the current pointer held by this object. If this object
43273ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org  // holds a nullptr, the return value is nullptr. After this operation, this
43373ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org  // object will hold a nullptr, and will not own the object any more.
434f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  element_type* release() WARN_UNUSED_RESULT {
435f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return impl_.release();
436f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
437f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
438f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Delete the currently held pointer and return a pointer
439f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // to allow overwriting of the current pointer address.
440f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  element_type** accept() WARN_UNUSED_RESULT {
441f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return impl_.accept();
442f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
443f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
444f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Return a pointer to the current pointer address.
445f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  element_type** use() WARN_UNUSED_RESULT {
446f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return impl_.use();
447f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
448f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
449f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org private:
450f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Needed to reach into |impl_| in the constructor.
451f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  template <typename U, typename V> friend class scoped_ptr;
452f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  rtc::internal::scoped_ptr_impl<element_type, deleter_type> impl_;
453f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
454f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Forbidden for API compatibility with std::unique_ptr.
455f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  explicit scoped_ptr(int disallow_construction_from_null);
456f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
457f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Forbid comparison of scoped_ptr types.  If U != T, it totally
458f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // doesn't make sense, and if U == T, it still doesn't make sense
459f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // because you should never have the same object owned by two different
460f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // scoped_ptrs.
461f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  template <class U> bool operator==(scoped_ptr<U> const& p2) const;
462f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  template <class U> bool operator!=(scoped_ptr<U> const& p2) const;
463f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org};
464f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
465f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgtemplate <class T, class D>
466f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgclass scoped_ptr<T[], D> {
467f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org public:
468f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // The element and deleter types.
469f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  typedef T element_type;
470f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  typedef D deleter_type;
471f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
47273ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org  // Constructor.  Defaults to initializing with nullptr.
47373ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org  scoped_ptr() : impl_(nullptr) {}
474f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
475f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Constructor. Stores the given array. Note that the argument's type
476f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // must exactly match T*. In particular:
477f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // - it cannot be a pointer to a type derived from T, because it is
478f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  //   inherently unsafe in the general case to access an array through a
479f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  //   pointer whose dynamic type does not match its static type (eg., if
480f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  //   T and the derived types had different sizes access would be
481f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  //   incorrectly calculated). Deletion is also always undefined
482f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  //   (C++98 [expr.delete]p3). If you're doing this, fix your code.
483f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // - it cannot be const-qualified differently from T per unique_ptr spec
484f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  //   (http://cplusplus.github.com/LWG/lwg-active.html#2118). Users wanting
485f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  //   to work around this may use implicit_cast<const T*>().
486f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  //   However, because of the first bullet in this comment, users MUST
487f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  //   NOT use implicit_cast<Base*>() to upcast the static type of the array.
48873ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org  explicit scoped_ptr(element_type* array) : impl_(array) {}
48973ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org
49073ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org  // Constructor.  Allows construction from a nullptr.
4919390f84a4a0ccaca7f3eeec55e3b111158583665kwiberg  scoped_ptr(std::nullptr_t) : impl_(nullptr) {}
49273ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org
49373ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org  // Constructor.  Allows construction from a scoped_ptr rvalue.
49473ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org  scoped_ptr(scoped_ptr&& other) : impl_(&other.impl_) {}
495f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
49673ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org  // operator=.  Allows assignment from a scoped_ptr rvalue.
49773ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org  scoped_ptr& operator=(scoped_ptr&& rhs) {
49873ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org    impl_.TakeState(&rhs.impl_);
49973ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org    return *this;
50073ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org  }
501f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
50273ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org  // operator=.  Allows assignment from a nullptr. Deletes the currently owned
50373ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org  // array, if any.
5049390f84a4a0ccaca7f3eeec55e3b111158583665kwiberg  scoped_ptr& operator=(std::nullptr_t) {
50573ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org    reset();
506f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return *this;
507f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
508f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
509a8e285d1934f2dc739d8a9f810fb4372d8d782b1Karl Wiberg  // Deleted copy constructor and copy assignment, to make the type move-only.
510a8e285d1934f2dc739d8a9f810fb4372d8d782b1Karl Wiberg  scoped_ptr(const scoped_ptr& other) = delete;
511a8e285d1934f2dc739d8a9f810fb4372d8d782b1Karl Wiberg  scoped_ptr& operator=(const scoped_ptr& other) = delete;
512a8e285d1934f2dc739d8a9f810fb4372d8d782b1Karl Wiberg
513a8e285d1934f2dc739d8a9f810fb4372d8d782b1Karl Wiberg  // Get an rvalue reference. (sp.Pass() does the same thing as std::move(sp).)
51436220ae24f8f5d34b660d6c4c91dd4260886dcb9kwiberg  // Deprecated; remove in March 2016 (bug 5373).
51536220ae24f8f5d34b660d6c4c91dd4260886dcb9kwiberg  RTC_DEPRECATED scoped_ptr&& Pass() {
51636220ae24f8f5d34b660d6c4c91dd4260886dcb9kwiberg    return std::move(*this);
51736220ae24f8f5d34b660d6c4c91dd4260886dcb9kwiberg  }
518a8e285d1934f2dc739d8a9f810fb4372d8d782b1Karl Wiberg
519f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Reset.  Deletes the currently owned array, if any.
520f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Then takes ownership of a new object, if given.
52173ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org  void reset(element_type* array = nullptr) { impl_.reset(array); }
522f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
523f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Accessors to get the owned array.
524f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  element_type& operator[](size_t i) const {
52573ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org    assert(impl_.get() != nullptr);
526f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return impl_.get()[i];
527f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
528f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  element_type* get() const { return impl_.get(); }
529f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
530f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Access to the deleter.
531f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  deleter_type& get_deleter() { return impl_.get_deleter(); }
532f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  const deleter_type& get_deleter() const { return impl_.get_deleter(); }
533f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
534f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Allow scoped_ptr<element_type> to be used in boolean expressions, but not
535f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // implicitly convertible to a real bool (which is dangerous).
536f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org private:
537f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  typedef rtc::internal::scoped_ptr_impl<element_type, deleter_type>
538f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      scoped_ptr::*Testable;
539f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
540f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org public:
54173ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org  operator Testable() const {
54273ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org    return impl_.get() ? &scoped_ptr::impl_ : nullptr;
54373ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org  }
544f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
545f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Comparison operators.
546f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // These return whether two scoped_ptr refer to the same object, not just to
547f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // two different but equal objects.
548f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  bool operator==(element_type* array) const { return impl_.get() == array; }
549f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  bool operator!=(element_type* array) const { return impl_.get() != array; }
550f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
551f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Swap two scoped pointers.
552f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  void swap(scoped_ptr& p2) {
553f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    impl_.swap(p2.impl_);
554f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
555f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
556f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Release a pointer.
55773ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org  // The return value is the current pointer held by this object. If this object
55873ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org  // holds a nullptr, the return value is nullptr. After this operation, this
55973ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org  // object will hold a nullptr, and will not own the object any more.
560f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  element_type* release() WARN_UNUSED_RESULT {
561f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return impl_.release();
562f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
563f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
564f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Delete the currently held pointer and return a pointer
565f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // to allow overwriting of the current pointer address.
566f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  element_type** accept() WARN_UNUSED_RESULT {
567f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return impl_.accept();
568f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
569f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
570f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Return a pointer to the current pointer address.
571f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  element_type** use() WARN_UNUSED_RESULT {
572f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return impl_.use();
573f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
574f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
575f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org private:
576f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Force element_type to be a complete type.
577f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  enum { type_must_be_complete = sizeof(element_type) };
578f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
579f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Actually hold the data.
580f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  rtc::internal::scoped_ptr_impl<element_type, deleter_type> impl_;
581f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
582f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Disable initialization from any type other than element_type*, by
583f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // providing a constructor that matches such an initialization, but is
584f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // private and has no definition. This is disabled because it is not safe to
585f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // call delete[] on an array whose static type does not match its dynamic
586f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // type.
587f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  template <typename U> explicit scoped_ptr(U* array);
588f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  explicit scoped_ptr(int disallow_construction_from_null);
589f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
590f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Disable reset() from any type other than element_type*, for the same
591f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // reasons as the constructor above.
592f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  template <typename U> void reset(U* array);
593f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  void reset(int disallow_reset_from_null);
594f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
595f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Forbid comparison of scoped_ptr types.  If U != T, it totally
596f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // doesn't make sense, and if U == T, it still doesn't make sense
597f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // because you should never have the same object owned by two different
598f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // scoped_ptrs.
599f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  template <class U> bool operator==(scoped_ptr<U> const& p2) const;
600f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  template <class U> bool operator!=(scoped_ptr<U> const& p2) const;
601f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org};
602f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
603f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgtemplate <class T, class D>
604f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid swap(rtc::scoped_ptr<T, D>& p1, rtc::scoped_ptr<T, D>& p2) {
605f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  p1.swap(p2);
606f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
607f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
6089478437fdea4eb31b92ffe0c10368fe5bc9b9e16Karl Wiberg}  // namespace rtc
6099478437fdea4eb31b92ffe0c10368fe5bc9b9e16Karl Wiberg
610f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgtemplate <class T, class D>
611f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgbool operator==(T* p1, const rtc::scoped_ptr<T, D>& p2) {
612f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return p1 == p2.get();
613f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
614f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
615f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgtemplate <class T, class D>
616f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgbool operator!=(T* p1, const rtc::scoped_ptr<T, D>& p2) {
617f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return p1 != p2.get();
618f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
619f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
62073ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org// A function to convert T* into scoped_ptr<T>
62173ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org// Doing e.g. make_scoped_ptr(new FooBarBaz<type>(arg)) is a shorter notation
62273ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org// for scoped_ptr<FooBarBaz<type> >(new FooBarBaz<type>(arg))
62373ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.orgtemplate <typename T>
62473ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.orgrtc::scoped_ptr<T> rtc_make_scoped_ptr(T* ptr) {
62573ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org  return rtc::scoped_ptr<T>(ptr);
62673ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org}
62773ca1945eccf8e52d2a237a6ef7d3352a4d11d4dkwiberg@webrtc.org
628f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#endif  // #ifndef WEBRTC_BASE_SCOPED_PTR_H__
629