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