LLVM API Documentation

OwningPtr.h
Go to the documentation of this file.
00001 //===- llvm/ADT/OwningPtr.h - Smart ptr that owns the pointee ---*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file defines and implements the OwningPtr class.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #ifndef LLVM_ADT_OWNINGPTR_H
00015 #define LLVM_ADT_OWNINGPTR_H
00016 
00017 #include "llvm/Support/Compiler.h"
00018 #include <cassert>
00019 #include <cstddef>
00020 #include <memory>
00021 
00022 namespace llvm {
00023 
00024 /// OwningPtr smart pointer - OwningPtr mimics a built-in pointer except that it
00025 /// guarantees deletion of the object pointed to, either on destruction of the
00026 /// OwningPtr or via an explicit reset().  Once created, ownership of the
00027 /// pointee object can be taken away from OwningPtr by using the take method.
00028 template<class T>
00029 class OwningPtr {
00030   OwningPtr(OwningPtr const &) LLVM_DELETED_FUNCTION;
00031   OwningPtr &operator=(OwningPtr const &) LLVM_DELETED_FUNCTION;
00032   T *Ptr;
00033 public:
00034   explicit OwningPtr(T *P = 0) : Ptr(P) {}
00035 
00036   OwningPtr(OwningPtr &&Other) : Ptr(Other.take()) {}
00037 
00038   OwningPtr &operator=(OwningPtr &&Other) {
00039     reset(Other.take());
00040     return *this;
00041   }
00042 
00043   OwningPtr(std::unique_ptr<T> Other) : Ptr(Other.release()) {}
00044 
00045   OwningPtr &operator=(std::unique_ptr<T> Other) {
00046     reset(Other.release());
00047     return *this;
00048   }
00049 
00050 #if LLVM_HAS_RVALUE_REFERENCE_THIS
00051   operator std::unique_ptr<T>() && { return std::unique_ptr<T>(take()); }
00052 #endif
00053 
00054   ~OwningPtr() {
00055     delete Ptr;
00056   }
00057 
00058   /// reset - Change the current pointee to the specified pointer.  Note that
00059   /// calling this with any pointer (including a null pointer) deletes the
00060   /// current pointer.
00061   void reset(T *P = 0) {
00062     if (P == Ptr) return;
00063     T *Tmp = Ptr;
00064     Ptr = P;
00065     delete Tmp;
00066   }
00067 
00068   /// take - Reset the owning pointer to null and return its pointer.  This does
00069   /// not delete the pointer before returning it.
00070   T *take() {
00071     T *Tmp = Ptr;
00072     Ptr = 0;
00073     return Tmp;
00074   }
00075 
00076   T *release() { return take(); }
00077 
00078   std::unique_ptr<T> take_unique() { return std::unique_ptr<T>(take()); }
00079 
00080   T &operator*() const {
00081     assert(Ptr && "Cannot dereference null pointer");
00082     return *Ptr;
00083   }
00084 
00085   T *operator->() const { return Ptr; }
00086   T *get() const { return Ptr; }
00087   LLVM_EXPLICIT operator bool() const { return Ptr != 0; }
00088   bool operator!() const { return Ptr == 0; }
00089   bool isValid() const { return Ptr != 0; }
00090 
00091   void swap(OwningPtr &RHS) {
00092     T *Tmp = RHS.Ptr;
00093     RHS.Ptr = Ptr;
00094     Ptr = Tmp;
00095   }
00096 };
00097 
00098 template<class T>
00099 inline void swap(OwningPtr<T> &a, OwningPtr<T> &b) {
00100   a.swap(b);
00101 }
00102 
00103 /// OwningArrayPtr smart pointer - OwningArrayPtr provides the same
00104 ///  functionality as OwningPtr, except that it works for array types.
00105 template<class T>
00106 class OwningArrayPtr {
00107   OwningArrayPtr(OwningArrayPtr const &) LLVM_DELETED_FUNCTION;
00108   OwningArrayPtr &operator=(OwningArrayPtr const &) LLVM_DELETED_FUNCTION;
00109   T *Ptr;
00110 public:
00111   explicit OwningArrayPtr(T *P = 0) : Ptr(P) {}
00112 
00113   OwningArrayPtr(OwningArrayPtr &&Other) : Ptr(Other.take()) {}
00114 
00115   OwningArrayPtr &operator=(OwningArrayPtr &&Other) {
00116     reset(Other.take());
00117     return *this;
00118   }
00119 
00120   ~OwningArrayPtr() {
00121     delete [] Ptr;
00122   }
00123 
00124   /// reset - Change the current pointee to the specified pointer.  Note that
00125   /// calling this with any pointer (including a null pointer) deletes the
00126   /// current pointer.
00127   void reset(T *P = 0) {
00128     if (P == Ptr) return;
00129     T *Tmp = Ptr;
00130     Ptr = P;
00131     delete [] Tmp;
00132   }
00133 
00134   /// take - Reset the owning pointer to null and return its pointer.  This does
00135   /// not delete the pointer before returning it.
00136   T *take() {
00137     T *Tmp = Ptr;
00138     Ptr = 0;
00139     return Tmp;
00140   }
00141 
00142   T &operator[](std::ptrdiff_t i) const {
00143     assert(Ptr && "Cannot dereference null pointer");
00144     return Ptr[i];
00145   }
00146 
00147   T *get() const { return Ptr; }
00148   LLVM_EXPLICIT operator bool() const { return Ptr != 0; }
00149   bool operator!() const { return Ptr == nullptr; }
00150 
00151   void swap(OwningArrayPtr &RHS) {
00152     T *Tmp = RHS.Ptr;
00153     RHS.Ptr = Ptr;
00154     Ptr = Tmp;
00155   }
00156 };
00157 
00158 template<class T>
00159 inline void swap(OwningArrayPtr<T> &a, OwningArrayPtr<T> &b) {
00160   a.swap(b);
00161 }
00162 
00163 } // end namespace llvm
00164 
00165 #endif