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 21 namespace 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. 27 template<class T> 28 class OwningPtr { 29 OwningPtr(OwningPtr const &) LLVM_DELETED_FUNCTION; 30 OwningPtr &operator=(OwningPtr const &) LLVM_DELETED_FUNCTION; 31 T *Ptr; 32 public: Ptr(P)33 explicit OwningPtr(T *P = 0) : Ptr(P) {} 34 35 #if LLVM_HAS_RVALUE_REFERENCES OwningPtr(OwningPtr && Other)36 OwningPtr(OwningPtr &&Other) : Ptr(Other.take()) {} 37 38 OwningPtr &operator=(OwningPtr &&Other) { 39 reset(Other.take()); 40 return *this; 41 } 42 #endif 43 ~OwningPtr()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. take()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; } get()72 T *get() const { return Ptr; } 73 operator bool() const { return Ptr != 0; } 74 bool operator!() const { return Ptr == 0; } 75 swap(OwningPtr & RHS)76 void swap(OwningPtr &RHS) { 77 T *Tmp = RHS.Ptr; 78 RHS.Ptr = Ptr; 79 Ptr = Tmp; 80 } 81 }; 82 83 template<class T> swap(OwningPtr<T> & a,OwningPtr<T> & b)84inline void swap(OwningPtr<T> &a, OwningPtr<T> &b) { 85 a.swap(b); 86 } 87 88 /// OwningArrayPtr smart pointer - OwningArrayPtr provides the same 89 /// functionality as OwningPtr, except that it works for array types. 90 template<class T> 91 class OwningArrayPtr { 92 OwningArrayPtr(OwningArrayPtr const &) LLVM_DELETED_FUNCTION; 93 OwningArrayPtr &operator=(OwningArrayPtr const &) LLVM_DELETED_FUNCTION; 94 T *Ptr; 95 public: Ptr(P)96 explicit OwningArrayPtr(T *P = 0) : Ptr(P) {} 97 98 #if LLVM_HAS_RVALUE_REFERENCES OwningArrayPtr(OwningArrayPtr && Other)99 OwningArrayPtr(OwningArrayPtr &&Other) : Ptr(Other.take()) {} 100 101 OwningArrayPtr &operator=(OwningArrayPtr &&Other) { 102 reset(Other.take()); 103 return *this; 104 } 105 #endif 106 ~OwningArrayPtr()107 ~OwningArrayPtr() { 108 delete [] Ptr; 109 } 110 111 /// reset - Change the current pointee to the specified pointer. Note that 112 /// calling this with any pointer (including a null pointer) deletes the 113 /// current pointer. 114 void reset(T *P = 0) { 115 if (P == Ptr) return; 116 T *Tmp = Ptr; 117 Ptr = P; 118 delete [] Tmp; 119 } 120 121 /// take - Reset the owning pointer to null and return its pointer. This does 122 /// not delete the pointer before returning it. take()123 T *take() { 124 T *Tmp = Ptr; 125 Ptr = 0; 126 return Tmp; 127 } 128 129 T &operator[](std::ptrdiff_t i) const { 130 assert(Ptr && "Cannot dereference null pointer"); 131 return Ptr[i]; 132 } 133 get()134 T *get() const { return Ptr; } 135 operator bool() const { return Ptr != 0; } 136 bool operator!() const { return Ptr == 0; } 137 swap(OwningArrayPtr & RHS)138 void swap(OwningArrayPtr &RHS) { 139 T *Tmp = RHS.Ptr; 140 RHS.Ptr = Ptr; 141 Ptr = Tmp; 142 } 143 }; 144 145 template<class T> swap(OwningArrayPtr<T> & a,OwningArrayPtr<T> & b)146inline void swap(OwningArrayPtr<T> &a, OwningArrayPtr<T> &b) { 147 a.swap(b); 148 } 149 150 } // end namespace llvm 151 152 #endif 153