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