Home | History | Annotate | Download | only in ADT
      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:
     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 
     84 template<class T>
     85 inline 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.
     91 template<class T>
     92 class OwningArrayPtr {
     93   OwningArrayPtr(OwningArrayPtr const &) LLVM_DELETED_FUNCTION;
     94   OwningArrayPtr &operator=(OwningArrayPtr const &) LLVM_DELETED_FUNCTION;
     95   T *Ptr;
     96 public:
     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 
    146 template<class T>
    147 inline void swap(OwningArrayPtr<T> &a, OwningArrayPtr<T> &b) {
    148   a.swap(b);
    149 }
    150 
    151 } // end namespace llvm
    152 
    153 #endif
    154