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