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