Line data Source code
1 : // unique_ptr implementation -*- C++ -*-
2 :
3 : // Copyright (C) 2008-2019 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 :
41 : namespace std _GLIBCXX_VISIBILITY(default)
42 : {
43 : _GLIBCXX_BEGIN_NAMESPACE_VERSION
44 :
45 : /**
46 : * @addtogroup pointer_abstractions
47 : * @{
48 : */
49 :
50 : #if _GLIBCXX_USE_DEPRECATED
51 : #pragma GCC diagnostic push
52 : #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
53 : template<typename> class auto_ptr;
54 : #pragma GCC diagnostic pop
55 : #endif
56 :
57 : /// Primary template of default_delete, used by unique_ptr
58 : template<typename _Tp>
59 : struct default_delete
60 : {
61 : /// Default constructor
62 : constexpr default_delete() noexcept = default;
63 :
64 : /** @brief Converting constructor.
65 : *
66 : * Allows conversion from a deleter for arrays of another type, @p _Up,
67 : * only if @p _Up* is convertible to @p _Tp*.
68 : */
69 : template<typename _Up, typename = typename
70 : enable_if<is_convertible<_Up*, _Tp*>::value>::type>
71 : default_delete(const default_delete<_Up>&) noexcept { }
72 :
73 : /// Calls @c delete @p __ptr
74 : void
75 0 : operator()(_Tp* __ptr) const
76 : {
77 : static_assert(!is_void<_Tp>::value,
78 : "can't delete pointer to incomplete type");
79 : static_assert(sizeof(_Tp)>0,
80 : "can't delete pointer to incomplete type");
81 0 : delete __ptr;
82 0 : }
83 : };
84 :
85 : // _GLIBCXX_RESOLVE_LIB_DEFECTS
86 : // DR 740 - omit specialization for array objects with a compile time length
87 : /// Specialization for arrays, default_delete.
88 : template<typename _Tp>
89 : struct default_delete<_Tp[]>
90 : {
91 : public:
92 : /// Default constructor
93 : constexpr default_delete() noexcept = default;
94 :
95 : /** @brief Converting constructor.
96 : *
97 : * Allows conversion from a deleter for arrays of another type, such as
98 : * a const-qualified version of @p _Tp.
99 : *
100 : * Conversions from types derived from @c _Tp are not allowed because
101 : * it is unsafe to @c delete[] an array of derived types through a
102 : * pointer to the base type.
103 : */
104 : template<typename _Up, typename = typename
105 : enable_if<is_convertible<_Up(*)[], _Tp(*)[]>::value>::type>
106 : default_delete(const default_delete<_Up[]>&) noexcept { }
107 :
108 : /// Calls @c delete[] @p __ptr
109 : template<typename _Up>
110 : typename enable_if<is_convertible<_Up(*)[], _Tp(*)[]>::value>::type
111 0 : operator()(_Up* __ptr) const
112 : {
113 : static_assert(sizeof(_Tp)>0,
114 : "can't delete pointer to incomplete type");
115 0 : delete [] __ptr;
116 : }
117 : };
118 :
119 : template <typename _Tp, typename _Dp>
120 : class __uniq_ptr_impl
121 : {
122 : template <typename _Up, typename _Ep, typename = void>
123 : struct _Ptr
124 : {
125 : using type = _Up*;
126 : };
127 :
128 : template <typename _Up, typename _Ep>
129 : struct
130 : _Ptr<_Up, _Ep, __void_t<typename remove_reference<_Ep>::type::pointer>>
131 : {
132 : using type = typename remove_reference<_Ep>::type::pointer;
133 : };
134 :
135 : public:
136 : using _DeleterConstraint = enable_if<
137 : __and_<__not_<is_pointer<_Dp>>,
138 : is_default_constructible<_Dp>>::value>;
139 :
140 : using pointer = typename _Ptr<_Tp, _Dp>::type;
141 :
142 : static_assert( !is_rvalue_reference<_Dp>::value,
143 : "unique_ptr's deleter type must be a function object type"
144 : " or an lvalue reference type" );
145 :
146 : __uniq_ptr_impl() = default;
147 0 : __uniq_ptr_impl(pointer __p) : _M_t() { _M_ptr() = __p; }
148 :
149 : template<typename _Del>
150 0 : __uniq_ptr_impl(pointer __p, _Del&& __d)
151 0 : : _M_t(__p, std::forward<_Del>(__d)) { }
152 :
153 0 : pointer& _M_ptr() { return std::get<0>(_M_t); }
154 0 : pointer _M_ptr() const { return std::get<0>(_M_t); }
155 0 : _Dp& _M_deleter() { return std::get<1>(_M_t); }
156 : const _Dp& _M_deleter() const { return std::get<1>(_M_t); }
157 :
158 : void
159 : swap(__uniq_ptr_impl& __rhs) noexcept
160 : {
161 : using std::swap;
162 : swap(this->_M_ptr(), __rhs._M_ptr());
163 : swap(this->_M_deleter(), __rhs._M_deleter());
164 : }
165 :
166 : private:
167 : tuple<pointer, _Dp> _M_t;
168 : };
169 :
170 : /// 20.7.1.2 unique_ptr for single objects.
171 : template <typename _Tp, typename _Dp = default_delete<_Tp>>
172 : class unique_ptr
173 : {
174 : template <typename _Up>
175 : using _DeleterConstraint =
176 : typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type;
177 :
178 : __uniq_ptr_impl<_Tp, _Dp> _M_t;
179 :
180 : public:
181 : using pointer = typename __uniq_ptr_impl<_Tp, _Dp>::pointer;
182 : using element_type = _Tp;
183 : using deleter_type = _Dp;
184 :
185 : private:
186 : // helper template for detecting a safe conversion from another
187 : // unique_ptr
188 : template<typename _Up, typename _Ep>
189 : using __safe_conversion_up = __and_<
190 : is_convertible<typename unique_ptr<_Up, _Ep>::pointer, pointer>,
191 : __not_<is_array<_Up>>
192 : >;
193 :
194 : public:
195 : // Constructors.
196 :
197 : /// Default constructor, creates a unique_ptr that owns nothing.
198 : template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>>
199 : constexpr unique_ptr() noexcept
200 : : _M_t()
201 : { }
202 :
203 : /** Takes ownership of a pointer.
204 : *
205 : * @param __p A pointer to an object of @c element_type
206 : *
207 : * The deleter will be value-initialized.
208 : */
209 : template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>>
210 : explicit
211 0 : unique_ptr(pointer __p) noexcept
212 0 : : _M_t(__p)
213 : { }
214 :
215 : /** Takes ownership of a pointer.
216 : *
217 : * @param __p A pointer to an object of @c element_type
218 : * @param __d A reference to a deleter.
219 : *
220 : * The deleter will be initialized with @p __d
221 : */
222 : template<typename _Del = deleter_type,
223 : typename = _Require<is_copy_constructible<_Del>>>
224 : unique_ptr(pointer __p, const deleter_type& __d) noexcept
225 : : _M_t(__p, __d) { }
226 :
227 : /** Takes ownership of a pointer.
228 : *
229 : * @param __p A pointer to an object of @c element_type
230 : * @param __d An rvalue reference to a (non-reference) deleter.
231 : *
232 : * The deleter will be initialized with @p std::move(__d)
233 : */
234 : template<typename _Del = deleter_type,
235 : typename = _Require<is_move_constructible<_Del>>>
236 : unique_ptr(pointer __p,
237 : __enable_if_t<!is_lvalue_reference<_Del>::value,
238 : _Del&&> __d) noexcept
239 : : _M_t(__p, std::move(__d))
240 : { }
241 :
242 : template<typename _Del = deleter_type,
243 : typename _DelUnref = typename remove_reference<_Del>::type>
244 : unique_ptr(pointer,
245 : __enable_if_t<is_lvalue_reference<_Del>::value,
246 : _DelUnref&&>) = delete;
247 :
248 : /// Creates a unique_ptr that owns nothing.
249 : template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>>
250 : constexpr unique_ptr(nullptr_t) noexcept
251 : : _M_t()
252 : { }
253 :
254 : // Move constructors.
255 :
256 : /// Move constructor.
257 0 : unique_ptr(unique_ptr&& __u) noexcept
258 0 : : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter())) { }
259 :
260 : /** @brief Converting constructor from another type
261 : *
262 : * Requires that the pointer owned by @p __u is convertible to the
263 : * type of pointer owned by this object, @p __u does not own an array,
264 : * and @p __u has a compatible deleter type.
265 : */
266 : template<typename _Up, typename _Ep, typename = _Require<
267 : __safe_conversion_up<_Up, _Ep>,
268 : typename conditional<is_reference<_Dp>::value,
269 : is_same<_Ep, _Dp>,
270 : is_convertible<_Ep, _Dp>>::type>>
271 : unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept
272 : : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter()))
273 : { }
274 :
275 : #if _GLIBCXX_USE_DEPRECATED
276 : #pragma GCC diagnostic push
277 : #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
278 : /// Converting constructor from @c auto_ptr
279 : template<typename _Up, typename = _Require<
280 : is_convertible<_Up*, _Tp*>, is_same<_Dp, default_delete<_Tp>>>>
281 : unique_ptr(auto_ptr<_Up>&& __u) noexcept;
282 : #pragma GCC diagnostic pop
283 : #endif
284 :
285 : /// Destructor, invokes the deleter if the stored pointer is not null.
286 0 : ~unique_ptr() noexcept
287 : {
288 : static_assert(__is_invocable<deleter_type&, pointer>::value,
289 : "unique_ptr's deleter must be invocable with a pointer");
290 0 : auto& __ptr = _M_t._M_ptr();
291 0 : if (__ptr != nullptr)
292 0 : get_deleter()(std::move(__ptr));
293 : __ptr = pointer();
294 0 : }
295 :
296 : // Assignment.
297 :
298 : /** @brief Move assignment operator.
299 : *
300 : * @param __u The object to transfer ownership from.
301 : *
302 : * Invokes the deleter first if this object owns a pointer.
303 : */
304 : unique_ptr&
305 : operator=(unique_ptr&& __u) noexcept
306 : {
307 : reset(__u.release());
308 : get_deleter() = std::forward<deleter_type>(__u.get_deleter());
309 : return *this;
310 : }
311 :
312 : /** @brief Assignment from another type.
313 : *
314 : * @param __u The object to transfer ownership from, which owns a
315 : * convertible pointer to a non-array object.
316 : *
317 : * Invokes the deleter first if this object owns a pointer.
318 : */
319 : template<typename _Up, typename _Ep>
320 : typename enable_if< __and_<
321 : __safe_conversion_up<_Up, _Ep>,
322 : is_assignable<deleter_type&, _Ep&&>
323 : >::value,
324 : unique_ptr&>::type
325 : operator=(unique_ptr<_Up, _Ep>&& __u) noexcept
326 : {
327 : reset(__u.release());
328 : get_deleter() = std::forward<_Ep>(__u.get_deleter());
329 : return *this;
330 : }
331 :
332 : /// Reset the %unique_ptr to empty, invoking the deleter if necessary.
333 : unique_ptr&
334 : operator=(nullptr_t) noexcept
335 : {
336 : reset();
337 : return *this;
338 : }
339 :
340 : // Observers.
341 :
342 : /// Dereference the stored pointer.
343 : typename add_lvalue_reference<element_type>::type
344 0 : operator*() const
345 : {
346 : __glibcxx_assert(get() != pointer());
347 0 : return *get();
348 : }
349 :
350 : /// Return the stored pointer.
351 : pointer
352 : operator->() const noexcept
353 : {
354 : _GLIBCXX_DEBUG_PEDASSERT(get() != pointer());
355 : return get();
356 : }
357 :
358 : /// Return the stored pointer.
359 : pointer
360 0 : get() const noexcept
361 0 : { return _M_t._M_ptr(); }
362 :
363 : /// Return a reference to the stored deleter.
364 : deleter_type&
365 0 : get_deleter() noexcept
366 0 : { return _M_t._M_deleter(); }
367 :
368 : /// Return a reference to the stored deleter.
369 : const deleter_type&
370 : get_deleter() const noexcept
371 : { return _M_t._M_deleter(); }
372 :
373 : /// Return @c true if the stored pointer is not null.
374 : explicit operator bool() const noexcept
375 : { return get() == pointer() ? false : true; }
376 :
377 : // Modifiers.
378 :
379 : /// Release ownership of any stored pointer.
380 : pointer
381 0 : release() noexcept
382 : {
383 0 : pointer __p = get();
384 0 : _M_t._M_ptr() = pointer();
385 : return __p;
386 : }
387 :
388 : /** @brief Replace the stored pointer.
389 : *
390 : * @param __p The new pointer to store.
391 : *
392 : * The deleter will be invoked if a pointer is already owned.
393 : */
394 : void
395 : reset(pointer __p = pointer()) noexcept
396 : {
397 : static_assert(__is_invocable<deleter_type&, pointer>::value,
398 : "unique_ptr's deleter must be invocable with a pointer");
399 : using std::swap;
400 : swap(_M_t._M_ptr(), __p);
401 : if (__p != pointer())
402 : get_deleter()(std::move(__p));
403 : }
404 :
405 : /// Exchange the pointer and deleter with another object.
406 : void
407 : swap(unique_ptr& __u) noexcept
408 : {
409 : static_assert(__is_swappable<_Dp>::value, "deleter must be swappable");
410 : _M_t.swap(__u._M_t);
411 : }
412 :
413 : // Disable copy from lvalue.
414 : unique_ptr(const unique_ptr&) = delete;
415 : unique_ptr& operator=(const unique_ptr&) = delete;
416 : };
417 :
418 : /// 20.7.1.3 unique_ptr for array objects with a runtime length
419 : // [unique.ptr.runtime]
420 : // _GLIBCXX_RESOLVE_LIB_DEFECTS
421 : // DR 740 - omit specialization for array objects with a compile time length
422 : template<typename _Tp, typename _Dp>
423 : class unique_ptr<_Tp[], _Dp>
424 : {
425 : template <typename _Up>
426 : using _DeleterConstraint =
427 : typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type;
428 :
429 : __uniq_ptr_impl<_Tp, _Dp> _M_t;
430 :
431 : template<typename _Up>
432 : using __remove_cv = typename remove_cv<_Up>::type;
433 :
434 : // like is_base_of<_Tp, _Up> but false if unqualified types are the same
435 : template<typename _Up>
436 : using __is_derived_Tp
437 : = __and_< is_base_of<_Tp, _Up>,
438 : __not_<is_same<__remove_cv<_Tp>, __remove_cv<_Up>>> >;
439 :
440 : public:
441 : using pointer = typename __uniq_ptr_impl<_Tp, _Dp>::pointer;
442 : using element_type = _Tp;
443 : using deleter_type = _Dp;
444 :
445 : // helper template for detecting a safe conversion from another
446 : // unique_ptr
447 : template<typename _Up, typename _Ep,
448 : typename _UPtr = unique_ptr<_Up, _Ep>,
449 : typename _UP_pointer = typename _UPtr::pointer,
450 : typename _UP_element_type = typename _UPtr::element_type>
451 : using __safe_conversion_up = __and_<
452 : is_array<_Up>,
453 : is_same<pointer, element_type*>,
454 : is_same<_UP_pointer, _UP_element_type*>,
455 : is_convertible<_UP_element_type(*)[], element_type(*)[]>
456 : >;
457 :
458 : // helper template for detecting a safe conversion from a raw pointer
459 : template<typename _Up>
460 : using __safe_conversion_raw = __and_<
461 : __or_<__or_<is_same<_Up, pointer>,
462 : is_same<_Up, nullptr_t>>,
463 : __and_<is_pointer<_Up>,
464 : is_same<pointer, element_type*>,
465 : is_convertible<
466 : typename remove_pointer<_Up>::type(*)[],
467 : element_type(*)[]>
468 : >
469 : >
470 : >;
471 :
472 : // Constructors.
473 :
474 : /// Default constructor, creates a unique_ptr that owns nothing.
475 : template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>>
476 : constexpr unique_ptr() noexcept
477 : : _M_t()
478 : { }
479 :
480 : /** Takes ownership of a pointer.
481 : *
482 : * @param __p A pointer to an array of a type safely convertible
483 : * to an array of @c element_type
484 : *
485 : * The deleter will be value-initialized.
486 : */
487 : template<typename _Up,
488 : typename _Vp = _Dp,
489 : typename = _DeleterConstraint<_Vp>,
490 : typename = typename enable_if<
491 : __safe_conversion_raw<_Up>::value, bool>::type>
492 : explicit
493 0 : unique_ptr(_Up __p) noexcept
494 0 : : _M_t(__p)
495 : { }
496 :
497 : /** Takes ownership of a pointer.
498 : *
499 : * @param __p A pointer to an array of a type safely convertible
500 : * to an array of @c element_type
501 : * @param __d A reference to a deleter.
502 : *
503 : * The deleter will be initialized with @p __d
504 : */
505 : template<typename _Up, typename _Del = deleter_type,
506 : typename = _Require<__safe_conversion_raw<_Up>,
507 : is_copy_constructible<_Del>>>
508 : unique_ptr(_Up __p, const deleter_type& __d) noexcept
509 : : _M_t(__p, __d) { }
510 :
511 : /** Takes ownership of a pointer.
512 : *
513 : * @param __p A pointer to an array of a type safely convertible
514 : * to an array of @c element_type
515 : * @param __d A reference to a deleter.
516 : *
517 : * The deleter will be initialized with @p std::move(__d)
518 : */
519 : template<typename _Up, typename _Del = deleter_type,
520 : typename = _Require<__safe_conversion_raw<_Up>,
521 : is_move_constructible<_Del>>>
522 : unique_ptr(_Up __p,
523 : __enable_if_t<!is_lvalue_reference<_Del>::value,
524 : _Del&&> __d) noexcept
525 : : _M_t(std::move(__p), std::move(__d))
526 : { }
527 :
528 : template<typename _Up, typename _Del = deleter_type,
529 : typename _DelUnref = typename remove_reference<_Del>::type,
530 : typename = _Require<__safe_conversion_raw<_Up>>>
531 : unique_ptr(_Up,
532 : __enable_if_t<is_lvalue_reference<_Del>::value,
533 : _DelUnref&&>) = delete;
534 :
535 : /// Move constructor.
536 : unique_ptr(unique_ptr&& __u) noexcept
537 : : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter())) { }
538 :
539 : /// Creates a unique_ptr that owns nothing.
540 : template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>>
541 : constexpr unique_ptr(nullptr_t) noexcept
542 : : _M_t()
543 : { }
544 :
545 : template<typename _Up, typename _Ep, typename = _Require<
546 : __safe_conversion_up<_Up, _Ep>,
547 : typename conditional<is_reference<_Dp>::value,
548 : is_same<_Ep, _Dp>,
549 : is_convertible<_Ep, _Dp>>::type>>
550 : unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept
551 : : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter()))
552 : { }
553 :
554 : /// Destructor, invokes the deleter if the stored pointer is not null.
555 0 : ~unique_ptr()
556 : {
557 0 : auto& __ptr = _M_t._M_ptr();
558 : if (__ptr != nullptr)
559 0 : get_deleter()(__ptr);
560 : __ptr = pointer();
561 0 : }
562 :
563 : // Assignment.
564 :
565 : /** @brief Move assignment operator.
566 : *
567 : * @param __u The object to transfer ownership from.
568 : *
569 : * Invokes the deleter first if this object owns a pointer.
570 : */
571 : unique_ptr&
572 : operator=(unique_ptr&& __u) noexcept
573 : {
574 : reset(__u.release());
575 : get_deleter() = std::forward<deleter_type>(__u.get_deleter());
576 : return *this;
577 : }
578 :
579 : /** @brief Assignment from another type.
580 : *
581 : * @param __u The object to transfer ownership from, which owns a
582 : * convertible pointer to an array object.
583 : *
584 : * Invokes the deleter first if this object owns a pointer.
585 : */
586 : template<typename _Up, typename _Ep>
587 : typename
588 : enable_if<__and_<__safe_conversion_up<_Up, _Ep>,
589 : is_assignable<deleter_type&, _Ep&&>
590 : >::value,
591 : unique_ptr&>::type
592 : operator=(unique_ptr<_Up, _Ep>&& __u) noexcept
593 : {
594 : reset(__u.release());
595 : get_deleter() = std::forward<_Ep>(__u.get_deleter());
596 : return *this;
597 : }
598 :
599 : /// Reset the %unique_ptr to empty, invoking the deleter if necessary.
600 : unique_ptr&
601 : operator=(nullptr_t) noexcept
602 : {
603 : reset();
604 : return *this;
605 : }
606 :
607 : // Observers.
608 :
609 : /// Access an element of owned array.
610 : typename std::add_lvalue_reference<element_type>::type
611 0 : operator[](size_t __i) const
612 : {
613 : __glibcxx_assert(get() != pointer());
614 0 : return get()[__i];
615 : }
616 :
617 : /// Return the stored pointer.
618 : pointer
619 0 : get() const noexcept
620 0 : { return _M_t._M_ptr(); }
621 :
622 : /// Return a reference to the stored deleter.
623 : deleter_type&
624 0 : get_deleter() noexcept
625 0 : { return _M_t._M_deleter(); }
626 :
627 : /// Return a reference to the stored deleter.
628 : const deleter_type&
629 : get_deleter() const noexcept
630 : { return _M_t._M_deleter(); }
631 :
632 : /// Return @c true if the stored pointer is not null.
633 : explicit operator bool() const noexcept
634 : { return get() == pointer() ? false : true; }
635 :
636 : // Modifiers.
637 :
638 : /// Release ownership of any stored pointer.
639 : pointer
640 : release() noexcept
641 : {
642 : pointer __p = get();
643 : _M_t._M_ptr() = pointer();
644 : return __p;
645 : }
646 :
647 : /** @brief Replace the stored pointer.
648 : *
649 : * @param __p The new pointer to store.
650 : *
651 : * The deleter will be invoked if a pointer is already owned.
652 : */
653 : template <typename _Up,
654 : typename = _Require<
655 : __or_<is_same<_Up, pointer>,
656 : __and_<is_same<pointer, element_type*>,
657 : is_pointer<_Up>,
658 : is_convertible<
659 : typename remove_pointer<_Up>::type(*)[],
660 : element_type(*)[]
661 : >
662 : >
663 : >
664 : >>
665 : void
666 : reset(_Up __p) noexcept
667 : {
668 : pointer __ptr = __p;
669 : using std::swap;
670 : swap(_M_t._M_ptr(), __ptr);
671 : if (__ptr != nullptr)
672 : get_deleter()(__ptr);
673 : }
674 :
675 : void reset(nullptr_t = nullptr) noexcept
676 : {
677 : reset(pointer());
678 : }
679 :
680 : /// Exchange the pointer and deleter with another object.
681 : void
682 : swap(unique_ptr& __u) noexcept
683 : {
684 : static_assert(__is_swappable<_Dp>::value, "deleter must be swappable");
685 : _M_t.swap(__u._M_t);
686 : }
687 :
688 : // Disable copy from lvalue.
689 : unique_ptr(const unique_ptr&) = delete;
690 : unique_ptr& operator=(const unique_ptr&) = delete;
691 : };
692 :
693 : template<typename _Tp, typename _Dp>
694 : inline
695 : #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
696 : // Constrained free swap overload, see p0185r1
697 : typename enable_if<__is_swappable<_Dp>::value>::type
698 : #else
699 : void
700 : #endif
701 : swap(unique_ptr<_Tp, _Dp>& __x,
702 : unique_ptr<_Tp, _Dp>& __y) noexcept
703 : { __x.swap(__y); }
704 :
705 : #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
706 : template<typename _Tp, typename _Dp>
707 : typename enable_if<!__is_swappable<_Dp>::value>::type
708 : swap(unique_ptr<_Tp, _Dp>&,
709 : unique_ptr<_Tp, _Dp>&) = delete;
710 : #endif
711 :
712 : template<typename _Tp, typename _Dp,
713 : typename _Up, typename _Ep>
714 : _GLIBCXX_NODISCARD inline bool
715 : operator==(const unique_ptr<_Tp, _Dp>& __x,
716 : const unique_ptr<_Up, _Ep>& __y)
717 : { return __x.get() == __y.get(); }
718 :
719 : template<typename _Tp, typename _Dp>
720 : _GLIBCXX_NODISCARD inline bool
721 : operator==(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept
722 : { return !__x; }
723 :
724 : template<typename _Tp, typename _Dp>
725 : _GLIBCXX_NODISCARD inline bool
726 : operator==(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept
727 : { return !__x; }
728 :
729 : template<typename _Tp, typename _Dp,
730 : typename _Up, typename _Ep>
731 : _GLIBCXX_NODISCARD inline bool
732 : operator!=(const unique_ptr<_Tp, _Dp>& __x,
733 : const unique_ptr<_Up, _Ep>& __y)
734 : { return __x.get() != __y.get(); }
735 :
736 : template<typename _Tp, typename _Dp>
737 : _GLIBCXX_NODISCARD inline bool
738 : operator!=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept
739 : { return (bool)__x; }
740 :
741 : template<typename _Tp, typename _Dp>
742 : _GLIBCXX_NODISCARD inline bool
743 : operator!=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept
744 : { return (bool)__x; }
745 :
746 : template<typename _Tp, typename _Dp,
747 : typename _Up, typename _Ep>
748 : _GLIBCXX_NODISCARD inline bool
749 : operator<(const unique_ptr<_Tp, _Dp>& __x,
750 : const unique_ptr<_Up, _Ep>& __y)
751 : {
752 : typedef typename
753 : std::common_type<typename unique_ptr<_Tp, _Dp>::pointer,
754 : typename unique_ptr<_Up, _Ep>::pointer>::type _CT;
755 : return std::less<_CT>()(__x.get(), __y.get());
756 : }
757 :
758 : template<typename _Tp, typename _Dp>
759 : _GLIBCXX_NODISCARD inline bool
760 : operator<(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
761 : { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(__x.get(),
762 : nullptr); }
763 :
764 : template<typename _Tp, typename _Dp>
765 : _GLIBCXX_NODISCARD inline bool
766 : operator<(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
767 : { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(nullptr,
768 : __x.get()); }
769 :
770 : template<typename _Tp, typename _Dp,
771 : typename _Up, typename _Ep>
772 : _GLIBCXX_NODISCARD inline bool
773 : operator<=(const unique_ptr<_Tp, _Dp>& __x,
774 : const unique_ptr<_Up, _Ep>& __y)
775 : { return !(__y < __x); }
776 :
777 : template<typename _Tp, typename _Dp>
778 : _GLIBCXX_NODISCARD inline bool
779 : operator<=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
780 : { return !(nullptr < __x); }
781 :
782 : template<typename _Tp, typename _Dp>
783 : _GLIBCXX_NODISCARD inline bool
784 : operator<=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
785 : { return !(__x < nullptr); }
786 :
787 : template<typename _Tp, typename _Dp,
788 : typename _Up, typename _Ep>
789 : _GLIBCXX_NODISCARD inline bool
790 : operator>(const unique_ptr<_Tp, _Dp>& __x,
791 : const unique_ptr<_Up, _Ep>& __y)
792 : { return (__y < __x); }
793 :
794 : template<typename _Tp, typename _Dp>
795 : _GLIBCXX_NODISCARD inline bool
796 : operator>(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
797 : { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(nullptr,
798 : __x.get()); }
799 :
800 : template<typename _Tp, typename _Dp>
801 : _GLIBCXX_NODISCARD inline bool
802 : operator>(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
803 : { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(__x.get(),
804 : nullptr); }
805 :
806 : template<typename _Tp, typename _Dp,
807 : typename _Up, typename _Ep>
808 : _GLIBCXX_NODISCARD inline bool
809 : operator>=(const unique_ptr<_Tp, _Dp>& __x,
810 : const unique_ptr<_Up, _Ep>& __y)
811 : { return !(__x < __y); }
812 :
813 : template<typename _Tp, typename _Dp>
814 : _GLIBCXX_NODISCARD inline bool
815 : operator>=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
816 : { return !(__x < nullptr); }
817 :
818 : template<typename _Tp, typename _Dp>
819 : _GLIBCXX_NODISCARD inline bool
820 : operator>=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
821 : { return !(nullptr < __x); }
822 :
823 : /// std::hash specialization for unique_ptr.
824 : template<typename _Tp, typename _Dp>
825 : struct hash<unique_ptr<_Tp, _Dp>>
826 : : public __hash_base<size_t, unique_ptr<_Tp, _Dp>>,
827 : private __poison_hash<typename unique_ptr<_Tp, _Dp>::pointer>
828 : {
829 : size_t
830 : operator()(const unique_ptr<_Tp, _Dp>& __u) const noexcept
831 : {
832 : typedef unique_ptr<_Tp, _Dp> _UP;
833 : return std::hash<typename _UP::pointer>()(__u.get());
834 : }
835 : };
836 :
837 : #if __cplusplus > 201103L
838 :
839 : #define __cpp_lib_make_unique 201304
840 :
841 : template<typename _Tp>
842 : struct _MakeUniq
843 : { typedef unique_ptr<_Tp> __single_object; };
844 :
845 : template<typename _Tp>
846 : struct _MakeUniq<_Tp[]>
847 : { typedef unique_ptr<_Tp[]> __array; };
848 :
849 : template<typename _Tp, size_t _Bound>
850 : struct _MakeUniq<_Tp[_Bound]>
851 : { struct __invalid_type { }; };
852 :
853 : /// std::make_unique for single objects
854 : template<typename _Tp, typename... _Args>
855 : inline typename _MakeUniq<_Tp>::__single_object
856 0 : make_unique(_Args&&... __args)
857 0 : { return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); }
858 :
859 : /// std::make_unique for arrays of unknown bound
860 : template<typename _Tp>
861 : inline typename _MakeUniq<_Tp>::__array
862 : make_unique(size_t __num)
863 : { return unique_ptr<_Tp>(new remove_extent_t<_Tp>[__num]()); }
864 :
865 : /// Disable std::make_unique for arrays of known bound
866 : template<typename _Tp, typename... _Args>
867 : inline typename _MakeUniq<_Tp>::__invalid_type
868 : make_unique(_Args&&...) = delete;
869 : #endif
870 :
871 : /// @} group pointer_abstractions
872 :
873 : #if __cplusplus >= 201703L
874 : namespace __detail::__variant
875 : {
876 : template<typename> struct _Never_valueless_alt; // see <variant>
877 :
878 : // Provide the strong exception-safety guarantee when emplacing a
879 : // unique_ptr into a variant.
880 : template<typename _Tp, typename _Del>
881 : struct _Never_valueless_alt<std::unique_ptr<_Tp, _Del>>
882 : : std::true_type
883 : { };
884 : } // namespace __detail::__variant
885 : #endif // C++17
886 :
887 : _GLIBCXX_END_NAMESPACE_VERSION
888 : } // namespace
889 :
890 : #endif /* _UNIQUE_PTR_H */
|