[C++11] Add release() to OwningPtr.
[oota-llvm.git] / include / llvm / ADT / OwningPtr.h
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 #include <memory>
21
22 namespace llvm {
23
24 /// OwningPtr smart pointer - OwningPtr mimics a built-in pointer except that it
25 /// guarantees deletion of the object pointed to, either on destruction of the
26 /// OwningPtr or via an explicit reset().  Once created, ownership of the
27 /// pointee object can be taken away from OwningPtr by using the take method.
28 template<class T>
29 class OwningPtr {
30   OwningPtr(OwningPtr const &) LLVM_DELETED_FUNCTION;
31   OwningPtr &operator=(OwningPtr const &) LLVM_DELETED_FUNCTION;
32   T *Ptr;
33 public:
34   explicit OwningPtr(T *P = 0) : Ptr(P) {}
35
36   OwningPtr(OwningPtr &&Other) : Ptr(Other.take()) {}
37
38   OwningPtr &operator=(OwningPtr &&Other) {
39     reset(Other.take());
40     return *this;
41   }
42
43   OwningPtr(std::unique_ptr<T> Other) : Ptr(Other.release()) {}
44
45   OwningPtr &operator=(std::unique_ptr<T> Other) {
46     reset(Other.release());
47     return *this;
48   }
49
50 #if LLVM_HAS_RVALUE_REFERENCE_THIS
51   operator std::unique_ptr<T>() && { return std::unique_ptr<T>(take()); }
52 #endif
53
54   ~OwningPtr() {
55     delete Ptr;
56   }
57
58   /// reset - Change the current pointee to the specified pointer.  Note that
59   /// calling this with any pointer (including a null pointer) deletes the
60   /// current pointer.
61   void reset(T *P = 0) {
62     if (P == Ptr) return;
63     T *Tmp = Ptr;
64     Ptr = P;
65     delete Tmp;
66   }
67
68   /// take - Reset the owning pointer to null and return its pointer.  This does
69   /// not delete the pointer before returning it.
70   T *take() {
71     T *Tmp = Ptr;
72     Ptr = 0;
73     return Tmp;
74   }
75
76   T *release() { return take(); }
77
78   std::unique_ptr<T> take_unique() { return std::unique_ptr<T>(take()); }
79
80   T &operator*() const {
81     assert(Ptr && "Cannot dereference null pointer");
82     return *Ptr;
83   }
84
85   T *operator->() const { return Ptr; }
86   T *get() const { return Ptr; }
87   LLVM_EXPLICIT operator bool() const { return Ptr != 0; }
88   bool operator!() const { return Ptr == 0; }
89   bool isValid() const { return Ptr != 0; }
90
91   void swap(OwningPtr &RHS) {
92     T *Tmp = RHS.Ptr;
93     RHS.Ptr = Ptr;
94     Ptr = Tmp;
95   }
96 };
97
98 template<class T>
99 inline void swap(OwningPtr<T> &a, OwningPtr<T> &b) {
100   a.swap(b);
101 }
102
103 /// OwningArrayPtr smart pointer - OwningArrayPtr provides the same
104 ///  functionality as OwningPtr, except that it works for array types.
105 template<class T>
106 class OwningArrayPtr {
107   OwningArrayPtr(OwningArrayPtr const &) LLVM_DELETED_FUNCTION;
108   OwningArrayPtr &operator=(OwningArrayPtr const &) LLVM_DELETED_FUNCTION;
109   T *Ptr;
110 public:
111   explicit OwningArrayPtr(T *P = 0) : Ptr(P) {}
112
113   OwningArrayPtr(OwningArrayPtr &&Other) : Ptr(Other.take()) {}
114
115   OwningArrayPtr &operator=(OwningArrayPtr &&Other) {
116     reset(Other.take());
117     return *this;
118   }
119
120   ~OwningArrayPtr() {
121     delete [] Ptr;
122   }
123
124   /// reset - Change the current pointee to the specified pointer.  Note that
125   /// calling this with any pointer (including a null pointer) deletes the
126   /// current pointer.
127   void reset(T *P = 0) {
128     if (P == Ptr) return;
129     T *Tmp = Ptr;
130     Ptr = P;
131     delete [] Tmp;
132   }
133
134   /// take - Reset the owning pointer to null and return its pointer.  This does
135   /// not delete the pointer before returning it.
136   T *take() {
137     T *Tmp = Ptr;
138     Ptr = 0;
139     return Tmp;
140   }
141
142   T &operator[](std::ptrdiff_t i) const {
143     assert(Ptr && "Cannot dereference null pointer");
144     return Ptr[i];
145   }
146
147   T *get() const { return Ptr; }
148   LLVM_EXPLICIT operator bool() const { return Ptr != 0; }
149   bool operator!() const { return Ptr == 0; }
150
151   void swap(OwningArrayPtr &RHS) {
152     T *Tmp = RHS.Ptr;
153     RHS.Ptr = Ptr;
154     Ptr = Tmp;
155   }
156 };
157
158 template<class T>
159 inline void swap(OwningArrayPtr<T> &a, OwningArrayPtr<T> &b) {
160   a.swap(b);
161 }
162
163 } // end namespace llvm
164
165 #endif