Branch data Line data Source code
1 : : // unique_ptr implementation -*- C++ -*-
2 : :
3 : : // Copyright (C) 2008-2015 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 : : 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 : 0 : 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 [ # # ][ # # ]: 0 : delete __ptr;
[ # # ]
[ # # # # ]
[ # # ][ # # ]
[ # # ]
[ # # # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # # ]
[ # # ][ # # ]
[ # # # # ]
[ # # ][ # # ]
[ # # # # ]
[ # # ]
[ # # # # ]
[ # # # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # #
# # # # #
# # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
77 : 0 : }
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 [ # # ][ # # ]: 4 : 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 : : constexpr unique_ptr() noexcept
158 : : : _M_t()
159 : : { static_assert(!is_pointer<deleter_type>::value,
160 : : "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 : : unique_ptr(pointer __p) noexcept
170 : : : _M_t(__p, deleter_type())
171 : : { static_assert(!is_pointer<deleter_type>::value,
172 : : "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 : : unique_ptr(unique_ptr&& __u) noexcept
206 : : : _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 : : ~unique_ptr() noexcept
233 : : {
234 : : auto& __ptr = std::get<0>(_M_t);
235 [ # # ][ # # ]: 25 : if (__ptr != nullptr)
[ # # ][ - + ]
[ - + # #
# # ][ - +
# # # # #
# ][ - + ]
[ # # # #
# # # # #
# # # # #
# # ][ - + ]
[ - + ][ - + ]
[ - + ][ # #
# # # # ]
[ # # # #
# # ][ + -
# # # # -
+ # # ]
[ # # # # ]
[ # # ][ # #
# # # # ]
[ # # # #
# # ][ # # ]
[ # # # #
# # ][ # # ]
[ # # # #
# # ][ # # ]
[ # # # #
# # ][ + - ]
[ - + # # ]
[ - + ]
[ # # # # ]
[ # # # #
# # ][ # # ]
[ # # # #
# # # # #
# # # #
# ][ # # ]
[ - + ][ - + ]
[ - + ][ - + ]
[ # # ][ - + ]
[ - + # #
# # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # # ]
[ # # ][ # #
# # # # #
# # # # #
# # # # ]
[ # # ][ - + ]
[ - + ][ - + ]
236 : 0 : get_deleter()(__ptr);
237 : 44 : __ptr = pointer();
238 : 6 : }
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 : : operator=(unique_ptr&& __u) noexcept
250 : : {
251 : : reset(__u.release());
252 : : get_deleter() = std::forward<deleter_type>(__u.get_deleter());
253 : : 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 : : operator->() const noexcept
297 : : {
298 : : _GLIBCXX_DEBUG_ASSERT(get() != pointer());
299 : : return get();
300 : : }
301 : :
302 : : /// Return the stored pointer.
303 : : pointer
304 : : get() const noexcept
305 : 34 : { return std::get<0>(_M_t); }
306 : :
307 : : /// Return a reference to the stored deleter.
308 : : deleter_type&
309 : : get_deleter() noexcept
310 : : { 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 : : explicit operator bool() const noexcept
319 : : { return get() == pointer() ? false : true; }
320 : :
321 : : // Modifiers.
322 : :
323 : : /// Release ownership of any stored pointer.
324 : : pointer
325 : : release() noexcept
326 : : {
327 : : pointer __p = get();
328 : 14 : std::get<0>(_M_t) = pointer();
329 : : 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 : : reset(pointer __p = pointer()) noexcept
340 : : {
341 : : using std::swap;
342 : : swap(std::get<0>(_M_t), __p);
343 [ # # ][ # # ]: 3 : if (__p != pointer())
[ - + ][ + - ]
[ # # # # ]
[ # # # # ]
[ # # # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # # ]
[ # # # # ]
[ # # ]
[ # # # # ]
[ # # # # ]
[ # # ]
344 : 0 : get_deleter()(__p);
345 : : }
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 [ # # ][ # # : 4 : 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 remove_extent_t<_Tp>[__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 */
|