1 // unique_ptr implementation -*- C++ -*-
3 // Copyright (C) 2008-2016 Free Software Foundation, Inc.
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)
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.
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.
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/>.
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}
31 #define _UNIQUE_PTR_H 1
33 #include <bits/c++config.h>
34 #include <debug/assertions.h>
35 #include <type_traits>
38 #include <bits/stl_function.h>
40 namespace std
_GLIBCXX_VISIBILITY(default)
42 _GLIBCXX_BEGIN_NAMESPACE_VERSION
45 * @addtogroup pointer_abstractions
49 #if _GLIBCXX_USE_DEPRECATED
50 template<typename
> class auto_ptr
;
53 /// Primary template of default_delete, used by unique_ptr
54 template<typename _Tp
>
57 /// Default constructor
58 constexpr default_delete() noexcept
= default;
60 /** @brief Converting constructor.
62 * Allows conversion from a deleter for arrays of another type, @p _Up,
63 * only if @p _Up* is convertible to @p _Tp*.
65 template<typename _Up
, typename
= typename
66 enable_if
<is_convertible
<_Up
*, _Tp
*>::value
>::type
>
67 default_delete(const default_delete
<_Up
>&) noexcept
{ }
69 /// Calls @c delete @p __ptr
71 operator()(_Tp
* __ptr
) const
73 static_assert(!is_void
<_Tp
>::value
,
74 "can't delete pointer to incomplete type");
75 static_assert(sizeof(_Tp
)>0,
76 "can't delete pointer to incomplete type");
81 // _GLIBCXX_RESOLVE_LIB_DEFECTS
82 // DR 740 - omit specialization for array objects with a compile time length
83 /// Specialization for arrays, default_delete.
84 template<typename _Tp
>
85 struct default_delete
<_Tp
[]>
88 /// Default constructor
89 constexpr default_delete() noexcept
= default;
91 /** @brief Converting constructor.
93 * Allows conversion from a deleter for arrays of another type, such as
94 * a const-qualified version of @p _Tp.
96 * Conversions from types derived from @c _Tp are not allowed because
97 * it is unsafe to @c delete[] an array of derived types through a
98 * pointer to the base type.
100 template<typename _Up
, typename
= typename
101 enable_if
<is_convertible
<_Up(*)[], _Tp(*)[]>::value
>::type
>
102 default_delete(const default_delete
<_Up
[]>&) noexcept
{ }
104 /// Calls @c delete[] @p __ptr
105 template<typename _Up
>
106 typename enable_if
<is_convertible
<_Up(*)[], _Tp(*)[]>::value
>::type
107 operator()(_Up
* __ptr
) const
109 static_assert(sizeof(_Tp
)>0,
110 "can't delete pointer to incomplete type");
115 template <typename _Tp
, typename _Dp
>
116 class __uniq_ptr_impl
118 template <typename _Up
, typename _Ep
, typename
= void>
124 template <typename _Up
, typename _Ep
>
126 _Ptr
<_Up
, _Ep
, __void_t
<typename remove_reference
<_Ep
>::type::pointer
>>
128 using type
= typename remove_reference
<_Ep
>::type::pointer
;
132 using pointer
= typename _Ptr
<_Tp
, _Dp
>::type
;
134 __uniq_ptr_impl() = default;
135 __uniq_ptr_impl(pointer __p
) : _M_t() { _M_ptr() = __p
; }
137 template<typename _Del
>
138 __uniq_ptr_impl(pointer __p
, _Del
&& __d
)
139 : _M_t(__p
, std::forward
<_Del
>(__d
)) { }
141 pointer
& _M_ptr() { return std::get
<0>(_M_t
); }
142 pointer
_M_ptr() const { return std::get
<0>(_M_t
); }
143 _Dp
& _M_deleter() { return std::get
<1>(_M_t
); }
144 const _Dp
& _M_deleter() const { return std::get
<1>(_M_t
); }
147 tuple
<pointer
, _Dp
> _M_t
;
150 /// 20.7.1.2 unique_ptr for single objects.
151 template <typename _Tp
, typename _Dp
= default_delete
<_Tp
>>
154 __uniq_ptr_impl
<_Tp
, _Dp
> _M_t
;
157 using pointer
= typename __uniq_ptr_impl
<_Tp
, _Dp
>::pointer
;
158 using element_type
= _Tp
;
159 using deleter_type
= _Dp
;
161 // helper template for detecting a safe conversion from another
163 template<typename _Up
, typename _Ep
>
164 using __safe_conversion_up
= __and_
<
165 is_convertible
<typename unique_ptr
<_Up
, _Ep
>::pointer
, pointer
>,
166 __not_
<is_array
<_Up
>>,
167 __or_
<__and_
<is_reference
<deleter_type
>,
168 is_same
<deleter_type
, _Ep
>>,
169 __and_
<__not_
<is_reference
<deleter_type
>>,
170 is_convertible
<_Ep
, deleter_type
>>
176 /// Default constructor, creates a unique_ptr that owns nothing.
177 constexpr unique_ptr() noexcept
179 { static_assert(!is_pointer
<deleter_type
>::value
,
180 "constructed with null function pointer deleter"); }
182 /** Takes ownership of a pointer.
184 * @param __p A pointer to an object of @c element_type
186 * The deleter will be value-initialized.
189 unique_ptr(pointer __p
) noexcept
191 { static_assert(!is_pointer
<deleter_type
>::value
,
192 "constructed with null function pointer deleter"); }
194 /** Takes ownership of a pointer.
196 * @param __p A pointer to an object of @c element_type
197 * @param __d A reference to a deleter.
199 * The deleter will be initialized with @p __d
201 unique_ptr(pointer __p
,
202 typename conditional
<is_reference
<deleter_type
>::value
,
203 deleter_type
, const deleter_type
&>::type __d
) noexcept
206 /** Takes ownership of a pointer.
208 * @param __p A pointer to an object of @c element_type
209 * @param __d An rvalue reference to a deleter.
211 * The deleter will be initialized with @p std::move(__d)
213 unique_ptr(pointer __p
,
214 typename remove_reference
<deleter_type
>::type
&& __d
) noexcept
215 : _M_t(std::move(__p
), std::move(__d
))
216 { static_assert(!std::is_reference
<deleter_type
>::value
,
217 "rvalue deleter bound to reference"); }
219 /// Creates a unique_ptr that owns nothing.
220 constexpr unique_ptr(nullptr_t
) noexcept
: unique_ptr() { }
222 // Move constructors.
224 /// Move constructor.
225 unique_ptr(unique_ptr
&& __u
) noexcept
226 : _M_t(__u
.release(), std::forward
<deleter_type
>(__u
.get_deleter())) { }
228 /** @brief Converting constructor from another type
230 * Requires that the pointer owned by @p __u is convertible to the
231 * type of pointer owned by this object, @p __u does not own an array,
232 * and @p __u has a compatible deleter type.
234 template<typename _Up
, typename _Ep
, typename
= _Require
<
235 __safe_conversion_up
<_Up
, _Ep
>,
236 typename conditional
<is_reference
<_Dp
>::value
,
238 is_convertible
<_Ep
, _Dp
>>::type
>>
239 unique_ptr(unique_ptr
<_Up
, _Ep
>&& __u
) noexcept
240 : _M_t(__u
.release(), std::forward
<_Ep
>(__u
.get_deleter()))
243 #if _GLIBCXX_USE_DEPRECATED
244 /// Converting constructor from @c auto_ptr
245 template<typename _Up
, typename
= _Require
<
246 is_convertible
<_Up
*, _Tp
*>, is_same
<_Dp
, default_delete
<_Tp
>>>>
247 unique_ptr(auto_ptr
<_Up
>&& __u
) noexcept
;
250 /// Destructor, invokes the deleter if the stored pointer is not null.
251 ~unique_ptr() noexcept
253 auto& __ptr
= _M_t
._M_ptr();
254 if (__ptr
!= nullptr)
255 get_deleter()(__ptr
);
261 /** @brief Move assignment operator.
263 * @param __u The object to transfer ownership from.
265 * Invokes the deleter first if this object owns a pointer.
268 operator=(unique_ptr
&& __u
) noexcept
270 reset(__u
.release());
271 get_deleter() = std::forward
<deleter_type
>(__u
.get_deleter());
275 /** @brief Assignment from another type.
277 * @param __u The object to transfer ownership from, which owns a
278 * convertible pointer to a non-array object.
280 * Invokes the deleter first if this object owns a pointer.
282 template<typename _Up
, typename _Ep
>
283 typename enable_if
< __and_
<
284 __safe_conversion_up
<_Up
, _Ep
>,
285 is_assignable
<deleter_type
&, _Ep
&&>
288 operator=(unique_ptr
<_Up
, _Ep
>&& __u
) noexcept
290 reset(__u
.release());
291 get_deleter() = std::forward
<_Ep
>(__u
.get_deleter());
295 /// Reset the %unique_ptr to empty, invoking the deleter if necessary.
297 operator=(nullptr_t
) noexcept
305 /// Dereference the stored pointer.
306 typename add_lvalue_reference
<element_type
>::type
309 __glibcxx_assert(get() != pointer());
313 /// Return the stored pointer.
315 operator->() const noexcept
317 _GLIBCXX_DEBUG_PEDASSERT(get() != pointer());
321 /// Return the stored pointer.
324 { return _M_t
._M_ptr(); }
326 /// Return a reference to the stored deleter.
328 get_deleter() noexcept
329 { return _M_t
._M_deleter(); }
331 /// Return a reference to the stored deleter.
333 get_deleter() const noexcept
334 { return _M_t
._M_deleter(); }
336 /// Return @c true if the stored pointer is not null.
337 explicit operator bool() const noexcept
338 { return get() == pointer() ? false : true; }
342 /// Release ownership of any stored pointer.
347 _M_t
._M_ptr() = pointer();
351 /** @brief Replace the stored pointer.
353 * @param __p The new pointer to store.
355 * The deleter will be invoked if a pointer is already owned.
358 reset(pointer __p
= pointer()) noexcept
361 swap(_M_t
._M_ptr(), __p
);
362 if (__p
!= pointer())
366 /// Exchange the pointer and deleter with another object.
368 swap(unique_ptr
& __u
) noexcept
371 swap(_M_t
, __u
._M_t
);
374 // Disable copy from lvalue.
375 unique_ptr(const unique_ptr
&) = delete;
376 unique_ptr
& operator=(const unique_ptr
&) = delete;
379 /// 20.7.1.3 unique_ptr for array objects with a runtime length
380 // [unique.ptr.runtime]
381 // _GLIBCXX_RESOLVE_LIB_DEFECTS
382 // DR 740 - omit specialization for array objects with a compile time length
383 template<typename _Tp
, typename _Dp
>
384 class unique_ptr
<_Tp
[], _Dp
>
386 __uniq_ptr_impl
<_Tp
, _Dp
> _M_t
;
388 template<typename _Up
>
389 using __remove_cv
= typename remove_cv
<_Up
>::type
;
391 // like is_base_of<_Tp, _Up> but false if unqualified types are the same
392 template<typename _Up
>
393 using __is_derived_Tp
394 = __and_
< is_base_of
<_Tp
, _Up
>,
395 __not_
<is_same
<__remove_cv
<_Tp
>, __remove_cv
<_Up
>>> >;
398 using pointer
= typename __uniq_ptr_impl
<_Tp
, _Dp
>::pointer
;
399 using element_type
= _Tp
;
400 using deleter_type
= _Dp
;
402 // helper template for detecting a safe conversion from another
404 template<typename _Up
, typename _Ep
,
405 typename _Up_up
= unique_ptr
<_Up
, _Ep
>,
406 typename _Up_element_type
= typename
_Up_up::element_type
>
407 using __safe_conversion_up
= __and_
<
409 is_same
<pointer
, element_type
*>,
410 is_same
<typename
_Up_up::pointer
, _Up_element_type
*>,
411 is_convertible
<_Up_element_type(*)[], element_type(*)[]>,
412 __or_
<__and_
<is_reference
<deleter_type
>, is_same
<deleter_type
, _Ep
>>,
413 __and_
<__not_
<is_reference
<deleter_type
>>,
414 is_convertible
<_Ep
, deleter_type
>>>
417 // helper template for detecting a safe conversion from a raw pointer
418 template<typename _Up
>
419 using __safe_conversion_raw
= __and_
<
420 __or_
<__or_
<is_same
<_Up
, pointer
>,
421 is_same
<_Up
, nullptr_t
>>,
422 __and_
<is_pointer
<_Up
>,
423 is_same
<pointer
, element_type
*>,
425 typename remove_pointer
<_Up
>::type(*)[],
433 /// Default constructor, creates a unique_ptr that owns nothing.
434 constexpr unique_ptr() noexcept
436 { static_assert(!std::is_pointer
<deleter_type
>::value
,
437 "constructed with null function pointer deleter"); }
439 /** Takes ownership of a pointer.
441 * @param __p A pointer to an array of a type safely convertible
442 * to an array of @c element_type
444 * The deleter will be value-initialized.
446 template<typename _Up
,
447 typename
= typename enable_if
<
448 __safe_conversion_raw
<_Up
>::value
, bool>::type
>
450 unique_ptr(_Up __p
) noexcept
452 { static_assert(!is_pointer
<deleter_type
>::value
,
453 "constructed with null function pointer deleter"); }
455 /** Takes ownership of a pointer.
457 * @param __p A pointer to an array of a type safely convertible
458 * to an array of @c element_type
459 * @param __d A reference to a deleter.
461 * The deleter will be initialized with @p __d
463 template<typename _Up
,
464 typename
= typename enable_if
<
465 __safe_conversion_raw
<_Up
>::value
, bool>::type
>
467 typename conditional
<is_reference
<deleter_type
>::value
,
468 deleter_type
, const deleter_type
&>::type __d
) noexcept
471 /** Takes ownership of a pointer.
473 * @param __p A pointer to an array of a type safely convertible
474 * to an array of @c element_type
475 * @param __d A reference to a deleter.
477 * The deleter will be initialized with @p std::move(__d)
479 template<typename _Up
,
480 typename
= typename enable_if
<
481 __safe_conversion_raw
<_Up
>::value
, bool>::type
>
482 unique_ptr(_Up __p
, typename
483 remove_reference
<deleter_type
>::type
&& __d
) noexcept
484 : _M_t(std::move(__p
), std::move(__d
))
485 { static_assert(!is_reference
<deleter_type
>::value
,
486 "rvalue deleter bound to reference"); }
488 /// Move constructor.
489 unique_ptr(unique_ptr
&& __u
) noexcept
490 : _M_t(__u
.release(), std::forward
<deleter_type
>(__u
.get_deleter())) { }
492 /// Creates a unique_ptr that owns nothing.
493 constexpr unique_ptr(nullptr_t
) noexcept
: unique_ptr() { }
495 template<typename _Up
, typename _Ep
,
496 typename
= _Require
<__safe_conversion_up
<_Up
, _Ep
>>>
497 unique_ptr(unique_ptr
<_Up
, _Ep
>&& __u
) noexcept
498 : _M_t(__u
.release(), std::forward
<_Ep
>(__u
.get_deleter()))
501 /// Destructor, invokes the deleter if the stored pointer is not null.
504 auto& __ptr
= _M_t
._M_ptr();
505 if (__ptr
!= nullptr)
506 get_deleter()(__ptr
);
512 /** @brief Move assignment operator.
514 * @param __u The object to transfer ownership from.
516 * Invokes the deleter first if this object owns a pointer.
519 operator=(unique_ptr
&& __u
) noexcept
521 reset(__u
.release());
522 get_deleter() = std::forward
<deleter_type
>(__u
.get_deleter());
526 /** @brief Assignment from another type.
528 * @param __u The object to transfer ownership from, which owns a
529 * convertible pointer to an array object.
531 * Invokes the deleter first if this object owns a pointer.
533 template<typename _Up
, typename _Ep
>
535 enable_if
<__and_
<__safe_conversion_up
<_Up
, _Ep
>,
536 is_assignable
<deleter_type
&, _Ep
&&>
539 operator=(unique_ptr
<_Up
, _Ep
>&& __u
) noexcept
541 reset(__u
.release());
542 get_deleter() = std::forward
<_Ep
>(__u
.get_deleter());
546 /// Reset the %unique_ptr to empty, invoking the deleter if necessary.
548 operator=(nullptr_t
) noexcept
556 /// Access an element of owned array.
557 typename
std::add_lvalue_reference
<element_type
>::type
558 operator[](size_t __i
) const
560 __glibcxx_assert(get() != pointer());
564 /// Return the stored pointer.
567 { return _M_t
._M_ptr(); }
569 /// Return a reference to the stored deleter.
571 get_deleter() noexcept
572 { return _M_t
._M_deleter(); }
574 /// Return a reference to the stored deleter.
576 get_deleter() const noexcept
577 { return _M_t
._M_deleter(); }
579 /// Return @c true if the stored pointer is not null.
580 explicit operator bool() const noexcept
581 { return get() == pointer() ? false : true; }
585 /// Release ownership of any stored pointer.
590 _M_t
._M_ptr() = pointer();
594 /** @brief Replace the stored pointer.
596 * @param __p The new pointer to store.
598 * The deleter will be invoked if a pointer is already owned.
600 template <typename _Up
,
602 __or_
<is_same
<_Up
, pointer
>,
603 __and_
<is_same
<pointer
, element_type
*>,
606 typename remove_pointer
<_Up
>::type(*)[],
613 reset(_Up __p
) noexcept
617 swap(_M_t
._M_ptr(), __ptr
);
618 if (__ptr
!= nullptr)
619 get_deleter()(__ptr
);
622 void reset(nullptr_t
= nullptr) noexcept
627 /// Exchange the pointer and deleter with another object.
629 swap(unique_ptr
& __u
) noexcept
632 swap(_M_t
, __u
._M_t
);
635 // Disable copy from lvalue.
636 unique_ptr(const unique_ptr
&) = delete;
637 unique_ptr
& operator=(const unique_ptr
&) = delete;
640 template<typename _Tp
, typename _Dp
>
642 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
643 // Constrained free swap overload, see p0185r1
644 typename enable_if
<__is_swappable
<_Dp
>::value
>::type
648 swap(unique_ptr
<_Tp
, _Dp
>& __x
,
649 unique_ptr
<_Tp
, _Dp
>& __y
) noexcept
652 template<typename _Tp
, typename _Dp
,
653 typename _Up
, typename _Ep
>
655 operator==(const unique_ptr
<_Tp
, _Dp
>& __x
,
656 const unique_ptr
<_Up
, _Ep
>& __y
)
657 { return __x
.get() == __y
.get(); }
659 template<typename _Tp
, typename _Dp
>
661 operator==(const unique_ptr
<_Tp
, _Dp
>& __x
, nullptr_t
) noexcept
664 template<typename _Tp
, typename _Dp
>
666 operator==(nullptr_t
, const unique_ptr
<_Tp
, _Dp
>& __x
) noexcept
669 template<typename _Tp
, typename _Dp
,
670 typename _Up
, typename _Ep
>
672 operator!=(const unique_ptr
<_Tp
, _Dp
>& __x
,
673 const unique_ptr
<_Up
, _Ep
>& __y
)
674 { return __x
.get() != __y
.get(); }
676 template<typename _Tp
, typename _Dp
>
678 operator!=(const unique_ptr
<_Tp
, _Dp
>& __x
, nullptr_t
) noexcept
679 { return (bool)__x
; }
681 template<typename _Tp
, typename _Dp
>
683 operator!=(nullptr_t
, const unique_ptr
<_Tp
, _Dp
>& __x
) noexcept
684 { return (bool)__x
; }
686 template<typename _Tp
, typename _Dp
,
687 typename _Up
, typename _Ep
>
689 operator<(const unique_ptr
<_Tp
, _Dp
>& __x
,
690 const unique_ptr
<_Up
, _Ep
>& __y
)
693 std::common_type
<typename unique_ptr
<_Tp
, _Dp
>::pointer
,
694 typename unique_ptr
<_Up
, _Ep
>::pointer
>::type _CT
;
695 return std::less
<_CT
>()(__x
.get(), __y
.get());
698 template<typename _Tp
, typename _Dp
>
700 operator<(const unique_ptr
<_Tp
, _Dp
>& __x
, nullptr_t
)
701 { return std::less
<typename unique_ptr
<_Tp
, _Dp
>::pointer
>()(__x
.get(),
704 template<typename _Tp
, typename _Dp
>
706 operator<(nullptr_t
, const unique_ptr
<_Tp
, _Dp
>& __x
)
707 { return std::less
<typename unique_ptr
<_Tp
, _Dp
>::pointer
>()(nullptr,
710 template<typename _Tp
, typename _Dp
,
711 typename _Up
, typename _Ep
>
713 operator<=(const unique_ptr
<_Tp
, _Dp
>& __x
,
714 const unique_ptr
<_Up
, _Ep
>& __y
)
715 { return !(__y
< __x
); }
717 template<typename _Tp
, typename _Dp
>
719 operator<=(const unique_ptr
<_Tp
, _Dp
>& __x
, nullptr_t
)
720 { return !(nullptr < __x
); }
722 template<typename _Tp
, typename _Dp
>
724 operator<=(nullptr_t
, const unique_ptr
<_Tp
, _Dp
>& __x
)
725 { return !(__x
< nullptr); }
727 template<typename _Tp
, typename _Dp
,
728 typename _Up
, typename _Ep
>
730 operator>(const unique_ptr
<_Tp
, _Dp
>& __x
,
731 const unique_ptr
<_Up
, _Ep
>& __y
)
732 { return (__y
< __x
); }
734 template<typename _Tp
, typename _Dp
>
736 operator>(const unique_ptr
<_Tp
, _Dp
>& __x
, nullptr_t
)
737 { return std::less
<typename unique_ptr
<_Tp
, _Dp
>::pointer
>()(nullptr,
740 template<typename _Tp
, typename _Dp
>
742 operator>(nullptr_t
, const unique_ptr
<_Tp
, _Dp
>& __x
)
743 { return std::less
<typename unique_ptr
<_Tp
, _Dp
>::pointer
>()(__x
.get(),
746 template<typename _Tp
, typename _Dp
,
747 typename _Up
, typename _Ep
>
749 operator>=(const unique_ptr
<_Tp
, _Dp
>& __x
,
750 const unique_ptr
<_Up
, _Ep
>& __y
)
751 { return !(__x
< __y
); }
753 template<typename _Tp
, typename _Dp
>
755 operator>=(const unique_ptr
<_Tp
, _Dp
>& __x
, nullptr_t
)
756 { return !(__x
< nullptr); }
758 template<typename _Tp
, typename _Dp
>
760 operator>=(nullptr_t
, const unique_ptr
<_Tp
, _Dp
>& __x
)
761 { return !(nullptr < __x
); }
763 /// std::hash specialization for unique_ptr.
764 template<typename _Tp
, typename _Dp
>
765 struct hash
<unique_ptr
<_Tp
, _Dp
>>
766 : public __hash_base
<size_t, unique_ptr
<_Tp
, _Dp
>>
769 operator()(const unique_ptr
<_Tp
, _Dp
>& __u
) const noexcept
771 typedef unique_ptr
<_Tp
, _Dp
> _UP
;
772 return std::hash
<typename
_UP::pointer
>()(__u
.get());
776 #if __cplusplus > 201103L
778 #define __cpp_lib_make_unique 201304
780 template<typename _Tp
>
782 { typedef unique_ptr
<_Tp
> __single_object
; };
784 template<typename _Tp
>
785 struct _MakeUniq
<_Tp
[]>
786 { typedef unique_ptr
<_Tp
[]> __array
; };
788 template<typename _Tp
, size_t _Bound
>
789 struct _MakeUniq
<_Tp
[_Bound
]>
790 { struct __invalid_type
{ }; };
792 /// std::make_unique for single objects
793 template<typename _Tp
, typename
... _Args
>
794 inline typename _MakeUniq
<_Tp
>::__single_object
795 make_unique(_Args
&&... __args
)
796 { return unique_ptr
<_Tp
>(new _Tp(std::forward
<_Args
>(__args
)...)); }
798 /// std::make_unique for arrays of unknown bound
799 template<typename _Tp
>
800 inline typename _MakeUniq
<_Tp
>::__array
801 make_unique(size_t __num
)
802 { return unique_ptr
<_Tp
>(new remove_extent_t
<_Tp
>[__num
]()); }
804 /// Disable std::make_unique for arrays of known bound
805 template<typename _Tp
, typename
... _Args
>
806 inline typename _MakeUniq
<_Tp
>::__invalid_type
807 make_unique(_Args
&&...) = delete;
810 // @} group pointer_abstractions
812 _GLIBCXX_END_NAMESPACE_VERSION
815 #endif /* _UNIQUE_PTR_H */