xref: /netbsd-src/external/gpl3/gcc/dist/libstdc++-v3/include/bits/unique_ptr.h (revision d79abf08584d17438738b62a4ac1b023f122bf52)
1 // unique_ptr implementation -*- C++ -*-
2 
3 // Copyright (C) 2008-2016 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library.  This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
9 // any later version.
10 
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 // GNU General Public License for more details.
15 
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
19 
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23 // <http://www.gnu.org/licenses/>.
24 
25 /** @file bits/unique_ptr.h
26  *  This is an internal header file, included by other library headers.
27  *  Do not attempt to use it directly. @headername{memory}
28  */
29 
30 #ifndef _UNIQUE_PTR_H
31 #define _UNIQUE_PTR_H 1
32 
33 #include <bits/c++config.h>
34 #include <debug/assertions.h>
35 #include <type_traits>
36 #include <utility>
37 #include <tuple>
38 
39 namespace std _GLIBCXX_VISIBILITY(default)
40 {
41 _GLIBCXX_BEGIN_NAMESPACE_VERSION
42 
43   /**
44    * @addtogroup pointer_abstractions
45    * @{
46    */
47 
48 #if _GLIBCXX_USE_DEPRECATED
49   template<typename> class auto_ptr;
50 #endif
51 
52   /// Primary template of default_delete, used by unique_ptr
53   template<typename _Tp>
54     struct default_delete
55     {
56       /// Default constructor
57       constexpr default_delete() noexcept = default;
58 
59       /** @brief Converting constructor.
60        *
61        * Allows conversion from a deleter for arrays of another type, @p _Up,
62        * only if @p _Up* is convertible to @p _Tp*.
63        */
64       template<typename _Up, typename = typename
65 	       enable_if<is_convertible<_Up*, _Tp*>::value>::type>
66         default_delete(const default_delete<_Up>&) noexcept { }
67 
68       /// Calls @c delete @p __ptr
69       void
70       operator()(_Tp* __ptr) const
71       {
72 	static_assert(!is_void<_Tp>::value,
73 		      "can't delete pointer to incomplete type");
74 	static_assert(sizeof(_Tp)>0,
75 		      "can't delete pointer to incomplete type");
76 	delete __ptr;
77       }
78     };
79 
80   // _GLIBCXX_RESOLVE_LIB_DEFECTS
81   // DR 740 - omit specialization for array objects with a compile time length
82   /// Specialization for arrays, default_delete.
83   template<typename _Tp>
84     struct default_delete<_Tp[]>
85     {
86     public:
87       /// Default constructor
88       constexpr default_delete() noexcept = default;
89 
90       /** @brief Converting constructor.
91        *
92        * Allows conversion from a deleter for arrays of another type, such as
93        * a const-qualified version of @p _Tp.
94        *
95        * Conversions from types derived from @c _Tp are not allowed because
96        * it is unsafe to @c delete[] an array of derived types through a
97        * pointer to the base type.
98        */
99       template<typename _Up, typename = typename
100 	       enable_if<is_convertible<_Up(*)[], _Tp(*)[]>::value>::type>
101         default_delete(const default_delete<_Up[]>&) noexcept { }
102 
103       /// Calls @c delete[] @p __ptr
104       template<typename _Up>
105       typename enable_if<is_convertible<_Up(*)[], _Tp(*)[]>::value>::type
106 	operator()(_Up* __ptr) const
107       {
108 	static_assert(sizeof(_Tp)>0,
109 		      "can't delete pointer to incomplete type");
110 	delete [] __ptr;
111       }
112     };
113 
114   /// 20.7.1.2 unique_ptr for single objects.
115   template <typename _Tp, typename _Dp = default_delete<_Tp> >
116     class unique_ptr
117     {
118       // use SFINAE to determine whether _Del::pointer exists
119       class _Pointer
120       {
121 	template<typename _Up>
122 	  static typename _Up::pointer __test(typename _Up::pointer*);
123 
124 	template<typename _Up>
125 	  static _Tp* __test(...);
126 
127 	typedef typename remove_reference<_Dp>::type _Del;
128 
129       public:
130 	typedef decltype(__test<_Del>(0)) type;
131       };
132 
133       typedef std::tuple<typename _Pointer::type, _Dp>  __tuple_type;
134       __tuple_type                                      _M_t;
135 
136     public:
137       typedef typename _Pointer::type   pointer;
138       typedef _Tp                       element_type;
139       typedef _Dp                       deleter_type;
140 
141 
142       // helper template for detecting a safe conversion from another
143       // unique_ptr
144       template<typename _Up, typename _Ep>
145 	using __safe_conversion_up = __and_<
146 	        is_convertible<typename unique_ptr<_Up, _Ep>::pointer, pointer>,
147                 __not_<is_array<_Up>>,
148                 __or_<__and_<is_reference<deleter_type>,
149                              is_same<deleter_type, _Ep>>,
150                       __and_<__not_<is_reference<deleter_type>>,
151                              is_convertible<_Ep, deleter_type>>
152                 >
153               >;
154 
155       // Constructors.
156 
157       /// Default constructor, creates a unique_ptr that owns nothing.
158       constexpr unique_ptr() noexcept
159       : _M_t()
160       { static_assert(!is_pointer<deleter_type>::value,
161 		     "constructed with null function pointer deleter"); }
162 
163       /** Takes ownership of a pointer.
164        *
165        * @param __p  A pointer to an object of @c element_type
166        *
167        * The deleter will be value-initialized.
168        */
169       explicit
170       unique_ptr(pointer __p) noexcept
171       : _M_t()
172       {
173 	std::get<0>(_M_t) = __p;
174 	static_assert(!is_pointer<deleter_type>::value,
175 		     "constructed with null function pointer deleter");
176       }
177 
178       /** Takes ownership of a pointer.
179        *
180        * @param __p  A pointer to an object of @c element_type
181        * @param __d  A reference to a deleter.
182        *
183        * The deleter will be initialized with @p __d
184        */
185       unique_ptr(pointer __p,
186 	  typename conditional<is_reference<deleter_type>::value,
187 	    deleter_type, const deleter_type&>::type __d) noexcept
188       : _M_t(__p, __d) { }
189 
190       /** Takes ownership of a pointer.
191        *
192        * @param __p  A pointer to an object of @c element_type
193        * @param __d  An rvalue reference to a deleter.
194        *
195        * The deleter will be initialized with @p std::move(__d)
196        */
197       unique_ptr(pointer __p,
198 	  typename remove_reference<deleter_type>::type&& __d) noexcept
199       : _M_t(std::move(__p), std::move(__d))
200       { static_assert(!std::is_reference<deleter_type>::value,
201 		      "rvalue deleter bound to reference"); }
202 
203       /// Creates a unique_ptr that owns nothing.
204       constexpr unique_ptr(nullptr_t) noexcept : _M_t()
205       { static_assert(!is_pointer<deleter_type>::value,
206 		      "constructed with null function pointer deleter"); }
207 
208       // Move constructors.
209 
210       /// Move constructor.
211       unique_ptr(unique_ptr&& __u) noexcept
212       : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter())) { }
213 
214       /** @brief Converting constructor from another type
215        *
216        * Requires that the pointer owned by @p __u is convertible to the
217        * type of pointer owned by this object, @p __u does not own an array,
218        * and @p __u has a compatible deleter type.
219        */
220       template<typename _Up, typename _Ep, typename = _Require<
221                __safe_conversion_up<_Up, _Ep>,
222 	       typename conditional<is_reference<_Dp>::value,
223 				    is_same<_Ep, _Dp>,
224 				    is_convertible<_Ep, _Dp>>::type>>
225 	unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept
226 	: _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter()))
227 	{ }
228 
229 #if _GLIBCXX_USE_DEPRECATED
230       /// Converting constructor from @c auto_ptr
231       template<typename _Up, typename = _Require<
232 	       is_convertible<_Up*, _Tp*>, is_same<_Dp, default_delete<_Tp>>>>
233 	unique_ptr(auto_ptr<_Up>&& __u) noexcept;
234 #endif
235 
236       /// Destructor, invokes the deleter if the stored pointer is not null.
237       ~unique_ptr() noexcept
238       {
239 	auto& __ptr = std::get<0>(_M_t);
240 	if (__ptr != nullptr)
241 	  get_deleter()(__ptr);
242 	__ptr = pointer();
243       }
244 
245       // Assignment.
246 
247       /** @brief Move assignment operator.
248        *
249        * @param __u  The object to transfer ownership from.
250        *
251        * Invokes the deleter first if this object owns a pointer.
252        */
253       unique_ptr&
254       operator=(unique_ptr&& __u) noexcept
255       {
256 	reset(__u.release());
257 	get_deleter() = std::forward<deleter_type>(__u.get_deleter());
258 	return *this;
259       }
260 
261       /** @brief Assignment from another type.
262        *
263        * @param __u  The object to transfer ownership from, which owns a
264        *             convertible pointer to a non-array object.
265        *
266        * Invokes the deleter first if this object owns a pointer.
267        */
268       template<typename _Up, typename _Ep>
269         typename enable_if< __and_<
270           __safe_conversion_up<_Up, _Ep>,
271           is_assignable<deleter_type&, _Ep&&>
272           >::value,
273           unique_ptr&>::type
274 	operator=(unique_ptr<_Up, _Ep>&& __u) noexcept
275 	{
276 	  reset(__u.release());
277 	  get_deleter() = std::forward<_Ep>(__u.get_deleter());
278 	  return *this;
279 	}
280 
281       /// Reset the %unique_ptr to empty, invoking the deleter if necessary.
282       unique_ptr&
283       operator=(nullptr_t) noexcept
284       {
285 	reset();
286 	return *this;
287       }
288 
289       // Observers.
290 
291       /// Dereference the stored pointer.
292       typename add_lvalue_reference<element_type>::type
293       operator*() const
294       {
295 	__glibcxx_assert(get() != pointer());
296 	return *get();
297       }
298 
299       /// Return the stored pointer.
300       pointer
301       operator->() const noexcept
302       {
303 	_GLIBCXX_DEBUG_PEDASSERT(get() != pointer());
304 	return get();
305       }
306 
307       /// Return the stored pointer.
308       pointer
309       get() const noexcept
310       { return std::get<0>(_M_t); }
311 
312       /// Return a reference to the stored deleter.
313       deleter_type&
314       get_deleter() noexcept
315       { return std::get<1>(_M_t); }
316 
317       /// Return a reference to the stored deleter.
318       const deleter_type&
319       get_deleter() const noexcept
320       { return std::get<1>(_M_t); }
321 
322       /// Return @c true if the stored pointer is not null.
323       explicit operator bool() const noexcept
324       { return get() == pointer() ? false : true; }
325 
326       // Modifiers.
327 
328       /// Release ownership of any stored pointer.
329       pointer
330       release() noexcept
331       {
332 	pointer __p = get();
333 	std::get<0>(_M_t) = pointer();
334 	return __p;
335       }
336 
337       /** @brief Replace the stored pointer.
338        *
339        * @param __p  The new pointer to store.
340        *
341        * The deleter will be invoked if a pointer is already owned.
342        */
343       void
344       reset(pointer __p = pointer()) noexcept
345       {
346 	using std::swap;
347 	swap(std::get<0>(_M_t), __p);
348 	if (__p != pointer())
349 	  get_deleter()(__p);
350       }
351 
352       /// Exchange the pointer and deleter with another object.
353       void
354       swap(unique_ptr& __u) noexcept
355       {
356 	using std::swap;
357 	swap(_M_t, __u._M_t);
358       }
359 
360       // Disable copy from lvalue.
361       unique_ptr(const unique_ptr&) = delete;
362       unique_ptr& operator=(const unique_ptr&) = delete;
363   };
364 
365   /// 20.7.1.3 unique_ptr for array objects with a runtime length
366   // [unique.ptr.runtime]
367   // _GLIBCXX_RESOLVE_LIB_DEFECTS
368   // DR 740 - omit specialization for array objects with a compile time length
369   template<typename _Tp, typename _Dp>
370     class unique_ptr<_Tp[], _Dp>
371     {
372       // use SFINAE to determine whether _Del::pointer exists
373       class _Pointer
374       {
375 	template<typename _Up>
376 	  static typename _Up::pointer __test(typename _Up::pointer*);
377 
378 	template<typename _Up>
379 	  static _Tp* __test(...);
380 
381 	typedef typename remove_reference<_Dp>::type _Del;
382 
383       public:
384 	typedef decltype(__test<_Del>(0)) type;
385       };
386 
387       typedef std::tuple<typename _Pointer::type, _Dp>  __tuple_type;
388       __tuple_type                                      _M_t;
389 
390       template<typename _Up>
391 	using __remove_cv = typename remove_cv<_Up>::type;
392 
393       // like is_base_of<_Tp, _Up> but false if unqualified types are the same
394       template<typename _Up>
395 	using __is_derived_Tp
396 	  = __and_< is_base_of<_Tp, _Up>,
397 		    __not_<is_same<__remove_cv<_Tp>, __remove_cv<_Up>>> >;
398 
399 
400     public:
401       typedef typename _Pointer::type	pointer;
402       typedef _Tp		 	element_type;
403       typedef _Dp                       deleter_type;
404 
405       // helper template for detecting a safe conversion from another
406       // unique_ptr
407       template<typename _Up, typename _Ep,
408                typename _Up_up = unique_ptr<_Up, _Ep>,
409 	       typename _Up_element_type = typename _Up_up::element_type>
410 	using __safe_conversion_up = __and_<
411           is_array<_Up>,
412           is_same<pointer, element_type*>,
413           is_same<typename _Up_up::pointer, _Up_element_type*>,
414           is_convertible<_Up_element_type(*)[], element_type(*)[]>,
415           __or_<__and_<is_reference<deleter_type>, is_same<deleter_type, _Ep>>,
416                 __and_<__not_<is_reference<deleter_type>>,
417                        is_convertible<_Ep, deleter_type>>>
418         >;
419 
420       // helper template for detecting a safe conversion from a raw pointer
421       template<typename _Up>
422         using __safe_conversion_raw = __and_<
423           __or_<__or_<is_same<_Up, pointer>,
424                       is_same<_Up, nullptr_t>>,
425                 __and_<is_pointer<_Up>,
426                        is_same<pointer, element_type*>,
427                        is_convertible<
428                          typename remove_pointer<_Up>::type(*)[],
429                          element_type(*)[]>
430                 >
431           >
432         >;
433 
434       // Constructors.
435 
436       /// Default constructor, creates a unique_ptr that owns nothing.
437       constexpr unique_ptr() noexcept
438       : _M_t()
439       { static_assert(!std::is_pointer<deleter_type>::value,
440 		      "constructed with null function pointer deleter"); }
441 
442       /** Takes ownership of a pointer.
443        *
444        * @param __p  A pointer to an array of a type safely convertible
445        * to an array of @c element_type
446        *
447        * The deleter will be value-initialized.
448        */
449       template<typename _Up,
450                typename = typename enable_if<
451                  __safe_conversion_raw<_Up>::value, bool>::type>
452       explicit
453       unique_ptr(_Up __p) noexcept
454       : _M_t(__p, deleter_type())
455       { static_assert(!is_pointer<deleter_type>::value,
456 		      "constructed with null function pointer deleter"); }
457 
458       /** Takes ownership of a pointer.
459        *
460        * @param __p  A pointer to an array of a type safely convertible
461        * to an array of @c element_type
462        * @param __d  A reference to a deleter.
463        *
464        * The deleter will be initialized with @p __d
465        */
466       template<typename _Up,
467                typename = typename enable_if<
468                  __safe_conversion_raw<_Up>::value, bool>::type>
469       unique_ptr(_Up __p,
470                  typename conditional<is_reference<deleter_type>::value,
471                  deleter_type, const deleter_type&>::type __d) noexcept
472       : _M_t(__p, __d) { }
473 
474       /** Takes ownership of a pointer.
475        *
476        * @param __p  A pointer to an array of a type safely convertible
477        * to an array of @c element_type
478        * @param __d  A reference to a deleter.
479        *
480        * The deleter will be initialized with @p std::move(__d)
481        */
482       template<typename _Up,
483                typename = typename enable_if<
484                  __safe_conversion_raw<_Up>::value, bool>::type>
485       unique_ptr(_Up __p, typename
486 		 remove_reference<deleter_type>::type&& __d) noexcept
487       : _M_t(std::move(__p), std::move(__d))
488       { static_assert(!is_reference<deleter_type>::value,
489 		      "rvalue deleter bound to reference"); }
490 
491       /// Move constructor.
492       unique_ptr(unique_ptr&& __u) noexcept
493       : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter())) { }
494 
495       /// Creates a unique_ptr that owns nothing.
496       constexpr unique_ptr(nullptr_t) noexcept : _M_t()
497       { static_assert(!is_pointer<deleter_type>::value,
498 		      "constructed with null function pointer deleter"); }
499 
500       template<typename _Up, typename _Ep,
501 	       typename = _Require<__safe_conversion_up<_Up, _Ep>>>
502 	unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept
503 	: _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter()))
504 	{ }
505 
506       /// Destructor, invokes the deleter if the stored pointer is not null.
507       ~unique_ptr()
508       {
509 	auto& __ptr = std::get<0>(_M_t);
510 	if (__ptr != nullptr)
511 	  get_deleter()(__ptr);
512 	__ptr = pointer();
513       }
514 
515       // Assignment.
516 
517       /** @brief Move assignment operator.
518        *
519        * @param __u  The object to transfer ownership from.
520        *
521        * Invokes the deleter first if this object owns a pointer.
522        */
523       unique_ptr&
524       operator=(unique_ptr&& __u) noexcept
525       {
526 	reset(__u.release());
527 	get_deleter() = std::forward<deleter_type>(__u.get_deleter());
528 	return *this;
529       }
530 
531       /** @brief Assignment from another type.
532        *
533        * @param __u  The object to transfer ownership from, which owns a
534        *             convertible pointer to an array object.
535        *
536        * Invokes the deleter first if this object owns a pointer.
537        */
538       template<typename _Up, typename _Ep>
539 	typename
540 	enable_if<__and_<__safe_conversion_up<_Up, _Ep>,
541                          is_assignable<deleter_type&, _Ep&&>
542                   >::value,
543                   unique_ptr&>::type
544 	operator=(unique_ptr<_Up, _Ep>&& __u) noexcept
545 	{
546 	  reset(__u.release());
547 	  get_deleter() = std::forward<_Ep>(__u.get_deleter());
548 	  return *this;
549 	}
550 
551       /// Reset the %unique_ptr to empty, invoking the deleter if necessary.
552       unique_ptr&
553       operator=(nullptr_t) noexcept
554       {
555 	reset();
556 	return *this;
557       }
558 
559       // Observers.
560 
561       /// Access an element of owned array.
562       typename std::add_lvalue_reference<element_type>::type
563       operator[](size_t __i) const
564       {
565 	__glibcxx_assert(get() != pointer());
566 	return get()[__i];
567       }
568 
569       /// Return the stored pointer.
570       pointer
571       get() const noexcept
572       { return std::get<0>(_M_t); }
573 
574       /// Return a reference to the stored deleter.
575       deleter_type&
576       get_deleter() noexcept
577       { return std::get<1>(_M_t); }
578 
579       /// Return a reference to the stored deleter.
580       const deleter_type&
581       get_deleter() const noexcept
582       { return std::get<1>(_M_t); }
583 
584       /// Return @c true if the stored pointer is not null.
585       explicit operator bool() const noexcept
586       { return get() == pointer() ? false : true; }
587 
588       // Modifiers.
589 
590       /// Release ownership of any stored pointer.
591       pointer
592       release() noexcept
593       {
594 	pointer __p = get();
595 	std::get<0>(_M_t) = pointer();
596 	return __p;
597       }
598 
599       /** @brief Replace the stored pointer.
600        *
601        * @param __p  The new pointer to store.
602        *
603        * The deleter will be invoked if a pointer is already owned.
604        */
605       template <typename _Up,
606                 typename = _Require<
607                   __or_<is_same<_Up, pointer>,
608                         __and_<is_same<pointer, element_type*>,
609                                is_pointer<_Up>,
610                                is_convertible<
611                                  typename remove_pointer<_Up>::type(*)[],
612                                  element_type(*)[]
613                                >
614                         >
615                   >
616                >>
617       void
618       reset(_Up __p) noexcept
619       {
620 	pointer __ptr = __p;
621 	using std::swap;
622 	swap(std::get<0>(_M_t), __ptr);
623 	if (__ptr != nullptr)
624 	  get_deleter()(__ptr);
625       }
626 
627       void reset(nullptr_t = nullptr) noexcept
628       {
629         reset(pointer());
630       }
631 
632       /// Exchange the pointer and deleter with another object.
633       void
634       swap(unique_ptr& __u) noexcept
635       {
636 	using std::swap;
637 	swap(_M_t, __u._M_t);
638       }
639 
640       // Disable copy from lvalue.
641       unique_ptr(const unique_ptr&) = delete;
642       unique_ptr& operator=(const unique_ptr&) = delete;
643     };
644 
645   template<typename _Tp, typename _Dp>
646     inline void
647     swap(unique_ptr<_Tp, _Dp>& __x,
648 	 unique_ptr<_Tp, _Dp>& __y) noexcept
649     { __x.swap(__y); }
650 
651   template<typename _Tp, typename _Dp,
652 	   typename _Up, typename _Ep>
653     inline bool
654     operator==(const unique_ptr<_Tp, _Dp>& __x,
655 	       const unique_ptr<_Up, _Ep>& __y)
656     { return __x.get() == __y.get(); }
657 
658   template<typename _Tp, typename _Dp>
659     inline bool
660     operator==(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept
661     { return !__x; }
662 
663   template<typename _Tp, typename _Dp>
664     inline bool
665     operator==(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept
666     { return !__x; }
667 
668   template<typename _Tp, typename _Dp,
669 	   typename _Up, typename _Ep>
670     inline bool
671     operator!=(const unique_ptr<_Tp, _Dp>& __x,
672 	       const unique_ptr<_Up, _Ep>& __y)
673     { return __x.get() != __y.get(); }
674 
675   template<typename _Tp, typename _Dp>
676     inline bool
677     operator!=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept
678     { return (bool)__x; }
679 
680   template<typename _Tp, typename _Dp>
681     inline bool
682     operator!=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept
683     { return (bool)__x; }
684 
685   template<typename _Tp, typename _Dp,
686 	   typename _Up, typename _Ep>
687     inline bool
688     operator<(const unique_ptr<_Tp, _Dp>& __x,
689 	      const unique_ptr<_Up, _Ep>& __y)
690     {
691       typedef typename
692 	std::common_type<typename unique_ptr<_Tp, _Dp>::pointer,
693 	                 typename unique_ptr<_Up, _Ep>::pointer>::type _CT;
694       return std::less<_CT>()(__x.get(), __y.get());
695     }
696 
697   template<typename _Tp, typename _Dp>
698     inline bool
699     operator<(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
700     { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(__x.get(),
701 								 nullptr); }
702 
703   template<typename _Tp, typename _Dp>
704     inline bool
705     operator<(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
706     { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(nullptr,
707 								 __x.get()); }
708 
709   template<typename _Tp, typename _Dp,
710 	   typename _Up, typename _Ep>
711     inline bool
712     operator<=(const unique_ptr<_Tp, _Dp>& __x,
713 	       const unique_ptr<_Up, _Ep>& __y)
714     { return !(__y < __x); }
715 
716   template<typename _Tp, typename _Dp>
717     inline bool
718     operator<=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
719     { return !(nullptr < __x); }
720 
721   template<typename _Tp, typename _Dp>
722     inline bool
723     operator<=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
724     { return !(__x < nullptr); }
725 
726   template<typename _Tp, typename _Dp,
727 	   typename _Up, typename _Ep>
728     inline bool
729     operator>(const unique_ptr<_Tp, _Dp>& __x,
730 	      const unique_ptr<_Up, _Ep>& __y)
731     { return (__y < __x); }
732 
733   template<typename _Tp, typename _Dp>
734     inline bool
735     operator>(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
736     { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(nullptr,
737 								 __x.get()); }
738 
739   template<typename _Tp, typename _Dp>
740     inline bool
741     operator>(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
742     { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(__x.get(),
743 								 nullptr); }
744 
745   template<typename _Tp, typename _Dp,
746 	   typename _Up, typename _Ep>
747     inline bool
748     operator>=(const unique_ptr<_Tp, _Dp>& __x,
749 	       const unique_ptr<_Up, _Ep>& __y)
750     { return !(__x < __y); }
751 
752   template<typename _Tp, typename _Dp>
753     inline bool
754     operator>=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
755     { return !(__x < nullptr); }
756 
757   template<typename _Tp, typename _Dp>
758     inline bool
759     operator>=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
760     { return !(nullptr < __x); }
761 
762   /// std::hash specialization for unique_ptr.
763   template<typename _Tp, typename _Dp>
764     struct hash<unique_ptr<_Tp, _Dp>>
765     : public __hash_base<size_t, unique_ptr<_Tp, _Dp>>
766     {
767       size_t
768       operator()(const unique_ptr<_Tp, _Dp>& __u) const noexcept
769       {
770 	typedef unique_ptr<_Tp, _Dp> _UP;
771 	return std::hash<typename _UP::pointer>()(__u.get());
772       }
773     };
774 
775 #if __cplusplus > 201103L
776 
777 #define __cpp_lib_make_unique 201304
778 
779   template<typename _Tp>
780     struct _MakeUniq
781     { typedef unique_ptr<_Tp> __single_object; };
782 
783   template<typename _Tp>
784     struct _MakeUniq<_Tp[]>
785     { typedef unique_ptr<_Tp[]> __array; };
786 
787   template<typename _Tp, size_t _Bound>
788     struct _MakeUniq<_Tp[_Bound]>
789     { struct __invalid_type { }; };
790 
791   /// std::make_unique for single objects
792   template<typename _Tp, typename... _Args>
793     inline typename _MakeUniq<_Tp>::__single_object
794     make_unique(_Args&&... __args)
795     { return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); }
796 
797   /// std::make_unique for arrays of unknown bound
798   template<typename _Tp>
799     inline typename _MakeUniq<_Tp>::__array
800     make_unique(size_t __num)
801     { return unique_ptr<_Tp>(new remove_extent_t<_Tp>[__num]()); }
802 
803   /// Disable std::make_unique for arrays of known bound
804   template<typename _Tp, typename... _Args>
805     inline typename _MakeUniq<_Tp>::__invalid_type
806     make_unique(_Args&&...) = delete;
807 #endif
808 
809   // @} group pointer_abstractions
810 
811 _GLIBCXX_END_NAMESPACE_VERSION
812 } // namespace
813 
814 #endif /* _UNIQUE_PTR_H */
815