Remove old C++03 move emulation code.

Chrome allows the use of C++11 features now, so just use rvalue
references directly.

BUG=543901

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

Cr-Commit-Position: refs/heads/master@{#362394}


CrOS-Libchrome-Original-Commit: e1b0277c20198c31b8782f567634552243182d08
diff --git a/base/files/file.cc b/base/files/file.cc
index 47b9f88..036d43b 100644
--- a/base/files/file.cc
+++ b/base/files/file.cc
@@ -50,13 +50,12 @@
       async_(false) {
 }
 
-File::File(RValue other)
-    : file_(other.object->TakePlatformFile()),
-      tracing_path_(other.object->tracing_path_),
-      error_details_(other.object->error_details()),
-      created_(other.object->created()),
-      async_(other.object->async_) {
-}
+File::File(File&& other)
+    : file_(other.TakePlatformFile()),
+      tracing_path_(other.tracing_path_),
+      error_details_(other.error_details()),
+      created_(other.created()),
+      async_(other.async_) {}
 
 File::~File() {
   // Go through the AssertIOAllowed logic.
@@ -72,15 +71,14 @@
   return file.Pass();
 }
 
-File& File::operator=(RValue other) {
-  if (this != other.object) {
-    Close();
-    SetPlatformFile(other.object->TakePlatformFile());
-    tracing_path_ = other.object->tracing_path_;
-    error_details_ = other.object->error_details();
-    created_ = other.object->created();
-    async_ = other.object->async_;
-  }
+File& File::operator=(File&& other) {
+  DCHECK_NE(this, &other);
+  Close();
+  SetPlatformFile(other.TakePlatformFile());
+  tracing_path_ = other.tracing_path_;
+  error_details_ = other.error_details();
+  created_ = other.created();
+  async_ = other.async_;
   return *this;
 }
 
diff --git a/base/files/file.h b/base/files/file.h
index 66b78fa..ba4dd34 100644
--- a/base/files/file.h
+++ b/base/files/file.h
@@ -53,7 +53,7 @@
 // to the OS is not considered const, even if there is no apparent change to
 // member variables.
 class BASE_EXPORT File {
-  MOVE_ONLY_TYPE_FOR_CPP_03(File, RValue)
+  MOVE_ONLY_TYPE_FOR_CPP_03(File)
 
  public:
   // FLAG_(OPEN|CREATE).* are mutually exclusive. You should specify exactly one
@@ -169,16 +169,14 @@
   // Creates an object with a specific error_details code.
   explicit File(Error error_details);
 
-  // Move constructor for C++03 move emulation of this type.
-  File(RValue other);
+  File(File&& other);
 
   ~File();
 
   // Takes ownership of |platform_file|.
   static File CreateForAsyncHandle(PlatformFile platform_file);
 
-  // Move operator= for C++03 move emulation of this type.
-  File& operator=(RValue other);
+  File& operator=(File&& other);
 
   // Creates or opens the given file.
   void Initialize(const FilePath& path, uint32 flags);
diff --git a/base/memory/scoped_vector.h b/base/memory/scoped_vector.h
index 250947f..5bfd94e 100644
--- a/base/memory/scoped_vector.h
+++ b/base/memory/scoped_vector.h
@@ -20,7 +20,7 @@
 // we have support for moveable types inside containers).
 template <class T>
 class ScopedVector {
-  MOVE_ONLY_TYPE_FOR_CPP_03(ScopedVector, RValue)
+  MOVE_ONLY_TYPE_FOR_CPP_03(ScopedVector)
 
  public:
   typedef typename std::vector<T*>::allocator_type allocator_type;
@@ -39,10 +39,10 @@
 
   ScopedVector() {}
   ~ScopedVector() { clear(); }
-  ScopedVector(RValue other) { swap(*other.object); }
+  ScopedVector(ScopedVector&& other) { swap(other); }
 
-  ScopedVector& operator=(RValue rhs) {
-    swap(*rhs.object);
+  ScopedVector& operator=(ScopedVector&& rhs) {
+    swap(rhs);
     return *this;
   }
 
diff --git a/base/move.h b/base/move.h
index ce8a8e1..fe0517e 100644
--- a/base/move.h
+++ b/base/move.h
@@ -9,7 +9,7 @@
 
 #include "base/compiler_specific.h"
 
-// Macro with the boilerplate that makes a type move-only in C++03.
+// Macro with the boilerplate that makes a type move-only in C++11.
 //
 // USAGE
 //
@@ -24,121 +24,21 @@
 //   * Used as the right-hand side of an assignment
 //   * Returned from a function
 //
-// Each class will still need to define their own "move constructor" and "move
-// operator=" to make this useful.  Here's an example of the macro, the move
-// constructor, and the move operator= from the scoped_ptr class:
+// Each class will still need to define their own move constructor and move
+// operator= to make this useful.  Here's an example of the macro, the move
+// constructor, and the move operator= from a hypothetical scoped_ptr class:
 //
 //  template <typename T>
 //  class scoped_ptr {
-//     MOVE_ONLY_TYPE_FOR_CPP_03(scoped_ptr, RValue)
+//    MOVE_ONLY_TYPE_WITH_MOVE_CONSTRUCTOR_FOR_CPP_03(type);
 //   public:
-//    scoped_ptr(RValue& other) : ptr_(other.release()) { }
-//    scoped_ptr& operator=(RValue& other) {
-//      swap(other);
+//    scoped_ptr(scoped_ptr&& other) : ptr_(other.release()) { }
+//    scoped_ptr& operator=(scoped_ptr&& other) {
+//      reset(other.release());
 //      return *this;
 //    }
 //  };
 //
-// Note that the constructor must NOT be marked explicit.
-//
-// For consistency, the second parameter to the macro should always be RValue
-// unless you have a strong reason to do otherwise.  It is only exposed as a
-// macro parameter so that the move constructor and move operator= don't look
-// like they're using a phantom type.
-//
-//
-// HOW THIS WORKS
-//
-// For a thorough explanation of this technique, see:
-//
-//   http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Move_Constructor
-//
-// The summary is that we take advantage of 2 properties:
-//
-//   1) non-const references will not bind to r-values.
-//   2) C++ can apply one user-defined conversion when initializing a
-//      variable.
-//
-// The first lets us disable the copy constructor and assignment operator
-// by declaring private version of them with a non-const reference parameter.
-//
-// For l-values, direct initialization still fails like in
-// DISALLOW_COPY_AND_ASSIGN because the copy constructor and assignment
-// operators are private.
-//
-// For r-values, the situation is different. The copy constructor and
-// assignment operator are not viable due to (1), so we are trying to call
-// a non-existent constructor and non-existing operator= rather than a private
-// one.  Since we have not committed an error quite yet, we can provide an
-// alternate conversion sequence and a constructor.  We add
-//
-//   * a private struct named "RValue"
-//   * a user-defined conversion "operator RValue()"
-//   * a "move constructor" and "move operator=" that take the RValue& as
-//     their sole parameter.
-//
-// Only r-values will trigger this sequence and execute our "move constructor"
-// or "move operator=."  L-values will match the private copy constructor and
-// operator= first giving a "private in this context" error.  This combination
-// gives us a move-only type.
-//
-// For signaling a destructive transfer of data from an l-value, we provide a
-// method named Pass() which creates an r-value for the current instance
-// triggering the move constructor or move operator=.
-//
-// Other ways to get r-values is to use the result of an expression like a
-// function call.
-//
-// Here's an example with comments explaining what gets triggered where:
-//
-//    class Foo {
-//      MOVE_ONLY_TYPE_FOR_CPP_03(Foo, RValue);
-//
-//     public:
-//       ... API ...
-//       Foo(RValue other);           // Move constructor.
-//       Foo& operator=(RValue rhs);  // Move operator=
-//    };
-//
-//    Foo MakeFoo();  // Function that returns a Foo.
-//
-//    Foo f;
-//    Foo f_copy(f);  // ERROR: Foo(Foo&) is private in this context.
-//    Foo f_assign;
-//    f_assign = f;   // ERROR: operator=(Foo&) is private in this context.
-//
-//
-//    Foo f(MakeFoo());      // R-value so alternate conversion executed.
-//    Foo f_copy(f.Pass());  // R-value so alternate conversion executed.
-//    f = f_copy.Pass();     // R-value so alternate conversion executed.
-//
-//
-// IMPLEMENTATION SUBTLETIES WITH RValue
-//
-// The RValue struct is just a container for a pointer back to the original
-// object. It should only ever be created as a temporary, and no external
-// class should ever declare it or use it in a parameter.
-//
-// It is tempting to want to use the RValue type in function parameters, but
-// excluding the limited usage here for the move constructor and move
-// operator=, doing so would mean that the function could take both r-values
-// and l-values equially which is unexpected.  See COMPARED To Boost.Move for
-// more details.
-//
-// An alternate, and incorrect, implementation of the RValue class used by
-// Boost.Move makes RValue a fieldless child of the move-only type. RValue&
-// is then used in place of RValue in the various operators.  The RValue& is
-// "created" by doing *reinterpret_cast<RValue*>(this).  This has the appeal
-// of never creating a temporary RValue struct even with optimizations
-// disabled.  Also, by virtue of inheritance you can treat the RValue
-// reference as if it were the move-only type itself.  Unfortunately,
-// using the result of this reinterpret_cast<> is actually undefined behavior
-// due to C++98 5.2.10.7. In certain compilers (e.g., NaCl) the optimizer
-// will generate non-working code.
-//
-// In optimized builds, both implementations generate the same assembly so we
-// choose the one that adheres to the standard.
-//
 //
 // WHY HAVE typedef void MoveOnlyTypeForCPP03
 //
@@ -148,84 +48,19 @@
 // easy and automatic in helper templates for Callback<>/Bind().
 // See IsMoveOnlyType template and its usage in base/callback_internal.h
 // for more details.
-//
-//
-// COMPARED TO C++11
-//
-// In C++11, you would implement this functionality using an r-value reference
-// and our .Pass() method would be replaced with a call to std::move().
-//
-// This emulation also has a deficiency where it uses up the single
-// user-defined conversion allowed by C++ during initialization.  This can
-// cause problems in some API edge cases.  For instance, in scoped_ptr, it is
-// impossible to make a function "void Foo(scoped_ptr<Parent> p)" accept a
-// value of type scoped_ptr<Child> even if you add a constructor to
-// scoped_ptr<> that would make it look like it should work.  C++11 does not
-// have this deficiency.
-//
-//
-// COMPARED TO Boost.Move
-//
-// Our implementation similar to Boost.Move, but we keep the RValue struct
-// private to the move-only type, and we don't use the reinterpret_cast<> hack.
-//
-// In Boost.Move, RValue is the boost::rv<> template.  This type can be used
-// when writing APIs like:
-//
-//   void MyFunc(boost::rv<Foo>& f)
-//
-// that can take advantage of rv<> to avoid extra copies of a type.  However you
-// would still be able to call this version of MyFunc with an l-value:
-//
-//   Foo f;
-//   MyFunc(f);  // Uh oh, we probably just destroyed |f| w/o calling Pass().
-//
-// unless someone is very careful to also declare a parallel override like:
-//
-//   void MyFunc(const Foo& f)
-//
-// that would catch the l-values first.  This was declared unsafe in C++11 and
-// a C++11 compiler will explicitly fail MyFunc(f).  Unfortunately, we cannot
-// ensure this in C++03.
-//
-// Since we have no need for writing such APIs yet, our implementation keeps
-// RValue private and uses a .Pass() method to do the conversion instead of
-// trying to write a version of "std::move()." Writing an API like std::move()
-// would require the RValue struct to be public.
-//
-//
-// CAVEATS
-//
-// If you include a move-only type as a field inside a class that does not
-// explicitly declare a copy constructor, the containing class's implicit
-// copy constructor will change from Containing(const Containing&) to
-// Containing(Containing&).  This can cause some unexpected errors.
-//
-//   http://llvm.org/bugs/show_bug.cgi?id=11528
-//
-// The workaround is to explicitly declare your copy constructor.
-//
-#define MOVE_ONLY_TYPE_FOR_CPP_03(type, rvalue_type) \
- private: \
-  struct rvalue_type { \
-    explicit rvalue_type(type* object) : object(object) {} \
-    type* object; \
-  }; \
-  type(type&); \
-  void operator=(type&); \
- public: \
-  operator rvalue_type() { return rvalue_type(this); } \
-  type Pass() WARN_UNUSED_RESULT { return type(rvalue_type(this)); } \
-  typedef void MoveOnlyTypeForCPP03; \
- private:
 
-#define MOVE_ONLY_TYPE_WITH_MOVE_CONSTRUCTOR_FOR_CPP_03(type) \
- private: \
-  type(const type&); \
-  void operator=(const type&); \
- public: \
+#define MOVE_ONLY_TYPE_FOR_CPP_03(type) \
+  MOVE_ONLY_TYPE_WITH_MOVE_CONSTRUCTOR_FOR_CPP_03(type)
+
+#define MOVE_ONLY_TYPE_WITH_MOVE_CONSTRUCTOR_FOR_CPP_03(type)   \
+ private:                                                       \
+  type(const type&) = delete;                                   \
+  void operator=(const type&) = delete;                         \
+                                                                \
+ public:                                                        \
   type&& Pass() WARN_UNUSED_RESULT { return std::move(*this); } \
-  typedef void MoveOnlyTypeForCPP03; \
+  typedef void MoveOnlyTypeForCPP03;                            \
+                                                                \
  private:
 
 #define TYPE_WITH_MOVE_CONSTRUCTOR_FOR_CPP_03(type) \
diff --git a/base/process/process.h b/base/process/process.h
index 6ff7d76..36f8574 100644
--- a/base/process/process.h
+++ b/base/process/process.h
@@ -32,19 +32,17 @@
 // the process dies, and it may be reused by the system, which means that it may
 // end up pointing to the wrong process.
 class BASE_EXPORT Process {
-  MOVE_ONLY_TYPE_FOR_CPP_03(Process, RValue)
+  MOVE_ONLY_TYPE_FOR_CPP_03(Process)
 
  public:
   explicit Process(ProcessHandle handle = kNullProcessHandle);
 
-  // Move constructor for C++03 move emulation of this type.
-  Process(RValue other);
+  Process(Process&& other);
 
   // The destructor does not terminate the process.
   ~Process();
 
-  // Move operator= for C++03 move emulation of this type.
-  Process& operator=(RValue other);
+  Process& operator=(Process&& other);
 
   // Returns an object for the current process.
   static Process Current();
diff --git a/base/process/process_posix.cc b/base/process/process_posix.cc
index 2320ce7..7b2eed7 100644
--- a/base/process/process_posix.cc
+++ b/base/process/process_posix.cc
@@ -217,16 +217,14 @@
 Process::~Process() {
 }
 
-Process::Process(RValue other)
-    : process_(other.object->process_) {
-  other.object->Close();
+Process::Process(Process&& other) : process_(other.process_) {
+  other.Close();
 }
 
-Process& Process::operator=(RValue other) {
-  if (this != other.object) {
-    process_ = other.object->process_;
-    other.object->Close();
-  }
+Process& Process::operator=(Process&& other) {
+  DCHECK_NE(this, &other);
+  process_ = other.process_;
+  other.Close();
   return *this;
 }
 
diff --git a/dbus/file_descriptor.cc b/dbus/file_descriptor.cc
index c740f28..b690881 100644
--- a/dbus/file_descriptor.cc
+++ b/dbus/file_descriptor.cc
@@ -21,9 +21,8 @@
       FROM_HERE, base::Bind(&base::DeletePointer<FileDescriptor>, fd), false);
 }
 
-FileDescriptor::FileDescriptor(RValue other)
-    : value_(-1), owner_(false), valid_(false) {
-  Swap(other.object);
+FileDescriptor::FileDescriptor(FileDescriptor&& other) : FileDescriptor() {
+  Swap(&other);
 }
 
 FileDescriptor::~FileDescriptor() {
@@ -31,8 +30,8 @@
     base::File auto_closer(value_);
 }
 
-FileDescriptor& FileDescriptor::operator=(RValue other) {
-  Swap(other.object);
+FileDescriptor& FileDescriptor::operator=(FileDescriptor&& other) {
+  Swap(&other);
   return *this;
 }
 
diff --git a/dbus/file_descriptor.h b/dbus/file_descriptor.h
index 8a41097..41f7b4e 100644
--- a/dbus/file_descriptor.h
+++ b/dbus/file_descriptor.h
@@ -34,7 +34,7 @@
 // also allows the caller to do this work on the File thread to conform
 // with i/o restrictions.
 class CHROME_DBUS_EXPORT FileDescriptor {
-  MOVE_ONLY_TYPE_FOR_CPP_03(FileDescriptor, RValue);
+  MOVE_ONLY_TYPE_FOR_CPP_03(FileDescriptor);
 
  public:
   // This provides a simple way to pass around file descriptors since they must
@@ -49,13 +49,11 @@
   explicit FileDescriptor(int value) : value_(value), owner_(false),
       valid_(false) {}
 
-  // Move constructor for C++03 move emulation of this type.
-  FileDescriptor(RValue other);
+  FileDescriptor(FileDescriptor&& other);
 
   virtual ~FileDescriptor();
 
-  // Move operator= for C++03 move emulation of this type.
-  FileDescriptor& operator=(RValue other);
+  FileDescriptor& operator=(FileDescriptor&& other);
 
   // Retrieves value as an int without affecting ownership.
   int value() const;