1193323Sed//===- llvm/ADT/OwningPtr.h - Smart ptr that owns the pointee ---*- C++ -*-===// 2193323Sed// 3193323Sed// The LLVM Compiler Infrastructure 4193323Sed// 5193323Sed// This file is distributed under the University of Illinois Open Source 6193323Sed// License. See LICENSE.TXT for details. 7193323Sed// 8193323Sed//===----------------------------------------------------------------------===// 9193323Sed// 10193323Sed// This file defines and implements the OwningPtr class. 11193323Sed// 12193323Sed//===----------------------------------------------------------------------===// 13193323Sed 14249423Sdim#ifndef LLVM_ADT_OWNINGPTR_H 15249423Sdim#define LLVM_ADT_OWNINGPTR_H 16193323Sed 17243830Sdim#include "llvm/Support/Compiler.h" 18193323Sed#include <cassert> 19193323Sed#include <cstddef> 20193323Sed 21193323Sednamespace llvm { 22193323Sed 23193323Sed/// OwningPtr smart pointer - OwningPtr mimics a built-in pointer except that it 24193323Sed/// guarantees deletion of the object pointed to, either on destruction of the 25193323Sed/// OwningPtr or via an explicit reset(). Once created, ownership of the 26193323Sed/// pointee object can be taken away from OwningPtr by using the take method. 27193323Sedtemplate<class T> 28193323Sedclass OwningPtr { 29243830Sdim OwningPtr(OwningPtr const &) LLVM_DELETED_FUNCTION; 30243830Sdim OwningPtr &operator=(OwningPtr const &) LLVM_DELETED_FUNCTION; 31193323Sed T *Ptr; 32193323Sedpublic: 33193323Sed explicit OwningPtr(T *P = 0) : Ptr(P) {} 34193323Sed 35249423Sdim#if LLVM_HAS_RVALUE_REFERENCES 36243830Sdim OwningPtr(OwningPtr &&Other) : Ptr(Other.take()) {} 37243830Sdim 38243830Sdim OwningPtr &operator=(OwningPtr &&Other) { 39243830Sdim reset(Other.take()); 40243830Sdim return *this; 41243830Sdim } 42243830Sdim#endif 43243830Sdim 44193323Sed ~OwningPtr() { 45193323Sed delete Ptr; 46193323Sed } 47193323Sed 48193323Sed /// reset - Change the current pointee to the specified pointer. Note that 49193323Sed /// calling this with any pointer (including a null pointer) deletes the 50193323Sed /// current pointer. 51193323Sed void reset(T *P = 0) { 52193323Sed if (P == Ptr) return; 53193323Sed T *Tmp = Ptr; 54193323Sed Ptr = P; 55193323Sed delete Tmp; 56193323Sed } 57193323Sed 58193323Sed /// take - Reset the owning pointer to null and return its pointer. This does 59193323Sed /// not delete the pointer before returning it. 60193323Sed T *take() { 61193323Sed T *Tmp = Ptr; 62193323Sed Ptr = 0; 63193323Sed return Tmp; 64193323Sed } 65193323Sed 66193323Sed T &operator*() const { 67193323Sed assert(Ptr && "Cannot dereference null pointer"); 68193323Sed return *Ptr; 69193323Sed } 70193323Sed 71193323Sed T *operator->() const { return Ptr; } 72193323Sed T *get() const { return Ptr; } 73193323Sed operator bool() const { return Ptr != 0; } 74193323Sed bool operator!() const { return Ptr == 0; } 75193323Sed 76193323Sed void swap(OwningPtr &RHS) { 77193323Sed T *Tmp = RHS.Ptr; 78193323Sed RHS.Ptr = Ptr; 79193323Sed Ptr = Tmp; 80193323Sed } 81193323Sed}; 82193323Sed 83193323Sedtemplate<class T> 84193323Sedinline void swap(OwningPtr<T> &a, OwningPtr<T> &b) { 85193323Sed a.swap(b); 86193323Sed} 87193323Sed 88193323Sed/// OwningArrayPtr smart pointer - OwningArrayPtr provides the same 89193323Sed/// functionality as OwningPtr, except that it works for array types. 90193323Sedtemplate<class T> 91193323Sedclass OwningArrayPtr { 92243830Sdim OwningArrayPtr(OwningArrayPtr const &) LLVM_DELETED_FUNCTION; 93243830Sdim OwningArrayPtr &operator=(OwningArrayPtr const &) LLVM_DELETED_FUNCTION; 94193323Sed T *Ptr; 95193323Sedpublic: 96193323Sed explicit OwningArrayPtr(T *P = 0) : Ptr(P) {} 97193323Sed 98249423Sdim#if LLVM_HAS_RVALUE_REFERENCES 99243830Sdim OwningArrayPtr(OwningArrayPtr &&Other) : Ptr(Other.take()) {} 100243830Sdim 101243830Sdim OwningArrayPtr &operator=(OwningArrayPtr &&Other) { 102243830Sdim reset(Other.take()); 103243830Sdim return *this; 104243830Sdim } 105243830Sdim#endif 106243830Sdim 107193323Sed ~OwningArrayPtr() { 108193323Sed delete [] Ptr; 109193323Sed } 110193323Sed 111193323Sed /// reset - Change the current pointee to the specified pointer. Note that 112193323Sed /// calling this with any pointer (including a null pointer) deletes the 113193323Sed /// current pointer. 114193323Sed void reset(T *P = 0) { 115193323Sed if (P == Ptr) return; 116193323Sed T *Tmp = Ptr; 117193323Sed Ptr = P; 118193323Sed delete [] Tmp; 119193323Sed } 120193323Sed 121193323Sed /// take - Reset the owning pointer to null and return its pointer. This does 122193323Sed /// not delete the pointer before returning it. 123193323Sed T *take() { 124193323Sed T *Tmp = Ptr; 125193323Sed Ptr = 0; 126193323Sed return Tmp; 127193323Sed } 128193323Sed 129193323Sed T &operator[](std::ptrdiff_t i) const { 130193323Sed assert(Ptr && "Cannot dereference null pointer"); 131193323Sed return Ptr[i]; 132193323Sed } 133193323Sed 134193323Sed T *get() const { return Ptr; } 135193323Sed operator bool() const { return Ptr != 0; } 136193323Sed bool operator!() const { return Ptr == 0; } 137193323Sed 138193323Sed void swap(OwningArrayPtr &RHS) { 139193323Sed T *Tmp = RHS.Ptr; 140193323Sed RHS.Ptr = Ptr; 141193323Sed Ptr = Tmp; 142193323Sed } 143193323Sed}; 144193323Sed 145193323Sedtemplate<class T> 146193323Sedinline void swap(OwningArrayPtr<T> &a, OwningArrayPtr<T> &b) { 147193323Sed a.swap(b); 148193323Sed} 149193323Sed 150193323Sed} // end namespace llvm 151193323Sed 152193323Sed#endif 153