diff options
author | dcheng <dcheng@chromium.org> | 2015-12-01 04:09:52 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-12-01 12:10:42 +0000 |
commit | e1b0277c20198c31b8782f567634552243182d08 (patch) | |
tree | 75fde33e5410051ddff4de64bbdd9766d294ef25 | |
parent | 7f54a6c611e793e47712cd4a988a46b5fbbdfd07 (diff) | |
download | chromium_src-e1b0277c20198c31b8782f567634552243182d08.zip chromium_src-e1b0277c20198c31b8782f567634552243182d08.tar.gz chromium_src-e1b0277c20198c31b8782f567634552243182d08.tar.bz2 |
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}
24 files changed, 155 insertions, 347 deletions
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 @@ File::File(Error error_details) 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 @@ File File::CreateForAsyncHandle(PlatformFile platform_file) { 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 @@ typedef struct stat64 stat_wrapper_t; // 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 @@ class BASE_EXPORT File { // 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 @@ class ScopedVector { 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 @@ namespace base { // 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(ProcessHandle handle) : process_(handle) { 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/base/process/process_win.cc b/base/process/process_win.cc index 818864f..e7f35b3 100644 --- a/base/process/process_win.cc +++ b/base/process/process_win.cc @@ -25,21 +25,20 @@ Process::Process(ProcessHandle handle) CHECK_NE(handle, ::GetCurrentProcess()); } -Process::Process(RValue other) - : is_current_process_(other.object->is_current_process_), - process_(other.object->process_.Take()) { - other.object->Close(); +Process::Process(Process&& other) + : is_current_process_(other.is_current_process_), + process_(other.process_.Take()) { + other.Close(); } Process::~Process() { } -Process& Process::operator=(RValue other) { - if (this != other.object) { - process_.Set(other.object->process_.Take()); - is_current_process_ = other.object->is_current_process_; - other.object->Close(); - } +Process& Process::operator=(Process&& other) { + DCHECK_NE(this, &other); + process_.Set(other.process_.Take()); + is_current_process_ = other.is_current_process_; + other.Close(); return *this; } diff --git a/base/win/scoped_handle.h b/base/win/scoped_handle.h index d1eb1d6..3e8a748 100644 --- a/base/win/scoped_handle.h +++ b/base/win/scoped_handle.h @@ -36,7 +36,7 @@ namespace win { // this explicitly is necessary because of bug 528394 and VC++ 2015. template <class Traits, class Verifier> class GenericScopedHandle { - MOVE_ONLY_TYPE_FOR_CPP_03(GenericScopedHandle, RValue) + MOVE_ONLY_TYPE_FOR_CPP_03(GenericScopedHandle) public: typedef typename Traits::Handle Handle; @@ -47,9 +47,9 @@ class GenericScopedHandle { Set(handle); } - // Move constructor for C++03 move emulation of this type. - GenericScopedHandle(RValue other) : handle_(Traits::NullHandle()) { - Set(other.object->Take()); + GenericScopedHandle(GenericScopedHandle&& other) + : handle_(Traits::NullHandle()) { + Set(other.Take()); } ~GenericScopedHandle() { @@ -60,11 +60,9 @@ class GenericScopedHandle { return Traits::IsHandleValid(handle_); } - // Move operator= for C++03 move emulation of this type. - GenericScopedHandle& operator=(RValue other) { - if (this != other.object) { - Set(other.object->Take()); - } + GenericScopedHandle& operator=(GenericScopedHandle&& other) { + DCHECK_NE(this, &other); + Set(other.Take()); return *this; } diff --git a/chrome/browser/printing/pdf_to_emf_converter.cc b/chrome/browser/printing/pdf_to_emf_converter.cc index e07bf6a..071327e 100644 --- a/chrome/browser/printing/pdf_to_emf_converter.cc +++ b/chrome/browser/printing/pdf_to_emf_converter.cc @@ -5,6 +5,7 @@ #include "chrome/browser/printing/pdf_to_emf_converter.h" #include <queue> +#include <utility> #include "base/files/file.h" #include "base/files/file_util.h" @@ -113,21 +114,21 @@ class PdfToEmfUtilityProcessHostClient private: class GetPageCallbackData { - MOVE_ONLY_TYPE_FOR_CPP_03(GetPageCallbackData, RValue); + MOVE_ONLY_TYPE_FOR_CPP_03(GetPageCallbackData); public: GetPageCallbackData(int page_number, PdfToEmfConverter::GetPageCallback callback) : page_number_(page_number), callback_(callback) {} - // Move constructor for STL. - GetPageCallbackData(RValue other) { this->operator=(other); } + GetPageCallbackData(GetPageCallbackData&& other) { + *this = std::move(other); + } - // Move assignment for STL. - GetPageCallbackData& operator=(RValue rhs) { - page_number_ = rhs.object->page_number_; - callback_ = rhs.object->callback_; - emf_ = rhs.object->emf_.Pass(); + GetPageCallbackData& operator=(GetPageCallbackData&& rhs) { + page_number_ = rhs.page_number_; + callback_ = rhs.callback_; + emf_ = std::move(rhs.emf_); return *this; } diff --git a/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.cc b/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.cc index 8ce3037..fd575c3 100644 --- a/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.cc +++ b/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.cc @@ -4,6 +4,8 @@ #include "chrome/browser/spellchecker/spellcheck_hunspell_dictionary.h" +#include <utility> + #include "base/files/file_util.h" #include "base/logging.h" #include "base/message_loop/message_loop.h" @@ -79,17 +81,15 @@ SpellcheckHunspellDictionary::DictionaryFile::~DictionaryFile() { } } -SpellcheckHunspellDictionary::DictionaryFile::DictionaryFile(RValue other) - : path(other.object->path), - file(other.object->file.Pass()) { -} +SpellcheckHunspellDictionary::DictionaryFile::DictionaryFile( + DictionaryFile&& other) + : path(other.path), file(std::move(other.file)) {} SpellcheckHunspellDictionary::DictionaryFile& -SpellcheckHunspellDictionary::DictionaryFile::operator=(RValue other) { - if (this != other.object) { - path = other.object->path; - file = other.object->file.Pass(); - } + SpellcheckHunspellDictionary::DictionaryFile:: + operator=(DictionaryFile&& other) { + path = other.path; + file = std::move(other.file); return *this; } diff --git a/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.h b/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.h index a2c5068..a53dc00 100644 --- a/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.h +++ b/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.h @@ -92,14 +92,13 @@ class SpellcheckHunspellDictionary // Dictionary file information to be passed between the FILE and UI threads. struct DictionaryFile { - MOVE_ONLY_TYPE_FOR_CPP_03(DictionaryFile, RValue) + MOVE_ONLY_TYPE_FOR_CPP_03(DictionaryFile) public: DictionaryFile(); ~DictionaryFile(); - // C++03 move emulation of this type. - DictionaryFile(RValue other); - DictionaryFile& operator=(RValue other); + DictionaryFile(DictionaryFile&& other); + DictionaryFile& operator=(DictionaryFile&& other); // The desired location of the dictionary file, whether or not it exists. base::FilePath path; diff --git a/chrome/common/media_galleries/picasa_types.cc b/chrome/common/media_galleries/picasa_types.cc index c39cbf0..6404259 100644 --- a/chrome/common/media_galleries/picasa_types.cc +++ b/chrome/common/media_galleries/picasa_types.cc @@ -4,6 +4,8 @@ #include "chrome/common/media_galleries/picasa_types.h" +#include <utility> + #include "base/logging.h" #include "chrome/common/media_galleries/pmp_constants.h" @@ -66,26 +68,23 @@ AlbumTableFiles::AlbumTableFiles(const base::FilePath& directory_path) AlbumTableFiles::~AlbumTableFiles() { } -AlbumTableFiles::AlbumTableFiles(RValue other) - : indicator_file(other.object->indicator_file.Pass()), - category_file(other.object->category_file.Pass()), - date_file(other.object->date_file.Pass()), - filename_file(other.object->filename_file.Pass()), - name_file(other.object->name_file.Pass()), - token_file(other.object->token_file.Pass()), - uid_file(other.object->uid_file.Pass()) { -} - -AlbumTableFiles& AlbumTableFiles::operator=(RValue other) { - if (this != other.object) { - indicator_file = other.object->indicator_file.Pass(); - category_file = other.object->category_file.Pass(); - date_file = other.object->date_file.Pass(); - filename_file = other.object->filename_file.Pass(); - name_file = other.object->name_file.Pass(); - token_file = other.object->token_file.Pass(); - uid_file = other.object->uid_file.Pass(); - } +AlbumTableFiles::AlbumTableFiles(AlbumTableFiles&& other) + : indicator_file(std::move(other.indicator_file)), + category_file(std::move(other.category_file)), + date_file(std::move(other.date_file)), + filename_file(std::move(other.filename_file)), + name_file(std::move(other.name_file)), + token_file(std::move(other.token_file)), + uid_file(std::move(other.uid_file)) {} + +AlbumTableFiles& AlbumTableFiles::operator=(AlbumTableFiles&& other) { + indicator_file = std::move(other.indicator_file); + category_file = std::move(other.category_file); + date_file = std::move(other.date_file); + filename_file = std::move(other.filename_file); + name_file = std::move(other.name_file); + token_file = std::move(other.token_file); + uid_file = std::move(other.uid_file); return *this; } diff --git a/chrome/common/media_galleries/picasa_types.h b/chrome/common/media_galleries/picasa_types.h index b76946a..03cc78c 100644 --- a/chrome/common/media_galleries/picasa_types.h +++ b/chrome/common/media_galleries/picasa_types.h @@ -55,15 +55,14 @@ struct AlbumInfo { }; struct AlbumTableFiles { - MOVE_ONLY_TYPE_FOR_CPP_03(AlbumTableFiles, RValue) + MOVE_ONLY_TYPE_FOR_CPP_03(AlbumTableFiles) public: AlbumTableFiles(); explicit AlbumTableFiles(const base::FilePath& directory_path); ~AlbumTableFiles(); - // C++03 move emulation of this type. - AlbumTableFiles(RValue other); - AlbumTableFiles& operator=(RValue other); + AlbumTableFiles(AlbumTableFiles&& other); + AlbumTableFiles& operator=(AlbumTableFiles&& other); // Special empty file used to confirm existence of table. base::File indicator_file; diff --git a/components/nacl/browser/nacl_process_host.cc b/components/nacl/browser/nacl_process_host.cc index 6d44c35..7a82df4 100644 --- a/components/nacl/browser/nacl_process_host.cc +++ b/components/nacl/browser/nacl_process_host.cc @@ -213,7 +213,8 @@ unsigned NaClProcessHost::keepalive_throttle_interval_milliseconds_ = // that this only takes a transferred IPC::ChannelHandle or one to be // transferred via IPC. class NaClProcessHost::ScopedChannelHandle { - MOVE_ONLY_TYPE_FOR_CPP_03(ScopedChannelHandle, RValue); + MOVE_ONLY_TYPE_FOR_CPP_03(ScopedChannelHandle); + public: ScopedChannelHandle() { } @@ -221,8 +222,8 @@ class NaClProcessHost::ScopedChannelHandle { : handle_(handle) { DCHECK(IsSupportedHandle(handle_)); } - ScopedChannelHandle(RValue other) : handle_(other.object->handle_) { - other.object->handle_ = IPC::ChannelHandle(); + ScopedChannelHandle(ScopedChannelHandle&& other) : handle_(other.handle_) { + other.handle_ = IPC::ChannelHandle(); DCHECK(IsSupportedHandle(handle_)); } ~ScopedChannelHandle() { diff --git a/content/child/scoped_web_callbacks.h b/content/child/scoped_web_callbacks.h index 7f578dd..b0c3b2b 100644 --- a/content/child/scoped_web_callbacks.h +++ b/content/child/scoped_web_callbacks.h @@ -5,6 +5,8 @@ #ifndef CONTENT_CHILD_SCOPED_WEB_CALLBACKS_H_ #define CONTENT_CHILD_SCOPED_WEB_CALLBACKS_H_ +#include <utility> + #include "base/callback.h" #include "base/memory/scoped_ptr.h" #include "base/move.h" @@ -64,7 +66,7 @@ // our desired default behavior before deleting the WebCallbacks. template <typename CallbacksType> class ScopedWebCallbacks { - MOVE_ONLY_TYPE_FOR_CPP_03(ScopedWebCallbacks, RValue); + MOVE_ONLY_TYPE_FOR_CPP_03(ScopedWebCallbacks); public: using DestructionCallback = @@ -80,11 +82,11 @@ class ScopedWebCallbacks { destruction_callback_.Run(callbacks_.Pass()); } - ScopedWebCallbacks(RValue other) { *this = other; } + ScopedWebCallbacks(ScopedWebCallbacks&& other) { *this = std::move(other); } - ScopedWebCallbacks& operator=(RValue other) { - callbacks_ = other.object->callbacks_.Pass(); - destruction_callback_ = other.object->destruction_callback_; + ScopedWebCallbacks& operator=(ScopedWebCallbacks&& other) { + callbacks_ = std::move(other.callbacks_); + destruction_callback_ = other.destruction_callback_; 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 @@ void CHROME_DBUS_EXPORT FileDescriptor::Deleter::operator()( 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 @@ FileDescriptor::~FileDescriptor() { 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 @@ namespace dbus { // 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 @@ class CHROME_DBUS_EXPORT FileDescriptor { 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; diff --git a/net/base/file_stream_context.cc b/net/base/file_stream_context.cc index 3ddf4bb..6d77d6d 100644 --- a/net/base/file_stream_context.cc +++ b/net/base/file_stream_context.cc @@ -4,6 +4,8 @@ #include "net/base/file_stream_context.h" +#include <utility> + #include "base/files/file_path.h" #include "base/location.h" #include "base/profiler/scoped_tracker.h" @@ -54,17 +56,13 @@ FileStream::Context::OpenResult::OpenResult(base::File file, error_code(error_code) { } -FileStream::Context::OpenResult::OpenResult(RValue other) - : file(other.object->file.Pass()), - error_code(other.object->error_code) { -} +FileStream::Context::OpenResult::OpenResult(OpenResult&& other) + : file(std::move(other.file)), error_code(other.error_code) {} FileStream::Context::OpenResult& FileStream::Context::OpenResult::operator=( - RValue other) { - if (this != other.object) { - file = other.object->file.Pass(); - error_code = other.object->error_code; - } + OpenResult&& other) { + file = std::move(other.file); + error_code = other.error_code; return *this; } diff --git a/net/base/file_stream_context.h b/net/base/file_stream_context.h index c1846c4..a42634d 100644 --- a/net/base/file_stream_context.h +++ b/net/base/file_stream_context.h @@ -110,13 +110,12 @@ class FileStream::Context { }; struct OpenResult { - MOVE_ONLY_TYPE_FOR_CPP_03(OpenResult, RValue) + MOVE_ONLY_TYPE_FOR_CPP_03(OpenResult) public: OpenResult(); OpenResult(base::File file, IOResult error_code); - // C++03 move emulation of this type. - OpenResult(RValue other); - OpenResult& operator=(RValue other); + OpenResult(OpenResult&& other); + OpenResult& operator=(OpenResult&& other); base::File file; IOResult error_code; diff --git a/remoting/base/typed_buffer.h b/remoting/base/typed_buffer.h index c80f720..fd46646 100644 --- a/remoting/base/typed_buffer.h +++ b/remoting/base/typed_buffer.h @@ -10,6 +10,7 @@ #include <algorithm> #include "base/basictypes.h" +#include "base/logging.h" #include "base/move.h" namespace remoting { @@ -20,11 +21,10 @@ namespace remoting { // move-only semantics and typed buffer getters. template <typename T> class TypedBuffer { - MOVE_ONLY_TYPE_FOR_CPP_03(TypedBuffer, RValue) + MOVE_ONLY_TYPE_FOR_CPP_03(TypedBuffer) public: - TypedBuffer() : buffer_(NULL), length_(0) { - } + TypedBuffer() : TypedBuffer(0) {} // Creates an instance of the object allocating a buffer of the given size. explicit TypedBuffer(uint32 length) : buffer_(NULL), length_(length) { @@ -32,12 +32,7 @@ class TypedBuffer { buffer_ = reinterpret_cast<T*>(new uint8[length_]); } - // Move constructor for C++03 move emulation of this type. - TypedBuffer(RValue rvalue) : buffer_(NULL), length_(0) { - TypedBuffer temp; - temp.Swap(*rvalue.object); - Swap(temp); - } + TypedBuffer(TypedBuffer&& rvalue) : TypedBuffer() { Swap(rvalue); } ~TypedBuffer() { if (buffer_) { @@ -46,11 +41,8 @@ class TypedBuffer { } } - // Move operator= for C++03 move emulation of this type. - TypedBuffer& operator=(RValue rvalue) { - TypedBuffer temp; - temp.Swap(*rvalue.object); - Swap(temp); + TypedBuffer& operator=(TypedBuffer&& rvalue) { + Swap(rvalue); return *this; } diff --git a/storage/browser/blob/scoped_file.cc b/storage/browser/blob/scoped_file.cc index 825dc04..b57e882 100644 --- a/storage/browser/blob/scoped_file.cc +++ b/storage/browser/blob/scoped_file.cc @@ -29,8 +29,8 @@ ScopedFile::ScopedFile(const base::FilePath& path, << " runner:" << file_task_runner.get(); } -ScopedFile::ScopedFile(RValue other) { - MoveFrom(*other.object); +ScopedFile::ScopedFile(ScopedFile&& other) { + MoveFrom(other); } ScopedFile::~ScopedFile() { diff --git a/storage/browser/blob/scoped_file.h b/storage/browser/blob/scoped_file.h index a8fd730..583ce78 100644 --- a/storage/browser/blob/scoped_file.h +++ b/storage/browser/blob/scoped_file.h @@ -27,10 +27,7 @@ namespace storage { // TODO(kinuko): Probably this can be moved under base or somewhere more // common place. class STORAGE_EXPORT ScopedFile { - // To support destructive assignment from an l-value assignment. - // This provides Pass() method which creates an r-value for the current - // instance. (See base/move.h for details) - MOVE_ONLY_TYPE_FOR_CPP_03(ScopedFile, RValue) + MOVE_ONLY_TYPE_FOR_CPP_03(ScopedFile) public: typedef base::Callback<void(const base::FilePath&)> ScopeOutCallback; @@ -53,9 +50,9 @@ class STORAGE_EXPORT ScopedFile { // Move constructor and operator. The data of r-value will be transfered // in a destructive way. (See base/move.h) - ScopedFile(RValue other); - ScopedFile& operator=(RValue rhs) { - MoveFrom(*rhs.object); + ScopedFile(ScopedFile&& other); + ScopedFile& operator=(ScopedFile&& rhs) { + MoveFrom(rhs); return *this; } diff --git a/ui/gl/android/scoped_java_surface.cc b/ui/gl/android/scoped_java_surface.cc index ae4f81a..37118ae 100644 --- a/ui/gl/android/scoped_java_surface.cc +++ b/ui/gl/android/scoped_java_surface.cc @@ -48,12 +48,12 @@ ScopedJavaSurface::ScopedJavaSurface( j_surface_.Reset(tmp); } -ScopedJavaSurface::ScopedJavaSurface(RValue rvalue) { - MoveFrom(*rvalue.object); +ScopedJavaSurface::ScopedJavaSurface(ScopedJavaSurface&& rvalue) { + MoveFrom(rvalue); } -ScopedJavaSurface& ScopedJavaSurface::operator=(RValue rhs) { - MoveFrom(*rhs.object); +ScopedJavaSurface& ScopedJavaSurface::operator=(ScopedJavaSurface&& rhs) { + MoveFrom(rhs); return *this; } diff --git a/ui/gl/android/scoped_java_surface.h b/ui/gl/android/scoped_java_surface.h index 641df64..c955cc2 100644 --- a/ui/gl/android/scoped_java_surface.h +++ b/ui/gl/android/scoped_java_surface.h @@ -19,7 +19,7 @@ class SurfaceTexture; // When going out of scope, Surface.release() is called on the Java object to // make sure server-side references (esp. wrt graphics memory) are released. class GL_EXPORT ScopedJavaSurface { - MOVE_ONLY_TYPE_FOR_CPP_03(ScopedJavaSurface, RValue); + MOVE_ONLY_TYPE_FOR_CPP_03(ScopedJavaSurface); public: ScopedJavaSurface(); @@ -33,8 +33,8 @@ class GL_EXPORT ScopedJavaSurface { // Move constructor. Take the surface from another ScopedJavaSurface object, // the latter no longer owns the surface afterwards. - ScopedJavaSurface(RValue rvalue); - ScopedJavaSurface& operator=(RValue rhs); + ScopedJavaSurface(ScopedJavaSurface&& rvalue); + ScopedJavaSurface& operator=(ScopedJavaSurface&& rhs); // Creates a ScopedJavaSurface that is owned externally, i.e., // someone else is responsible to call Surface.release(). |