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