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 3 // found in the LICENSE file. 4 5 #ifndef I18N_PHONENUMBERS_BASE_MEMORY_SCOPED_PTR_H_ 6 #define I18N_PHONENUMBERS_BASE_MEMORY_SCOPED_PTR_H_ 7 8 #if defined(I18N_PHONENUMBERS_USE_BOOST) 9 10 #include <boost/scoped_ptr.hpp> 11 using boost::scoped_ptr; 12 13 #else // !I18N_PHONENUMBERS_USE_BOOST 14 15 // This is an implementation designed to match the anticipated future TR2 16 // implementation of the scoped_ptr class and scoped_ptr_malloc (deprecated). 17 18 #include <assert.h> 19 #include <stddef.h> 20 #include <stdlib.h> 21 22 #include <algorithm> // For std::swap(). 23 24 #include "phonenumbers/base/basictypes.h" 25 #include "phonenumbers/base/template_util.h" 26 27 namespace i18n { 28 namespace phonenumbers { 29 30 // Function object which deletes its parameter, which must be a pointer. 31 // If C is an array type, invokes 'delete[]' on the parameter; otherwise, 32 // invokes 'delete'. The default deleter for scoped_ptr<T>. 33 template <class T> 34 struct DefaultDeleter { DefaultDeleterDefaultDeleter35 DefaultDeleter() {} DefaultDeleterDefaultDeleter36 template <typename U> DefaultDeleter(const DefaultDeleter<U>& /*other*/) { 37 // IMPLEMENTATION NOTE: C++11 20.7.1.1.2p2 only provides this constructor 38 // if U* is implicitly convertible to T* and U is not an array type. 39 // 40 // Correct implementation should use SFINAE to disable this 41 // constructor. However, since there are no other 1-argument constructors, 42 // using a COMPILE_ASSERT() based on is_convertible<> and requiring 43 // complete types is simpler and will cause compile failures for equivalent 44 // misuses. 45 // 46 // Note, the is_convertible<U*, T*> check also ensures that U is not an 47 // array. T is guaranteed to be a non-array, so any U* where U is an array 48 // cannot convert to T*. 49 enum { T_must_be_complete = sizeof(T) }; 50 enum { U_must_be_complete = sizeof(U) }; 51 COMPILE_ASSERT((is_convertible<U*, T*>::value), 52 U_ptr_must_implicitly_convert_to_T_ptr); 53 } operatorDefaultDeleter54 inline void operator()(T* ptr) const { 55 enum { type_must_be_complete = sizeof(T) }; 56 delete ptr; 57 } 58 }; 59 60 // Specialization of DefaultDeleter for array types. 61 template <class T> 62 struct DefaultDeleter<T[]> { 63 inline void operator()(T* ptr) const { 64 enum { type_must_be_complete = sizeof(T) }; 65 delete[] ptr; 66 } 67 68 private: 69 // Disable this operator for any U != T because it is undefined to execute 70 // an array delete when the static type of the array mismatches the dynamic 71 // type. 72 // 73 // References: 74 // C++98 [expr.delete]p3 75 // http://cplusplus.github.com/LWG/lwg-defects.html#938 76 template <typename U> void operator()(U* array) const; 77 }; 78 79 template <class T, int n> 80 struct DefaultDeleter<T[n]> { 81 // Never allow someone to declare something like scoped_ptr<int[10]>. 82 COMPILE_ASSERT(sizeof(T) == -1, do_not_use_array_with_size_as_type); 83 }; 84 85 // Function object which invokes 'free' on its parameter, which must be 86 // a pointer. Can be used to store malloc-allocated pointers in scoped_ptr: 87 // 88 // scoped_ptr<int, base::FreeDeleter> foo_ptr( 89 // static_cast<int*>(malloc(sizeof(int)))); 90 struct FreeDeleter { 91 inline void operator()(void* ptr) const { 92 free(ptr); 93 } 94 }; 95 96 // Minimal implementation of the core logic of scoped_ptr, suitable for 97 // reuse in both scoped_ptr and its specializations. 98 template <class T, class D> 99 class scoped_ptr_impl { 100 public: 101 explicit scoped_ptr_impl(T* p) : data_(p) { } 102 103 // Initializer for deleters that have data parameters. 104 scoped_ptr_impl(T* p, const D& d) : data_(p, d) {} 105 106 // Templated constructor that destructively takes the value from another 107 // scoped_ptr_impl. 108 template <typename U, typename V> 109 scoped_ptr_impl(scoped_ptr_impl<U, V>* other) 110 : data_(other->release(), other->get_deleter()) { 111 // We do not support move-only deleters. We could modify our move 112 // emulation to have base::subtle::move() and base::subtle::forward() 113 // functions that are imperfect emulations of their C++11 equivalents, 114 // but until there's a requirement, just assume deleters are copyable. 115 } 116 117 template <typename U, typename V> 118 void TakeState(scoped_ptr_impl<U, V>* other) { 119 // See comment in templated constructor above regarding lack of support 120 // for move-only deleters. 121 reset(other->release()); 122 get_deleter() = other->get_deleter(); 123 } 124 125 ~scoped_ptr_impl() { 126 if (data_.ptr != NULL) { 127 // Not using get_deleter() saves one function call in non-optimized 128 // builds. 129 static_cast<D&>(data_)(data_.ptr); 130 } 131 } 132 133 void reset(T* p) { 134 // This is a self-reset, which is no longer allowed: http://crbug.com/162971 135 if (p != NULL && p == data_.ptr) 136 abort(); 137 138 // Note that running data_.ptr = p can lead to undefined behavior if 139 // get_deleter()(get()) deletes this. In order to pevent this, reset() 140 // should update the stored pointer before deleting its old value. 141 // 142 // However, changing reset() to use that behavior may cause current code to 143 // break in unexpected ways. If the destruction of the owned object 144 // dereferences the scoped_ptr when it is destroyed by a call to reset(), 145 // then it will incorrectly dispatch calls to |p| rather than the original 146 // value of |data_.ptr|. 147 // 148 // During the transition period, set the stored pointer to NULL while 149 // deleting the object. Eventually, this safety check will be removed to 150 // prevent the scenario initially described from occuring and 151 // http://crbug.com/176091 can be closed. 152 T* old = data_.ptr; 153 data_.ptr = NULL; 154 if (old != NULL) 155 static_cast<D&>(data_)(old); 156 data_.ptr = p; 157 } 158 159 T* get() const { return data_.ptr; } 160 161 D& get_deleter() { return data_; } 162 const D& get_deleter() const { return data_; } 163 164 void swap(scoped_ptr_impl& p2) { 165 // Standard swap idiom: 'using std::swap' ensures that std::swap is 166 // present in the overload set, but we call swap unqualified so that 167 // any more-specific overloads can be used, if available. 168 using std::swap; 169 swap(static_cast<D&>(data_), static_cast<D&>(p2.data_)); 170 swap(data_.ptr, p2.data_.ptr); 171 } 172 173 T* release() { 174 T* old_ptr = data_.ptr; 175 data_.ptr = NULL; 176 return old_ptr; 177 } 178 179 private: 180 // Needed to allow type-converting constructor. 181 template <typename U, typename V> friend class scoped_ptr_impl; 182 183 // Use the empty base class optimization to allow us to have a D 184 // member, while avoiding any space overhead for it when D is an 185 // empty class. See e.g. http://www.cantrip.org/emptyopt.html for a good 186 // discussion of this technique. 187 struct Data : public D { 188 explicit Data(T* ptr_in) : ptr(ptr_in) {} 189 Data(T* ptr_in, const D& other) : D(other), ptr(ptr_in) {} 190 T* ptr; 191 }; 192 193 Data data_; 194 195 DISALLOW_COPY_AND_ASSIGN(scoped_ptr_impl); 196 }; 197 198 // A scoped_ptr<T> is like a T*, except that the destructor of scoped_ptr<T> 199 // automatically deletes the pointer it holds (if any). 200 // That is, scoped_ptr<T> owns the T object that it points to. 201 // Like a T*, a scoped_ptr<T> may hold either NULL or a pointer to a T object. 202 // Also like T*, scoped_ptr<T> is thread-compatible, and once you 203 // dereference it, you get the thread safety guarantees of T. 204 // 205 // The size of scoped_ptr is small. On most compilers, when using the 206 // DefaultDeleter, sizeof(scoped_ptr<T>) == sizeof(T*). Custom deleters will 207 // increase the size proportional to whatever state they need to have. See 208 // comments inside scoped_ptr_impl<> for details. 209 // 210 // Current implementation targets having a strict subset of C++11's 211 // unique_ptr<> features. Known deficiencies include not supporting move-only 212 // deleteres, function pointers as deleters, and deleters with reference 213 // types. 214 template <class T, class D = DefaultDeleter<T> > 215 class scoped_ptr { 216 public: 217 // The element and deleter types. 218 typedef T element_type; 219 typedef D deleter_type; 220 221 // Constructor. Defaults to initializing with NULL. 222 scoped_ptr() : impl_(NULL) { } 223 224 // Constructor. Takes ownership of p. 225 explicit scoped_ptr(element_type* p) : impl_(p) { } 226 227 // Constructor. Allows initialization of a stateful deleter. 228 scoped_ptr(element_type* p, const D& d) : impl_(p, d) { } 229 230 // Constructor. Allows construction from a scoped_ptr rvalue for a 231 // convertible type and deleter. 232 // 233 // IMPLEMENTATION NOTE: C++11 unique_ptr<> keeps this constructor distinct 234 // from the normal move constructor. By C++11 20.7.1.2.1.21, this constructor 235 // has different post-conditions if D is a reference type. Since this 236 // implementation does not support deleters with reference type, 237 // we do not need a separate move constructor allowing us to avoid one 238 // use of SFINAE. You only need to care about this if you modify the 239 // implementation of scoped_ptr. 240 template <typename U, typename V> 241 scoped_ptr(scoped_ptr<U, V> other) : impl_(&other.impl_) { 242 COMPILE_ASSERT(!is_array<U>::value, U_cannot_be_an_array); 243 } 244 245 // operator=. Allows assignment from a scoped_ptr rvalue for a convertible 246 // type and deleter. 247 // 248 // IMPLEMENTATION NOTE: C++11 unique_ptr<> keeps this operator= distinct from 249 // the normal move assignment operator. By C++11 20.7.1.2.3.4, this templated 250 // form has different requirements on for move-only Deleters. Since this 251 // implementation does not support move-only Deleters, we do not need a 252 // separate move assignment operator allowing us to avoid one use of SFINAE. 253 // You only need to care about this if you modify the implementation of 254 // scoped_ptr. 255 template <typename U, typename V> 256 scoped_ptr& operator=(scoped_ptr<U, V> rhs) { 257 COMPILE_ASSERT(!is_array<U>::value, U_cannot_be_an_array); 258 impl_.TakeState(&rhs.impl_); 259 return *this; 260 } 261 262 // Reset. Deletes the currently owned object, if any. 263 // Then takes ownership of a new object, if given. 264 void reset(element_type* p = NULL) { impl_.reset(p); } 265 266 // Accessors to get the owned object. 267 // operator* and operator-> will assert() if there is no current object. 268 element_type& operator*() const { 269 assert(impl_.get() != NULL); 270 return *impl_.get(); 271 } 272 element_type* operator->() const { 273 assert(impl_.get() != NULL); 274 return impl_.get(); 275 } 276 element_type* get() const { return impl_.get(); } 277 278 // Access to the deleter. 279 deleter_type& get_deleter() { return impl_.get_deleter(); } 280 const deleter_type& get_deleter() const { return impl_.get_deleter(); } 281 282 // Allow scoped_ptr<element_type> to be used in boolean expressions, but not 283 // implicitly convertible to a real bool (which is dangerous). 284 private: 285 typedef scoped_ptr_impl<element_type, deleter_type> scoped_ptr::*Testable; 286 287 public: 288 operator Testable() const { return impl_.get() ? &scoped_ptr::impl_ : NULL; } 289 290 // Comparison operators. 291 // These return whether two scoped_ptr refer to the same object, not just to 292 // two different but equal objects. 293 bool operator==(const element_type* p) const { return impl_.get() == p; } 294 bool operator!=(const element_type* p) const { return impl_.get() != p; } 295 296 // Swap two scoped pointers. 297 void swap(scoped_ptr& p2) { 298 impl_.swap(p2.impl_); 299 } 300 301 // Release a pointer. 302 // The return value is the current pointer held by this object. 303 // If this object holds a NULL pointer, the return value is NULL. 304 // After this operation, this object will hold a NULL pointer, 305 // and will not own the object any more. 306 element_type* release() { 307 return impl_.release(); 308 } 309 310 private: 311 // Needed to reach into |impl_| in the constructor. 312 template <typename U, typename V> friend class scoped_ptr; 313 scoped_ptr_impl<element_type, deleter_type> impl_; 314 315 // Forbid comparison of scoped_ptr types. If U != T, it totally 316 // doesn't make sense, and if U == T, it still doesn't make sense 317 // because you should never have the same object owned by two different 318 // scoped_ptrs. 319 template <class U> bool operator==(scoped_ptr<U> const& p2) const; 320 template <class U> bool operator!=(scoped_ptr<U> const& p2) const; 321 }; 322 323 template <class T, class D> 324 class scoped_ptr<T[], D> { 325 public: 326 // The element and deleter types. 327 typedef T element_type; 328 typedef D deleter_type; 329 330 // Constructor. Defaults to initializing with NULL. 331 scoped_ptr() : impl_(NULL) { } 332 333 // Constructor. Stores the given array. Note that the argument's type 334 // must exactly match T*. In particular: 335 // - it cannot be a pointer to a type derived from T, because it is 336 // inherently unsafe in the general case to access an array through a 337 // pointer whose dynamic type does not match its static type (eg., if 338 // T and the derived types had different sizes access would be 339 // incorrectly calculated). Deletion is also always undefined 340 // (C++98 [expr.delete]p3). If you're doing this, fix your code. 341 // - it cannot be NULL, because NULL is an integral expression, not a 342 // pointer to T. Use the no-argument version instead of explicitly 343 // passing NULL. 344 // - it cannot be const-qualified differently from T per unique_ptr spec 345 // (http://cplusplus.github.com/LWG/lwg-active.html#2118). Users wanting 346 // to work around this may use implicit_cast<const T*>(). 347 // However, because of the first bullet in this comment, users MUST 348 // NOT use implicit_cast<Base*>() to upcast the static type of the array. 349 explicit scoped_ptr(element_type* array) : impl_(array) { } 350 351 // Reset. Deletes the currently owned array, if any. 352 // Then takes ownership of a new object, if given. 353 void reset(element_type* array = NULL) { impl_.reset(array); } 354 355 // Accessors to get the owned array. 356 element_type& operator[](size_t i) const { 357 assert(impl_.get() != NULL); 358 return impl_.get()[i]; 359 } 360 element_type* get() const { return impl_.get(); } 361 362 // Access to the deleter. 363 deleter_type& get_deleter() { return impl_.get_deleter(); } 364 const deleter_type& get_deleter() const { return impl_.get_deleter(); } 365 366 // Allow scoped_ptr<element_type> to be used in boolean expressions, but not 367 // implicitly convertible to a real bool (which is dangerous). 368 private: 369 typedef scoped_ptr_impl<element_type, deleter_type> scoped_ptr::*Testable; 370 371 public: 372 operator Testable() const { return impl_.get() ? &scoped_ptr::impl_ : NULL; } 373 374 // Comparison operators. 375 // These return whether two scoped_ptr refer to the same object, not just to 376 // two different but equal objects. 377 bool operator==(element_type* array) const { return impl_.get() == array; } 378 bool operator!=(element_type* array) const { return impl_.get() != array; } 379 380 // Swap two scoped pointers. 381 void swap(scoped_ptr& p2) { 382 impl_.swap(p2.impl_); 383 } 384 385 // Release a pointer. 386 // The return value is the current pointer held by this object. 387 // If this object holds a NULL pointer, the return value is NULL. 388 // After this operation, this object will hold a NULL pointer, 389 // and will not own the object any more. 390 element_type* release() { 391 return impl_.release(); 392 } 393 394 private: 395 // Force element_type to be a complete type. 396 enum { type_must_be_complete = sizeof(element_type) }; 397 398 // Actually hold the data. 399 scoped_ptr_impl<element_type, deleter_type> impl_; 400 401 // Disable initialization from any type other than element_type*, by 402 // providing a constructor that matches such an initialization, but is 403 // private and has no definition. This is disabled because it is not safe to 404 // call delete[] on an array whose static type does not match its dynamic 405 // type. 406 template <typename U> explicit scoped_ptr(U* array); 407 explicit scoped_ptr(int disallow_construction_from_null); 408 409 // Disable reset() from any type other than element_type*, for the same 410 // reasons as the constructor above. 411 template <typename U> void reset(U* array); 412 void reset(int disallow_reset_from_null); 413 414 // Forbid comparison of scoped_ptr types. If U != T, it totally 415 // doesn't make sense, and if U == T, it still doesn't make sense 416 // because you should never have the same object owned by two different 417 // scoped_ptrs. 418 template <class U> bool operator==(scoped_ptr<U> const& p2) const; 419 template <class U> bool operator!=(scoped_ptr<U> const& p2) const; 420 }; 421 422 // Free functions 423 template <class T, class D> 424 void swap(scoped_ptr<T, D>& p1, scoped_ptr<T, D>& p2) { 425 p1.swap(p2); 426 } 427 428 template <class T, class D> 429 bool operator==(T* p1, const scoped_ptr<T, D>& p2) { 430 return p1 == p2.get(); 431 } 432 433 template <class T, class D> 434 bool operator!=(T* p1, const scoped_ptr<T, D>& p2) { 435 return p1 != p2.get(); 436 } 437 438 // A function to convert T* into scoped_ptr<T> 439 // Doing e.g. make_scoped_ptr(new FooBarBaz<type>(arg)) is a shorter notation 440 // for scoped_ptr<FooBarBaz<type> >(new FooBarBaz<type>(arg)) 441 template <typename T> 442 scoped_ptr<T> make_scoped_ptr(T* ptr) { 443 return scoped_ptr<T>(ptr); 444 } 445 446 } // namespace phonenumbers 447 } // namespace i18n 448 449 #endif // !I18N_PHONENUMBERS_USE_BOOST 450 #endif // I18N_PHONENUMBERS_BASE_MEMORY_SCOPED_PTR_H_ 451