1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
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 | |
47 | |
48 | |
49 | |
50 | #if _GLIBCXX_USE_DEPRECATED |
51 | template<typename> class auto_ptr; |
52 | #endif |
53 | |
54 | |
55 | template<typename _Tp> |
56 | struct default_delete |
57 | { |
58 | |
59 | constexpr default_delete() noexcept = default; |
60 | |
61 | |
62 | |
63 | |
64 | |
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 | |
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 | |
83 | |
84 | |
85 | template<typename _Tp> |
86 | struct default_delete<_Tp[]> |
87 | { |
88 | public: |
89 | |
90 | constexpr default_delete() noexcept = default; |
91 | |
92 | |
93 | |
94 | |
95 | |
96 | |
97 | |
98 | |
99 | |
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 | |
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 | |
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 | |
171 | |
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 | |
179 | |
180 | |
181 | template <typename _Up = _Dp, |
182 | typename = _DeleterConstraint<_Up>> |
183 | constexpr unique_ptr() noexcept |
184 | : _M_t() |
185 | { } |
186 | |
187 | |
188 | |
189 | |
190 | |
191 | |
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 | |
201 | |
202 | |
203 | |
204 | |
205 | |
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 | |
213 | |
214 | |
215 | |
216 | |
217 | |
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 | |
226 | template <typename _Up = _Dp, |
227 | typename = _DeleterConstraint<_Up>> |
228 | constexpr unique_ptr(nullptr_t) noexcept : _M_t() { } |
229 | |
230 | |
231 | |
232 | |
233 | unique_ptr(unique_ptr&& __u) noexcept |
234 | : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter())) { } |
235 | |
236 | |
237 | |
238 | |
239 | |
240 | |
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 | |
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 | |
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 | |
268 | |
269 | |
270 | |
271 | |
272 | |
273 | |
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 | |
284 | |
285 | |
286 | |
287 | |
288 | |
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 | |
304 | unique_ptr& |
305 | operator=(nullptr_t) noexcept |
306 | { |
307 | reset(); |
308 | return *this; |
309 | } |
310 | |
311 | |
312 | |
313 | |
314 | typename add_lvalue_reference<element_type>::type |
315 | operator*() const |
316 | { |
317 | __glibcxx_assert(get() != pointer()); |
318 | return *get(); |
319 | } |
320 | |
321 | |
322 | pointer |
323 | operator->() const noexcept |
324 | { |
325 | _GLIBCXX_DEBUG_PEDASSERT(get() != pointer()); |
326 | return get(); |
327 | } |
328 | |
329 | |
330 | pointer |
331 | get() const noexcept |
332 | { return _M_t._M_ptr(); } |
333 | |
334 | |
335 | deleter_type& |
336 | get_deleter() noexcept |
337 | { return _M_t._M_deleter(); } |
338 | |
339 | |
340 | const deleter_type& |
341 | get_deleter() const noexcept |
342 | { return _M_t._M_deleter(); } |
343 | |
344 | |
345 | explicit operator bool() const noexcept |
346 | { return get() == pointer() ? false : true; } |
347 | |
348 | |
349 | |
350 | |
351 | pointer |
352 | release() noexcept |
353 | { |
354 | pointer __p = get(); |
355 | _M_t._M_ptr() = pointer(); |
356 | return __p; |
357 | } |
358 | |
359 | |
360 | |
361 | |
362 | |
363 | |
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 | |
375 | void |
376 | swap(unique_ptr& __u) noexcept |
377 | { |
378 | using std::swap; |
379 | swap(_M_t, __u._M_t); |
380 | } |
381 | |
382 | |
383 | unique_ptr(const unique_ptr&) = delete; |
384 | unique_ptr& operator=(const unique_ptr&) = delete; |
385 | }; |
386 | |
387 | |
388 | |
389 | |
390 | |
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 | |
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 | |
415 | |
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 | |
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 | |
442 | |
443 | |
444 | template <typename _Up = _Dp, |
445 | typename = _DeleterConstraint<_Up>> |
446 | constexpr unique_ptr() noexcept |
447 | : _M_t() |
448 | { } |
449 | |
450 | |
451 | |
452 | |
453 | |
454 | |
455 | |
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 | |
468 | |
469 | |
470 | |
471 | |
472 | |
473 | |
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 | |
484 | |
485 | |
486 | |
487 | |
488 | |
489 | |
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 | |
501 | unique_ptr(unique_ptr&& __u) noexcept |
502 | : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter())) { } |
503 | |
504 | |
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 | |
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 | |
528 | |
529 | |
530 | |
531 | |
532 | |
533 | |
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 | |
544 | |
545 | |
546 | |
547 | |
548 | |
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 | |
564 | unique_ptr& |
565 | operator=(nullptr_t) noexcept |
566 | { |
567 | reset(); |
568 | return *this; |
569 | } |
570 | |
571 | |
572 | |
573 | |
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 | |
582 | pointer |
583 | get() const noexcept |
584 | { return _M_t._M_ptr(); } |
585 | |
586 | |
587 | deleter_type& |
588 | get_deleter() noexcept |
589 | { return _M_t._M_deleter(); } |
590 | |
591 | |
592 | const deleter_type& |
593 | get_deleter() const noexcept |
594 | { return _M_t._M_deleter(); } |
595 | |
596 | |
597 | explicit operator bool() const noexcept |
598 | { return get() == pointer() ? false : true; } |
599 | |
600 | |
601 | |
602 | |
603 | pointer |
604 | release() noexcept |
605 | { |
606 | pointer __p = get(); |
607 | _M_t._M_ptr() = pointer(); |
608 | return __p; |
609 | } |
610 | |
611 | |
612 | |
613 | |
614 | |
615 | |
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 | |
645 | void |
646 | swap(unique_ptr& __u) noexcept |
647 | { |
648 | using std::swap; |
649 | swap(_M_t, __u._M_t); |
650 | } |
651 | |
652 | |
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__) |
660 | |
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__) |
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 | |
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 | |
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 | |
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 | |
830 | template<typename _Tp, typename... _Args> |
831 | inline typename _MakeUniq<_Tp>::__invalid_type |
832 | make_unique(_Args&&...) = delete; |
833 | #endif |
834 | |
835 | |
836 | |
837 | _GLIBCXX_END_NAMESPACE_VERSION |
838 | } |
839 | |
840 | #endif |
841 | |