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