Implement LWG 2905 changes to constrain unique_ptr constructors
[official-gcc.git] / libstdc++-v3 / include / bits / unique_ptr.h
blobddc6ae0e2332f83de30e05ab336fd5f299ee1822
1 // unique_ptr implementation -*- C++ -*-
3 // Copyright (C) 2008-2018 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.
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.
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.
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/>.
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}
30 #ifndef _UNIQUE_PTR_H
31 #define _UNIQUE_PTR_H 1
33 #include <bits/c++config.h>
34 #include <debug/assertions.h>
35 #include <type_traits>
36 #include <utility>
37 #include <tuple>
38 #include <bits/stl_function.h>
39 #include <bits/functional_hash.h>
41 namespace std _GLIBCXX_VISIBILITY(default)
43 _GLIBCXX_BEGIN_NAMESPACE_VERSION
45 /**
46 * @addtogroup pointer_abstractions
47 * @{
50 #if _GLIBCXX_USE_DEPRECATED
51 #pragma GCC diagnostic push
52 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
53 template<typename> class auto_ptr;
54 #pragma GCC diagnostic pop
55 #endif
57 /// Primary template of default_delete, used by unique_ptr
58 template<typename _Tp>
59 struct default_delete
61 /// Default constructor
62 constexpr default_delete() noexcept = default;
64 /** @brief Converting constructor.
66 * Allows conversion from a deleter for arrays of another type, @p _Up,
67 * only if @p _Up* is convertible to @p _Tp*.
69 template<typename _Up, typename = typename
70 enable_if<is_convertible<_Up*, _Tp*>::value>::type>
71 default_delete(const default_delete<_Up>&) noexcept { }
73 /// Calls @c delete @p __ptr
74 void
75 operator()(_Tp* __ptr) const
77 static_assert(!is_void<_Tp>::value,
78 "can't delete pointer to incomplete type");
79 static_assert(sizeof(_Tp)>0,
80 "can't delete pointer to incomplete type");
81 delete __ptr;
85 // _GLIBCXX_RESOLVE_LIB_DEFECTS
86 // DR 740 - omit specialization for array objects with a compile time length
87 /// Specialization for arrays, default_delete.
88 template<typename _Tp>
89 struct default_delete<_Tp[]>
91 public:
92 /// Default constructor
93 constexpr default_delete() noexcept = default;
95 /** @brief Converting constructor.
97 * Allows conversion from a deleter for arrays of another type, such as
98 * a const-qualified version of @p _Tp.
100 * Conversions from types derived from @c _Tp are not allowed because
101 * it is unsafe to @c delete[] an array of derived types through a
102 * pointer to the base type.
104 template<typename _Up, typename = typename
105 enable_if<is_convertible<_Up(*)[], _Tp(*)[]>::value>::type>
106 default_delete(const default_delete<_Up[]>&) noexcept { }
108 /// Calls @c delete[] @p __ptr
109 template<typename _Up>
110 typename enable_if<is_convertible<_Up(*)[], _Tp(*)[]>::value>::type
111 operator()(_Up* __ptr) const
113 static_assert(sizeof(_Tp)>0,
114 "can't delete pointer to incomplete type");
115 delete [] __ptr;
119 template <typename _Tp, typename _Dp>
120 class __uniq_ptr_impl
122 template <typename _Up, typename _Ep, typename = void>
123 struct _Ptr
125 using type = _Up*;
128 template <typename _Up, typename _Ep>
129 struct
130 _Ptr<_Up, _Ep, __void_t<typename remove_reference<_Ep>::type::pointer>>
132 using type = typename remove_reference<_Ep>::type::pointer;
135 public:
136 using _DeleterConstraint = enable_if<
137 __and_<__not_<is_pointer<_Dp>>,
138 is_default_constructible<_Dp>>::value>;
140 using pointer = typename _Ptr<_Tp, _Dp>::type;
142 static_assert( !is_rvalue_reference<_Dp>::value,
143 "unique_ptr's deleter type must be a function object type"
144 " or an lvalue reference type" );
145 static_assert( __is_invocable<_Dp&, pointer&>::value,
146 "unique_ptr's deleter must be invocable with a pointer" );
148 __uniq_ptr_impl() = default;
149 __uniq_ptr_impl(pointer __p) : _M_t() { _M_ptr() = __p; }
151 template<typename _Del>
152 __uniq_ptr_impl(pointer __p, _Del&& __d)
153 : _M_t(__p, std::forward<_Del>(__d)) { }
155 pointer& _M_ptr() { return std::get<0>(_M_t); }
156 pointer _M_ptr() const { return std::get<0>(_M_t); }
157 _Dp& _M_deleter() { return std::get<1>(_M_t); }
158 const _Dp& _M_deleter() const { return std::get<1>(_M_t); }
160 private:
161 tuple<pointer, _Dp> _M_t;
164 /// 20.7.1.2 unique_ptr for single objects.
165 template <typename _Tp, typename _Dp = default_delete<_Tp>>
166 class unique_ptr
168 template <typename _Up>
169 using _DeleterConstraint =
170 typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type;
172 __uniq_ptr_impl<_Tp, _Dp> _M_t;
174 public:
175 using pointer = typename __uniq_ptr_impl<_Tp, _Dp>::pointer;
176 using element_type = _Tp;
177 using deleter_type = _Dp;
179 private:
180 // helper template for detecting a safe conversion from another
181 // unique_ptr
182 template<typename _Up, typename _Ep>
183 using __safe_conversion_up = __and_<
184 is_convertible<typename unique_ptr<_Up, _Ep>::pointer, pointer>,
185 __not_<is_array<_Up>>,
186 __or_<__and_<is_reference<deleter_type>,
187 is_same<deleter_type, _Ep>>,
188 __and_<__not_<is_reference<deleter_type>>,
189 is_convertible<_Ep, deleter_type>>
193 public:
194 // Constructors.
196 /// Default constructor, creates a unique_ptr that owns nothing.
197 template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>>
198 constexpr unique_ptr() noexcept
199 : _M_t()
202 /** Takes ownership of a pointer.
204 * @param __p A pointer to an object of @c element_type
206 * The deleter will be value-initialized.
208 template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>>
209 explicit
210 unique_ptr(pointer __p) noexcept
211 : _M_t(__p)
214 /** Takes ownership of a pointer.
216 * @param __p A pointer to an object of @c element_type
217 * @param __d A reference to a deleter.
219 * The deleter will be initialized with @p __d
221 template<typename _Del = deleter_type,
222 typename = _Require<is_copy_constructible<_Del>>>
223 unique_ptr(pointer __p, const deleter_type& __d) noexcept
224 : _M_t(__p, __d) { }
226 /** Takes ownership of a pointer.
228 * @param __p A pointer to an object of @c element_type
229 * @param __d An rvalue reference to a (non-reference) deleter.
231 * The deleter will be initialized with @p std::move(__d)
233 template<typename _Del = deleter_type,
234 typename = _Require<is_move_constructible<_Del>>>
235 unique_ptr(pointer __p,
236 __enable_if_t<!is_lvalue_reference<_Del>::value,
237 _Del&&> __d) noexcept
238 : _M_t(__p, std::move(__d))
241 template<typename _Del = deleter_type,
242 typename _DelUnref = typename remove_reference<_Del>::type>
243 unique_ptr(pointer,
244 __enable_if_t<is_lvalue_reference<_Del>::value,
245 _DelUnref&&>) = delete;
247 /// Creates a unique_ptr that owns nothing.
248 template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>>
249 constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { }
251 // Move constructors.
253 /// Move constructor.
254 unique_ptr(unique_ptr&& __u) noexcept
255 : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter())) { }
257 /** @brief Converting constructor from another type
259 * Requires that the pointer owned by @p __u is convertible to the
260 * type of pointer owned by this object, @p __u does not own an array,
261 * and @p __u has a compatible deleter type.
263 template<typename _Up, typename _Ep, typename = _Require<
264 __safe_conversion_up<_Up, _Ep>,
265 typename conditional<is_reference<_Dp>::value,
266 is_same<_Ep, _Dp>,
267 is_convertible<_Ep, _Dp>>::type>>
268 unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept
269 : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter()))
272 #if _GLIBCXX_USE_DEPRECATED
273 #pragma GCC diagnostic push
274 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
275 /// Converting constructor from @c auto_ptr
276 template<typename _Up, typename = _Require<
277 is_convertible<_Up*, _Tp*>, is_same<_Dp, default_delete<_Tp>>>>
278 unique_ptr(auto_ptr<_Up>&& __u) noexcept;
279 #pragma GCC diagnostic pop
280 #endif
282 /// Destructor, invokes the deleter if the stored pointer is not null.
283 ~unique_ptr() noexcept
285 auto& __ptr = _M_t._M_ptr();
286 if (__ptr != nullptr)
287 get_deleter()(__ptr);
288 __ptr = pointer();
291 // Assignment.
293 /** @brief Move assignment operator.
295 * @param __u The object to transfer ownership from.
297 * Invokes the deleter first if this object owns a pointer.
299 unique_ptr&
300 operator=(unique_ptr&& __u) noexcept
302 reset(__u.release());
303 get_deleter() = std::forward<deleter_type>(__u.get_deleter());
304 return *this;
307 /** @brief Assignment from another type.
309 * @param __u The object to transfer ownership from, which owns a
310 * convertible pointer to a non-array object.
312 * Invokes the deleter first if this object owns a pointer.
314 template<typename _Up, typename _Ep>
315 typename enable_if< __and_<
316 __safe_conversion_up<_Up, _Ep>,
317 is_assignable<deleter_type&, _Ep&&>
318 >::value,
319 unique_ptr&>::type
320 operator=(unique_ptr<_Up, _Ep>&& __u) noexcept
322 reset(__u.release());
323 get_deleter() = std::forward<_Ep>(__u.get_deleter());
324 return *this;
327 /// Reset the %unique_ptr to empty, invoking the deleter if necessary.
328 unique_ptr&
329 operator=(nullptr_t) noexcept
331 reset();
332 return *this;
335 // Observers.
337 /// Dereference the stored pointer.
338 typename add_lvalue_reference<element_type>::type
339 operator*() const
341 __glibcxx_assert(get() != pointer());
342 return *get();
345 /// Return the stored pointer.
346 pointer
347 operator->() const noexcept
349 _GLIBCXX_DEBUG_PEDASSERT(get() != pointer());
350 return get();
353 /// Return the stored pointer.
354 pointer
355 get() const noexcept
356 { return _M_t._M_ptr(); }
358 /// Return a reference to the stored deleter.
359 deleter_type&
360 get_deleter() noexcept
361 { return _M_t._M_deleter(); }
363 /// Return a reference to the stored deleter.
364 const deleter_type&
365 get_deleter() const noexcept
366 { return _M_t._M_deleter(); }
368 /// Return @c true if the stored pointer is not null.
369 explicit operator bool() const noexcept
370 { return get() == pointer() ? false : true; }
372 // Modifiers.
374 /// Release ownership of any stored pointer.
375 pointer
376 release() noexcept
378 pointer __p = get();
379 _M_t._M_ptr() = pointer();
380 return __p;
383 /** @brief Replace the stored pointer.
385 * @param __p The new pointer to store.
387 * The deleter will be invoked if a pointer is already owned.
389 void
390 reset(pointer __p = pointer()) noexcept
392 using std::swap;
393 swap(_M_t._M_ptr(), __p);
394 if (__p != pointer())
395 get_deleter()(__p);
398 /// Exchange the pointer and deleter with another object.
399 void
400 swap(unique_ptr& __u) noexcept
402 using std::swap;
403 swap(_M_t, __u._M_t);
406 // Disable copy from lvalue.
407 unique_ptr(const unique_ptr&) = delete;
408 unique_ptr& operator=(const unique_ptr&) = delete;
411 /// 20.7.1.3 unique_ptr for array objects with a runtime length
412 // [unique.ptr.runtime]
413 // _GLIBCXX_RESOLVE_LIB_DEFECTS
414 // DR 740 - omit specialization for array objects with a compile time length
415 template<typename _Tp, typename _Dp>
416 class unique_ptr<_Tp[], _Dp>
418 template <typename _Up>
419 using _DeleterConstraint =
420 typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type;
422 __uniq_ptr_impl<_Tp, _Dp> _M_t;
424 template<typename _Up>
425 using __remove_cv = typename remove_cv<_Up>::type;
427 // like is_base_of<_Tp, _Up> but false if unqualified types are the same
428 template<typename _Up>
429 using __is_derived_Tp
430 = __and_< is_base_of<_Tp, _Up>,
431 __not_<is_same<__remove_cv<_Tp>, __remove_cv<_Up>>> >;
433 public:
434 using pointer = typename __uniq_ptr_impl<_Tp, _Dp>::pointer;
435 using element_type = _Tp;
436 using deleter_type = _Dp;
438 // helper template for detecting a safe conversion from another
439 // unique_ptr
440 template<typename _Up, typename _Ep,
441 typename _Up_up = unique_ptr<_Up, _Ep>,
442 typename _Up_element_type = typename _Up_up::element_type>
443 using __safe_conversion_up = __and_<
444 is_array<_Up>,
445 is_same<pointer, element_type*>,
446 is_same<typename _Up_up::pointer, _Up_element_type*>,
447 is_convertible<_Up_element_type(*)[], element_type(*)[]>,
448 __or_<__and_<is_reference<deleter_type>, is_same<deleter_type, _Ep>>,
449 __and_<__not_<is_reference<deleter_type>>,
450 is_convertible<_Ep, deleter_type>>>
453 // helper template for detecting a safe conversion from a raw pointer
454 template<typename _Up>
455 using __safe_conversion_raw = __and_<
456 __or_<__or_<is_same<_Up, pointer>,
457 is_same<_Up, nullptr_t>>,
458 __and_<is_pointer<_Up>,
459 is_same<pointer, element_type*>,
460 is_convertible<
461 typename remove_pointer<_Up>::type(*)[],
462 element_type(*)[]>
467 // Constructors.
469 /// Default constructor, creates a unique_ptr that owns nothing.
470 template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>>
471 constexpr unique_ptr() noexcept
472 : _M_t()
475 /** Takes ownership of a pointer.
477 * @param __p A pointer to an array of a type safely convertible
478 * to an array of @c element_type
480 * The deleter will be value-initialized.
482 template<typename _Up,
483 typename _Vp = _Dp,
484 typename = _DeleterConstraint<_Vp>,
485 typename = typename enable_if<
486 __safe_conversion_raw<_Up>::value, bool>::type>
487 explicit
488 unique_ptr(_Up __p) noexcept
489 : _M_t(__p)
492 /** Takes ownership of a pointer.
494 * @param __p A pointer to an array of a type safely convertible
495 * to an array of @c element_type
496 * @param __d A reference to a deleter.
498 * The deleter will be initialized with @p __d
500 template<typename _Up, typename _Del = deleter_type,
501 typename = _Require<__safe_conversion_raw<_Up>,
502 is_copy_constructible<_Del>>>
503 unique_ptr(_Up __p, const deleter_type& __d) noexcept
504 : _M_t(__p, __d) { }
506 /** Takes ownership of a pointer.
508 * @param __p A pointer to an array of a type safely convertible
509 * to an array of @c element_type
510 * @param __d A reference to a deleter.
512 * The deleter will be initialized with @p std::move(__d)
514 template<typename _Up, typename _Del = deleter_type,
515 typename = _Require<__safe_conversion_raw<_Up>,
516 is_move_constructible<_Del>>>
517 unique_ptr(_Up __p,
518 __enable_if_t<!is_lvalue_reference<_Del>::value,
519 _Del&&> __d) noexcept
520 : _M_t(std::move(__p), std::move(__d))
523 template<typename _Up, typename _Del = deleter_type,
524 typename _DelUnref = typename remove_reference<_Del>::type,
525 typename = _Require<__safe_conversion_raw<_Up>>>
526 unique_ptr(_Up,
527 __enable_if_t<is_lvalue_reference<_Del>::value,
528 _DelUnref&&>) = delete;
530 /// Move constructor.
531 unique_ptr(unique_ptr&& __u) noexcept
532 : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter())) { }
534 /// Creates a unique_ptr that owns nothing.
535 template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>>
536 constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { }
538 template<typename _Up, typename _Ep,
539 typename = _Require<__safe_conversion_up<_Up, _Ep>>>
540 unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept
541 : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter()))
544 /// Destructor, invokes the deleter if the stored pointer is not null.
545 ~unique_ptr()
547 auto& __ptr = _M_t._M_ptr();
548 if (__ptr != nullptr)
549 get_deleter()(__ptr);
550 __ptr = pointer();
553 // Assignment.
555 /** @brief Move assignment operator.
557 * @param __u The object to transfer ownership from.
559 * Invokes the deleter first if this object owns a pointer.
561 unique_ptr&
562 operator=(unique_ptr&& __u) noexcept
564 reset(__u.release());
565 get_deleter() = std::forward<deleter_type>(__u.get_deleter());
566 return *this;
569 /** @brief Assignment from another type.
571 * @param __u The object to transfer ownership from, which owns a
572 * convertible pointer to an array object.
574 * Invokes the deleter first if this object owns a pointer.
576 template<typename _Up, typename _Ep>
577 typename
578 enable_if<__and_<__safe_conversion_up<_Up, _Ep>,
579 is_assignable<deleter_type&, _Ep&&>
580 >::value,
581 unique_ptr&>::type
582 operator=(unique_ptr<_Up, _Ep>&& __u) noexcept
584 reset(__u.release());
585 get_deleter() = std::forward<_Ep>(__u.get_deleter());
586 return *this;
589 /// Reset the %unique_ptr to empty, invoking the deleter if necessary.
590 unique_ptr&
591 operator=(nullptr_t) noexcept
593 reset();
594 return *this;
597 // Observers.
599 /// Access an element of owned array.
600 typename std::add_lvalue_reference<element_type>::type
601 operator[](size_t __i) const
603 __glibcxx_assert(get() != pointer());
604 return get()[__i];
607 /// Return the stored pointer.
608 pointer
609 get() const noexcept
610 { return _M_t._M_ptr(); }
612 /// Return a reference to the stored deleter.
613 deleter_type&
614 get_deleter() noexcept
615 { return _M_t._M_deleter(); }
617 /// Return a reference to the stored deleter.
618 const deleter_type&
619 get_deleter() const noexcept
620 { return _M_t._M_deleter(); }
622 /// Return @c true if the stored pointer is not null.
623 explicit operator bool() const noexcept
624 { return get() == pointer() ? false : true; }
626 // Modifiers.
628 /// Release ownership of any stored pointer.
629 pointer
630 release() noexcept
632 pointer __p = get();
633 _M_t._M_ptr() = pointer();
634 return __p;
637 /** @brief Replace the stored pointer.
639 * @param __p The new pointer to store.
641 * The deleter will be invoked if a pointer is already owned.
643 template <typename _Up,
644 typename = _Require<
645 __or_<is_same<_Up, pointer>,
646 __and_<is_same<pointer, element_type*>,
647 is_pointer<_Up>,
648 is_convertible<
649 typename remove_pointer<_Up>::type(*)[],
650 element_type(*)[]
655 void
656 reset(_Up __p) noexcept
658 pointer __ptr = __p;
659 using std::swap;
660 swap(_M_t._M_ptr(), __ptr);
661 if (__ptr != nullptr)
662 get_deleter()(__ptr);
665 void reset(nullptr_t = nullptr) noexcept
667 reset(pointer());
670 /// Exchange the pointer and deleter with another object.
671 void
672 swap(unique_ptr& __u) noexcept
674 using std::swap;
675 swap(_M_t, __u._M_t);
678 // Disable copy from lvalue.
679 unique_ptr(const unique_ptr&) = delete;
680 unique_ptr& operator=(const unique_ptr&) = delete;
683 template<typename _Tp, typename _Dp>
684 inline
685 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
686 // Constrained free swap overload, see p0185r1
687 typename enable_if<__is_swappable<_Dp>::value>::type
688 #else
689 void
690 #endif
691 swap(unique_ptr<_Tp, _Dp>& __x,
692 unique_ptr<_Tp, _Dp>& __y) noexcept
693 { __x.swap(__y); }
695 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
696 template<typename _Tp, typename _Dp>
697 typename enable_if<!__is_swappable<_Dp>::value>::type
698 swap(unique_ptr<_Tp, _Dp>&,
699 unique_ptr<_Tp, _Dp>&) = delete;
700 #endif
702 template<typename _Tp, typename _Dp,
703 typename _Up, typename _Ep>
704 inline bool
705 operator==(const unique_ptr<_Tp, _Dp>& __x,
706 const unique_ptr<_Up, _Ep>& __y)
707 { return __x.get() == __y.get(); }
709 template<typename _Tp, typename _Dp>
710 inline bool
711 operator==(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept
712 { return !__x; }
714 template<typename _Tp, typename _Dp>
715 inline bool
716 operator==(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept
717 { return !__x; }
719 template<typename _Tp, typename _Dp,
720 typename _Up, typename _Ep>
721 inline bool
722 operator!=(const unique_ptr<_Tp, _Dp>& __x,
723 const unique_ptr<_Up, _Ep>& __y)
724 { return __x.get() != __y.get(); }
726 template<typename _Tp, typename _Dp>
727 inline bool
728 operator!=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept
729 { return (bool)__x; }
731 template<typename _Tp, typename _Dp>
732 inline bool
733 operator!=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept
734 { return (bool)__x; }
736 template<typename _Tp, typename _Dp,
737 typename _Up, typename _Ep>
738 inline bool
739 operator<(const unique_ptr<_Tp, _Dp>& __x,
740 const unique_ptr<_Up, _Ep>& __y)
742 typedef typename
743 std::common_type<typename unique_ptr<_Tp, _Dp>::pointer,
744 typename unique_ptr<_Up, _Ep>::pointer>::type _CT;
745 return std::less<_CT>()(__x.get(), __y.get());
748 template<typename _Tp, typename _Dp>
749 inline bool
750 operator<(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
751 { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(__x.get(),
752 nullptr); }
754 template<typename _Tp, typename _Dp>
755 inline bool
756 operator<(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
757 { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(nullptr,
758 __x.get()); }
760 template<typename _Tp, typename _Dp,
761 typename _Up, typename _Ep>
762 inline bool
763 operator<=(const unique_ptr<_Tp, _Dp>& __x,
764 const unique_ptr<_Up, _Ep>& __y)
765 { return !(__y < __x); }
767 template<typename _Tp, typename _Dp>
768 inline bool
769 operator<=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
770 { return !(nullptr < __x); }
772 template<typename _Tp, typename _Dp>
773 inline bool
774 operator<=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
775 { return !(__x < nullptr); }
777 template<typename _Tp, typename _Dp,
778 typename _Up, typename _Ep>
779 inline bool
780 operator>(const unique_ptr<_Tp, _Dp>& __x,
781 const unique_ptr<_Up, _Ep>& __y)
782 { return (__y < __x); }
784 template<typename _Tp, typename _Dp>
785 inline bool
786 operator>(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
787 { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(nullptr,
788 __x.get()); }
790 template<typename _Tp, typename _Dp>
791 inline bool
792 operator>(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
793 { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(__x.get(),
794 nullptr); }
796 template<typename _Tp, typename _Dp,
797 typename _Up, typename _Ep>
798 inline bool
799 operator>=(const unique_ptr<_Tp, _Dp>& __x,
800 const unique_ptr<_Up, _Ep>& __y)
801 { return !(__x < __y); }
803 template<typename _Tp, typename _Dp>
804 inline bool
805 operator>=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
806 { return !(__x < nullptr); }
808 template<typename _Tp, typename _Dp>
809 inline bool
810 operator>=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
811 { return !(nullptr < __x); }
813 /// std::hash specialization for unique_ptr.
814 template<typename _Tp, typename _Dp>
815 struct hash<unique_ptr<_Tp, _Dp>>
816 : public __hash_base<size_t, unique_ptr<_Tp, _Dp>>,
817 private __poison_hash<typename unique_ptr<_Tp, _Dp>::pointer>
819 size_t
820 operator()(const unique_ptr<_Tp, _Dp>& __u) const noexcept
822 typedef unique_ptr<_Tp, _Dp> _UP;
823 return std::hash<typename _UP::pointer>()(__u.get());
827 #if __cplusplus > 201103L
829 #define __cpp_lib_make_unique 201304
831 template<typename _Tp>
832 struct _MakeUniq
833 { typedef unique_ptr<_Tp> __single_object; };
835 template<typename _Tp>
836 struct _MakeUniq<_Tp[]>
837 { typedef unique_ptr<_Tp[]> __array; };
839 template<typename _Tp, size_t _Bound>
840 struct _MakeUniq<_Tp[_Bound]>
841 { struct __invalid_type { }; };
843 /// std::make_unique for single objects
844 template<typename _Tp, typename... _Args>
845 inline typename _MakeUniq<_Tp>::__single_object
846 make_unique(_Args&&... __args)
847 { return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); }
849 /// std::make_unique for arrays of unknown bound
850 template<typename _Tp>
851 inline typename _MakeUniq<_Tp>::__array
852 make_unique(size_t __num)
853 { return unique_ptr<_Tp>(new remove_extent_t<_Tp>[__num]()); }
855 /// Disable std::make_unique for arrays of known bound
856 template<typename _Tp, typename... _Args>
857 inline typename _MakeUniq<_Tp>::__invalid_type
858 make_unique(_Args&&...) = delete;
859 #endif
861 // @} group pointer_abstractions
863 _GLIBCXX_END_NAMESPACE_VERSION
864 } // namespace
866 #endif /* _UNIQUE_PTR_H */