Line data Source code
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 :
52 : namespace 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 666 : 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 666 : delete __ptr;
96 666 : }
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 10248 : __uniq_ptr_impl() = default;
167 : _GLIBCXX23_CONSTEXPR
168 2730 : __uniq_ptr_impl(pointer __p) : _M_t() { _M_ptr() = __p; }
169 :
170 : template<typename _Del>
171 : _GLIBCXX23_CONSTEXPR
172 18 : __uniq_ptr_impl(pointer __p, _Del&& __d)
173 18 : : _M_t(__p, std::forward<_Del>(__d)) { }
174 :
175 : _GLIBCXX23_CONSTEXPR
176 4210 : __uniq_ptr_impl(__uniq_ptr_impl&& __u) noexcept
177 4210 : : _M_t(std::move(__u._M_t))
178 4210 : { __u._M_ptr() = nullptr; }
179 :
180 : _GLIBCXX23_CONSTEXPR
181 2548 : __uniq_ptr_impl& operator=(__uniq_ptr_impl&& __u) noexcept
182 : {
183 5096 : reset(__u.release());
184 2548 : _M_deleter() = std::forward<_Dp>(__u._M_deleter());
185 2548 : return *this;
186 : }
187 :
188 : _GLIBCXX23_CONSTEXPR
189 15868 : pointer& _M_ptr() noexcept { return std::get<0>(_M_t); }
190 : _GLIBCXX23_CONSTEXPR
191 2334 : pointer _M_ptr() const noexcept { return std::get<0>(_M_t); }
192 : _GLIBCXX23_CONSTEXPR
193 473 : _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 2548 : void reset(pointer __p) noexcept
199 : {
200 2548 : const pointer __old_p = _M_ptr();
201 2548 : _M_ptr() = __p;
202 2548 : if (__old_p)
203 0 : _M_deleter()(__old_p);
204 : }
205 :
206 : _GLIBCXX23_CONSTEXPR
207 2548 : pointer release() noexcept
208 : {
209 2548 : pointer __p = _M_ptr();
210 2548 : _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 12996 : using __uniq_ptr_impl<_Tp, _Dp>::__uniq_ptr_impl;
234 4210 : __uniq_ptr_data(__uniq_ptr_data&&) = default;
235 2548 : __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 10248 : constexpr unique_ptr() noexcept
297 10248 : : _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 2730 : unique_ptr(pointer __p) noexcept
310 2715 : : _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 18 : unique_ptr(pointer __p,
337 : __enable_if_t<!is_lvalue_reference<_Del>::value,
338 : _Del&&> __d) noexcept
339 18 : : _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 4210 : 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 17209 : ~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 17209 : auto& __ptr = _M_t._M_ptr();
395 17209 : if (__ptr != nullptr)
396 684 : get_deleter()(std::move(__ptr));
397 : __ptr = pointer();
398 17209 : }
399 :
400 : // Assignment.
401 :
402 : /** @brief Move assignment operator.
403 : *
404 : * Invokes the deleter if this object owns a pointer.
405 : */
406 2548 : 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(__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 2334 : get() const noexcept
462 2334 : { return _M_t._M_ptr(); }
463 :
464 : /// Return a reference to the stored deleter.
465 : _GLIBCXX23_CONSTEXPR
466 : deleter_type&
467 684 : get_deleter() noexcept
468 684 : { 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 2334 : explicit operator bool() const noexcept
479 2334 : { 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 2334 : operator!=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept
857 2334 : { 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
1031 : namespace __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 */
|