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