libstdc++
unique_ptr.h
Go to the documentation of this file.
1
2// unique_ptr implementation -*- C++ -*-
3
4// Copyright (C) 2008-2025 Free Software Foundation, Inc.
5//
6// This file is part of the GNU ISO C++ Library. This library is free
7// software; you can redistribute it and/or modify it under the
8// terms of the GNU General Public License as published by the
9// Free Software Foundation; either version 3, or (at your option)
10// any later version.
11
12// This library is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15// GNU General Public License for more details.
16
17// Under Section 7 of GPL version 3, you are granted additional
18// permissions described in the GCC Runtime Library Exception, version
19// 3.1, as published by the Free Software Foundation.
20
21// You should have received a copy of the GNU General Public License and
22// a copy of the GCC Runtime Library Exception along with this program;
23// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24// <http://www.gnu.org/licenses/>.
25
26/** @file bits/unique_ptr.h
27 * This is an internal header file, included by other library headers.
28 * Do not attempt to use it directly. @headername{memory}
29 */
30
31#ifndef _UNIQUE_PTR_H
32#define _UNIQUE_PTR_H 1
33
34#include <bits/c++config.h>
35#include <debug/assertions.h>
36#include <type_traits>
37#include <tuple>
38#include <bits/stl_function.h>
40#if __cplusplus >= 202002L
41# include <compare>
42# if _GLIBCXX_HOSTED
43# include <bits/ostream.h>
44# endif
45#endif
46
47namespace std _GLIBCXX_VISIBILITY(default)
48{
49_GLIBCXX_BEGIN_NAMESPACE_VERSION
50
51 /**
52 * @addtogroup pointer_abstractions
53 * @{
54 */
55
56#if _GLIBCXX_USE_DEPRECATED
57#pragma GCC diagnostic push
58#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
59 template<typename> class auto_ptr;
60#pragma GCC diagnostic pop
61#endif
62
63 /** Primary template of default_delete, used by unique_ptr for single objects
64 *
65 * @headerfile memory
66 * @since C++11
67 */
68 template<typename _Tp>
70 {
71 /// Default constructor
72 constexpr default_delete() noexcept = default;
73
74 /** @brief Converting constructor.
75 *
76 * Allows conversion from a deleter for objects of another type, `_Up`,
77 * only if `_Up*` is convertible to `_Tp*`.
78 */
79 template<typename _Up,
80 typename = _Require<is_convertible<_Up*, _Tp*>>>
81 _GLIBCXX23_CONSTEXPR
82 default_delete(const default_delete<_Up>&) noexcept { }
83
84 /// Calls `delete __ptr`
85 _GLIBCXX23_CONSTEXPR
86 void
87 operator()(_Tp* __ptr) const
88 {
89 static_assert(!is_void<_Tp>::value,
90 "can't delete pointer to incomplete type");
91 static_assert(sizeof(_Tp)>0,
92 "can't delete pointer to incomplete type");
93 delete __ptr;
94 }
95 };
96
97 // _GLIBCXX_RESOLVE_LIB_DEFECTS
98 // DR 740 - omit specialization for array objects with a compile time length
99
100 /** Specialization of default_delete for arrays, used by `unique_ptr<T[]>`
101 *
102 * @headerfile memory
103 * @since C++11
104 */
105 template<typename _Tp>
106 struct default_delete<_Tp[]>
107 {
108 public:
109 /// Default constructor
110 constexpr default_delete() noexcept = default;
111
112 /** @brief Converting constructor.
113 *
114 * Allows conversion from a deleter for arrays of another type, such as
115 * a const-qualified version of `_Tp`.
116 *
117 * Conversions from types derived from `_Tp` are not allowed because
118 * it is undefined to `delete[]` an array of derived types through a
119 * pointer to the base type.
120 */
121 template<typename _Up,
122 typename = _Require<is_convertible<_Up(*)[], _Tp(*)[]>>>
123 _GLIBCXX23_CONSTEXPR
124 default_delete(const default_delete<_Up[]>&) noexcept { }
125
126 /// Calls `delete[] __ptr`
127 template<typename _Up>
128 _GLIBCXX23_CONSTEXPR
129 typename enable_if<is_convertible<_Up(*)[], _Tp(*)[]>::value>::type
130 operator()(_Up* __ptr) const
131 {
132 static_assert(sizeof(_Tp)>0,
133 "can't delete pointer to incomplete type");
134 delete [] __ptr;
135 }
136 };
137
138 /// @cond undocumented
139
140 // Manages the pointer and deleter of a unique_ptr
141 template <typename _Tp, typename _Dp>
142 class __uniq_ptr_impl
143 {
144 template <typename _Up, typename _Ep, typename = void>
145 struct _Ptr
146 {
147 using type = _Up*;
148 };
149
150 template <typename _Up, typename _Ep>
151 struct
152 _Ptr<_Up, _Ep, __void_t<typename remove_reference<_Ep>::type::pointer>>
153 {
154 using type = typename remove_reference<_Ep>::type::pointer;
155 };
156
157 public:
158 using _DeleterConstraint = enable_if<
159 __and_<__not_<is_pointer<_Dp>>,
160 is_default_constructible<_Dp>>::value>;
161
162 using pointer = typename _Ptr<_Tp, _Dp>::type;
163
164 static_assert( !is_rvalue_reference<_Dp>::value,
165 "unique_ptr's deleter type must be a function object type"
166 " or an lvalue reference type" );
167
168 __uniq_ptr_impl() = default;
169 _GLIBCXX23_CONSTEXPR
170 __uniq_ptr_impl(pointer __p) : _M_t() { _M_ptr() = __p; }
171
172 template<typename _Del>
173 _GLIBCXX23_CONSTEXPR
174 __uniq_ptr_impl(pointer __p, _Del&& __d)
175 : _M_t(__p, std::forward<_Del>(__d)) { }
176
177 _GLIBCXX23_CONSTEXPR
178 __uniq_ptr_impl(__uniq_ptr_impl&& __u) noexcept
179 : _M_t(std::move(__u._M_t))
180 { __u._M_ptr() = nullptr; }
181
182 _GLIBCXX23_CONSTEXPR
183 __uniq_ptr_impl& operator=(__uniq_ptr_impl&& __u) noexcept
184 {
185 reset(__u.release());
186 _M_deleter() = std::forward<_Dp>(__u._M_deleter());
187 return *this;
188 }
189
190 _GLIBCXX23_CONSTEXPR
191 pointer& _M_ptr() noexcept { return std::get<0>(_M_t); }
192 _GLIBCXX23_CONSTEXPR
193 pointer _M_ptr() const noexcept { return std::get<0>(_M_t); }
194 _GLIBCXX23_CONSTEXPR
195 _Dp& _M_deleter() noexcept { return std::get<1>(_M_t); }
196 _GLIBCXX23_CONSTEXPR
197 const _Dp& _M_deleter() const noexcept { return std::get<1>(_M_t); }
198
199 _GLIBCXX23_CONSTEXPR
200 void reset(pointer __p) noexcept
201 {
202 const pointer __old_p = _M_ptr();
203 _M_ptr() = __p;
204 if (__old_p)
205 _M_deleter()(__old_p);
206 }
207
208 _GLIBCXX23_CONSTEXPR
209 pointer release() noexcept
210 {
211 pointer __p = _M_ptr();
212 _M_ptr() = nullptr;
213 return __p;
214 }
215
216 _GLIBCXX23_CONSTEXPR
217 void
218 swap(__uniq_ptr_impl& __rhs) noexcept
219 {
220 using std::swap;
221 swap(this->_M_ptr(), __rhs._M_ptr());
222 swap(this->_M_deleter(), __rhs._M_deleter());
223 }
224
225 private:
226 tuple<pointer, _Dp> _M_t;
227 };
228
229 // Defines move construction + assignment as either defaulted or deleted.
230 template <typename _Tp, typename _Dp,
233 struct __uniq_ptr_data : __uniq_ptr_impl<_Tp, _Dp>
234 {
235 using __uniq_ptr_impl<_Tp, _Dp>::__uniq_ptr_impl;
236 __uniq_ptr_data(__uniq_ptr_data&&) = default;
237 __uniq_ptr_data& operator=(__uniq_ptr_data&&) = default;
238 };
239
240 template <typename _Tp, typename _Dp>
241 struct __uniq_ptr_data<_Tp, _Dp, true, false> : __uniq_ptr_impl<_Tp, _Dp>
242 {
243 using __uniq_ptr_impl<_Tp, _Dp>::__uniq_ptr_impl;
244 __uniq_ptr_data(__uniq_ptr_data&&) = default;
245 __uniq_ptr_data& operator=(__uniq_ptr_data&&) = delete;
246 };
247
248 template <typename _Tp, typename _Dp>
249 struct __uniq_ptr_data<_Tp, _Dp, false, true> : __uniq_ptr_impl<_Tp, _Dp>
250 {
251 using __uniq_ptr_impl<_Tp, _Dp>::__uniq_ptr_impl;
252 __uniq_ptr_data(__uniq_ptr_data&&) = delete;
253 __uniq_ptr_data& operator=(__uniq_ptr_data&&) = default;
254 };
255
256 template <typename _Tp, typename _Dp>
257 struct __uniq_ptr_data<_Tp, _Dp, false, false> : __uniq_ptr_impl<_Tp, _Dp>
258 {
259 using __uniq_ptr_impl<_Tp, _Dp>::__uniq_ptr_impl;
260 __uniq_ptr_data(__uniq_ptr_data&&) = delete;
261 __uniq_ptr_data& operator=(__uniq_ptr_data&&) = delete;
262 };
263 /// @endcond
264
265 // 20.7.1.2 unique_ptr for single objects.
266
267 /// A move-only smart pointer that manages unique ownership of a resource.
268 /// @headerfile memory
269 /// @since C++11
270 template <typename _Tp, typename _Dp = default_delete<_Tp>>
272 {
273 template <typename _Up>
274 using _DeleterConstraint =
275 typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type;
276
277 __uniq_ptr_data<_Tp, _Dp> _M_t;
278
279 public:
280 using pointer = typename __uniq_ptr_impl<_Tp, _Dp>::pointer;
281 using element_type = _Tp;
282 using deleter_type = _Dp;
283
284 private:
285 // helper template for detecting a safe conversion from another
286 // unique_ptr
287 template<typename _Up, typename _Ep>
288 using __safe_conversion_up = __and_<
289 is_convertible<typename unique_ptr<_Up, _Ep>::pointer, pointer>,
290 __not_<is_array<_Up>>
291 >;
292
293 public:
294 // Constructors.
295
296 /// Default constructor, creates a unique_ptr that owns nothing.
297 template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>>
298 constexpr unique_ptr() noexcept
299 : _M_t()
300 { }
301
302 /** Takes ownership of a pointer.
303 *
304 * @param __p A pointer to an object of @c element_type
305 *
306 * The deleter will be value-initialized.
307 */
308 template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>>
309 _GLIBCXX23_CONSTEXPR
310 explicit
311 unique_ptr(pointer __p) noexcept
312 : _M_t(__p)
313 { }
314
315 /** Takes ownership of a pointer.
316 *
317 * @param __p A pointer to an object of @c element_type
318 * @param __d A reference to a deleter.
319 *
320 * The deleter will be initialized with @p __d
321 */
322 template<typename _Del = deleter_type,
323 typename = _Require<is_copy_constructible<_Del>>>
324 _GLIBCXX23_CONSTEXPR
325 unique_ptr(pointer __p, const deleter_type& __d) noexcept
326 : _M_t(__p, __d) { }
327
328 /** Takes ownership of a pointer.
329 *
330 * @param __p A pointer to an object of @c element_type
331 * @param __d An rvalue reference to a (non-reference) deleter.
332 *
333 * The deleter will be initialized with @p std::move(__d)
334 */
335 template<typename _Del = deleter_type,
336 typename = _Require<is_move_constructible<_Del>>>
337 _GLIBCXX23_CONSTEXPR
338 unique_ptr(pointer __p,
340 _Del&&> __d) noexcept
341 : _M_t(__p, std::move(__d))
342 { }
343
344 template<typename _Del = deleter_type,
345 typename _DelUnref = typename remove_reference<_Del>::type>
346 _GLIBCXX23_CONSTEXPR
347 unique_ptr(pointer,
349 _DelUnref&&>) = delete;
350
351 /// Creates a unique_ptr that owns nothing.
352 template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>>
353 constexpr unique_ptr(nullptr_t) noexcept
354 : _M_t()
355 { }
356
357 // Move constructors.
358
359 /// Move constructor.
360 unique_ptr(unique_ptr&&) = default;
361
362 /** @brief Converting constructor from another type
363 *
364 * Requires that the pointer owned by @p __u is convertible to the
365 * type of pointer owned by this object, @p __u does not own an array,
366 * and @p __u has a compatible deleter type.
367 */
368 template<typename _Up, typename _Ep, typename = _Require<
369 __safe_conversion_up<_Up, _Ep>,
370 __conditional_t<is_reference<_Dp>::value,
372 is_convertible<_Ep, _Dp>>>>
373 _GLIBCXX23_CONSTEXPR
375 : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter()))
376 { }
377
378#if _GLIBCXX_USE_DEPRECATED
379#pragma GCC diagnostic push
380#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
381 /// Converting constructor from @c auto_ptr
382 template<typename _Up,
383 typename = _Require<is_convertible<_Up*, pointer>,
385 unique_ptr(auto_ptr<_Up>&& __u) noexcept;
386#pragma GCC diagnostic pop
387#endif
388
389 /// Destructor, invokes the deleter if the stored pointer is not null.
390#if __cplusplus > 202002L && __cpp_constexpr_dynamic_alloc
391 constexpr
392#endif
393 ~unique_ptr() noexcept
394 {
395 static_assert(__is_invocable<deleter_type&, pointer>::value,
396 "unique_ptr's deleter must be invocable with a pointer");
397 auto& __ptr = _M_t._M_ptr();
398 if (__ptr != nullptr)
399 get_deleter()(std::move(__ptr));
400 __ptr = pointer();
401 }
402
403 // Assignment.
404
405 /** @brief Move assignment operator.
406 *
407 * Invokes the deleter if this object owns a pointer.
408 */
410
411 /** @brief Assignment from another type.
412 *
413 * @param __u The object to transfer ownership from, which owns a
414 * convertible pointer to a non-array object.
415 *
416 * Invokes the deleter if this object owns a pointer.
417 */
418 template<typename _Up, typename _Ep>
419 _GLIBCXX23_CONSTEXPR
420 typename enable_if< __and_<
421 __safe_conversion_up<_Up, _Ep>,
423 >::value,
426 {
427 reset(__u.release());
428 get_deleter() = std::forward<_Ep>(__u.get_deleter());
429 return *this;
430 }
431
432 /// Reset the %unique_ptr to empty, invoking the deleter if necessary.
433 _GLIBCXX23_CONSTEXPR
435 operator=(nullptr_t) noexcept
436 {
437 reset();
438 return *this;
439 }
440
441 // Observers.
442
443 /// Dereference the stored pointer.
444 _GLIBCXX23_CONSTEXPR
445 typename add_lvalue_reference<element_type>::type
446 operator*() const noexcept(noexcept(*std::declval<pointer>()))
447 {
448#if _GLIBCXX_USE_BUILTIN_TRAIT(__reference_converts_from_temporary)
449 // _GLIBCXX_RESOLVE_LIB_DEFECTS
450 // 4148. unique_ptr::operator* should not allow dangling references
451 using _ResT = typename add_lvalue_reference<element_type>::type;
452 using _DerefT = decltype(*get());
453 static_assert(!__reference_converts_from_temporary(_ResT, _DerefT),
454 "operator* must not return a dangling reference");
455#endif
456 __glibcxx_assert(get() != pointer());
457 return *get();
458 }
459
460 /// Return the stored pointer.
461 _GLIBCXX23_CONSTEXPR
462 pointer
463 operator->() const noexcept
464 {
465 _GLIBCXX_DEBUG_PEDASSERT(get() != pointer());
466 return get();
467 }
468
469 /// Return the stored pointer.
470 _GLIBCXX23_CONSTEXPR
471 pointer
472 get() const noexcept
473 { return _M_t._M_ptr(); }
474
475 /// Return a reference to the stored deleter.
476 _GLIBCXX23_CONSTEXPR
477 deleter_type&
478 get_deleter() noexcept
479 { return _M_t._M_deleter(); }
480
481 /// Return a reference to the stored deleter.
482 _GLIBCXX23_CONSTEXPR
483 const deleter_type&
484 get_deleter() const noexcept
485 { return _M_t._M_deleter(); }
486
487 /// Return @c true if the stored pointer is not null.
488 _GLIBCXX23_CONSTEXPR
489 explicit operator bool() const noexcept
490 { return get() == pointer() ? false : true; }
491
492 // Modifiers.
493
494 /// Release ownership of any stored pointer.
495 _GLIBCXX23_CONSTEXPR
496 pointer
497 release() noexcept
498 { return _M_t.release(); }
499
500 /** @brief Replace the stored pointer.
501 *
502 * @param __p The new pointer to store.
503 *
504 * The deleter will be invoked if a pointer is already owned.
505 */
506 _GLIBCXX23_CONSTEXPR
507 void
508 reset(pointer __p = pointer()) noexcept
509 {
510 static_assert(__is_invocable<deleter_type&, pointer>::value,
511 "unique_ptr's deleter must be invocable with a pointer");
512 _M_t.reset(std::move(__p));
513 }
514
515 /// Exchange the pointer and deleter with another object.
516 _GLIBCXX23_CONSTEXPR
517 void
518 swap(unique_ptr& __u) noexcept
519 {
520 static_assert(__is_swappable<_Dp>::value, "deleter must be swappable");
521 _M_t.swap(__u._M_t);
522 }
523
524 // Disable copy from lvalue.
525 unique_ptr(const unique_ptr&) = delete;
526 unique_ptr& operator=(const unique_ptr&) = delete;
527
528 private:
529#ifdef __glibcxx_out_ptr
530 template<typename, typename, typename...>
531 friend class out_ptr_t;
532 template<typename, typename, typename...>
533 friend class inout_ptr_t;
534#endif
535 };
536
537 // 20.7.1.3 unique_ptr for array objects with a runtime length
538 // [unique.ptr.runtime]
539 // _GLIBCXX_RESOLVE_LIB_DEFECTS
540 // DR 740 - omit specialization for array objects with a compile time length
541
542 /// A move-only smart pointer that manages unique ownership of an array.
543 /// @headerfile memory
544 /// @since C++11
545 template<typename _Tp, typename _Dp>
547 {
548 template <typename _Up>
549 using _DeleterConstraint =
550 typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type;
551
552 __uniq_ptr_data<_Tp, _Dp> _M_t;
553
554 // like is_base_of<_Tp, _Up> but false if unqualified types are the same
555 template<typename _Up>
556 using __is_derived_Tp
557 = __and_< is_base_of<_Tp, _Up>,
558 __not_<is_same<__remove_cv_t<_Tp>, __remove_cv_t<_Up>>> >;
559
560 public:
561 using pointer = typename __uniq_ptr_impl<_Tp, _Dp>::pointer;
562 using element_type = _Tp;
563 using deleter_type = _Dp;
564
565 // helper template for detecting a safe conversion from another
566 // unique_ptr
567 template<typename _Up, typename _Ep,
568 typename _UPtr = unique_ptr<_Up, _Ep>,
569 typename _UP_pointer = typename _UPtr::pointer,
570 typename _UP_element_type = typename _UPtr::element_type>
571 using __safe_conversion_up = __and_<
575 is_convertible<_UP_element_type(*)[], element_type(*)[]>
576 >;
577
578 // helper template for detecting a safe conversion from a raw pointer
579 template<typename _Up>
580 using __safe_conversion_raw = __and_<
581 __or_<__or_<is_same<_Up, pointer>,
583 __and_<is_pointer<_Up>,
585 is_convertible<
586 typename remove_pointer<_Up>::type(*)[],
587 element_type(*)[]>
588 >
589 >
590 >;
591
592 // Constructors.
593
594 /// Default constructor, creates a unique_ptr that owns nothing.
595 template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>>
596 constexpr unique_ptr() noexcept
597 : _M_t()
598 { }
599
600 /** Takes ownership of a pointer.
601 *
602 * @param __p A pointer to an array of a type safely convertible
603 * to an array of @c element_type
604 *
605 * The deleter will be value-initialized.
606 */
607 template<typename _Up,
608 typename _Vp = _Dp,
609 typename = _DeleterConstraint<_Vp>,
610 typename = typename enable_if<
611 __safe_conversion_raw<_Up>::value, bool>::type>
612 _GLIBCXX23_CONSTEXPR
613 explicit
614 unique_ptr(_Up __p) noexcept
615 : _M_t(__p)
616 { }
617
618 /** Takes ownership of a pointer.
619 *
620 * @param __p A pointer to an array of a type safely convertible
621 * to an array of @c element_type
622 * @param __d A reference to a deleter.
623 *
624 * The deleter will be initialized with @p __d
625 */
626 template<typename _Up, typename _Del = deleter_type,
627 typename = _Require<__safe_conversion_raw<_Up>,
629 _GLIBCXX23_CONSTEXPR
630 unique_ptr(_Up __p, const deleter_type& __d) noexcept
631 : _M_t(__p, __d) { }
632
633 /** Takes ownership of a pointer.
634 *
635 * @param __p A pointer to an array of a type safely convertible
636 * to an array of @c element_type
637 * @param __d A reference to a deleter.
638 *
639 * The deleter will be initialized with @p std::move(__d)
640 */
641 template<typename _Up, typename _Del = deleter_type,
642 typename = _Require<__safe_conversion_raw<_Up>,
644 _GLIBCXX23_CONSTEXPR
645 unique_ptr(_Up __p,
647 _Del&&> __d) noexcept
648 : _M_t(std::move(__p), std::move(__d))
649 { }
650
651 template<typename _Up, typename _Del = deleter_type,
652 typename _DelUnref = typename remove_reference<_Del>::type,
653 typename = _Require<__safe_conversion_raw<_Up>>>
654 unique_ptr(_Up,
656 _DelUnref&&>) = delete;
657
658 /// Move constructor.
659 unique_ptr(unique_ptr&&) = default;
660
661 /// Creates a unique_ptr that owns nothing.
662 template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>>
663 constexpr unique_ptr(nullptr_t) noexcept
664 : _M_t()
665 { }
666
667 template<typename _Up, typename _Ep, typename = _Require<
668 __safe_conversion_up<_Up, _Ep>,
669 __conditional_t<is_reference<_Dp>::value,
671 is_convertible<_Ep, _Dp>>>>
672 _GLIBCXX23_CONSTEXPR
673 unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept
674 : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter()))
675 { }
676
677 /// Destructor, invokes the deleter if the stored pointer is not null.
678#if __cplusplus > 202002L && __cpp_constexpr_dynamic_alloc
679 constexpr
680#endif
682 {
683 auto& __ptr = _M_t._M_ptr();
684 if (__ptr != nullptr)
685 get_deleter()(__ptr);
686 __ptr = pointer();
687 }
688
689 // Assignment.
690
691 /** @brief Move assignment operator.
692 *
693 * Invokes the deleter if this object owns a pointer.
694 */
696 operator=(unique_ptr&&) = default;
697
698 /** @brief Assignment from another type.
699 *
700 * @param __u The object to transfer ownership from, which owns a
701 * convertible pointer to an array object.
702 *
703 * Invokes the deleter if this object owns a pointer.
704 */
705 template<typename _Up, typename _Ep>
706 _GLIBCXX23_CONSTEXPR
707 typename
710 >::value,
712 operator=(unique_ptr<_Up, _Ep>&& __u) noexcept
713 {
714 reset(__u.release());
715 get_deleter() = std::forward<_Ep>(__u.get_deleter());
716 return *this;
717 }
718
719 /// Reset the %unique_ptr to empty, invoking the deleter if necessary.
720 _GLIBCXX23_CONSTEXPR
722 operator=(nullptr_t) noexcept
723 {
724 reset();
725 return *this;
726 }
727
728 // Observers.
729
730 /// Access an element of owned array.
731 _GLIBCXX23_CONSTEXPR
732 typename std::add_lvalue_reference<element_type>::type
733 operator[](size_t __i) const
734 {
735 __glibcxx_assert(get() != pointer());
736 return get()[__i];
737 }
738
739 /// Return the stored pointer.
740 _GLIBCXX23_CONSTEXPR
741 pointer
742 get() const noexcept
743 { return _M_t._M_ptr(); }
744
745 /// Return a reference to the stored deleter.
746 _GLIBCXX23_CONSTEXPR
747 deleter_type&
748 get_deleter() noexcept
749 { return _M_t._M_deleter(); }
750
751 /// Return a reference to the stored deleter.
752 _GLIBCXX23_CONSTEXPR
753 const deleter_type&
754 get_deleter() const noexcept
755 { return _M_t._M_deleter(); }
756
757 /// Return @c true if the stored pointer is not null.
758 _GLIBCXX23_CONSTEXPR
759 explicit operator bool() const noexcept
760 { return get() == pointer() ? false : true; }
761
762 // Modifiers.
763
764 /// Release ownership of any stored pointer.
765 _GLIBCXX23_CONSTEXPR
766 pointer
767 release() noexcept
768 { return _M_t.release(); }
769
770 /** @brief Replace the stored pointer.
771 *
772 * @param __p The new pointer to store.
773 *
774 * The deleter will be invoked if a pointer is already owned.
775 */
776 template <typename _Up,
777 typename = _Require<
778 __or_<is_same<_Up, pointer>,
779 __and_<is_same<pointer, element_type*>,
781 is_convertible<
782 typename remove_pointer<_Up>::type(*)[],
783 element_type(*)[]
784 >
785 >
786 >
787 >>
788 _GLIBCXX23_CONSTEXPR
789 void
790 reset(_Up __p) noexcept
791 { _M_t.reset(std::move(__p)); }
792
793 _GLIBCXX23_CONSTEXPR
794 void reset(nullptr_t = nullptr) noexcept
795 { reset(pointer()); }
796
797 /// Exchange the pointer and deleter with another object.
798 _GLIBCXX23_CONSTEXPR
799 void
800 swap(unique_ptr& __u) noexcept
801 {
802 static_assert(__is_swappable<_Dp>::value, "deleter must be swappable");
803 _M_t.swap(__u._M_t);
804 }
805
806 // Disable copy from lvalue.
807 unique_ptr(const unique_ptr&) = delete;
808 unique_ptr& operator=(const unique_ptr&) = delete;
809
810 private:
811#ifdef __glibcxx_out_ptr
812 template<typename, typename, typename...> friend class out_ptr_t;
813 template<typename, typename, typename...> friend class inout_ptr_t;
814#endif
815 };
816
817 /// @{
818 /// @relates unique_ptr
819
820 /// Swap overload for unique_ptr
821 template<typename _Tp, typename _Dp>
822 inline
823#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
824 // Constrained free swap overload, see p0185r1
825 _GLIBCXX23_CONSTEXPR
826 typename enable_if<__is_swappable<_Dp>::value>::type
827#else
828 void
829#endif
831 unique_ptr<_Tp, _Dp>& __y) noexcept
832 { __x.swap(__y); }
833
834#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
835 // _GLIBCXX_RESOLVE_LIB_DEFECTS
836 // 2766. Swapping non-swappable types
837 template<typename _Tp, typename _Dp>
840 unique_ptr<_Tp, _Dp>&) = delete;
841#endif
842
843 /// Equality operator for unique_ptr objects, compares the owned pointers
844 template<typename _Tp, typename _Dp,
845 typename _Up, typename _Ep>
846 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
847 inline bool
848 operator==(const unique_ptr<_Tp, _Dp>& __x,
849 const unique_ptr<_Up, _Ep>& __y)
850 { return __x.get() == __y.get(); }
851
852 /// unique_ptr comparison with nullptr
853 template<typename _Tp, typename _Dp>
854 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
855 inline bool
856 operator==(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept
857 { return !__x; }
858
859#ifndef __cpp_lib_three_way_comparison
860 /// unique_ptr comparison with nullptr
861 template<typename _Tp, typename _Dp>
862 _GLIBCXX_NODISCARD
863 inline bool
864 operator==(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept
865 { return !__x; }
866
867 /// Inequality operator for unique_ptr objects, compares the owned pointers
868 template<typename _Tp, typename _Dp,
869 typename _Up, typename _Ep>
870 _GLIBCXX_NODISCARD
871 inline bool
872 operator!=(const unique_ptr<_Tp, _Dp>& __x,
873 const unique_ptr<_Up, _Ep>& __y)
874 { return __x.get() != __y.get(); }
875
876 /// unique_ptr comparison with nullptr
877 template<typename _Tp, typename _Dp>
878 _GLIBCXX_NODISCARD
879 inline bool
880 operator!=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept
881 { return (bool)__x; }
882
883 /// unique_ptr comparison with nullptr
884 template<typename _Tp, typename _Dp>
885 _GLIBCXX_NODISCARD
886 inline bool
887 operator!=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept
888 { return (bool)__x; }
889#endif // three way comparison
890
891 /// Relational operator for unique_ptr objects, compares the owned pointers
892 template<typename _Tp, typename _Dp,
893 typename _Up, typename _Ep>
894 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
895 inline bool
896 operator<(const unique_ptr<_Tp, _Dp>& __x,
897 const unique_ptr<_Up, _Ep>& __y)
898 {
899 typedef typename
901 typename unique_ptr<_Up, _Ep>::pointer>::type _CT;
902 return std::less<_CT>()(__x.get(), __y.get());
903 }
904
905 /// unique_ptr comparison with nullptr
906 template<typename _Tp, typename _Dp>
907 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
908 inline bool
909 operator<(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
910 {
912 nullptr);
913 }
914
915 /// unique_ptr comparison with nullptr
916 template<typename _Tp, typename _Dp>
917 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
918 inline bool
919 operator<(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
920 {
922 __x.get());
923 }
924
925 /// Relational operator for unique_ptr objects, compares the owned pointers
926 template<typename _Tp, typename _Dp,
927 typename _Up, typename _Ep>
928 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
929 inline bool
930 operator<=(const unique_ptr<_Tp, _Dp>& __x,
931 const unique_ptr<_Up, _Ep>& __y)
932 { return !(__y < __x); }
933
934 /// unique_ptr comparison with nullptr
935 template<typename _Tp, typename _Dp>
936 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
937 inline bool
938 operator<=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
939 { return !(nullptr < __x); }
940
941 /// unique_ptr comparison with nullptr
942 template<typename _Tp, typename _Dp>
943 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
944 inline bool
945 operator<=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
946 { return !(__x < nullptr); }
947
948 /// Relational operator for unique_ptr objects, compares the owned pointers
949 template<typename _Tp, typename _Dp,
950 typename _Up, typename _Ep>
951 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
952 inline bool
953 operator>(const unique_ptr<_Tp, _Dp>& __x,
954 const unique_ptr<_Up, _Ep>& __y)
955 { return (__y < __x); }
956
957 /// unique_ptr comparison with nullptr
958 template<typename _Tp, typename _Dp>
959 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
960 inline bool
961 operator>(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
962 {
964 __x.get());
965 }
966
967 /// unique_ptr comparison with nullptr
968 template<typename _Tp, typename _Dp>
969 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
970 inline bool
971 operator>(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
972 {
974 nullptr);
975 }
976
977 /// Relational operator for unique_ptr objects, compares the owned pointers
978 template<typename _Tp, typename _Dp,
979 typename _Up, typename _Ep>
980 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
981 inline bool
982 operator>=(const unique_ptr<_Tp, _Dp>& __x,
983 const unique_ptr<_Up, _Ep>& __y)
984 { return !(__x < __y); }
985
986 /// unique_ptr comparison with nullptr
987 template<typename _Tp, typename _Dp>
988 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR
989 inline bool
990 operator>=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
991 { return !(__x < nullptr); }
992
993 /// unique_ptr comparison with nullptr
994 template<typename _Tp, typename _Dp>
995 _GLIBCXX_NODISCARD inline bool
996 operator>=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
997 { return !(nullptr < __x); }
998
999#ifdef __cpp_lib_three_way_comparison
1000 template<typename _Tp, typename _Dp, typename _Up, typename _Ep>
1001 requires three_way_comparable_with<typename unique_ptr<_Tp, _Dp>::pointer,
1002 typename unique_ptr<_Up, _Ep>::pointer>
1003 _GLIBCXX23_CONSTEXPR
1004 inline
1005 compare_three_way_result_t<typename unique_ptr<_Tp, _Dp>::pointer,
1006 typename unique_ptr<_Up, _Ep>::pointer>
1007 operator<=>(const unique_ptr<_Tp, _Dp>& __x,
1008 const unique_ptr<_Up, _Ep>& __y)
1009 { return compare_three_way()(__x.get(), __y.get()); }
1010
1011 template<typename _Tp, typename _Dp>
1012 requires three_way_comparable<typename unique_ptr<_Tp, _Dp>::pointer>
1013 _GLIBCXX23_CONSTEXPR
1014 inline
1016 operator<=>(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
1017 {
1018 using pointer = typename unique_ptr<_Tp, _Dp>::pointer;
1019 return compare_three_way()(__x.get(), static_cast<pointer>(nullptr));
1020 }
1021#endif
1022 /// @} relates unique_ptr
1023
1024 /// @cond undocumented
1025 template<typename _Up, typename _Ptr = typename _Up::pointer>
1026 struct __uniq_ptr_hash
1027 : public __hash_base<size_t, _Up>
1028#if ! _GLIBCXX_INLINE_VERSION
1029 , private __hash_empty_base<_Ptr>
1030#endif
1031 {
1032 size_t
1033 operator()(const _Up& __u) const
1034 noexcept(noexcept(std::declval<hash<_Ptr>>()(std::declval<_Ptr>())))
1035 { return hash<_Ptr>()(__u.get()); }
1036 };
1037
1038 template<typename _Up>
1039 using __uniq_ptr_hash_base
1040 = __conditional_t<__is_hash_enabled_for<typename _Up::pointer>,
1041 __uniq_ptr_hash<_Up>,
1042 __hash_not_enabled<typename _Up::pointer>>;
1043 /// @endcond
1044
1045 /// std::hash specialization for unique_ptr.
1046 template<typename _Tp, typename _Dp>
1047 struct hash<unique_ptr<_Tp, _Dp>>
1048 : public __uniq_ptr_hash_base<unique_ptr<_Tp, _Dp>>
1049 { };
1050
1051#ifdef __glibcxx_make_unique // C++ >= 14 && HOSTED
1052 /// @cond undocumented
1053namespace __detail
1054{
1055 template<typename _Tp>
1056 struct _MakeUniq
1057 { typedef unique_ptr<_Tp> __single_object; };
1058
1059 template<typename _Tp>
1060 struct _MakeUniq<_Tp[]>
1061 { typedef unique_ptr<_Tp[]> __array; };
1062
1063 template<typename _Tp, size_t _Bound>
1064 struct _MakeUniq<_Tp[_Bound]>
1065 { struct __invalid_type { }; };
1066
1067 template<typename _Tp>
1068 using __unique_ptr_t = typename _MakeUniq<_Tp>::__single_object;
1069 template<typename _Tp>
1070 using __unique_ptr_array_t = typename _MakeUniq<_Tp>::__array;
1071 template<typename _Tp>
1072 using __invalid_make_unique_t = typename _MakeUniq<_Tp>::__invalid_type;
1073}
1074 /// @endcond
1075
1076 /** Create an object owned by a `unique_ptr`.
1077 * @tparam _Tp A non-array object type.
1078 * @param __args Constructor arguments for the new object.
1079 * @returns A `unique_ptr<_Tp>` that owns the new object.
1080 * @since C++14
1081 * @relates unique_ptr
1082 */
1083 template<typename _Tp, typename... _Args>
1084 _GLIBCXX23_CONSTEXPR
1085 inline __detail::__unique_ptr_t<_Tp>
1086 make_unique(_Args&&... __args)
1087 { return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); }
1088
1089 /** Create an array owned by a `unique_ptr`.
1090 * @tparam _Tp An array type of unknown bound, such as `U[]`.
1091 * @param __num The number of elements of type `U` in the new array.
1092 * @returns A `unique_ptr<U[]>` that owns the new array.
1093 * @since C++14
1094 * @relates unique_ptr
1095 *
1096 * The array elements are value-initialized.
1097 */
1098 template<typename _Tp>
1099 _GLIBCXX23_CONSTEXPR
1100 inline __detail::__unique_ptr_array_t<_Tp>
1101 make_unique(size_t __num)
1102 { return unique_ptr<_Tp>(new remove_extent_t<_Tp>[__num]()); }
1103
1104 /** Disable std::make_unique for arrays of known bound.
1105 * @tparam _Tp An array type of known bound, such as `U[N]`.
1106 * @since C++14
1107 * @relates unique_ptr
1108 */
1109 template<typename _Tp, typename... _Args>
1110 __detail::__invalid_make_unique_t<_Tp>
1111 make_unique(_Args&&...) = delete;
1112
1113#if __cplusplus > 201703L
1114 /** Create a default-initialied object owned by a `unique_ptr`.
1115 * @tparam _Tp A non-array object type.
1116 * @returns A `unique_ptr<_Tp>` that owns the new object.
1117 * @since C++20
1118 * @relates unique_ptr
1119 */
1120 template<typename _Tp>
1121 _GLIBCXX23_CONSTEXPR
1122 inline __detail::__unique_ptr_t<_Tp>
1123 make_unique_for_overwrite()
1124 { return unique_ptr<_Tp>(new _Tp); }
1125
1126 /** Create a default-initialized array owned by a `unique_ptr`.
1127 * @tparam _Tp An array type of unknown bound, such as `U[]`.
1128 * @param __num The number of elements of type `U` in the new array.
1129 * @returns A `unique_ptr<U[]>` that owns the new array.
1130 * @since C++20
1131 * @relates unique_ptr
1132 */
1133 template<typename _Tp>
1134 _GLIBCXX23_CONSTEXPR
1135 inline __detail::__unique_ptr_array_t<_Tp>
1136 make_unique_for_overwrite(size_t __num)
1137 { return unique_ptr<_Tp>(new remove_extent_t<_Tp>[__num]); }
1138
1139 /** Disable std::make_unique_for_overwrite for arrays of known bound.
1140 * @tparam _Tp An array type of known bound, such as `U[N]`.
1141 * @since C++20
1142 * @relates unique_ptr
1143 */
1144 template<typename _Tp, typename... _Args>
1145 __detail::__invalid_make_unique_t<_Tp>
1146 make_unique_for_overwrite(_Args&&...) = delete;
1147#endif // C++20
1148
1149#endif // C++14 && HOSTED
1150
1151#if __cplusplus > 201703L && __cpp_concepts && _GLIBCXX_HOSTED
1152 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1153 // 2948. unique_ptr does not define operator<< for stream output
1154 /// Stream output operator for unique_ptr
1155 /// @relates unique_ptr
1156 /// @since C++20
1157 template<typename _CharT, typename _Traits, typename _Tp, typename _Dp>
1160 const unique_ptr<_Tp, _Dp>& __p)
1161 requires requires { __os << __p.get(); }
1162 {
1163 __os << __p.get();
1164 return __os;
1165 }
1166#endif // C++20 && HOSTED
1167
1168#if __cpp_variable_templates
1169 template<typename _Tp>
1170 constexpr bool __is_unique_ptr = false;
1171 template<typename _Tp, typename _Del>
1172 constexpr bool __is_unique_ptr<unique_ptr<_Tp, _Del>> = true;
1173#endif
1174
1175 /// @} group pointer_abstractions
1176
1177#if __cplusplus >= 201703L
1178 namespace __detail::__variant
1179 {
1180 template<typename> struct _Never_valueless_alt; // see <variant>
1181
1182 // Provide the strong exception-safety guarantee when emplacing a
1183 // unique_ptr into a variant.
1184 template<typename _Tp, typename _Del>
1185 struct _Never_valueless_alt<std::unique_ptr<_Tp, _Del>>
1187 { };
1188 } // namespace __detail::__variant
1189#endif // C++17
1190
1191_GLIBCXX_END_NAMESPACE_VERSION
1192} // namespace
1193
1194#endif /* _UNIQUE_PTR_H */
constexpr enable_if< __is_swappable< _Dp >::value >::type swap(unique_ptr< _Tp, _Dp > &__x, unique_ptr< _Tp, _Dp > &__y) noexcept
Swap overload for unique_ptr.
Definition unique_ptr.h:830
__bool_constant< true > true_type
The type used as a compile-time boolean with true value.
Definition type_traits:116
typename remove_extent< _Tp >::type remove_extent_t
Alias template for remove_extent.
Definition type_traits:2248
auto declval() noexcept -> decltype(__declval< _Tp >(0))
Definition type_traits:2670
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
Definition move.h:138
constexpr _Tp && forward(typename std::remove_reference< _Tp >::type &__t) noexcept
Forward an lvalue.
Definition move.h:72
ISO C++ entities toplevel namespace is std.
typename __detail::__cmp3way_res_impl< _Tp, _Up >::type compare_three_way_result_t
[cmp.result], result of three-way comparison
Definition compare:548
std::basic_ostream< _CharT, _Traits > & operator<<(std::basic_ostream< _CharT, _Traits > &__os, const bitset< _Nb > &__x)
Global I/O operators for bitsets.
Definition bitset:1733
Template class basic_ostream.
Definition ostream.h:67
Primary class template hash.
Define a member typedef type only if a boolean constant is true.
Definition type_traits:134
is_void
Definition type_traits:328
is_array
Definition type_traits:552
is_pointer
Definition type_traits:572
is_lvalue_reference
Definition type_traits:598
is_copy_constructible
Definition type_traits:1230
is_move_constructible
Definition type_traits:1257
is_assignable
Definition type_traits:1313
is_move_assignable
Definition type_traits:1332
common_type
Definition type_traits:2529
A simple smart pointer providing strict ownership semantics.
Definition auto_ptr.h:94
One of the comparison functors.
constexpr void operator()(_Tp *__ptr) const
Calls delete __ptr
Definition unique_ptr.h:87
constexpr default_delete() noexcept=default
Default constructor.
constexpr enable_if< is_convertible< _Up(*)[], _Tp(*)[]>::value >::type operator()(_Up *__ptr) const
Calls delete[] __ptr
Definition unique_ptr.h:130
constexpr default_delete() noexcept=default
Default constructor.
A move-only smart pointer that manages unique ownership of a resource.
Definition unique_ptr.h:272
constexpr pointer operator->() const noexcept
Return the stored pointer.
Definition unique_ptr.h:463
constexpr unique_ptr & operator=(nullptr_t) noexcept
Reset the unique_ptr to empty, invoking the deleter if necessary.
Definition unique_ptr.h:435
constexpr unique_ptr(pointer __p) noexcept
Definition unique_ptr.h:311
constexpr unique_ptr() noexcept
Default constructor, creates a unique_ptr that owns nothing.
Definition unique_ptr.h:298
constexpr unique_ptr(pointer __p, const deleter_type &__d) noexcept
Definition unique_ptr.h:325
unique_ptr(unique_ptr &&)=default
Move constructor.
unique_ptr & operator=(unique_ptr &&)=default
Move assignment operator.
constexpr void reset(pointer __p=pointer()) noexcept
Replace the stored pointer.
Definition unique_ptr.h:508
constexpr enable_if< __and_< __safe_conversion_up< _Up, _Ep >, is_assignable< deleter_type &, _Ep && > >::value, unique_ptr & >::type operator=(unique_ptr< _Up, _Ep > &&__u) noexcept
Assignment from another type.
Definition unique_ptr.h:425
~unique_ptr() noexcept
Destructor, invokes the deleter if the stored pointer is not null.
Definition unique_ptr.h:393
unique_ptr(auto_ptr< _Up > &&__u) noexcept
Converting constructor from auto_ptr.
Definition auto_ptr.h:334
constexpr unique_ptr(unique_ptr< _Up, _Ep > &&__u) noexcept
Converting constructor from another type.
Definition unique_ptr.h:374
constexpr deleter_type & get_deleter() noexcept
Return a reference to the stored deleter.
Definition unique_ptr.h:478
constexpr add_lvalue_reference< element_type >::type operator*() const noexcept(noexcept(*std::declval< pointer >()))
Dereference the stored pointer.
Definition unique_ptr.h:446
constexpr void swap(unique_ptr &__u) noexcept
Exchange the pointer and deleter with another object.
Definition unique_ptr.h:518
constexpr pointer get() const noexcept
Return the stored pointer.
Definition unique_ptr.h:472
constexpr unique_ptr(pointer __p, __enable_if_t<!is_lvalue_reference< _Del >::value, _Del && > __d) noexcept
Definition unique_ptr.h:338
constexpr pointer release() noexcept
Release ownership of any stored pointer.
Definition unique_ptr.h:497
constexpr unique_ptr(nullptr_t) noexcept
Creates a unique_ptr that owns nothing.
Definition unique_ptr.h:353
constexpr const deleter_type & get_deleter() const noexcept
Return a reference to the stored deleter.
Definition unique_ptr.h:484
constexpr deleter_type & get_deleter() noexcept
Return a reference to the stored deleter.
Definition unique_ptr.h:747
constexpr pointer release() noexcept
Release ownership of any stored pointer.
Definition unique_ptr.h:766
constexpr void swap(unique_ptr &__u) noexcept
Exchange the pointer and deleter with another object.
Definition unique_ptr.h:799
constexpr unique_ptr() noexcept
Default constructor, creates a unique_ptr that owns nothing.
Definition unique_ptr.h:595
constexpr void reset(_Up __p) noexcept
Replace the stored pointer.
Definition unique_ptr.h:789
constexpr pointer get() const noexcept
Return the stored pointer.
Definition unique_ptr.h:741
unique_ptr & operator=(unique_ptr &&)=default
Move assignment operator.
constexpr std::add_lvalue_reference< element_type >::type operator[](size_t __i) const
Access an element of owned array.
Definition unique_ptr.h:732