Chromium Code Reviews| 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 <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 // Note that running data_.ptr = p can lead to undefined behavior if |
|
Jeffrey Yasskin
2015/09/23 00:53:34
I forgot to mention this: you can go straight to t
Lei Zhang
2015/09/23 01:11:30
Done.
| |
| 105 C& operator*() const { | 177 // get_deleter()(get()) deletes this. In order to prevent this, reset() |
| 106 assert(ptr_ != NULL); | 178 // should update the stored pointer before deleting its old value. |
| 107 return *ptr_; | 179 // |
| 180 // However, changing reset() to use that behavior may cause current code to | |
| 181 // break in unexpected ways. If the destruction of the owned object | |
| 182 // dereferences the unique_ptr when it is destroyed by a call to reset(), | |
| 183 // then it will incorrectly dispatch calls to |p| rather than the original | |
| 184 // value of |data_.ptr|. | |
| 185 // | |
| 186 // During the transition period, set the stored pointer to nullptr while | |
| 187 // deleting the object. Eventually, this safety check will be removed to | |
| 188 // prevent the scenario initially described from occuring and | |
| 189 // http://crbug.com/176091 can be closed. | |
| 190 C* old = data_.ptr; | |
| 191 data_.ptr = nullptr; | |
| 192 if (old != nullptr) | |
| 193 static_cast<D&>(data_)(old); | |
| 194 data_.ptr = p; | |
| 108 } | 195 } |
| 109 C* operator->() const { | 196 |
| 110 assert(ptr_ != NULL); | 197 C* get() const { return data_.ptr; } |
| 111 return ptr_; | 198 D& get_deleter() { return data_; } |
| 112 } | 199 const D& get_deleter() const { return data_; } |
| 113 C* get() const { return ptr_; } | |
| 114 | 200 |
| 115 // Comparison operators. | 201 // Comparison operators. |
| 116 // These return whether two unique_ptr refer to the same object, not just to | 202 // These return whether two unique_ptr refer to the same object, not just to |
| 117 // two different but equal objects. | 203 // two different but equal objects. |
| 118 bool operator==(C* p) const { return ptr_ == p; } | 204 bool operator==(C* p) const { return data_.ptr == p; } |
| 119 bool operator!=(C* p) const { return ptr_ != p; } | 205 bool operator!=(C* p) const { return data_.ptr != p; } |
| 120 | 206 |
| 121 // Swap two scoped pointers. | 207 // Swap two unique pointers. |
| 122 void swap(unique_ptr_base& p2) { | 208 void swap(unique_ptr_base& p2) { |
| 123 C* tmp = ptr_; | 209 Data tmp = data_; |
| 124 ptr_ = p2.ptr_; | 210 data_ = p2.data_; |
| 125 p2.ptr_ = tmp; | 211 p2.data_ = tmp; |
| 126 } | 212 } |
| 127 | 213 |
| 128 // Release a pointer. | 214 // Release a pointer. |
| 129 // The return value is the current pointer held by this object. | 215 // The return value is the current pointer held by this object. |
| 130 // If this object holds a NULL pointer, the return value is NULL. | 216 // If this object holds a NULL pointer, the return value is NULL. |
| 131 // After this operation, this object will hold a NULL pointer, | 217 // After this operation, this object will hold a NULL pointer, |
| 132 // and will not own the object any more. | 218 // and will not own the object any more. |
| 133 C* release() { | 219 C* release() { |
| 134 C* retVal = ptr_; | 220 C* ptr = data_.ptr; |
| 135 ptr_ = NULL; | 221 data_.ptr = nullptr; |
| 136 return retVal; | 222 return ptr; |
| 137 } | 223 } |
| 138 | 224 |
| 139 // Allow promotion to bool for conditional statements. | 225 // Allow promotion to bool for conditional statements. |
| 140 explicit operator bool() const { return ptr_ != NULL; } | 226 explicit operator bool() const { return data_.ptr != nullptr; } |
| 141 | 227 |
| 142 protected: | 228 protected: |
| 143 C* ptr_; | 229 // Use the empty base class optimization to allow us to have a D |
| 230 // member, while avoiding any space overhead for it when D is an | |
| 231 // empty class. See e.g. http://www.cantrip.org/emptyopt.html for a good | |
| 232 // discussion of this technique. | |
| 233 struct Data : public D { | |
| 234 explicit Data(C* ptr_in) : ptr(ptr_in) {} | |
| 235 Data(C* ptr_in, const D& other) : D(other), ptr(ptr_in) {} | |
| 236 C* ptr; | |
| 237 }; | |
| 238 | |
| 239 Data data_; | |
| 144 }; | 240 }; |
| 145 | 241 |
| 242 } // namespace internal | |
| 243 | |
| 146 // Implementation for ordinary pointers using delete. | 244 // Implementation for ordinary pointers using delete. |
| 147 template <class C> | 245 template <class C, class D = DefaultDeleter<C>> |
| 148 class unique_ptr : public unique_ptr_base<C> { | 246 class unique_ptr : public internal::unique_ptr_base<C, D> { |
| 149 public: | 247 public: |
| 150 using unique_ptr_base<C>::ptr_; | 248 // Constructor. Defaults to initializing with nullptr. |
| 249 unique_ptr() : internal::unique_ptr_base<C, D>(nullptr) {} | |
| 151 | 250 |
| 152 // Constructor. Defaults to initializing with NULL. There is no way | 251 // Constructor. Takes ownership of p. |
| 153 // to create an uninitialized unique_ptr. The input parameter must be | 252 explicit unique_ptr(C* p) : internal::unique_ptr_base<C, D>(p) {} |
| 154 // allocated with new (not new[] - see below). | 253 |
| 155 explicit unique_ptr(C* p = NULL) : unique_ptr_base<C>(p) { } | 254 // Constructor. Allows initialization of a stateful deleter. |
| 255 unique_ptr(C* p, const D& d) : internal::unique_ptr_base<C, D>(p, d) {} | |
| 256 | |
| 257 // Constructor. Allows construction from a nullptr. | |
| 258 unique_ptr(decltype(nullptr)) : internal::unique_ptr_base<C, D>(nullptr) {} | |
| 156 | 259 |
| 157 // Move constructor. | 260 // Move constructor. |
| 158 unique_ptr(unique_ptr<C>&& that) : unique_ptr_base<C>(nonstd::move(that)) {} | 261 unique_ptr(unique_ptr&& that) |
| 262 : internal::unique_ptr_base<C, D>(nonstd::move(that)) {} | |
| 159 | 263 |
| 160 // Destructor. If there is a C object, delete it. | 264 // 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. | 265 // object, if any. |
| 162 ~unique_ptr() { | 266 unique_ptr& operator=(decltype(nullptr)) { |
| 163 enum { type_must_be_complete = sizeof(C) }; | 267 this->reset(); |
| 164 delete ptr_; | 268 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 } | 269 } |
| 178 | 270 |
| 179 // Move assignment. | 271 // Move assignment. |
| 180 unique_ptr<C>& operator=(unique_ptr<C>&& that) { | 272 unique_ptr<C>& operator=(unique_ptr<C>&& that) { |
| 181 if (that.ptr_ != ptr_) | 273 if (that.data_.ptr != this->data_.ptr) |
|
Jeffrey Yasskin
2015/09/23 00:53:34
You can remove this check: a self-reset will natur
Lei Zhang
2015/09/23 01:11:30
Done.
| |
| 182 reset(that.release()); | 274 this->reset(that.release()); |
| 183 return *this; | 275 return *this; |
| 184 } | 276 } |
| 185 | 277 |
| 186 private: | 278 // Accessors to get the owned object. |
| 187 // Forbid comparison of unique_ptr types. If C2 != C, it totally doesn't | 279 // 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 | 280 C& operator*() const { |
| 189 // never have the same object owned by two different unique_ptrs. | 281 assert(this->data_.ptr != nullptr); |
| 190 template <class C2> bool operator==(unique_ptr<C2> const& p2) const; | 282 return *this->data_.ptr; |
| 191 template <class C2> bool operator!=(unique_ptr<C2> const& p2) const; | 283 } |
| 284 C* operator->() const { | |
| 285 assert(this->data_.ptr != nullptr); | |
| 286 return this->data_.ptr; | |
| 287 } | |
| 192 | 288 |
| 289 // Comparison operators. | |
| 290 // These return whether two unique_ptr refer to the same object, not just to | |
| 291 // two different but equal objects. | |
| 292 bool operator==(const C* p) const { return this->get() == p; } | |
| 293 bool operator!=(const C* p) const { return this->get() != p; } | |
| 294 | |
| 295 private: | |
| 193 // Disallow evil constructors. It doesn't make sense to make a copy of | 296 // Disallow evil constructors. It doesn't make sense to make a copy of |
| 194 // something that's allegedly unique. | 297 // something that's allegedly unique. |
| 195 unique_ptr(const unique_ptr&) = delete; | 298 unique_ptr(const unique_ptr&) = delete; |
| 196 void operator=(const unique_ptr&) = delete; | 299 void operator=(const unique_ptr&) = delete; |
| 300 | |
| 301 // Forbid comparison of unique_ptr types. If U != C, it totally | |
| 302 // doesn't make sense, and if U == C, it still doesn't make sense | |
| 303 // because you should never have the same object owned by two different | |
| 304 // unique_ptrs. | |
| 305 template <class U> | |
| 306 bool operator==(unique_ptr<U> const& p2) const; | |
| 307 template <class U> | |
| 308 bool operator!=(unique_ptr<U> const& p2) const; | |
| 197 }; | 309 }; |
| 198 | 310 |
| 199 // Specialization for arrays using delete[]. | 311 // Specialization for arrays using delete[]. |
| 200 template <class C> | 312 template <class C, class D> |
| 201 class unique_ptr<C[]> : public unique_ptr_base<C> { | 313 class unique_ptr<C[], D> : public internal::unique_ptr_base<C, D> { |
| 202 public: | 314 public: |
| 203 using unique_ptr_base<C>::ptr_; | 315 // Constructor. Defaults to initializing with nullptr. |
| 316 unique_ptr() : internal::unique_ptr_base<C, D>(nullptr) {} | |
| 204 | 317 |
| 205 // Constructor. Defaults to initializing with NULL. There is no way | 318 // Constructor. Stores the given array. Note that the argument's type |
| 206 // to create an uninitialized unique_ptr. The input parameter must be | 319 // must exactly match T*. In particular: |
| 207 // allocated with new[] (not new - see above). | 320 // - 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) { } | 321 // inherently unsafe in the general case to access an array through a |
| 322 // pointer whose dynamic type does not match its static type (eg., if | |
| 323 // T and the derived types had different sizes access would be | |
| 324 // incorrectly calculated). Deletion is also always undefined | |
| 325 // (C++98 [expr.delete]p3). If you're doing this, fix your code. | |
| 326 // - it cannot be const-qualified differently from T per unique_ptr spec | |
| 327 // (http://cplusplus.github.com/LWG/lwg-active.html#2118). Users wanting | |
| 328 // to work around this may use const_cast<const T*>(). | |
| 329 explicit unique_ptr(C* p) : internal::unique_ptr_base<C, D>(p) {} | |
| 330 | |
| 331 // Constructor. Allows construction from a nullptr. | |
| 332 unique_ptr(decltype(nullptr)) : internal::unique_ptr_base<C, D>(nullptr) {} | |
| 209 | 333 |
| 210 // Move constructor. | 334 // Move constructor. |
| 211 unique_ptr(unique_ptr<C>&& that) : unique_ptr_base<C>(nonstd::move(that)) {} | 335 unique_ptr(unique_ptr&& that) |
| 336 : internal::unique_ptr_base<C, D>(nonstd::move(that)) {} | |
| 212 | 337 |
| 213 // Destructor. If there is a C object, delete it. | 338 // 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. | 339 // array, if any. |
| 215 ~unique_ptr() { | 340 unique_ptr& operator=(decltype(nullptr)) { |
| 216 enum { type_must_be_complete = sizeof(C) }; | 341 this->reset(); |
| 217 delete[] ptr_; | 342 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 } | 343 } |
| 231 | 344 |
| 232 // Move assignment. | 345 // Move assignment. |
| 233 unique_ptr<C>& operator=(unique_ptr<C>&& that) { | 346 unique_ptr<C>& operator=(unique_ptr<C>&& that) { |
| 234 if (that.ptr_ != ptr_) | 347 if (that.data_.ptr != this->data_.ptr) |
|
Jeffrey Yasskin
2015/09/23 00:53:35
Same here.
Lei Zhang
2015/09/23 01:11:30
Done.
| |
| 235 reset(that.release()); | 348 this->reset(that.release()); |
| 236 return *this; | 349 return *this; |
| 237 } | 350 } |
| 238 | 351 |
| 352 // Reset. Deletes the currently owned array, if any. | |
| 353 // Then takes ownership of a new object, if given. | |
| 354 void reset(C* array = nullptr) { | |
| 355 static_cast<internal::unique_ptr_base<C, D>*>(this)->reset(array); | |
| 356 } | |
| 357 | |
| 239 // Support indexing since it is holding array. | 358 // Support indexing since it is holding array. |
| 240 C& operator[] (size_t i) { return ptr_[i]; } | 359 C& operator[](size_t i) { return this->data_.ptr[i]; } |
| 241 | 360 |
| 242 private: | 361 // Comparison operators. |
| 243 // Forbid comparison of unique_ptr types. If C2 != C, it totally doesn't | 362 // 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 | 363 // two different but equal objects. |
| 245 // never have the same object owned by two different unique_ptrs. | 364 bool operator==(C* array) const { return this->get() == array; } |
| 246 template <class C2> bool operator==(unique_ptr<C2> const& p2) const; | 365 bool operator!=(C* array) const { return this->get() != array; } |
| 247 template <class C2> bool operator!=(unique_ptr<C2> const& p2) const; | 366 |
| 367 private: | |
| 368 // Disable initialization from any type other than element_type*, by | |
| 369 // providing a constructor that matches such an initialization, but is | |
| 370 // private and has no definition. This is disabled because it is not safe to | |
| 371 // call delete[] on an array whose static type does not match its dynamic | |
| 372 // type. | |
| 373 template <typename U> | |
| 374 explicit unique_ptr(U* array); | |
| 375 explicit unique_ptr(int disallow_construction_from_null); | |
| 376 | |
| 377 // Disable reset() from any type other than element_type*, for the same | |
| 378 // reasons as the constructor above. | |
| 379 template <typename U> | |
| 380 void reset(U* array); | |
| 381 void reset(int disallow_reset_from_null); | |
| 248 | 382 |
| 249 // Disallow evil constructors. It doesn't make sense to make a copy of | 383 // Disallow evil constructors. It doesn't make sense to make a copy of |
| 250 // something that's allegedly unique. | 384 // something that's allegedly unique. |
| 251 unique_ptr(const unique_ptr&) = delete; | 385 unique_ptr(const unique_ptr&) = delete; |
| 252 void operator=(const unique_ptr&) = delete; | 386 void operator=(const unique_ptr&) = delete; |
| 387 | |
| 388 // Forbid comparison of unique_ptr types. If U != C, it totally | |
| 389 // doesn't make sense, and if U == C, it still doesn't make sense | |
| 390 // because you should never have the same object owned by two different | |
| 391 // unique_ptrs. | |
| 392 template <class U> | |
| 393 bool operator==(unique_ptr<U> const& p2) const; | |
| 394 template <class U> | |
| 395 bool operator!=(unique_ptr<U> const& p2) const; | |
| 253 }; | 396 }; |
| 254 | 397 |
| 255 // Free functions | 398 // Free functions |
| 256 template <class C> | 399 template <class C> |
| 257 void swap(unique_ptr<C>& p1, unique_ptr<C>& p2) { | 400 void swap(unique_ptr<C>& p1, unique_ptr<C>& p2) { |
| 258 p1.swap(p2); | 401 p1.swap(p2); |
| 259 } | 402 } |
| 260 | 403 |
| 261 template <class C> | 404 template <class C> |
| 262 bool operator==(C* p1, const unique_ptr<C>& p2) { | 405 bool operator==(C* p1, const unique_ptr<C>& p2) { |
| 263 return p1 == p2.get(); | 406 return p1 == p2.get(); |
| 264 } | 407 } |
| 265 | 408 |
| 266 template <class C> | 409 template <class C> |
| 267 bool operator!=(C* p1, const unique_ptr<C>& p2) { | 410 bool operator!=(C* p1, const unique_ptr<C>& p2) { |
| 268 return p1 != p2.get(); | 411 return p1 != p2.get(); |
| 269 } | 412 } |
| 270 | 413 |
| 414 template <typename T> | |
| 415 std::ostream& operator<<(std::ostream& out, const unique_ptr<T>& p) { | |
| 416 return out << p.get(); | |
| 417 } | |
| 418 | |
| 271 } // namespace nonstd | 419 } // namespace nonstd |
| 272 | 420 |
| 273 #endif // NONSTD_UNIQUE_PTR_H_ | 421 #endif // NONSTD_UNIQUE_PTR_H_ |
| OLD | NEW |