Add move ctor to nonstd::unique_ptr.
authorTom Sepez <tsepez@chromium.org>
Tue, 15 Sep 2015 17:18:52 +0000 (10:18 -0700)
committerTom Sepez <tsepez@chromium.org>
Tue, 15 Sep 2015 17:18:52 +0000 (10:18 -0700)
R=jyasskin@chromium.org

Review URL: https://codereview.chromium.org/1338383002 .

third_party/base/nonstd_unique_ptr.h

index c24bfff..2b08917 100644 (file)
@@ -66,7 +66,7 @@
 #ifndef NONSTD_UNIQUE_PTR_H_
 #define NONSTD_UNIQUE_PTR_H_
 
-// This is an implementation designed to match the anticipated future TR2
+// This is an implementation designed to match the anticipated future C++11
 // implementation of the unique_ptr class.
 
 #include <assert.h>
 
 namespace nonstd {
 
+// Replacement for move, but doesn't allow things that are already
+// rvalue references.
+template <class T>
+constexpr T&& move(T& t) {
+  return static_cast<T&&>(t);
+}
+
 // Common implementation for both pointers to elements and pointers to
 // arrays. These are differentiated below based on the need to invoke
 // delete vs. delete[] as appropriate.
@@ -87,6 +94,12 @@ class unique_ptr_base {
 
   explicit unique_ptr_base(C* p) : ptr_(p) { }
 
+  // Move constructor.
+  unique_ptr_base(unique_ptr_base<C>&& that) {
+    ptr_ = that.ptr_;
+    that.ptr_ = nullptr;
+  }
+
   // Accessors to get the owned object.
   // operator* and operator-> will assert() if there is no current object.
   C& operator*() const {
@@ -124,7 +137,7 @@ class unique_ptr_base {
   }
 
   // Allow promotion to bool for conditional statements.
-  operator bool() const { return ptr_ != NULL; }
+  explicit operator bool() const { return ptr_ != NULL; }
 
  protected:
   C* ptr_;
@@ -141,6 +154,9 @@ class unique_ptr : public unique_ptr_base<C> {
   // allocated with new (not new[] - see below).
   explicit unique_ptr(C* p = NULL) : unique_ptr_base<C>(p) { }
 
+  // Move constructor.
+  unique_ptr(unique_ptr<C>&& that) : unique_ptr_base<C>(nonstd::move(that)) {}
+
   // Destructor.  If there is a C object, delete it.
   // We don't need to test ptr_ == NULL because C++ does that for us.
   ~unique_ptr() {
@@ -167,9 +183,10 @@ private:
   template <class C2> bool operator==(unique_ptr<C2> const& p2) const;
   template <class C2> bool operator!=(unique_ptr<C2> const& p2) const;
 
-  // Disallow evil constructors
-  unique_ptr(const unique_ptr&);
-  void operator=(const unique_ptr&);
+  // Disallow evil constructors. It doesn't make sense to make a copy of
+  // something that's allegedly unique.
+  unique_ptr(const unique_ptr&) = delete;
+  void operator=(const unique_ptr&) = delete;
 };
 
 // Specialization for arrays using delete[].
@@ -183,6 +200,9 @@ class unique_ptr<C[]> : public unique_ptr_base<C> {
   // allocated with new[] (not new - see above).
   explicit unique_ptr(C* p = NULL) : unique_ptr_base<C>(p) { }
 
+  // Move constructor.
+  unique_ptr(unique_ptr<C>&& that) : unique_ptr_base<C>(nonstd::move(that)) {}
+
   // Destructor.  If there is a C object, delete it.
   // We don't need to test ptr_ == NULL because C++ does that for us.
   ~unique_ptr() {
@@ -212,9 +232,10 @@ private:
   template <class C2> bool operator==(unique_ptr<C2> const& p2) const;
   template <class C2> bool operator!=(unique_ptr<C2> const& p2) const;
 
-  // Disallow evil constructors
-  unique_ptr(const unique_ptr&);
-  void operator=(const unique_ptr&);
+  // Disallow evil constructors.  It doesn't make sense to make a copy of
+  // something that's allegedly unique.
+  unique_ptr(const unique_ptr&) = delete;
+  void operator=(const unique_ptr&) = delete;
 };
 
 // Free functions