OLD | NEW |
---|---|
1 // Copyright 2013 Google Inc. All Rights Reserved. | 1 // Copyright 2013 Google Inc. All Rights Reserved. |
2 // | 2 // |
3 // Redistribution and use in source and binary forms, with or without | 3 // Redistribution and use in source and binary forms, with or without |
4 // modification, are permitted provided that the following conditions are | 4 // modification, are permitted provided that the following conditions are |
5 // met: | 5 // met: |
6 // | 6 // |
7 // * Redistributions of source code must retain the above copyright | 7 // * Redistributions of source code must retain the above copyright |
8 // notice, this list of conditions and the following disclaimer. | 8 // notice, this list of conditions and the following disclaimer. |
9 // * Redistributions in binary form must reproduce the above | 9 // * Redistributions in binary form must reproduce the above |
10 // copyright notice, this list of conditions and the following disclaimer | 10 // copyright notice, this list of conditions and the following disclaimer |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
66 #ifndef NONSTD_UNIQUE_PTR_H_ | 66 #ifndef NONSTD_UNIQUE_PTR_H_ |
67 #define NONSTD_UNIQUE_PTR_H_ | 67 #define NONSTD_UNIQUE_PTR_H_ |
68 | 68 |
69 // This is an implementation designed to match the anticipated future C++11 | 69 // This is an implementation designed to match the anticipated future C++11 |
70 // implementation of the unique_ptr class. | 70 // implementation of the unique_ptr class. |
71 | 71 |
72 #include <assert.h> | 72 #include <assert.h> |
73 #include <stddef.h> | 73 #include <stddef.h> |
74 #include <stdlib.h> | 74 #include <stdlib.h> |
75 | 75 |
76 #include <algorithm> | |
Jeffrey Yasskin
2015/09/19 00:00:47
I don't see any uses of these two headers.
You ar
Lei Zhang
2015/09/23 00:38:56
Done.
| |
77 #include <sstream> | |
78 | |
79 #include "template_util.h" | |
80 | |
76 namespace nonstd { | 81 namespace nonstd { |
77 | 82 |
78 // Replacement for move, but doesn't allow things that are already | 83 // Replacement for move, but doesn't allow things that are already |
79 // rvalue references. | 84 // rvalue references. |
80 template <class T> | 85 template <class T> |
81 T&& move(T& t) { | 86 T&& move(T& t) { |
82 return static_cast<T&&>(t); | 87 return static_cast<T&&>(t); |
83 } | 88 } |
84 | 89 |
90 // Function object which deletes its parameter, which must be a pointer. | |
91 // If C is an array type, invokes 'delete[]' on the parameter; otherwise, | |
92 // invokes 'delete'. The default deleter for scoped_ptr<T>. | |
Jeffrey Yasskin
2015/09/19 00:00:47
s/scoped_ptr/unique_ptr/
Lei Zhang
2015/09/23 00:38:55
Done.
| |
93 template <class T> | |
94 struct DefaultDeleter { | |
95 DefaultDeleter() {} | |
96 template <typename U> | |
97 DefaultDeleter(const DefaultDeleter<U>& other) { | |
98 // IMPLEMENTATION NOTE: C++11 20.7.1.1.2p2 only provides this constructor | |
99 // if U* is implicitly convertible to T* and U is not an array type. | |
100 // | |
101 // Correct implementation should use SFINAE to disable this | |
102 // constructor. However, since there are no other 1-argument constructors, | |
103 // using a static_assert() based on is_convertible<> and requiring | |
104 // complete types is simpler and will cause compile failures for equivalent | |
105 // misuses. | |
106 // | |
107 // Note, the is_convertible<U*, T*> check also ensures that U is not an | |
108 // array. T is guaranteed to be a non-array, so any U* where U is an array | |
109 // cannot convert to T*. | |
110 enum { T_must_be_complete = sizeof(T) }; | |
111 enum { U_must_be_complete = sizeof(U) }; | |
112 static_assert((pdfium::base::is_convertible<U*, T*>::value), | |
113 "U_ptr_must_implicitly_convert_to_T_ptr"); | |
114 } | |
115 inline void operator()(T* ptr) const { | |
116 enum { type_must_be_complete = sizeof(T) }; | |
117 delete ptr; | |
118 } | |
119 }; | |
120 | |
121 // Specialization of DefaultDeleter for array types. | |
122 template <class T> | |
123 struct DefaultDeleter<T[]> { | |
124 inline void operator()(T* ptr) const { | |
125 enum { type_must_be_complete = sizeof(T) }; | |
126 delete[] ptr; | |
127 } | |
128 | |
129 private: | |
130 // Disable this operator for any U != T because it is undefined to execute | |
131 // an array delete when the static type of the array mismatches the dynamic | |
132 // type. | |
133 // | |
134 // References: | |
135 // C++98 [expr.delete]p3 | |
136 // http://cplusplus.github.com/LWG/lwg-defects.html#938 | |
137 template <typename U> | |
138 void operator()(U* array) const; | |
139 }; | |
140 | |
141 template <class T, int n> | |
142 struct DefaultDeleter<T[n]> { | |
143 // Never allow someone to declare something like scoped_ptr<int[10]>. | |
144 static_assert(sizeof(T) == -1, "do_not_use_array_with_size_as_type"); | |
145 }; | |
146 | |
147 namespace internal { | |
148 | |
149 template <typename T> | |
150 struct ShouldAbortOnSelfReset { | |
Jeffrey Yasskin
2015/09/19 00:00:47
Can you drop this, and just use the C++11 behavior
Lei Zhang
2015/09/23 00:38:55
So, let the caller shoot themselves in the foot wi
Jeffrey Yasskin
2015/09/23 00:53:34
Yeah. ASan should save us in a lot of cases, and w
| |
151 template <typename U> | |
152 static pdfium::base::internal::NoType Test(const typename U::AllowSelfReset*); | |
153 | |
154 template <typename U> | |
155 static pdfium::base::internal::YesType Test(...); | |
156 | |
157 static const bool value = | |
158 sizeof(Test<T>(0)) == sizeof(pdfium::base::internal::YesType); | |
159 }; | |
160 | |
85 // Common implementation for both pointers to elements and pointers to | 161 // Common implementation for both pointers to elements and pointers to |
86 // arrays. These are differentiated below based on the need to invoke | 162 // arrays. These are differentiated below based on the need to invoke |
87 // delete vs. delete[] as appropriate. | 163 // delete vs. delete[] as appropriate. |
88 template <class C> | 164 template <class C, class D> |
89 class unique_ptr_base { | 165 class unique_ptr_base { |
90 public: | 166 public: |
91 | |
92 // The element type | 167 // The element type |
93 typedef C element_type; | 168 typedef C element_type; |
94 | 169 |
95 explicit unique_ptr_base(C* p) : ptr_(p) { } | 170 explicit unique_ptr_base(C* p) : data_(p) {} |
171 | |
172 // Initializer for deleters that have data parameters. | |
173 unique_ptr_base(C* p, const D& d) : data_(p, d) {} | |
96 | 174 |
97 // Move constructor. | 175 // Move constructor. |
98 unique_ptr_base(unique_ptr_base<C>&& that) { | 176 unique_ptr_base(unique_ptr_base<C, D>&& that) |
99 ptr_ = that.ptr_; | 177 : data_(that.release(), that.get_deleter()) {} |
100 that.ptr_ = nullptr; | 178 |
179 ~unique_ptr_base() { | |
180 enum { type_must_be_complete = sizeof(C) }; | |
181 if (data_.ptr != nullptr) { | |
182 // Not using get_deleter() saves one function call in non-optimized | |
183 // builds. | |
184 static_cast<D&>(data_)(data_.ptr); | |
185 } | |
186 } | |
187 | |
188 void reset(C* p = nullptr) { | |
189 // This is a self-reset, which is no longer allowed for default deleters: | |
190 // https://crbug.com/162971 | |
191 assert(!ShouldAbortOnSelfReset<D>::value || p == nullptr || p != data_.ptr); | |
192 | |
193 // Note that running data_.ptr = p can lead to undefined behavior if | |
194 // get_deleter()(get()) deletes this. In order to prevent this, reset() | |
195 // should update the stored pointer before deleting its old value. | |
196 // | |
197 // However, changing reset() to use that behavior may cause current code to | |
198 // break in unexpected ways. If the destruction of the owned object | |
199 // dereferences the scoped_ptr when it is destroyed by a call to reset(), | |
200 // then it will incorrectly dispatch calls to |p| rather than the original | |
201 // value of |data_.ptr|. | |
202 // | |
203 // During the transition period, set the stored pointer to nullptr while | |
204 // deleting the object. Eventually, this safety check will be removed to | |
205 // prevent the scenario initially described from occuring and | |
206 // http://crbug.com/176091 can be closed. | |
207 C* old = data_.ptr; | |
208 data_.ptr = nullptr; | |
209 if (old != nullptr) | |
210 static_cast<D&>(data_)(old); | |
211 data_.ptr = p; | |
101 } | 212 } |
102 | 213 |
103 // Accessors to get the owned object. | 214 // Accessors to get the owned object. |
104 // operator* and operator-> will assert() if there is no current object. | 215 // operator* and operator-> will assert() if there is no current object. |
105 C& operator*() const { | 216 C& operator*() const { |
Jeffrey Yasskin
2015/09/19 00:00:47
Could you disable unique_ptr<T[]>::operator* and o
Lei Zhang
2015/09/23 00:38:55
Moved out of the base impl.
| |
106 assert(ptr_ != NULL); | 217 assert(data_.ptr != nullptr); |
107 return *ptr_; | 218 return *data_.ptr; |
108 } | 219 } |
109 C* operator->() const { | 220 C* operator->() const { |
110 assert(ptr_ != NULL); | 221 assert(data_.ptr != nullptr); |
111 return ptr_; | 222 return data_.ptr; |
112 } | 223 } |
113 C* get() const { return ptr_; } | 224 C* get() const { return data_.ptr; } |
225 D& get_deleter() { return data_; } | |
226 const D& get_deleter() const { return data_; } | |
114 | 227 |
115 // Comparison operators. | 228 // Comparison operators. |
116 // These return whether two unique_ptr refer to the same object, not just to | 229 // These return whether two unique_ptr refer to the same object, not just to |
117 // two different but equal objects. | 230 // two different but equal objects. |
118 bool operator==(C* p) const { return ptr_ == p; } | 231 bool operator==(C* p) const { return data_.ptr == p; } |
119 bool operator!=(C* p) const { return ptr_ != p; } | 232 bool operator!=(C* p) const { return data_.ptr != p; } |
120 | 233 |
121 // Swap two scoped pointers. | 234 // Swap two scoped pointers. |
122 void swap(unique_ptr_base& p2) { | 235 void swap(unique_ptr_base& p2) { |
123 C* tmp = ptr_; | 236 Data tmp = data_; |
124 ptr_ = p2.ptr_; | 237 data_ = p2.data_; |
125 p2.ptr_ = tmp; | 238 p2.data_ = tmp; |
126 } | 239 } |
127 | 240 |
128 // Release a pointer. | 241 // Release a pointer. |
129 // The return value is the current pointer held by this object. | 242 // The return value is the current pointer held by this object. |
130 // If this object holds a NULL pointer, the return value is NULL. | 243 // If this object holds a NULL pointer, the return value is NULL. |
131 // After this operation, this object will hold a NULL pointer, | 244 // After this operation, this object will hold a NULL pointer, |
132 // and will not own the object any more. | 245 // and will not own the object any more. |
133 C* release() { | 246 C* release() { |
134 C* retVal = ptr_; | 247 C* ptr = data_.ptr; |
135 ptr_ = NULL; | 248 data_.ptr = nullptr; |
136 return retVal; | 249 return ptr; |
137 } | 250 } |
138 | 251 |
139 // Allow promotion to bool for conditional statements. | 252 // Allow promotion to bool for conditional statements. |
140 explicit operator bool() const { return ptr_ != NULL; } | 253 explicit operator bool() const { return data_.ptr != nullptr; } |
141 | 254 |
142 protected: | 255 protected: |
143 C* ptr_; | 256 // Use the empty base class optimization to allow us to have a D |
257 // member, while avoiding any space overhead for it when D is an | |
258 // empty class. See e.g. http://www.cantrip.org/emptyopt.html for a good | |
259 // discussion of this technique. | |
260 struct Data : public D { | |
261 explicit Data(C* ptr_in) : ptr(ptr_in) {} | |
262 Data(C* ptr_in, const D& other) : D(other), ptr(ptr_in) {} | |
263 C* ptr; | |
264 }; | |
265 | |
266 Data data_; | |
144 }; | 267 }; |
145 | 268 |
269 } // namespace internal | |
270 | |
146 // Implementation for ordinary pointers using delete. | 271 // Implementation for ordinary pointers using delete. |
147 template <class C> | 272 template <class C, class D = DefaultDeleter<C>> |
148 class unique_ptr : public unique_ptr_base<C> { | 273 class unique_ptr : public internal::unique_ptr_base<C, D> { |
149 public: | 274 public: |
150 using unique_ptr_base<C>::ptr_; | 275 // Constructor. Defaults to initializing with nullptr. |
276 unique_ptr() : internal::unique_ptr_base<C, D>(nullptr) {} | |
151 | 277 |
152 // Constructor. Defaults to initializing with NULL. There is no way | 278 // Constructor. Takes ownership of p. |
153 // to create an uninitialized unique_ptr. The input parameter must be | 279 explicit unique_ptr(C* p) : internal::unique_ptr_base<C, D>(p) {} |
154 // allocated with new (not new[] - see below). | 280 |
155 explicit unique_ptr(C* p = NULL) : unique_ptr_base<C>(p) { } | 281 // Constructor. Allows initialization of a stateful deleter. |
282 unique_ptr(C* p, const D& d) : internal::unique_ptr_base<C, D>(p, d) {} | |
Jeffrey Yasskin
2015/09/19 00:00:47
This isn't quite the same as C++11, but it should
Lei Zhang
2015/09/23 00:38:55
Acknowledged.
| |
283 | |
284 // Constructor. Allows construction from a nullptr. | |
285 unique_ptr(decltype(nullptr)) : internal::unique_ptr_base<C, D>(nullptr) {} | |
156 | 286 |
157 // Move constructor. | 287 // Move constructor. |
158 unique_ptr(unique_ptr<C>&& that) : unique_ptr_base<C>(nonstd::move(that)) {} | 288 unique_ptr(unique_ptr&& that) |
289 : internal::unique_ptr_base<C, D>(nonstd::move(that)) {} | |
159 | 290 |
160 // Destructor. If there is a C object, delete it. | 291 // operator=. Allows assignment from a nullptr. Deletes the currently owned |
161 // We don't need to test ptr_ == NULL because C++ does that for us. | 292 // object, if any. |
162 ~unique_ptr() { | 293 unique_ptr& operator=(decltype(nullptr)) { |
163 enum { type_must_be_complete = sizeof(C) }; | 294 this->reset(); |
164 delete ptr_; | 295 return *this; |
165 } | 296 } |
166 | 297 |
167 // Reset. Deletes the current owned object, if any. | 298 private: |
168 // Then takes ownership of a new object, if given. | |
169 // this->reset(this->get()) works. | |
170 void reset(C* p = NULL) { | |
171 if (p != ptr_) { | |
172 enum { type_must_be_complete = sizeof(C) }; | |
173 C* old_ptr = ptr_; | |
174 ptr_ = p; | |
175 delete old_ptr; | |
176 } | |
177 } | |
178 | |
179 private: | |
180 // Forbid comparison of unique_ptr types. If C2 != C, it totally doesn't | |
181 // make sense, and if C2 == C, it still doesn't make sense because you should | |
182 // never have the same object owned by two different unique_ptrs. | |
183 template <class C2> bool operator==(unique_ptr<C2> const& p2) const; | |
184 template <class C2> bool operator!=(unique_ptr<C2> const& p2) const; | |
185 | |
186 // Disallow evil constructors. It doesn't make sense to make a copy of | 299 // Disallow evil constructors. It doesn't make sense to make a copy of |
187 // something that's allegedly unique. | 300 // something that's allegedly unique. |
188 unique_ptr(const unique_ptr&) = delete; | 301 unique_ptr(const unique_ptr&) = delete; |
189 void operator=(const unique_ptr&) = delete; | 302 void operator=(const unique_ptr&) = delete; |
190 }; | 303 }; |
191 | 304 |
192 // Specialization for arrays using delete[]. | 305 // Specialization for arrays using delete[]. |
193 template <class C> | 306 template <class C, class D> |
194 class unique_ptr<C[]> : public unique_ptr_base<C> { | 307 class unique_ptr<C[], D> : public internal::unique_ptr_base<C, D> { |
195 public: | 308 public: |
196 using unique_ptr_base<C>::ptr_; | 309 // Constructor. Defaults to initializing with nullptr. |
310 unique_ptr() : internal::unique_ptr_base<C, D>(nullptr) {} | |
197 | 311 |
198 // Constructor. Defaults to initializing with NULL. There is no way | 312 // Constructor. Stores the given array. Note that the argument's type |
199 // to create an uninitialized unique_ptr. The input parameter must be | 313 // must exactly match T*. In particular: |
200 // allocated with new[] (not new - see above). | 314 // - it cannot be a pointer to a type derived from T, because it is |
201 explicit unique_ptr(C* p = NULL) : unique_ptr_base<C>(p) { } | 315 // inherently unsafe in the general case to access an array through a |
316 // pointer whose dynamic type does not match its static type (eg., if | |
317 // T and the derived types had different sizes access would be | |
318 // incorrectly calculated). Deletion is also always undefined | |
319 // (C++98 [expr.delete]p3). If you're doing this, fix your code. | |
320 // - it cannot be const-qualified differently from T per unique_ptr spec | |
321 // (http://cplusplus.github.com/LWG/lwg-active.html#2118). Users wanting | |
322 // to work around this may use const_cast<const T*>(). | |
323 explicit unique_ptr(C* p) : internal::unique_ptr_base<C, D>(p) {} | |
Jeffrey Yasskin
2015/09/19 00:00:48
You need to also copy the "template <typename U> e
Lei Zhang
2015/09/23 00:38:55
Done.
| |
324 | |
325 // Constructor. Allows construction from a nullptr. | |
326 unique_ptr(decltype(nullptr)) : internal::unique_ptr_base<C, D>(nullptr) {} | |
202 | 327 |
203 // Move constructor. | 328 // Move constructor. |
204 unique_ptr(unique_ptr<C>&& that) : unique_ptr_base<C>(nonstd::move(that)) {} | 329 unique_ptr(unique_ptr&& that) |
330 : internal::unique_ptr_base<C, D>(nonstd::move(that)) {} | |
205 | 331 |
206 // Destructor. If there is a C object, delete it. | 332 // operator=. Allows assignment from a nullptr. Deletes the currently owned |
207 // We don't need to test ptr_ == NULL because C++ does that for us. | 333 // array, if any. |
208 ~unique_ptr() { | 334 unique_ptr& operator=(decltype(nullptr)) { |
209 enum { type_must_be_complete = sizeof(C) }; | 335 this->reset(); |
210 delete[] ptr_; | 336 return *this; |
211 } | |
212 | |
213 // Reset. Deletes the current owned object, if any. | |
214 // Then takes ownership of a new object, if given. | |
215 // this->reset(this->get()) works. | |
216 void reset(C* p = NULL) { | |
217 if (p != ptr_) { | |
218 enum { type_must_be_complete = sizeof(C) }; | |
219 C* old_ptr = ptr_; | |
220 ptr_ = p; | |
221 delete[] old_ptr; | |
222 } | |
223 } | 337 } |
224 | 338 |
225 // Support indexing since it is holding array. | 339 // Support indexing since it is holding array. |
226 C& operator[] (size_t i) { return ptr_[i]; } | 340 C& operator[](size_t i) { return this->data_.ptr[i]; } |
227 | 341 |
228 private: | 342 private: |
229 // Forbid comparison of unique_ptr types. If C2 != C, it totally doesn't | |
230 // make sense, and if C2 == C, it still doesn't make sense because you should | |
231 // never have the same object owned by two different unique_ptrs. | |
232 template <class C2> bool operator==(unique_ptr<C2> const& p2) const; | |
233 template <class C2> bool operator!=(unique_ptr<C2> const& p2) const; | |
234 | |
235 // Disallow evil constructors. It doesn't make sense to make a copy of | 343 // Disallow evil constructors. It doesn't make sense to make a copy of |
236 // something that's allegedly unique. | 344 // something that's allegedly unique. |
237 unique_ptr(const unique_ptr&) = delete; | 345 unique_ptr(const unique_ptr&) = delete; |
238 void operator=(const unique_ptr&) = delete; | 346 void operator=(const unique_ptr&) = delete; |
239 }; | 347 }; |
240 | 348 |
241 // Free functions | 349 // Free functions |
242 template <class C> | 350 template <class C> |
243 void swap(unique_ptr<C>& p1, unique_ptr<C>& p2) { | 351 void swap(unique_ptr<C>& p1, unique_ptr<C>& p2) { |
244 p1.swap(p2); | 352 p1.swap(p2); |
245 } | 353 } |
246 | 354 |
247 template <class C> | 355 template <class C> |
248 bool operator==(C* p1, const unique_ptr<C>& p2) { | 356 bool operator==(C* p1, const unique_ptr<C>& p2) { |
249 return p1 == p2.get(); | 357 return p1 == p2.get(); |
250 } | 358 } |
251 | 359 |
252 template <class C> | 360 template <class C> |
253 bool operator!=(C* p1, const unique_ptr<C>& p2) { | 361 bool operator!=(C* p1, const unique_ptr<C>& p2) { |
254 return p1 != p2.get(); | 362 return p1 != p2.get(); |
255 } | 363 } |
256 | 364 |
365 template <typename T> | |
366 std::ostream& operator<<(std::ostream& out, const unique_ptr<T>& p) { | |
367 return out << p.get(); | |
368 } | |
369 | |
257 } // namespace nonstd | 370 } // namespace nonstd |
258 | 371 |
259 #endif // NONSTD_UNIQUE_PTR_H_ | 372 #endif // NONSTD_UNIQUE_PTR_H_ |
OLD | NEW |