[C++] Use 'nullptr'.
[oota-llvm.git] / include / llvm / ADT / OwningPtr.h
index e82ebc7b049c848381eafae2192859dfffdea6d9..5e83358fc0715f8911003ad33ce73d74267ce876 100644 (file)
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef LLVM_ADT_OWNING_PTR_H
-#define LLVM_ADT_OWNING_PTR_H
+#ifndef LLVM_ADT_OWNINGPTR_H
+#define LLVM_ADT_OWNINGPTR_H
 
+#include "llvm/Support/Compiler.h"
 #include <cassert>
 #include <cstddef>
+#include <memory>
 
 namespace llvm {
 
@@ -25,15 +27,30 @@ namespace llvm {
 /// pointee object can be taken away from OwningPtr by using the take method.
 template<class T>
 class OwningPtr {
-  OwningPtr &operator=(const OwningPtr &);  // DO NOT IMPLEMENT
+  OwningPtr(OwningPtr const &) LLVM_DELETED_FUNCTION;
+  OwningPtr &operator=(OwningPtr const &) LLVM_DELETED_FUNCTION;
   T *Ptr;
 public:
   explicit OwningPtr(T *P = 0) : Ptr(P) {}
 
-  OwningPtr(const OwningPtr &RHS) : Ptr(0) {
-    assert(RHS.Ptr == 0 && "Only null OwningPtr's are copyable!");
+  OwningPtr(OwningPtr &&Other) : Ptr(Other.take()) {}
+
+  OwningPtr &operator=(OwningPtr &&Other) {
+    reset(Other.take());
+    return *this;
+  }
+
+  OwningPtr(std::unique_ptr<T> Other) : Ptr(Other.release()) {}
+
+  OwningPtr &operator=(std::unique_ptr<T> Other) {
+    reset(Other.release());
+    return *this;
   }
 
+#if LLVM_HAS_RVALUE_REFERENCE_THIS
+  operator std::unique_ptr<T>() && { return std::unique_ptr<T>(take()); }
+#endif
+
   ~OwningPtr() {
     delete Ptr;
   }
@@ -52,10 +69,14 @@ public:
   /// not delete the pointer before returning it.
   T *take() {
     T *Tmp = Ptr;
-    Ptr = 0;
+    Ptr = nullptr;
     return Tmp;
   }
 
+  T *release() { return take(); }
+
+  std::unique_ptr<T> take_unique() { return std::unique_ptr<T>(take()); }
+
   T &operator*() const {
     assert(Ptr && "Cannot dereference null pointer");
     return *Ptr;
@@ -63,8 +84,9 @@ public:
 
   T *operator->() const { return Ptr; }
   T *get() const { return Ptr; }
-  operator bool() const { return Ptr != 0; }
-  bool operator!() const { return Ptr == 0; }
+  LLVM_EXPLICIT operator bool() const { return Ptr != nullptr; }
+  bool operator!() const { return Ptr == nullptr; }
+  bool isValid() const { return Ptr != nullptr; }
 
   void swap(OwningPtr &RHS) {
     T *Tmp = RHS.Ptr;
@@ -82,12 +104,19 @@ inline void swap(OwningPtr<T> &a, OwningPtr<T> &b) {
 ///  functionality as OwningPtr, except that it works for array types.
 template<class T>
 class OwningArrayPtr {
-  OwningArrayPtr(OwningArrayPtr const &);            // DO NOT IMPLEMENT
-  OwningArrayPtr &operator=(OwningArrayPtr const &); // DO NOT IMPLEMENT
+  OwningArrayPtr(OwningArrayPtr const &) LLVM_DELETED_FUNCTION;
+  OwningArrayPtr &operator=(OwningArrayPtr const &) LLVM_DELETED_FUNCTION;
   T *Ptr;
 public:
   explicit OwningArrayPtr(T *P = 0) : Ptr(P) {}
 
+  OwningArrayPtr(OwningArrayPtr &&Other) : Ptr(Other.take()) {}
+
+  OwningArrayPtr &operator=(OwningArrayPtr &&Other) {
+    reset(Other.take());
+    return *this;
+  }
+
   ~OwningArrayPtr() {
     delete [] Ptr;
   }
@@ -116,8 +145,8 @@ public:
   }
 
   T *get() const { return Ptr; }
-  operator bool() const { return Ptr != 0; }
-  bool operator!() const { return Ptr == 0; }
+  LLVM_EXPLICIT operator bool() const { return Ptr != 0; }
+  bool operator!() const { return Ptr == nullptr; }
 
   void swap(OwningArrayPtr &RHS) {
     T *Tmp = RHS.Ptr;