1//===- llvm/ADT/OwningPtr.h - Smart ptr that owns the pointee ---*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file defines and implements the OwningPtr class. 11// 12//===----------------------------------------------------------------------===// 13 14#ifndef LLVM_ADT_OWNINGPTR_H 15#define LLVM_ADT_OWNINGPTR_H 16 17#include "llvm/Support/Compiler.h" 18#include <cassert> 19#include <cstddef> 20 21namespace llvm { 22 23/// OwningPtr smart pointer - OwningPtr mimics a built-in pointer except that it 24/// guarantees deletion of the object pointed to, either on destruction of the 25/// OwningPtr or via an explicit reset(). Once created, ownership of the 26/// pointee object can be taken away from OwningPtr by using the take method. 27template<class T> 28class OwningPtr { 29 OwningPtr(OwningPtr const &) LLVM_DELETED_FUNCTION; 30 OwningPtr &operator=(OwningPtr const &) LLVM_DELETED_FUNCTION; 31 T *Ptr; 32public: 33 explicit OwningPtr(T *P = 0) : Ptr(P) {} 34 35#if LLVM_HAS_RVALUE_REFERENCES 36 OwningPtr(OwningPtr &&Other) : Ptr(Other.take()) {} 37 38 OwningPtr &operator=(OwningPtr &&Other) { 39 reset(Other.take()); 40 return *this; 41 } 42#endif 43 44 ~OwningPtr() { 45 delete Ptr; 46 } 47 48 /// reset - Change the current pointee to the specified pointer. Note that 49 /// calling this with any pointer (including a null pointer) deletes the 50 /// current pointer. 51 void reset(T *P = 0) { 52 if (P == Ptr) return; 53 T *Tmp = Ptr; 54 Ptr = P; 55 delete Tmp; 56 } 57 58 /// take - Reset the owning pointer to null and return its pointer. This does 59 /// not delete the pointer before returning it. 60 T *take() { 61 T *Tmp = Ptr; 62 Ptr = 0; 63 return Tmp; 64 } 65 66 T &operator*() const { 67 assert(Ptr && "Cannot dereference null pointer"); 68 return *Ptr; 69 } 70 71 T *operator->() const { return Ptr; } 72 T *get() const { return Ptr; } 73 LLVM_EXPLICIT operator bool() const { return Ptr != 0; } 74 bool operator!() const { return Ptr == 0; } 75 bool isValid() const { return Ptr != 0; } 76 77 void swap(OwningPtr &RHS) { 78 T *Tmp = RHS.Ptr; 79 RHS.Ptr = Ptr; 80 Ptr = Tmp; 81 } 82}; 83 84template<class T> 85inline void swap(OwningPtr<T> &a, OwningPtr<T> &b) { 86 a.swap(b); 87} 88 89/// OwningArrayPtr smart pointer - OwningArrayPtr provides the same 90/// functionality as OwningPtr, except that it works for array types. 91template<class T> 92class OwningArrayPtr { 93 OwningArrayPtr(OwningArrayPtr const &) LLVM_DELETED_FUNCTION; 94 OwningArrayPtr &operator=(OwningArrayPtr const &) LLVM_DELETED_FUNCTION; 95 T *Ptr; 96public: 97 explicit OwningArrayPtr(T *P = 0) : Ptr(P) {} 98 99#if LLVM_HAS_RVALUE_REFERENCES 100 OwningArrayPtr(OwningArrayPtr &&Other) : Ptr(Other.take()) {} 101 102 OwningArrayPtr &operator=(OwningArrayPtr &&Other) { 103 reset(Other.take()); 104 return *this; 105 } 106#endif 107 108 ~OwningArrayPtr() { 109 delete [] Ptr; 110 } 111 112 /// reset - Change the current pointee to the specified pointer. Note that 113 /// calling this with any pointer (including a null pointer) deletes the 114 /// current pointer. 115 void reset(T *P = 0) { 116 if (P == Ptr) return; 117 T *Tmp = Ptr; 118 Ptr = P; 119 delete [] Tmp; 120 } 121 122 /// take - Reset the owning pointer to null and return its pointer. This does 123 /// not delete the pointer before returning it. 124 T *take() { 125 T *Tmp = Ptr; 126 Ptr = 0; 127 return Tmp; 128 } 129 130 T &operator[](std::ptrdiff_t i) const { 131 assert(Ptr && "Cannot dereference null pointer"); 132 return Ptr[i]; 133 } 134 135 T *get() const { return Ptr; } 136 LLVM_EXPLICIT operator bool() const { return Ptr != 0; } 137 bool operator!() const { return Ptr == 0; } 138 139 void swap(OwningArrayPtr &RHS) { 140 T *Tmp = RHS.Ptr; 141 RHS.Ptr = Ptr; 142 Ptr = Tmp; 143 } 144}; 145 146template<class T> 147inline void swap(OwningArrayPtr<T> &a, OwningArrayPtr<T> &b) { 148 a.swap(b); 149} 150 151} // end namespace llvm 152 153#endif 154