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

Side by Side Diff: third_party/base/nonstd_unique_ptr.h

Issue 1351383004: Change nonstd::unique_ptr to take a custom deleter. (Closed) Base URL: https://pdfium.googlesource.com/pdfium@master
Patch Set: address comments Created 5 years, 2 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
OLDNEW
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
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 <ostream>
77
78 #include "template_util.h"
79
76 namespace nonstd { 80 namespace nonstd {
77 81
78 // Replacement for move, but doesn't allow things that are already 82 // Replacement for move, but doesn't allow things that are already
79 // rvalue references. 83 // rvalue references.
80 template <class T> 84 template <class T>
81 T&& move(T& t) { 85 T&& move(T& t) {
82 return static_cast<T&&>(t); 86 return static_cast<T&&>(t);
83 } 87 }
84 88
89 // Function object which deletes its parameter, which must be a pointer.
90 // If C is an array type, invokes 'delete[]' on the parameter; otherwise,
91 // invokes 'delete'. The default deleter for unique_ptr<T>.
92 template <class T>
93 struct DefaultDeleter {
94 DefaultDeleter() {}
95 template <typename U>
96 DefaultDeleter(const DefaultDeleter<U>& other) {
97 // IMPLEMENTATION NOTE: C++11 20.7.1.1.2p2 only provides this constructor
98 // if U* is implicitly convertible to T* and U is not an array type.
99 //
100 // Correct implementation should use SFINAE to disable this
101 // constructor. However, since there are no other 1-argument constructors,
102 // using a static_assert() based on is_convertible<> and requiring
103 // complete types is simpler and will cause compile failures for equivalent
104 // misuses.
105 //
106 // Note, the is_convertible<U*, T*> check also ensures that U is not an
107 // array. T is guaranteed to be a non-array, so any U* where U is an array
108 // cannot convert to T*.
109 enum { T_must_be_complete = sizeof(T) };
110 enum { U_must_be_complete = sizeof(U) };
111 static_assert((pdfium::base::is_convertible<U*, T*>::value),
112 "U_ptr_must_implicitly_convert_to_T_ptr");
113 }
114 inline void operator()(T* ptr) const {
115 enum { type_must_be_complete = sizeof(T) };
116 delete ptr;
117 }
118 };
119
120 // Specialization of DefaultDeleter for array types.
121 template <class T>
122 struct DefaultDeleter<T[]> {
123 inline void operator()(T* ptr) const {
124 enum { type_must_be_complete = sizeof(T) };
125 delete[] ptr;
126 }
127
128 private:
129 // Disable this operator for any U != T because it is undefined to execute
130 // an array delete when the static type of the array mismatches the dynamic
131 // type.
132 //
133 // References:
134 // C++98 [expr.delete]p3
135 // http://cplusplus.github.com/LWG/lwg-defects.html#938
136 template <typename U>
137 void operator()(U* array) const;
138 };
139
140 template <class T, int n>
141 struct DefaultDeleter<T[n]> {
142 // Never allow someone to declare something like unique_ptr<int[10]>.
143 static_assert(sizeof(T) == -1, "do_not_use_array_with_size_as_type");
144 };
145
146 namespace internal {
147
85 // Common implementation for both pointers to elements and pointers to 148 // Common implementation for both pointers to elements and pointers to
86 // arrays. These are differentiated below based on the need to invoke 149 // arrays. These are differentiated below based on the need to invoke
87 // delete vs. delete[] as appropriate. 150 // delete vs. delete[] as appropriate.
88 template <class C> 151 template <class C, class D>
89 class unique_ptr_base { 152 class unique_ptr_base {
90 public: 153 public:
91
92 // The element type 154 // The element type
93 typedef C element_type; 155 typedef C element_type;
94 156
95 explicit unique_ptr_base(C* p) : ptr_(p) { } 157 explicit unique_ptr_base(C* p) : data_(p) {}
158
159 // Initializer for deleters that have data parameters.
160 unique_ptr_base(C* p, const D& d) : data_(p, d) {}
96 161
97 // Move constructor. 162 // Move constructor.
98 unique_ptr_base(unique_ptr_base<C>&& that) { 163 unique_ptr_base(unique_ptr_base<C, D>&& that)
99 ptr_ = that.ptr_; 164 : data_(that.release(), that.get_deleter()) {}
100 that.ptr_ = nullptr; 165
166 ~unique_ptr_base() {
167 enum { type_must_be_complete = sizeof(C) };
168 if (data_.ptr != nullptr) {
169 // Not using get_deleter() saves one function call in non-optimized
170 // builds.
171 static_cast<D&>(data_)(data_.ptr);
172 }
101 } 173 }
102 174
103 // Accessors to get the owned object. 175 void reset(C* p = nullptr) {
104 // operator* and operator-> will assert() if there is no current object. 176 C* old = data_.ptr;
105 C& operator*() const { 177 data_.ptr = p;
106 assert(ptr_ != NULL); 178 if (old != nullptr)
107 return *ptr_; 179 static_cast<D&>(data_)(old);
108 } 180 }
109 C* operator->() const { 181
110 assert(ptr_ != NULL); 182 C* get() const { return data_.ptr; }
111 return ptr_; 183 D& get_deleter() { return data_; }
112 } 184 const D& get_deleter() const { return data_; }
113 C* get() const { return ptr_; }
114 185
115 // Comparison operators. 186 // Comparison operators.
116 // These return whether two unique_ptr refer to the same object, not just to 187 // These return whether two unique_ptr refer to the same object, not just to
117 // two different but equal objects. 188 // two different but equal objects.
118 bool operator==(C* p) const { return ptr_ == p; } 189 bool operator==(C* p) const { return data_.ptr == p; }
119 bool operator!=(C* p) const { return ptr_ != p; } 190 bool operator!=(C* p) const { return data_.ptr != p; }
120 191
121 // Swap two scoped pointers. 192 // Swap two unique pointers.
122 void swap(unique_ptr_base& p2) { 193 void swap(unique_ptr_base& p2) {
123 C* tmp = ptr_; 194 Data tmp = data_;
124 ptr_ = p2.ptr_; 195 data_ = p2.data_;
125 p2.ptr_ = tmp; 196 p2.data_ = tmp;
126 } 197 }
127 198
128 // Release a pointer. 199 // Release a pointer.
129 // The return value is the current pointer held by this object. 200 // The return value is the current pointer held by this object.
130 // If this object holds a NULL pointer, the return value is NULL. 201 // If this object holds a NULL pointer, the return value is NULL.
131 // After this operation, this object will hold a NULL pointer, 202 // After this operation, this object will hold a NULL pointer,
132 // and will not own the object any more. 203 // and will not own the object any more.
133 C* release() { 204 C* release() {
134 C* retVal = ptr_; 205 C* ptr = data_.ptr;
135 ptr_ = NULL; 206 data_.ptr = nullptr;
136 return retVal; 207 return ptr;
137 } 208 }
138 209
139 // Allow promotion to bool for conditional statements. 210 // Allow promotion to bool for conditional statements.
140 explicit operator bool() const { return ptr_ != NULL; } 211 explicit operator bool() const { return data_.ptr != nullptr; }
141 212
142 protected: 213 protected:
143 C* ptr_; 214 // Use the empty base class optimization to allow us to have a D
215 // member, while avoiding any space overhead for it when D is an
216 // empty class. See e.g. http://www.cantrip.org/emptyopt.html for a good
217 // discussion of this technique.
218 struct Data : public D {
219 explicit Data(C* ptr_in) : ptr(ptr_in) {}
220 Data(C* ptr_in, const D& other) : D(other), ptr(ptr_in) {}
221 C* ptr;
222 };
223
224 Data data_;
144 }; 225 };
145 226
227 } // namespace internal
228
146 // Implementation for ordinary pointers using delete. 229 // Implementation for ordinary pointers using delete.
147 template <class C> 230 template <class C, class D = DefaultDeleter<C>>
148 class unique_ptr : public unique_ptr_base<C> { 231 class unique_ptr : public internal::unique_ptr_base<C, D> {
149 public: 232 public:
150 using unique_ptr_base<C>::ptr_; 233 // Constructor. Defaults to initializing with nullptr.
234 unique_ptr() : internal::unique_ptr_base<C, D>(nullptr) {}
151 235
152 // Constructor. Defaults to initializing with NULL. There is no way 236 // Constructor. Takes ownership of p.
153 // to create an uninitialized unique_ptr. The input parameter must be 237 explicit unique_ptr(C* p) : internal::unique_ptr_base<C, D>(p) {}
154 // allocated with new (not new[] - see below). 238
155 explicit unique_ptr(C* p = NULL) : unique_ptr_base<C>(p) { } 239 // Constructor. Allows initialization of a stateful deleter.
240 unique_ptr(C* p, const D& d) : internal::unique_ptr_base<C, D>(p, d) {}
241
242 // Constructor. Allows construction from a nullptr.
243 unique_ptr(decltype(nullptr)) : internal::unique_ptr_base<C, D>(nullptr) {}
156 244
157 // Move constructor. 245 // Move constructor.
158 unique_ptr(unique_ptr<C>&& that) : unique_ptr_base<C>(nonstd::move(that)) {} 246 unique_ptr(unique_ptr&& that)
247 : internal::unique_ptr_base<C, D>(nonstd::move(that)) {}
159 248
160 // Destructor. If there is a C object, delete it. 249 // 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. 250 // object, if any.
162 ~unique_ptr() { 251 unique_ptr& operator=(decltype(nullptr)) {
163 enum { type_must_be_complete = sizeof(C) }; 252 this->reset();
164 delete ptr_; 253 return *this;
165 }
166
167 // Reset. Deletes the current owned object, if any.
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 } 254 }
178 255
179 // Move assignment. 256 // Move assignment.
180 unique_ptr<C>& operator=(unique_ptr<C>&& that) { 257 unique_ptr<C>& operator=(unique_ptr<C>&& that) {
181 if (that.ptr_ != ptr_) 258 this->reset(that.release());
182 reset(that.release());
183 return *this; 259 return *this;
184 } 260 }
185 261
186 private: 262 // Accessors to get the owned object.
187 // Forbid comparison of unique_ptr types. If C2 != C, it totally doesn't 263 // operator* and operator-> will assert() if there is no current object.
188 // make sense, and if C2 == C, it still doesn't make sense because you should 264 C& operator*() const {
189 // never have the same object owned by two different unique_ptrs. 265 assert(this->data_.ptr != nullptr);
190 template <class C2> bool operator==(unique_ptr<C2> const& p2) const; 266 return *this->data_.ptr;
191 template <class C2> bool operator!=(unique_ptr<C2> const& p2) const; 267 }
268 C* operator->() const {
269 assert(this->data_.ptr != nullptr);
270 return this->data_.ptr;
271 }
192 272
273 // Comparison operators.
274 // These return whether two unique_ptr refer to the same object, not just to
275 // two different but equal objects.
276 bool operator==(const C* p) const { return this->get() == p; }
277 bool operator!=(const C* p) const { return this->get() != p; }
278
279 private:
193 // Disallow evil constructors. It doesn't make sense to make a copy of 280 // Disallow evil constructors. It doesn't make sense to make a copy of
194 // something that's allegedly unique. 281 // something that's allegedly unique.
195 unique_ptr(const unique_ptr&) = delete; 282 unique_ptr(const unique_ptr&) = delete;
196 void operator=(const unique_ptr&) = delete; 283 void operator=(const unique_ptr&) = delete;
284
285 // Forbid comparison of unique_ptr types. If U != C, it totally
286 // doesn't make sense, and if U == C, it still doesn't make sense
287 // because you should never have the same object owned by two different
288 // unique_ptrs.
289 template <class U>
290 bool operator==(unique_ptr<U> const& p2) const;
291 template <class U>
292 bool operator!=(unique_ptr<U> const& p2) const;
197 }; 293 };
198 294
199 // Specialization for arrays using delete[]. 295 // Specialization for arrays using delete[].
200 template <class C> 296 template <class C, class D>
201 class unique_ptr<C[]> : public unique_ptr_base<C> { 297 class unique_ptr<C[], D> : public internal::unique_ptr_base<C, D> {
202 public: 298 public:
203 using unique_ptr_base<C>::ptr_; 299 // Constructor. Defaults to initializing with nullptr.
300 unique_ptr() : internal::unique_ptr_base<C, D>(nullptr) {}
204 301
205 // Constructor. Defaults to initializing with NULL. There is no way 302 // Constructor. Stores the given array. Note that the argument's type
206 // to create an uninitialized unique_ptr. The input parameter must be 303 // must exactly match T*. In particular:
207 // allocated with new[] (not new - see above). 304 // - it cannot be a pointer to a type derived from T, because it is
208 explicit unique_ptr(C* p = NULL) : unique_ptr_base<C>(p) { } 305 // inherently unsafe in the general case to access an array through a
306 // pointer whose dynamic type does not match its static type (eg., if
307 // T and the derived types had different sizes access would be
308 // incorrectly calculated). Deletion is also always undefined
309 // (C++98 [expr.delete]p3). If you're doing this, fix your code.
310 // - it cannot be const-qualified differently from T per unique_ptr spec
311 // (http://cplusplus.github.com/LWG/lwg-active.html#2118). Users wanting
312 // to work around this may use const_cast<const T*>().
313 explicit unique_ptr(C* p) : internal::unique_ptr_base<C, D>(p) {}
314
315 // Constructor. Allows construction from a nullptr.
316 unique_ptr(decltype(nullptr)) : internal::unique_ptr_base<C, D>(nullptr) {}
209 317
210 // Move constructor. 318 // Move constructor.
211 unique_ptr(unique_ptr<C>&& that) : unique_ptr_base<C>(nonstd::move(that)) {} 319 unique_ptr(unique_ptr&& that)
320 : internal::unique_ptr_base<C, D>(nonstd::move(that)) {}
212 321
213 // Destructor. If there is a C object, delete it. 322 // operator=. Allows assignment from a nullptr. Deletes the currently owned
214 // We don't need to test ptr_ == NULL because C++ does that for us. 323 // array, if any.
215 ~unique_ptr() { 324 unique_ptr& operator=(decltype(nullptr)) {
216 enum { type_must_be_complete = sizeof(C) }; 325 this->reset();
217 delete[] ptr_; 326 return *this;
218 }
219
220 // Reset. Deletes the current owned object, if any.
221 // Then takes ownership of a new object, if given.
222 // this->reset(this->get()) works.
223 void reset(C* p = NULL) {
224 if (p != ptr_) {
225 enum { type_must_be_complete = sizeof(C) };
226 C* old_ptr = ptr_;
227 ptr_ = p;
228 delete[] old_ptr;
229 }
230 } 327 }
231 328
232 // Move assignment. 329 // Move assignment.
233 unique_ptr<C>& operator=(unique_ptr<C>&& that) { 330 unique_ptr<C>& operator=(unique_ptr<C>&& that) {
234 if (that.ptr_ != ptr_) 331 this->reset(that.release());
235 reset(that.release());
236 return *this; 332 return *this;
237 } 333 }
238 334
335 // Reset. Deletes the currently owned array, if any.
336 // Then takes ownership of a new object, if given.
337 void reset(C* array = nullptr) {
338 static_cast<internal::unique_ptr_base<C, D>*>(this)->reset(array);
339 }
340
239 // Support indexing since it is holding array. 341 // Support indexing since it is holding array.
240 C& operator[] (size_t i) { return ptr_[i]; } 342 C& operator[](size_t i) { return this->data_.ptr[i]; }
241 343
242 private: 344 // Comparison operators.
243 // Forbid comparison of unique_ptr types. If C2 != C, it totally doesn't 345 // These return whether two unique_ptr refer to the same object, not just to
244 // make sense, and if C2 == C, it still doesn't make sense because you should 346 // two different but equal objects.
245 // never have the same object owned by two different unique_ptrs. 347 bool operator==(C* array) const { return this->get() == array; }
246 template <class C2> bool operator==(unique_ptr<C2> const& p2) const; 348 bool operator!=(C* array) const { return this->get() != array; }
247 template <class C2> bool operator!=(unique_ptr<C2> const& p2) const; 349
350 private:
351 // Disable initialization from any type other than element_type*, by
352 // providing a constructor that matches such an initialization, but is
353 // private and has no definition. This is disabled because it is not safe to
354 // call delete[] on an array whose static type does not match its dynamic
355 // type.
356 template <typename U>
357 explicit unique_ptr(U* array);
358 explicit unique_ptr(int disallow_construction_from_null);
359
360 // Disable reset() from any type other than element_type*, for the same
361 // reasons as the constructor above.
362 template <typename U>
363 void reset(U* array);
364 void reset(int disallow_reset_from_null);
248 365
249 // Disallow evil constructors. It doesn't make sense to make a copy of 366 // Disallow evil constructors. It doesn't make sense to make a copy of
250 // something that's allegedly unique. 367 // something that's allegedly unique.
251 unique_ptr(const unique_ptr&) = delete; 368 unique_ptr(const unique_ptr&) = delete;
252 void operator=(const unique_ptr&) = delete; 369 void operator=(const unique_ptr&) = delete;
370
371 // Forbid comparison of unique_ptr types. If U != C, it totally
372 // doesn't make sense, and if U == C, it still doesn't make sense
373 // because you should never have the same object owned by two different
374 // unique_ptrs.
375 template <class U>
376 bool operator==(unique_ptr<U> const& p2) const;
377 template <class U>
378 bool operator!=(unique_ptr<U> const& p2) const;
253 }; 379 };
254 380
255 // Free functions 381 // Free functions
256 template <class C> 382 template <class C>
257 void swap(unique_ptr<C>& p1, unique_ptr<C>& p2) { 383 void swap(unique_ptr<C>& p1, unique_ptr<C>& p2) {
258 p1.swap(p2); 384 p1.swap(p2);
259 } 385 }
260 386
261 template <class C> 387 template <class C>
262 bool operator==(C* p1, const unique_ptr<C>& p2) { 388 bool operator==(C* p1, const unique_ptr<C>& p2) {
263 return p1 == p2.get(); 389 return p1 == p2.get();
264 } 390 }
265 391
266 template <class C> 392 template <class C>
267 bool operator!=(C* p1, const unique_ptr<C>& p2) { 393 bool operator!=(C* p1, const unique_ptr<C>& p2) {
268 return p1 != p2.get(); 394 return p1 != p2.get();
269 } 395 }
270 396
397 template <typename T>
398 std::ostream& operator<<(std::ostream& out, const unique_ptr<T>& p) {
399 return out << p.get();
400 }
401
271 } // namespace nonstd 402 } // namespace nonstd
272 403
273 #endif // NONSTD_UNIQUE_PTR_H_ 404 #endif // NONSTD_UNIQUE_PTR_H_
OLDNEW
« no previous file with comments | « core/src/fpdfapi/fpdf_parser/fpdf_parser_parser.cpp ('k') | third_party/base/nonstd_unique_ptr_unittest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698