1 ///////////////////////////////////////////////////////////////////////////////
2 // Copyright (c) Electronic Arts Inc. All rights reserved.
3 ///////////////////////////////////////////////////////////////////////////////
4 
5 
6 #ifndef EASTL_UNIQUE_PTR_H
7 #define EASTL_UNIQUE_PTR_H
8 
9 
10 #include <EABase/nullptr.h>
11 #include <EASTL/internal/config.h>
12 #include <EASTL/internal/smart_ptr.h>   // Defines smart_ptr_deleter
13 #include <EASTL/internal/move_help.h>   // Defines EASTL_MOVE
14 #include <EASTL/type_traits.h>
15 #include <EASTL/functional.h>
16 #include <EASTL/bonus/compressed_pair.h>
17 #include <stddef.h>
18 
19 #if defined(EA_PRAGMA_ONCE_SUPPORTED)
20 	#pragma once // Some compilers (e.g. VC++) benefit significantly from using this. We've measured 3-4% build speed improvements in apps as a result.
21 #endif
22 
23 
24 namespace eastl
25 {
26 	/// class unique_ptr
27 	///
28 	/// This class implements a unique_ptr template. This is a class which is
29 	/// similar to the C++ auto_ptr template, except that it prohibits copying
30 	/// of itself, for safety.
31 	///
32 	/// More specifically, the unique_ptr class template stores a pointer to a
33 	/// dynamically allocated object.  The object pointed to is automatically
34 	/// deleted on destructor of unique_ptr or can be manually deleted via the
35 	/// unique_ptr::reset function.
36 	///
37 	/// Memory allocation notes:
38 	/// unique_ptr doesn't allocate memory; all allocated pointers are externally
39 	/// derived. unique_ptr does deallocate memory, though always through the
40 	/// user-provided deleter. You need to make sure you are consistent in providing
41 	/// a deleter which frees memory in a way that matches how it was originally allocated.
42 	/// Deleters have instance information and are moved between containers the same way
43 	/// the allocated pointers are. Thus you can allocate memory via some heap and
44 	/// provide a deleter which contains a pointer to that same heap, and regardless
45 	/// of what you do with the unique_ptr, including moving it to another unique_ptr,
46 	/// the deletion will use the originally provided heap.
47 	///
48 	/// Example usage:
49 	///     unique_ptr<int> p(new int);
50 	///     *p = 4;
51 	///
52 	///     unique_ptr<int[]> pArray(new int[4]);
53 	///     p[0] = 4;
54 	///
55 	/// Type completeness requirements
56 	/// http://stackoverflow.com/questions/6012157/is-stdunique-ptrt-required-to-know-the-full-definition-of-t/6089065#6089065
57 	/// Here is a table which documents several members of shared_ptr and unique_ptr with respect to completeness requirements.
58 	/// If the member requires a complete type, the entry has a "C", otherwise the table entry is filled with "I".
59 	///
60 	///                                 unique_ptr       shared_ptr
61 	///     +------------------------+---------------+---------------+
62 	///     |          P()           |      I        |      I        |
63 	///     |  default constructor   |               |               |
64 	///     +------------------------+---------------+---------------+
65 	///     |      P(const P&)       |     N/A       |      I        |
66 	///     |    copy constructor    |               |               |
67 	///     +------------------------+---------------+---------------+
68 	///     |         P(P&&)         |      I        |      I        |
69 	///     |    move constructor    |               |               |
70 	///     +------------------------+---------------+---------------+
71 	///     |         ~P()           |      C        |      I        |
72 	///     |       destructor       |               |               |
73 	///     +------------------------+---------------+---------------+
74 	///     |         P(A*)          |      I        |      C        |
75 	///     +------------------------+---------------+---------------+
76 	///     |  operator=(const P&)   |     N/A       |      I        |
77 	///     |    copy assignment     |               |               |
78 	///     +------------------------+---------------+---------------+
79 	///     |    operator=(P&&)      |      C        |      I        |
80 	///     |    move assignment     |               |               |
81 	///     +------------------------+---------------+---------------+
82 	///     |        reset()         |      C        |      I        |
83 	///     +------------------------+---------------+---------------+
84 	///     |       reset(A*)        |      C        |      C        |
85 	///     +------------------------+---------------+---------------+
86 	///
87 	template <typename T, typename Deleter = eastl::default_delete<T> >
88 	class unique_ptr
89 	{
90 	public:
91 		typedef Deleter                                                                  deleter_type;
92 		typedef T                                                                        element_type;
93 		typedef unique_ptr<element_type, deleter_type>                                   this_type;
94 		typedef typename Internal::unique_pointer_type<element_type, deleter_type>::type pointer;
95 
96 	public:
97 		/// unique_ptr
98 		/// Construct a unique_ptr from a pointer allocated via new.
99 		/// Example usage:
100 		///    unique_ptr<int> ptr;
unique_ptr()101 		EA_CPP14_CONSTEXPR unique_ptr() EA_NOEXCEPT
102 			: mPair(pointer())
103 		{
104 			static_assert(!eastl::is_pointer<deleter_type>::value, "unique_ptr deleter default-constructed with null pointer. Use a different constructor or change your deleter to a class.");
105 		}
106 
107 		/// unique_ptr
108 		/// Construct a unique_ptr from a null pointer.
109 		/// Example usage:
110 		///    unique_ptr<int> ptr(nullptr);
unique_ptr(std::nullptr_t)111 		EA_CPP14_CONSTEXPR unique_ptr(std::nullptr_t) EA_NOEXCEPT
112 			: mPair(pointer())
113 		{
114 			static_assert(!eastl::is_pointer<deleter_type>::value, "unique_ptr deleter default-constructed with null pointer. Use a different constructor or change your deleter to a class.");
115 		}
116 
117 		/// unique_ptr
118 		/// Construct a unique_ptr from a pointer allocated via new.
119 		/// Example usage:
120 		///    unique_ptr<int> ptr(new int(3));
unique_ptr(pointer pValue)121 		explicit unique_ptr(pointer pValue) EA_NOEXCEPT
122 			: mPair(pValue)
123 		{
124 			static_assert(!eastl::is_pointer<deleter_type>::value, "unique_ptr deleter default-constructed with null pointer. Use a different constructor or change your deleter to a class.");
125 		}
126 
127 		/// unique_ptr
128 		/// Constructs a unique_ptr with the owner pointer and deleter specified
129 		/// Example usage:
130 		///     eastl::smart_ptr_deleter<int> del;
131 		///     unique_ptr<int> ptr(new int(3), del);
unique_ptr(pointer pValue,typename eastl::conditional<eastl::is_reference<deleter_type>::value,deleter_type,typename eastl::add_lvalue_reference<const deleter_type>::type>::type deleter)132 		unique_ptr(pointer pValue, typename eastl::conditional<eastl::is_reference<deleter_type>::value, deleter_type, typename eastl::add_lvalue_reference<const deleter_type>::type>::type deleter) EA_NOEXCEPT
133 			: mPair(pValue, deleter) {}
134 
135 		/// unique_ptr
136 		/// Constructs a unique_ptr with the owned pointer and deleter specified (rvalue)
137 		/// Example usage:
138 		///     unique_ptr<int> ptr(new int(3), eastl::smart_ptr_deleter<int>());
unique_ptr(pointer pValue,typename eastl::remove_reference<deleter_type>::type && deleter)139 		unique_ptr(pointer pValue, typename eastl::remove_reference<deleter_type>::type&& deleter) EA_NOEXCEPT
140 			: mPair(pValue, eastl::move(deleter))
141 		{
142 			static_assert(!eastl::is_reference<deleter_type>::value, "deleter_type reference refers to an rvalue deleter. The reference will probably become invalid before used. Change the deleter_type to not be a reference or construct with permanent deleter.");
143 		}
144 
145 		/// unique_ptr
146 		/// Move constructor
147 		/// Example usage:
148 		///     unique_ptr<int> ptr(new int(3));
149 		///     unique_ptr<int> newPtr = eastl::move(ptr);
unique_ptr(this_type && x)150 		unique_ptr(this_type&& x) EA_NOEXCEPT
151 			: mPair(x.release(), eastl::forward<deleter_type>(x.get_deleter())) {}
152 
153 		/// unique_ptr
154 		/// Move constructor
155 		/// Example usage:
156 		///     unique_ptr<int> ptr(new int(3));
157 		///     unique_ptr<int> newPtr = eastl::move(ptr);
158 		template <typename U, typename E>
159 		unique_ptr(unique_ptr<U, E>&& u, typename enable_if<!is_array<U>::value && is_convertible<typename unique_ptr<U, E>::pointer, pointer>::value && is_convertible<E, deleter_type>::value && (is_same<deleter_type, E>::value || !is_reference<deleter_type>::value)>::type* = 0) EA_NOEXCEPT
160 			: mPair(u.release(), eastl::forward<E>(u.get_deleter())) {}
161 
162 		/// unique_ptr
163 		/// Move assignment
164 		/// Example usage:
165 		///     unique_ptr<int> ptr(new int(3));
166 		///     unique_ptr<int> newPtr(new int(4));
167 		///     ptr = eastl::move(newPtr);  // Deletes int(3) and assigns mpValue to int(4)
168 		this_type& operator=(this_type&& x) EA_NOEXCEPT
169 		{
170 			reset(x.release());
171 			mPair.second() = eastl::move(eastl::forward<deleter_type>(x.get_deleter()));
172 			return *this;
173 		}
174 
175 		/// unique_ptr
176 		/// Move assignment
177 		template <typename U, typename E>
178 		typename enable_if<!is_array<U>::value && is_convertible<typename unique_ptr<U, E>::pointer, pointer>::value && is_assignable<deleter_type&, E&&>::value, this_type&>::type
179 		operator=(unique_ptr<U, E>&& u) EA_NOEXCEPT
180 		{
181 			reset(u.release());
182 			mPair.second() = eastl::move(eastl::forward<E>(u.get_deleter()));
183 			return *this;
184 		}
185 
186 		/// operator=(nullptr_t)
187 		this_type& operator=(std::nullptr_t) EA_NOEXCEPT
188 		{
189 			reset();
190 			return *this;
191 		}
192 
193 		/// ~unique_ptr
194 		/// Destroys the owned pointer. The destructor for the object
195 		/// referred to by the owned pointer will be called.
~unique_ptr()196 		~unique_ptr() EA_NOEXCEPT
197 		{
198 			reset();
199 		}
200 
201 		/// reset
202 		/// Deletes the owned pointer and takes ownership of the
203 		/// passed in pointer. If the passed in pointer is the same
204 		/// as the owned pointer, nothing is done.
205 		/// Example usage:
206 		///    unique_ptr<int> ptr(new int(3));
207 		///    ptr.reset(new int(4));  // deletes int(3)
208 		///    ptr.reset(NULL);        // deletes int(4)
209 		void reset(pointer pValue = pointer()) EA_NOEXCEPT
210 		{
211 			if (pValue != mPair.first())
212 			{
213 				if (mPair.first())
214 					get_deleter()(mPair.first());
215 
216 				mPair.first() = pValue;
217 			}
218 		}
219 
220 		/// release
221 		/// This simply forgets the owned pointer. It doesn't
222 		/// free it but rather assumes that the user does.
223 		/// Example usage:
224 		///    unique_ptr<int> ptr(new int(3));
225 		///    int* pInt = ptr.release();
226 		///    delete pInt;
release()227 		pointer release() EA_NOEXCEPT
228 		{
229 			pointer const pTemp = mPair.first();
230 			mPair.first() = pointer();
231 			return pTemp;
232 		}
233 
234 		/// detach
235 		/// For backwards-compatibility with pre-C++11 code.
detach()236 		pointer detach() EA_NOEXCEPT { return release(); }
237 
238 		/// swap
239 		/// Exchanges the owned pointer beween two unique_ptr objects.
swap(this_type & x)240 		void swap(this_type& x) EA_NOEXCEPT
241 		{
242 			mPair.swap(x.mPair);
243 		}
244 
245 		/// operator*
246 		/// Returns the owner pointer dereferenced.
247 		/// Example usage:
248 		///    unique_ptr<int> ptr(new int(3));
249 		///    int x = *ptr;
250 		typename add_lvalue_reference<T>::type operator*() const // Not noexcept, because the pointer may be NULL.
251 		{
252 			return *mPair.first();
253 		}
254 
255 		/// operator->
256 		/// Allows access to the owned pointer via operator->()
257 		/// Example usage:
258 		///    struct X{ void DoSomething(); };
259 		///    unique_ptr<int> ptr(new X);
260 		///    ptr->DoSomething();
261 		pointer operator->() const EA_NOEXCEPT
262 		{
263 			return mPair.first();
264 		}
265 
266 		/// get
267 		/// Returns the owned pointer. Note that this class does
268 		/// not provide an operator T() function. This is because such
269 		/// a thing (automatic conversion) is deemed unsafe.
270 		/// Example usage:
271 		///    struct X{ void DoSomething(); };
272 		///    unique_ptr<int> ptr(new X);
273 		///    X* pX = ptr.get();
274 		///    pX->DoSomething();
get()275 		pointer get() const EA_NOEXCEPT
276 		{
277 			return mPair.first();
278 		}
279 
280 		/// get_deleter
281 		/// Returns the deleter used to delete the owned pointer
282 		/// Example usage:
283 		/// unique_ptr<int> ptr(new int(3));
284 		/// eastl::smart_ptr_deleter<int>& del = ptr.get_deleter();
get_deleter()285 		deleter_type& get_deleter() EA_NOEXCEPT
286 		{
287 			return mPair.second();
288 		}
289 
290 		/// get_deleter
291 		/// Const version for getting the deleter
get_deleter()292 		const deleter_type& get_deleter() const EA_NOEXCEPT
293 		{
294 			return mPair.second();
295 		}
296 
297 		#ifdef EA_COMPILER_NO_EXPLICIT_CONVERSION_OPERATORS
298 			/// Note that below we do not use operator bool(). The reason for this
299 			/// is that booleans automatically convert up to short, int, float, etc.
300 			/// The result is that this: if(uniquePtr == 1) would yield true (bad).
301 			typedef T* (this_type::*bool_)() const;
bool_()302 			operator bool_() const EA_NOEXCEPT
303 			{
304 				if(mPair.first())
305 					return &this_type::get;
306 				return NULL;
307 			}
308 
309 			bool operator!() const EA_NOEXCEPT
310 			{
311 				return (mPair.first() == pointer());
312 			}
313 		#else
314 			/// operator bool
315 			/// Allows for using a unique_ptr as a boolean.
316 			/// Example usage:
317 			///    unique_ptr<int> ptr(new int(3));
318 			///    if(ptr)
319 			///        ++*ptr;
320 			///
321 			explicit operator bool() const EA_NOEXCEPT
322 			{
323 				return (mPair.first() != pointer());
324 			}
325 		#endif
326 
327 		/// These functions are deleted in order to prevent copying, for safety.
328 		unique_ptr(const this_type&) = delete;
329 		unique_ptr& operator=(const this_type&) = delete;
330 		unique_ptr& operator=(pointer pValue) = delete;
331 
332 	protected:
333 		eastl::compressed_pair<pointer, deleter_type> mPair;
334 	}; // class unique_ptr
335 
336 
337 
338 	/// unique_ptr specialization for unbounded arrays.
339 	///
340 	/// Differences from unique_ptr<T>:
341 	///     - Conversions between different types of unique_ptr<T[], D> or to or
342 	///       from the non-array forms of unique_ptr produce an ill-formed program.
343 	///     - Pointers to types derived from T are rejected by the constructors, and by reset.
344 	///     - The observers operator* and operator-> are not provided.
345 	///     - The indexing observer operator[] is provided.
346 	///     - The default deleter will call delete[].
347 	///
348 	/// It's not possible to create a unique_ptr for arrays of a known bound (e.g. int[4] as opposed to int[]).
349 	///
350 	/// Example usage:
351 	///     unique_ptr<int[]> ptr(new int[10]);
352 	///     ptr[4] = 4;
353 	///
354 	template <typename T, typename Deleter>
355 	class unique_ptr<T[], Deleter>
356 	{
357 	public:
358 		typedef Deleter                                                                  deleter_type;
359 		typedef T                                                                        element_type;
360 		typedef unique_ptr<element_type[], deleter_type>                                 this_type;
361 		typedef typename Internal::unique_pointer_type<element_type, deleter_type>::type pointer;
362 
363 	public:
unique_ptr()364 		EA_CPP14_CONSTEXPR unique_ptr() EA_NOEXCEPT
365 			: mPair(pointer())
366 		{
367 			static_assert(!eastl::is_pointer<deleter_type>::value, "unique_ptr deleter default-constructed with null pointer. Use a different constructor or change your deleter to a class.");
368 		}
369 
unique_ptr(std::nullptr_t)370 		EA_CPP14_CONSTEXPR unique_ptr(std::nullptr_t) EA_NOEXCEPT
371 			: mPair(pointer())
372 		{
373 			static_assert(!eastl::is_pointer<deleter_type>::value, "unique_ptr deleter default-constructed with null pointer. Use a different constructor or change your deleter to a class.");
374 		}
375 
376 		template <typename P> // Pointers to types derived from T are rejected by the constructors, and by reset.
377 		explicit unique_ptr(P pArray, typename eastl::enable_if<Internal::is_array_cv_convertible<P, pointer>::value>::type* = 0) EA_NOEXCEPT
mPair(pArray)378 			: mPair(pArray)
379 		{
380 			static_assert(!eastl::is_pointer<deleter_type>::value, "unique_ptr deleter default-constructed with null pointer. Use a different constructor or change your deleter to a class.");
381 		}
382 
383 		template <typename P>
384 		unique_ptr(P pArray, typename eastl::conditional<eastl::is_reference<deleter_type>::value, deleter_type,
385 														typename eastl::add_lvalue_reference<const deleter_type>::type>::type deleter,
386 														typename eastl::enable_if<Internal::is_array_cv_convertible<P, pointer>::value>::type* = 0) EA_NOEXCEPT
mPair(pArray,deleter)387 			: mPair(pArray, deleter) {}
388 
389 		template <typename P>
390 		unique_ptr(P pArray, typename eastl::remove_reference<deleter_type>::type&& deleter, typename eastl::enable_if<Internal::is_array_cv_convertible<P, pointer>::value>::type* = 0) EA_NOEXCEPT
mPair(pArray,eastl::move (deleter))391 			: mPair(pArray, eastl::move(deleter))
392 		{
393 			static_assert(!eastl::is_reference<deleter_type>::value, "deleter_type reference refers to an rvalue deleter. The reference will probably become invalid before used. Change the deleter_type to not be a reference or construct with permanent deleter.");
394 		}
395 
unique_ptr(this_type && x)396 		unique_ptr(this_type&& x) EA_NOEXCEPT
397 			: mPair(x.release(), eastl::forward<deleter_type>(x.get_deleter())) {}
398 
399 		template <typename U, typename E>
400 		unique_ptr(unique_ptr<U, E>&& u, typename enable_if<Internal::is_safe_array_conversion<T, pointer, U, typename unique_ptr<U, E>::pointer>::value &&
401 															eastl::is_convertible<E, deleter_type>::value &&
402 														   (!eastl::is_reference<deleter_type>::value || eastl::is_same<E, deleter_type>::value)>::type* = 0) EA_NOEXCEPT
403 			: mPair(u.release(), eastl::forward<E>(u.get_deleter())) {}
404 
405 		this_type& operator=(this_type&& x) EA_NOEXCEPT
406 		{
407 			reset(x.release());
408 			mPair.second() = eastl::move(eastl::forward<deleter_type>(x.get_deleter()));
409 			return *this;
410 		}
411 
412 		template <typename U, typename E>
413 		typename enable_if<Internal::is_safe_array_conversion<T, pointer, U, typename unique_ptr<U, E>::pointer>::value && is_assignable<deleter_type&, E&&>::value, this_type&>::type
414 		operator=(unique_ptr<U, E>&& u) EA_NOEXCEPT
415 		{
416 			reset(u.release());
417 			mPair.second() = eastl::move(eastl::forward<E>(u.get_deleter()));
418 			return *this;
419 		}
420 
421 		this_type& operator=(std::nullptr_t) EA_NOEXCEPT
422 		{
423 			reset();
424 			return *this;
425 		}
426 
~unique_ptr()427 		~unique_ptr() EA_NOEXCEPT
428 		{
429 			reset();
430 		}
431 
432 		void reset(pointer pArray = pointer()) EA_NOEXCEPT
433 		{
434 			if(pArray != mPair.first())
435 			{
436 				get_deleter()(mPair.first());
437 				mPair.first() = pArray;
438 			}
439 		}
440 
release()441 		pointer release() EA_NOEXCEPT
442 		{
443 			pointer const pTemp = mPair.first();
444 			mPair.first() = pointer();
445 			return pTemp;
446 		}
447 
448 		/// detach
449 		/// For backwards-compatibility with pre-C++11 code.
detach()450 		pointer detach() EA_NOEXCEPT { return release(); }
451 
swap(this_type & x)452 		void swap(this_type& x) EA_NOEXCEPT
453 		{
454 			mPair.swap(x.mPair);
455 		}
456 
457 		/// operator[]
458 		/// Returns a reference to the specified item in the owned pointer
459 		/// array.
460 		/// Example usage:
461 		///    unique_ptr<int> ptr(new int[6]);
462 		///    int x = ptr[2];
463 		typename add_lvalue_reference<T>::type operator[](ptrdiff_t i) const
464 		{
465 			// assert(mpArray && (i >= 0));
466 			return mPair.first()[i];
467 		}
468 
get()469 		pointer get() const EA_NOEXCEPT
470 		{
471 			return mPair.first();
472 		}
473 
get_deleter()474 		deleter_type& get_deleter() EA_NOEXCEPT
475 		{
476 			return mPair.second();
477 		}
478 
get_deleter()479 		const deleter_type& get_deleter() const EA_NOEXCEPT
480 		{
481 			return mPair.second();
482 		}
483 
484 		#ifdef EA_COMPILER_NO_EXPLICIT_CONVERSION_OPERATORS
485 			typedef T* (this_type::*bool_)() const;
bool_()486 			operator bool_() const EA_NOEXCEPT
487 			{
488 				if(mPair.first())
489 					return &this_type::get;
490 				return NULL;
491 			}
492 
493 			bool operator!() const EA_NOEXCEPT
494 			{
495 				return (mPair.first() == pointer());
496 			}
497 		#else
498 			explicit operator bool() const EA_NOEXCEPT
499 			{
500 				return (mPair.first() != pointer());
501 			}
502 		#endif
503 
504 		/// These functions are deleted in order to prevent copying, for safety.
505 		unique_ptr(const this_type&) = delete;
506 		unique_ptr& operator=(const this_type&) = delete;
507 		unique_ptr& operator=(pointer pArray) = delete;
508 
509 	protected:
510 		eastl::compressed_pair<pointer, deleter_type> mPair;
511 	};
512 
513 
514 
515 	/// make_unique
516 	///
517 	/// The C++11 Standard doesn't have make_unique, but there's no agreed reason as to why.
518 	/// http://stackoverflow.com/questions/12580432/why-does-c11-have-make-shared-but-not-make-unique
519 	/// http://herbsutter.com/2013/05/29/gotw-89-solution-smart-pointers/
520 	/// Herb's solution is OK but doesn't support unique_ptr<[]> (array version). We do the same
521 	/// thing libc++ does and make a specialization of make_unique for arrays.
522 	///
523 	/// make_unique has two cases where you can't use it and need to directly use unique_ptr:
524 	///     - You need to construct the unique_ptr with a raw pointer.
525 	///     - You need to specify a custom deleter.
526 	///
527 	/// Note: This function uses global new T by default to create the ptr instance, as per
528 	/// the C++11 Standard make_shared_ptr.
529 	///
530 	/// Example usage:
531 	///     struct Test{ Test(int, int){} };
532 	///     auto p = make_unique<Test>(1, 2);
533 	///
534 	///     auto pArray = make_unique<Test[]>(4);
535 	///
536 	namespace Internal
537 	{
538 		template <typename T>
539 		struct unique_type
540 			{ typedef unique_ptr<T>   unique_type_single; };
541 
542 		template <typename T>
543 		struct unique_type<T[]>
544 			{ typedef unique_ptr<T[]> unique_type_unbounded_array; };
545 
546 		template <typename T, size_t N>
547 		struct unique_type<T[N]>
548 			{ typedef void            unique_type_bounded_array; };
549 	}
550 
551 	template <typename T, typename... Args>
552 	inline typename Internal::unique_type<T>::unique_type_single make_unique(Args&&... args)
553 		{ return unique_ptr<T>(new T(eastl::forward<Args>(args)...)); }
554 
555 	template <typename T>
556 	inline typename Internal::unique_type<T>::unique_type_unbounded_array make_unique(size_t n)
557 	{
558 		typedef typename eastl::remove_extent<T>::type TBase;
559 		return unique_ptr<T>(new TBase[n]);
560 	}
561 
562 	// It's not possible to create a unique_ptr for arrays of a known bound (e.g. int[4] as opposed to int[]).
563 	template <typename T, typename... Args>
564 	typename Internal::unique_type<T>::unique_type_bounded_array
565 	make_unique(Args&&...) = delete;
566 
567 
568 
569 
570 	/// hash specialization for unique_ptr.
571 	/// It simply returns eastl::hash(x.get()). If your unique_ptr pointer type (the return value of unique_ptr<T>::get) is
572 	/// a custom type and not a built-in pointer type then you will need to independently define eastl::hash for that type.
573 	template <typename T, typename D>
574 	struct hash< unique_ptr<T, D> >
575 	{
576 		size_t operator()(const unique_ptr<T, D>& x) const EA_NOEXCEPT
577 			{ return eastl::hash<typename unique_ptr<T, D>::pointer>()(x.get()); }
578 	};
579 
580 	/// swap
581 	/// Exchanges the owned pointer beween two unique_ptr objects.
582 	/// This non-member version is useful for compatibility of unique_ptr
583 	/// objects with the C++ Standard Library and other libraries.
584 	template <typename T, typename D>
585 	inline void swap(unique_ptr<T, D>& a, unique_ptr<T, D>& b) EA_NOEXCEPT
586 	{
587 		a.swap(b);
588 	}
589 
590 
591 	template <typename T1, typename D1, typename T2, typename D2>
592 	inline bool operator==(const unique_ptr<T1, D1>& a, const unique_ptr<T2, D2>& b)
593 	{
594 		return (a.get() == b.get());
595 	}
596 
597 	template <typename T1, typename D1, typename T2, typename D2>
598 	inline bool operator!=(const unique_ptr<T1, D1>& a, const unique_ptr<T2, D2>& b)
599 	{
600 		return !(a.get() == b.get());
601 	}
602 
603 	/// Returns which unique_ptr is 'less' than the other. Useful when storing
604 	/// sorted containers of unique_ptr objects.
605 	template <typename T1, typename D1, typename T2, typename D2>
606 	inline bool operator<(const unique_ptr<T1, D1>& a, const unique_ptr<T2, D2>& b)
607 	{
608 		//typedef typename eastl::unique_ptr<T1, D1>::pointer P1;       // We currently need to make these temporary variables, as otherwise clang complains about CPointer being int*&&&.
609 		//typedef typename eastl::unique_ptr<T2, D2>::pointer P2;       // I think there's something wrong with our common_type type trait implementation.
610 		//typedef typename eastl::common_type<P1, P2>::type   PCommon;  // "in instantiation of function template specialization 'eastl::operator<<int, int>, no known conversion from 'element_type *' (aka 'int *') to 'int *&&&' for 1st argument"
611 		//return less<PCommon>()(a.get(), b.get());                     // It looks like common_type is making CPointer be (e.g.) int*&& instead of int*, though the problem may be in how less<> deals with that.
612 
613 		typedef typename eastl::unique_ptr<T1, D1>::pointer P1;
614 		typedef typename eastl::unique_ptr<T2, D2>::pointer P2;
615 		typedef typename eastl::common_type<P1, P2>::type   PCommon;
616 		PCommon pT1 = a.get();
617 		PCommon pT2 = b.get();
618 		return less<PCommon>()(pT1, pT2);
619 	}
620 
621 	template <typename T1, typename D1, typename T2, typename D2>
622 	inline bool operator>(const unique_ptr<T1, D1>& a, const unique_ptr<T2, D2>& b)
623 	{
624 		return (b < a);
625 	}
626 
627 	template <typename T1, typename D1, typename T2, typename D2>
628 	inline bool operator<=(const unique_ptr<T1, D1>& a, const unique_ptr<T2, D2>& b)
629 	{
630 		return !(b < a);
631 	}
632 
633 	template <typename T1, typename D1, typename T2, typename D2>
634 	inline bool operator>=(const unique_ptr<T1, D1>& a, const unique_ptr<T2, D2>& b)
635 	{
636 		return !(a < b);
637 	}
638 
639 
640 	template <typename T, typename D>
641 	inline bool operator==(const unique_ptr<T, D>& a, std::nullptr_t) EA_NOEXCEPT
642 	{
643 		return !a;
644 	}
645 
646 	template <typename T, typename D>
647 	inline bool operator==(std::nullptr_t, const unique_ptr<T, D>& a) EA_NOEXCEPT
648 	{
649 		return !a;
650 	}
651 
652 	template <typename T, typename D>
653 	inline bool operator!=(const unique_ptr<T, D>& a, std::nullptr_t) EA_NOEXCEPT
654 	{
655 		return static_cast<bool>(a);
656 	}
657 
658 	template <typename T, typename D>
659 	inline bool operator!=(std::nullptr_t, const unique_ptr<T, D>& a) EA_NOEXCEPT
660 	{
661 		return static_cast<bool>(a);
662 	}
663 
664 	template <typename T, typename D>
665 	inline bool operator<(const unique_ptr<T, D>& a, std::nullptr_t)
666 	{
667 		typedef typename unique_ptr<T, D>::pointer pointer;
668 		return less<pointer>()(a.get(), nullptr);
669 	}
670 
671 	template <typename T, typename D>
672 	inline bool operator<(std::nullptr_t, const unique_ptr<T, D>& b)
673 	{
674 		typedef typename unique_ptr<T, D>::pointer pointer;
675 		pointer pT = b.get();
676 		return less<pointer>()(nullptr, pT);
677 	}
678 
679 	template <typename T, typename D>
680 	inline bool operator>(const unique_ptr<T, D>& a, std::nullptr_t)
681 	{
682 		return (nullptr < a);
683 	}
684 
685 	template <typename T, typename D>
686 	inline bool operator>(std::nullptr_t, const unique_ptr<T, D>& b)
687 	{
688 		return (b < nullptr);
689 	}
690 
691 	template <typename T, typename D>
692 	inline bool operator<=(const unique_ptr<T, D>& a, std::nullptr_t)
693 	{
694 		return !(nullptr < a);
695 	}
696 
697 	template <typename T, typename D>
698 	inline bool operator<=(std::nullptr_t, const unique_ptr<T, D>& b)
699 	{
700 		return !(b < nullptr);
701 	}
702 
703 	template <typename T, typename D>
704 	inline bool operator>=(const unique_ptr<T, D>& a, std::nullptr_t)
705 	{
706 		return !(a < nullptr);
707 	}
708 
709 	template <typename T, typename D>
710 	inline bool operator>=(std::nullptr_t, const unique_ptr<T, D>& b)
711 	{
712 		return !(nullptr < b);
713 	}
714 
715 
716 } // namespace eastl
717 
718 
719 #endif // Header include guard
720 
721 
722 
723 
724 
725 
726 
727 
728 
729 
730 
731