1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 /* Smart pointer managing sole ownership of a resource. */ 8 9 #ifndef mozilla_UniquePtr_h 10 #define mozilla_UniquePtr_h 11 12 #include <type_traits> 13 #include <utility> 14 15 #include "mozilla/Assertions.h" 16 #include "mozilla/Attributes.h" 17 #include "mozilla/CompactPair.h" 18 #include "mozilla/Compiler.h" 19 20 namespace mozilla { 21 22 template <typename T> 23 class DefaultDelete; 24 template <typename T, class D = DefaultDelete<T>> 25 class UniquePtr; 26 27 } // namespace mozilla 28 29 namespace mozilla { 30 31 namespace detail { 32 33 struct HasPointerTypeHelper { 34 template <class U> 35 static double Test(...); 36 template <class U> 37 static char Test(typename U::pointer* = 0); 38 }; 39 40 template <class T> 41 class HasPointerType 42 : public std::integral_constant<bool, sizeof(HasPointerTypeHelper::Test<T>( 43 0)) == 1> {}; 44 45 template <class T, class D, bool = HasPointerType<D>::value> 46 struct PointerTypeImpl { 47 typedef typename D::pointer Type; 48 }; 49 50 template <class T, class D> 51 struct PointerTypeImpl<T, D, false> { 52 typedef T* Type; 53 }; 54 55 template <class T, class D> 56 struct PointerType { 57 typedef typename PointerTypeImpl<T, std::remove_reference_t<D>>::Type Type; 58 }; 59 60 } // namespace detail 61 62 /** 63 * UniquePtr is a smart pointer that wholly owns a resource. Ownership may be 64 * transferred out of a UniquePtr through explicit action, but otherwise the 65 * resource is destroyed when the UniquePtr is destroyed. 66 * 67 * UniquePtr is similar to C++98's std::auto_ptr, but it improves upon auto_ptr 68 * in one crucial way: it's impossible to copy a UniquePtr. Copying an auto_ptr 69 * obviously *can't* copy ownership of its singly-owned resource. So what 70 * happens if you try to copy one? Bizarrely, ownership is implicitly 71 * *transferred*, preserving single ownership but breaking code that assumes a 72 * copy of an object is identical to the original. (This is why auto_ptr is 73 * prohibited in STL containers.) 74 * 75 * UniquePtr solves this problem by being *movable* rather than copyable. 76 * Instead of passing a |UniquePtr u| directly to the constructor or assignment 77 * operator, you pass |Move(u)|. In doing so you indicate that you're *moving* 78 * ownership out of |u|, into the target of the construction/assignment. After 79 * the transfer completes, |u| contains |nullptr| and may be safely destroyed. 80 * This preserves single ownership but also allows UniquePtr to be moved by 81 * algorithms that have been made move-safe. (Note: if |u| is instead a 82 * temporary expression, don't use |Move()|: just pass the expression, because 83 * it's already move-ready. For more information see Move.h.) 84 * 85 * UniquePtr is also better than std::auto_ptr in that the deletion operation is 86 * customizable. An optional second template parameter specifies a class that 87 * (through its operator()(T*)) implements the desired deletion policy. If no 88 * policy is specified, mozilla::DefaultDelete<T> is used -- which will either 89 * |delete| or |delete[]| the resource, depending whether the resource is an 90 * array. Custom deletion policies ideally should be empty classes (no member 91 * fields, no member fields in base classes, no virtual methods/inheritance), 92 * because then UniquePtr can be just as efficient as a raw pointer. 93 * 94 * Use of UniquePtr proceeds like so: 95 * 96 * UniquePtr<int> g1; // initializes to nullptr 97 * g1.reset(new int); // switch resources using reset() 98 * g1 = nullptr; // clears g1, deletes the int 99 * 100 * UniquePtr<int> g2(new int); // owns that int 101 * int* p = g2.release(); // g2 leaks its int -- still requires deletion 102 * delete p; // now freed 103 * 104 * struct S { int x; S(int x) : x(x) {} }; 105 * UniquePtr<S> g3, g4(new S(5)); 106 * g3 = std::move(g4); // g3 owns the S, g4 cleared 107 * S* p = g3.get(); // g3 still owns |p| 108 * assert(g3->x == 5); // operator-> works (if .get() != nullptr) 109 * assert((*g3).x == 5); // also operator* (again, if not cleared) 110 * std::swap(g3, g4); // g4 now owns the S, g3 cleared 111 * g3.swap(g4); // g3 now owns the S, g4 cleared 112 * UniquePtr<S> g5(std::move(g3)); // g5 owns the S, g3 cleared 113 * g5.reset(); // deletes the S, g5 cleared 114 * 115 * struct FreePolicy { void operator()(void* p) { free(p); } }; 116 * UniquePtr<int, FreePolicy> g6(static_cast<int*>(malloc(sizeof(int)))); 117 * int* ptr = g6.get(); 118 * g6 = nullptr; // calls free(ptr) 119 * 120 * Now, carefully note a few things you *can't* do: 121 * 122 * UniquePtr<int> b1; 123 * b1 = new int; // BAD: can only assign another UniquePtr 124 * int* ptr = b1; // BAD: no auto-conversion to pointer, use get() 125 * 126 * UniquePtr<int> b2(b1); // BAD: can't copy a UniquePtr 127 * UniquePtr<int> b3 = b1; // BAD: can't copy-assign a UniquePtr 128 * 129 * (Note that changing a UniquePtr to store a direct |new| expression is 130 * permitted, but usually you should use MakeUnique, defined at the end of this 131 * header.) 132 * 133 * A few miscellaneous notes: 134 * 135 * UniquePtr, when not instantiated for an array type, can be move-constructed 136 * and move-assigned, not only from itself but from "derived" UniquePtr<U, E> 137 * instantiations where U converts to T and E converts to D. If you want to use 138 * this, you're going to have to specify a deletion policy for both UniquePtr 139 * instantations, and T pretty much has to have a virtual destructor. In other 140 * words, this doesn't work: 141 * 142 * struct Base { virtual ~Base() {} }; 143 * struct Derived : Base {}; 144 * 145 * UniquePtr<Base> b1; 146 * // BAD: DefaultDelete<Base> and DefaultDelete<Derived> don't interconvert 147 * UniquePtr<Derived> d1(std::move(b)); 148 * 149 * UniquePtr<Base> b2; 150 * UniquePtr<Derived, DefaultDelete<Base>> d2(std::move(b2)); // okay 151 * 152 * UniquePtr is specialized for array types. Specializing with an array type 153 * creates a smart-pointer version of that array -- not a pointer to such an 154 * array. 155 * 156 * UniquePtr<int[]> arr(new int[5]); 157 * arr[0] = 4; 158 * 159 * What else is different? Deletion of course uses |delete[]|. An operator[] 160 * is provided. Functionality that doesn't make sense for arrays is removed. 161 * The constructors and mutating methods only accept array pointers (not T*, U* 162 * that converts to T*, or UniquePtr<U[]> or UniquePtr<U>) or |nullptr|. 163 * 164 * It's perfectly okay for a function to return a UniquePtr. This transfers 165 * the UniquePtr's sole ownership of the data, to the fresh UniquePtr created 166 * in the calling function, that will then solely own that data. Such functions 167 * can return a local variable UniquePtr, |nullptr|, |UniquePtr(ptr)| where 168 * |ptr| is a |T*|, or a UniquePtr |Move()|'d from elsewhere. 169 * 170 * UniquePtr will commonly be a member of a class, with lifetime equivalent to 171 * that of that class. If you want to expose the related resource, you could 172 * expose a raw pointer via |get()|, but ownership of a raw pointer is 173 * inherently unclear. So it's better to expose a |const UniquePtr&| instead. 174 * This prohibits mutation but still allows use of |get()| when needed (but 175 * operator-> is preferred). Of course, you can only use this smart pointer as 176 * long as the enclosing class instance remains live -- no different than if you 177 * exposed the |get()| raw pointer. 178 * 179 * To pass a UniquePtr-managed resource as a pointer, use a |const UniquePtr&| 180 * argument. To specify an inout parameter (where the method may or may not 181 * take ownership of the resource, or reset it), or to specify an out parameter 182 * (where simply returning a |UniquePtr| isn't possible), use a |UniquePtr&| 183 * argument. To unconditionally transfer ownership of a UniquePtr 184 * into a method, use a |UniquePtr| argument. To conditionally transfer 185 * ownership of a resource into a method, should the method want it, use a 186 * |UniquePtr&&| argument. 187 */ 188 template <typename T, class D> 189 class UniquePtr { 190 public: 191 typedef T ElementType; 192 typedef D DeleterType; 193 typedef typename detail::PointerType<T, DeleterType>::Type Pointer; 194 195 private: 196 mozilla::CompactPair<Pointer, DeleterType> mTuple; 197 198 Pointer& ptr() { return mTuple.first(); } 199 const Pointer& ptr() const { return mTuple.first(); } 200 201 DeleterType& del() { return mTuple.second(); } 202 const DeleterType& del() const { return mTuple.second(); } 203 204 public: 205 /** 206 * Construct a UniquePtr containing |nullptr|. 207 */ 208 constexpr UniquePtr() : mTuple(static_cast<Pointer>(nullptr), DeleterType()) { 209 static_assert(!std::is_pointer_v<D>, "must provide a deleter instance"); 210 static_assert(!std::is_reference_v<D>, "must provide a deleter instance"); 211 } 212 213 /** 214 * Construct a UniquePtr containing |aPtr|. 215 */ 216 explicit UniquePtr(Pointer aPtr) : mTuple(aPtr, DeleterType()) { 217 static_assert(!std::is_pointer_v<D>, "must provide a deleter instance"); 218 static_assert(!std::is_reference_v<D>, "must provide a deleter instance"); 219 } 220 221 UniquePtr(Pointer aPtr, 222 std::conditional_t<std::is_reference_v<D>, D, const D&> aD1) 223 : mTuple(aPtr, aD1) {} 224 225 UniquePtr(Pointer aPtr, std::remove_reference_t<D>&& aD2) 226 : mTuple(aPtr, std::move(aD2)) { 227 static_assert(!std::is_reference_v<D>, 228 "rvalue deleter can't be stored by reference"); 229 } 230 231 UniquePtr(UniquePtr&& aOther) 232 : mTuple(aOther.release(), 233 std::forward<DeleterType>(aOther.get_deleter())) {} 234 235 MOZ_IMPLICIT 236 UniquePtr(decltype(nullptr)) : mTuple(nullptr, DeleterType()) { 237 static_assert(!std::is_pointer_v<D>, "must provide a deleter instance"); 238 static_assert(!std::is_reference_v<D>, "must provide a deleter instance"); 239 } 240 241 template <typename U, class E> 242 MOZ_IMPLICIT UniquePtr( 243 UniquePtr<U, E>&& aOther, 244 std::enable_if_t< 245 std::is_convertible_v<typename UniquePtr<U, E>::Pointer, Pointer> && 246 !std::is_array_v<U> && 247 (std::is_reference_v<D> ? std::is_same_v<D, E> 248 : std::is_convertible_v<E, D>), 249 int> 250 aDummy = 0) 251 : mTuple(aOther.release(), std::forward<E>(aOther.get_deleter())) {} 252 253 ~UniquePtr() { reset(nullptr); } 254 255 UniquePtr& operator=(UniquePtr&& aOther) { 256 reset(aOther.release()); 257 get_deleter() = std::forward<DeleterType>(aOther.get_deleter()); 258 return *this; 259 } 260 261 template <typename U, typename E> 262 UniquePtr& operator=(UniquePtr<U, E>&& aOther) { 263 static_assert( 264 std::is_convertible_v<typename UniquePtr<U, E>::Pointer, Pointer>, 265 "incompatible UniquePtr pointees"); 266 static_assert(!std::is_array_v<U>, 267 "can't assign from UniquePtr holding an array"); 268 269 reset(aOther.release()); 270 get_deleter() = std::forward<E>(aOther.get_deleter()); 271 return *this; 272 } 273 274 UniquePtr& operator=(decltype(nullptr)) { 275 reset(nullptr); 276 return *this; 277 } 278 279 std::add_lvalue_reference_t<T> operator*() const { 280 MOZ_ASSERT(get(), "dereferencing a UniquePtr containing nullptr with *"); 281 return *get(); 282 } 283 Pointer operator->() const { 284 MOZ_ASSERT(get(), "dereferencing a UniquePtr containing nullptr with ->"); 285 return get(); 286 } 287 288 explicit operator bool() const { return get() != nullptr; } 289 290 Pointer get() const { return ptr(); } 291 292 DeleterType& get_deleter() { return del(); } 293 const DeleterType& get_deleter() const { return del(); } 294 295 [[nodiscard]] Pointer release() { 296 Pointer p = ptr(); 297 ptr() = nullptr; 298 return p; 299 } 300 301 void reset(Pointer aPtr = Pointer()) { 302 Pointer old = ptr(); 303 ptr() = aPtr; 304 if (old != nullptr) { 305 get_deleter()(old); 306 } 307 } 308 309 void swap(UniquePtr& aOther) { mTuple.swap(aOther.mTuple); } 310 311 UniquePtr(const UniquePtr& aOther) = delete; // construct using std::move()! 312 void operator=(const UniquePtr& aOther) = 313 delete; // assign using std::move()! 314 }; 315 316 // In case you didn't read the comment by the main definition (you should!): the 317 // UniquePtr<T[]> specialization exists to manage array pointers. It deletes 318 // such pointers using delete[], it will reject construction and modification 319 // attempts using U* or U[]. Otherwise it works like the normal UniquePtr. 320 template <typename T, class D> 321 class UniquePtr<T[], D> { 322 public: 323 typedef T* Pointer; 324 typedef T ElementType; 325 typedef D DeleterType; 326 327 private: 328 mozilla::CompactPair<Pointer, DeleterType> mTuple; 329 330 public: 331 /** 332 * Construct a UniquePtr containing nullptr. 333 */ 334 constexpr UniquePtr() : mTuple(static_cast<Pointer>(nullptr), DeleterType()) { 335 static_assert(!std::is_pointer_v<D>, "must provide a deleter instance"); 336 static_assert(!std::is_reference_v<D>, "must provide a deleter instance"); 337 } 338 339 /** 340 * Construct a UniquePtr containing |aPtr|. 341 */ 342 explicit UniquePtr(Pointer aPtr) : mTuple(aPtr, DeleterType()) { 343 static_assert(!std::is_pointer_v<D>, "must provide a deleter instance"); 344 static_assert(!std::is_reference_v<D>, "must provide a deleter instance"); 345 } 346 347 // delete[] knows how to handle *only* an array of a single class type. For 348 // delete[] to work correctly, it must know the size of each element, the 349 // fields and base classes of each element requiring destruction, and so on. 350 // So forbid all overloads which would end up invoking delete[] on a pointer 351 // of the wrong type. 352 template <typename U> 353 UniquePtr(U&& aU, 354 std::enable_if_t< 355 std::is_pointer_v<U> && std::is_convertible_v<U, Pointer>, int> 356 aDummy = 0) = delete; 357 358 UniquePtr(Pointer aPtr, 359 std::conditional_t<std::is_reference_v<D>, D, const D&> aD1) 360 : mTuple(aPtr, aD1) {} 361 362 UniquePtr(Pointer aPtr, std::remove_reference_t<D>&& aD2) 363 : mTuple(aPtr, std::move(aD2)) { 364 static_assert(!std::is_reference_v<D>, 365 "rvalue deleter can't be stored by reference"); 366 } 367 368 // Forbidden for the same reasons as stated above. 369 template <typename U, typename V> 370 UniquePtr(U&& aU, V&& aV, 371 std::enable_if_t< 372 std::is_pointer_v<U> && std::is_convertible_v<U, Pointer>, int> 373 aDummy = 0) = delete; 374 375 UniquePtr(UniquePtr&& aOther) 376 : mTuple(aOther.release(), 377 std::forward<DeleterType>(aOther.get_deleter())) {} 378 379 MOZ_IMPLICIT 380 UniquePtr(decltype(nullptr)) : mTuple(nullptr, DeleterType()) { 381 static_assert(!std::is_pointer_v<D>, "must provide a deleter instance"); 382 static_assert(!std::is_reference_v<D>, "must provide a deleter instance"); 383 } 384 385 ~UniquePtr() { reset(nullptr); } 386 387 UniquePtr& operator=(UniquePtr&& aOther) { 388 reset(aOther.release()); 389 get_deleter() = std::forward<DeleterType>(aOther.get_deleter()); 390 return *this; 391 } 392 393 UniquePtr& operator=(decltype(nullptr)) { 394 reset(); 395 return *this; 396 } 397 398 explicit operator bool() const { return get() != nullptr; } 399 400 T& operator[](decltype(sizeof(int)) aIndex) const { return get()[aIndex]; } 401 Pointer get() const { return mTuple.first(); } 402 403 DeleterType& get_deleter() { return mTuple.second(); } 404 const DeleterType& get_deleter() const { return mTuple.second(); } 405 406 [[nodiscard]] Pointer release() { 407 Pointer p = mTuple.first(); 408 mTuple.first() = nullptr; 409 return p; 410 } 411 412 void reset(Pointer aPtr = Pointer()) { 413 Pointer old = mTuple.first(); 414 mTuple.first() = aPtr; 415 if (old != nullptr) { 416 mTuple.second()(old); 417 } 418 } 419 420 void reset(decltype(nullptr)) { 421 Pointer old = mTuple.first(); 422 mTuple.first() = nullptr; 423 if (old != nullptr) { 424 mTuple.second()(old); 425 } 426 } 427 428 template <typename U> 429 void reset(U) = delete; 430 431 void swap(UniquePtr& aOther) { mTuple.swap(aOther.mTuple); } 432 433 UniquePtr(const UniquePtr& aOther) = delete; // construct using std::move()! 434 void operator=(const UniquePtr& aOther) = 435 delete; // assign using std::move()! 436 }; 437 438 /** 439 * A default deletion policy using plain old operator delete. 440 * 441 * Note that this type can be specialized, but authors should beware of the risk 442 * that the specialization may at some point cease to match (either because it 443 * gets moved to a different compilation unit or the signature changes). If the 444 * non-specialized (|delete|-based) version compiles for that type but does the 445 * wrong thing, bad things could happen. 446 * 447 * This is a non-issue for types which are always incomplete (i.e. opaque handle 448 * types), since |delete|-ing such a type will always trigger a compilation 449 * error. 450 */ 451 template <typename T> 452 class DefaultDelete { 453 public: 454 constexpr DefaultDelete() = default; 455 456 template <typename U> 457 MOZ_IMPLICIT DefaultDelete( 458 const DefaultDelete<U>& aOther, 459 std::enable_if_t<std::is_convertible_v<U*, T*>, int> aDummy = 0) {} 460 461 void operator()(T* aPtr) const { 462 static_assert(sizeof(T) > 0, "T must be complete"); 463 delete aPtr; 464 } 465 }; 466 467 /** A default deletion policy using operator delete[]. */ 468 template <typename T> 469 class DefaultDelete<T[]> { 470 public: 471 constexpr DefaultDelete() = default; 472 473 void operator()(T* aPtr) const { 474 static_assert(sizeof(T) > 0, "T must be complete"); 475 delete[] aPtr; 476 } 477 478 template <typename U> 479 void operator()(U* aPtr) const = delete; 480 }; 481 482 template <typename T, class D, typename U, class E> 483 bool operator==(const UniquePtr<T, D>& aX, const UniquePtr<U, E>& aY) { 484 return aX.get() == aY.get(); 485 } 486 487 template <typename T, class D, typename U, class E> 488 bool operator!=(const UniquePtr<T, D>& aX, const UniquePtr<U, E>& aY) { 489 return aX.get() != aY.get(); 490 } 491 492 template <typename T, class D> 493 bool operator==(const UniquePtr<T, D>& aX, const T* aY) { 494 return aX.get() == aY; 495 } 496 497 template <typename T, class D> 498 bool operator==(const T* aY, const UniquePtr<T, D>& aX) { 499 return aY == aX.get(); 500 } 501 502 template <typename T, class D> 503 bool operator!=(const UniquePtr<T, D>& aX, const T* aY) { 504 return aX.get() != aY; 505 } 506 507 template <typename T, class D> 508 bool operator!=(const T* aY, const UniquePtr<T, D>& aX) { 509 return aY != aX.get(); 510 } 511 512 template <typename T, class D> 513 bool operator==(const UniquePtr<T, D>& aX, decltype(nullptr)) { 514 return !aX; 515 } 516 517 template <typename T, class D> 518 bool operator==(decltype(nullptr), const UniquePtr<T, D>& aX) { 519 return !aX; 520 } 521 522 template <typename T, class D> 523 bool operator!=(const UniquePtr<T, D>& aX, decltype(nullptr)) { 524 return bool(aX); 525 } 526 527 template <typename T, class D> 528 bool operator!=(decltype(nullptr), const UniquePtr<T, D>& aX) { 529 return bool(aX); 530 } 531 532 // No operator<, operator>, operator<=, operator>= for now because simplicity. 533 534 namespace detail { 535 536 template <typename T> 537 struct UniqueSelector { 538 typedef UniquePtr<T> SingleObject; 539 }; 540 541 template <typename T> 542 struct UniqueSelector<T[]> { 543 typedef UniquePtr<T[]> UnknownBound; 544 }; 545 546 template <typename T, decltype(sizeof(int)) N> 547 struct UniqueSelector<T[N]> { 548 typedef UniquePtr<T[N]> KnownBound; 549 }; 550 551 } // namespace detail 552 553 /** 554 * MakeUnique is a helper function for allocating new'd objects and arrays, 555 * returning a UniquePtr containing the resulting pointer. The semantics of 556 * MakeUnique<Type>(...) are as follows. 557 * 558 * If Type is an array T[n]: 559 * Disallowed, deleted, no overload for you! 560 * If Type is an array T[]: 561 * MakeUnique<T[]>(size_t) is the only valid overload. The pointer returned 562 * is as if by |new T[n]()|, which value-initializes each element. (If T 563 * isn't a class type, this will zero each element. If T is a class type, 564 * then roughly speaking, each element will be constructed using its default 565 * constructor. See C++11 [dcl.init]p7 for the full gory details.) 566 * If Type is non-array T: 567 * The arguments passed to MakeUnique<T>(...) are forwarded into a 568 * |new T(...)| call, initializing the T as would happen if executing 569 * |T(...)|. 570 * 571 * There are various benefits to using MakeUnique instead of |new| expressions. 572 * 573 * First, MakeUnique eliminates use of |new| from code entirely. If objects are 574 * only created through UniquePtr, then (assuming all explicit release() calls 575 * are safe, including transitively, and no type-safety casting funniness) 576 * correctly maintained ownership of the UniquePtr guarantees no leaks are 577 * possible. (This pays off best if a class is only ever created through a 578 * factory method on the class, using a private constructor.) 579 * 580 * Second, initializing a UniquePtr using a |new| expression requires repeating 581 * the name of the new'd type, whereas MakeUnique in concert with the |auto| 582 * keyword names it only once: 583 * 584 * UniquePtr<char> ptr1(new char()); // repetitive 585 * auto ptr2 = MakeUnique<char>(); // shorter 586 * 587 * Of course this assumes the reader understands the operation MakeUnique 588 * performs. In the long run this is probably a reasonable assumption. In the 589 * short run you'll have to use your judgment about what readers can be expected 590 * to know, or to quickly look up. 591 * 592 * Third, a call to MakeUnique can be assigned directly to a UniquePtr. In 593 * contrast you can't assign a pointer into a UniquePtr without using the 594 * cumbersome reset(). 595 * 596 * UniquePtr<char> p; 597 * p = new char; // ERROR 598 * p.reset(new char); // works, but fugly 599 * p = MakeUnique<char>(); // preferred 600 * 601 * (And third, although not relevant to Mozilla: MakeUnique is exception-safe. 602 * An exception thrown after |new T| succeeds will leak that memory, unless the 603 * pointer is assigned to an object that will manage its ownership. UniquePtr 604 * ably serves this function.) 605 */ 606 607 template <typename T, typename... Args> 608 typename detail::UniqueSelector<T>::SingleObject MakeUnique(Args&&... aArgs) { 609 return UniquePtr<T>(new T(std::forward<Args>(aArgs)...)); 610 } 611 612 template <typename T> 613 typename detail::UniqueSelector<T>::UnknownBound MakeUnique( 614 decltype(sizeof(int)) aN) { 615 using ArrayType = std::remove_extent_t<T>; 616 return UniquePtr<T>(new ArrayType[aN]()); 617 } 618 619 template <typename T, typename... Args> 620 typename detail::UniqueSelector<T>::KnownBound MakeUnique(Args&&... aArgs) = 621 delete; 622 623 /** 624 * WrapUnique is a helper function to transfer ownership from a raw pointer 625 * into a UniquePtr<T>. It can only be used with a single non-array type. 626 * 627 * It is generally used this way: 628 * 629 * auto p = WrapUnique(new char); 630 * 631 * It can be used when MakeUnique is not usable, for example, when the 632 * constructor you are using is private, or you want to use aggregate 633 * initialization. 634 */ 635 636 template <typename T> 637 typename detail::UniqueSelector<T>::SingleObject WrapUnique(T* aPtr) { 638 return UniquePtr<T>(aPtr); 639 } 640 641 } // namespace mozilla 642 643 namespace std { 644 645 template <typename T, class D> 646 void swap(mozilla::UniquePtr<T, D>& aX, mozilla::UniquePtr<T, D>& aY) { 647 aX.swap(aY); 648 } 649 650 } // namespace std 651 652 #endif /* mozilla_UniquePtr_h */ 653