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}
This commit is contained in:
base
chrome
browser
printing
spellchecker
common
media_galleries
components/nacl/browser
content/child
dbus
net/base
remoting/base
storage/browser/blob
ui/gl/android
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
203
base/move.h
203
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) \
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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(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=(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::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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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() {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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() {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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().
|
||||
|
Reference in New Issue
Block a user