Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(285)

Side by Side Diff: base/move.h

Issue 12316136: Small non-essential fixes around the code. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Reconciled commits Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef BASE_MOVE_H_ 5 #ifndef BASE_MOVE_H_
6 #define BASE_MOVE_H_ 6 #define BASE_MOVE_H_
7 7
8 // Macro with the boilerplate that makes a type move-only in C++03. 8 // Macro with the boilerplate that makes a type move-only in C++03.
9 // 9 //
10 // USAGE 10 // USAGE
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
118 // It is tempting to want to use the RValue type in function parameters, but 118 // It is tempting to want to use the RValue type in function parameters, but
119 // excluding the limited usage here for the move constructor and move 119 // excluding the limited usage here for the move constructor and move
120 // operator=, doing so would mean that the function could take both r-values 120 // operator=, doing so would mean that the function could take both r-values
121 // and l-values equially which is unexpected. See COMPARED To Boost.Move for 121 // and l-values equially which is unexpected. See COMPARED To Boost.Move for
122 // more details. 122 // more details.
123 // 123 //
124 // An alternate, and incorrect, implementation of the RValue class used by 124 // An alternate, and incorrect, implementation of the RValue class used by
125 // Boost.Move makes RValue a fieldless child of the move-only type. RValue& 125 // Boost.Move makes RValue a fieldless child of the move-only type. RValue&
126 // is then used in place of RValue in the various operators. The RValue& is 126 // is then used in place of RValue in the various operators. The RValue& is
127 // "created" by doing *reinterpret_cast<RValue*>(this). This has the appeal 127 // "created" by doing *reinterpret_cast<RValue*>(this). This has the appeal
128 // of never creating a temproary RValue struct even with optimizations 128 // of never creating a temporary RValue struct even with optimizations
129 // disabled. Also, by virtue of inheritance you can treat the RValue 129 // disabled. Also, by virtue of inheritance you can treat the RValue
130 // reference as if it were the move-only type itself. Unfortuantely, 130 // reference as if it were the move-only type itself. Unfortunately,
131 // using the result of this reinterpret_cast<> is actually undefined behavior 131 // using the result of this reinterpret_cast<> is actually undefined behavior
132 // due to C++98 5.2.10.7. In certain compilers (eg., NaCl) the optimizer 132 // due to C++98 5.2.10.7. In certain compilers (e.g., NaCl) the optimizer
133 // will generate non-working code. 133 // will generate non-working code.
134 // 134 //
135 // In optimized builds, both implementations generate the same assembly so we 135 // In optimized builds, both implementations generate the same assembly so we
136 // choose the one that adheres to the standard. 136 // choose the one that adheres to the standard.
137 // 137 //
138 // 138 //
139 // COMPARED TO C++11 139 // COMPARED TO C++11
140 // 140 //
141 // In C++11, you would implement this functionality using an r-value reference 141 // In C++11, you would implement this functionality using an r-value reference
142 // and our .Pass() method would be replaced with a call to std::move(). 142 // and our .Pass() method would be replaced with a call to std::move().
143 // 143 //
144 // This emulation also has a deficiency where it uses up the single 144 // This emulation also has a deficiency where it uses up the single
145 // user-defined conversion allowed by C++ during initialization. This can 145 // user-defined conversion allowed by C++ during initialization. This can
146 // cause problems in some API edge cases. For instance, in scoped_ptr, it is 146 // cause problems in some API edge cases. For instance, in scoped_ptr, it is
147 // impossible to make an function "void Foo(scoped_ptr<Parent> p)" accept a 147 // impossible to make a function "void Foo(scoped_ptr<Parent> p)" accept a
148 // value of type scoped_ptr<Child> even if you add a constructor to 148 // value of type scoped_ptr<Child> even if you add a constructor to
149 // scoped_ptr<> that would make it look like it should work. C++11 does not 149 // scoped_ptr<> that would make it look like it should work. C++11 does not
150 // have this deficiency. 150 // have this deficiency.
151 // 151 //
152 // 152 //
153 // COMPARED TO Boost.Move 153 // COMPARED TO Boost.Move
154 // 154 //
155 // Our implementation similar to Boost.Move, but we keep the RValue struct 155 // Our implementation similar to Boost.Move, but we keep the RValue struct
156 // private to the move-only type, and we don't use the reinterpret_cast<> hack. 156 // private to the move-only type, and we don't use the reinterpret_cast<> hack.
157 // 157 //
(...skipping 12 matching lines...) Expand all
170 // 170 //
171 // void MyFunc(const Foo& f) 171 // void MyFunc(const Foo& f)
172 // 172 //
173 // that would catch the l-values first. This was declared unsafe in C++11 and 173 // that would catch the l-values first. This was declared unsafe in C++11 and
174 // a C++11 compiler will explicitly fail MyFunc(f). Unfortunately, we cannot 174 // a C++11 compiler will explicitly fail MyFunc(f). Unfortunately, we cannot
175 // ensure this in C++03. 175 // ensure this in C++03.
176 // 176 //
177 // Since we have no need for writing such APIs yet, our implementation keeps 177 // Since we have no need for writing such APIs yet, our implementation keeps
178 // RValue private and uses a .Pass() method to do the conversion instead of 178 // RValue private and uses a .Pass() method to do the conversion instead of
179 // trying to write a version of "std::move()." Writing an API like std::move() 179 // trying to write a version of "std::move()." Writing an API like std::move()
180 // would require the RValue structs to be public. 180 // would require the RValue struct to be public.
181 // 181 //
182 // 182 //
183 // CAVEATS 183 // CAVEATS
184 // 184 //
185 // If you include a move-only type as a field inside a class that does not 185 // If you include a move-only type as a field inside a class that does not
186 // explicitly declare a copy constructor, the containing class's implicit 186 // explicitly declare a copy constructor, the containing class's implicit
187 // copy constructor will change from Containing(const Containing&) to 187 // copy constructor will change from Containing(const Containing&) to
188 // Containing(Containing&). This can cause some unexpected errors. 188 // Containing(Containing&). This can cause some unexpected errors.
189 // 189 //
190 // http://llvm.org/bugs/show_bug.cgi?id=11528 190 // http://llvm.org/bugs/show_bug.cgi?id=11528
191 // 191 //
192 // The workaround is to explicitly declare your copy constructor. 192 // The workaround is to explicitly declare your copy constructor.
193 // 193 //
194 #define MOVE_ONLY_TYPE_FOR_CPP_03(type, rvalue_type) \ 194 #define MOVE_ONLY_TYPE_FOR_CPP_03(type, rvalue_type) \
195 private: \ 195 private: \
196 struct rvalue_type { \ 196 struct rvalue_type { \
197 explicit rvalue_type(type* object) : object(object) {} \ 197 explicit rvalue_type(type* object) : object(object) {} \
198 type* object; \ 198 type* object; \
199 }; \ 199 }; \
200 type(type&); \ 200 type(type&); \
201 void operator=(type&); \ 201 void operator=(type&); \
202 public: \ 202 public: \
203 operator rvalue_type() { return rvalue_type(this); } \ 203 operator rvalue_type() { return rvalue_type(this); } \
204 type Pass() { return type(rvalue_type(this)); } \ 204 type Pass() { return type(rvalue_type(this)); } \
205 private: 205 private:
206 206
207 #endif // BASE_MOVE_H_ 207 #endif // BASE_MOVE_H_
OLDNEW
« no previous file with comments | « ash/accelerators/accelerator_dispatcher.cc ('k') | content/browser/web_contents/web_contents_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698