OLD | NEW |
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 |
11 // | 11 // |
12 // This macro should be used instead of DISALLOW_COPY_AND_ASSIGN to create | 12 // This macro should be used instead of DISALLOW_COPY_AND_ASSIGN to create |
13 // a "move-only" type. Unlike DISALLOW_COPY_AND_ASSIGN, this macro should be | 13 // a "move-only" type. Unlike DISALLOW_COPY_AND_ASSIGN, this macro should be |
14 // the first line in a class declaration. | 14 // the first line in a class declaration. |
15 // | 15 // |
16 // A class using this macro must call .Pass() (or somehow be an r-value already) | 16 // A class using this macro must call .Pass() (or somehow be an r-value already) |
17 // before it can be: | 17 // before it can be: |
18 // | 18 // |
19 // * Passed as a function argument | 19 // * Passed as a function argument |
20 // * Used as the right-hand side of an assignment | 20 // * Used as the right-hand side of an assignment |
21 // * Return from a function | 21 // * Returned from a function |
22 // | 22 // |
23 // Each class will still need to define their own "move constructor" and "move | 23 // Each class will still need to define their own "move constructor" and "move |
24 // operator=" to make this useful. Here's an example of the macro, the move | 24 // operator=" to make this useful. Here's an example of the macro, the move |
25 // constructor, and the move operator= from the scoped_ptr class: | 25 // constructor, and the move operator= from the scoped_ptr class: |
26 // | 26 // |
27 // template <typename T> | 27 // template <typename T> |
28 // class scoped_ptr { | 28 // class scoped_ptr { |
29 // MOVE_ONLY_TYPE_FOR_CPP_03(scoped_ptr, RValue) | 29 // MOVE_ONLY_TYPE_FOR_CPP_03(scoped_ptr, RValue) |
30 // public: | 30 // public: |
31 // scoped_ptr(RValue& other) : ptr_(other.release()) { } | 31 // scoped_ptr(RValue& other) : ptr_(other.release()) { } |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
115 // | 115 // |
116 // 1) All its methods are declared, but intentionally not defined. | 116 // 1) All its methods are declared, but intentionally not defined. |
117 // 2) It is *never* instantiated. | 117 // 2) It is *never* instantiated. |
118 // 3) It is a child of the move-only type. | 118 // 3) It is a child of the move-only type. |
119 // | 119 // |
120 // (1) is a guard against accidental violation of (2). If an instance of | 120 // (1) is a guard against accidental violation of (2). If an instance of |
121 // RValue were ever created, either as a temporary, or as a copy to some | 121 // RValue were ever created, either as a temporary, or as a copy to some |
122 // function parameter or field of a class, the binary will not link. | 122 // function parameter or field of a class, the binary will not link. |
123 // | 123 // |
124 // This ensures that RValue can only exist as a temporary which is important | 124 // This ensures that RValue can only exist as a temporary which is important |
125 // to avoid accidental danging references. | 125 // to avoid accidental dangling references. |
126 // | 126 // |
127 // (3) allows us to get around instantiations because our user-defined | 127 // (3) allows us to get around instantiations because our user-defined |
128 // conversion can return a downcast of this pointer. | 128 // conversion can return a downcast of this pointer. |
129 // | 129 // |
130 // operator RValue&() { return *reinterpret_cast<RValue*>(this); } | 130 // operator RValue&() { return *reinterpret_cast<RValue*>(this); } |
131 // | 131 // |
132 // Because RValue does not extend the object size or add any virtual methods, | 132 // Because RValue does not extend the object size or add any virtual methods, |
133 // this type-pun is safe. | 133 // this type-pun is safe. |
134 // | 134 // |
135 // An alternative implementation would be to make RValue into a concrete | 135 // An alternative implementation would be to make RValue into a concrete |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
202 void operator=(const rvalue_type&); \ | 202 void operator=(const rvalue_type&); \ |
203 }; \ | 203 }; \ |
204 type(type&); \ | 204 type(type&); \ |
205 void operator=(type&); \ | 205 void operator=(type&); \ |
206 public: \ | 206 public: \ |
207 operator rvalue_type&() { return *reinterpret_cast<rvalue_type*>(this); } \ | 207 operator rvalue_type&() { return *reinterpret_cast<rvalue_type*>(this); } \ |
208 type Pass() { return type(*reinterpret_cast<rvalue_type*>(this)); } \ | 208 type Pass() { return type(*reinterpret_cast<rvalue_type*>(this)); } \ |
209 private: | 209 private: |
210 | 210 |
211 #endif // BASE_MOVE_H_ | 211 #endif // BASE_MOVE_H_ |
OLD | NEW |