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