1 // unique_ptr implementation -*- C++ -*-
2 
3 // Copyright (C) 2008-2013 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 
_GLIBCXX_VISIBILITY(default)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, default_delete.
53   template<typename _Tp>
54     struct default_delete
55     {
56       constexpr default_delete() noexcept = default;
57 
58       template<typename _Up, typename = typename
59 	       enable_if<is_convertible<_Up*, _Tp*>::value>::type>
60         default_delete(const default_delete<_Up>&) noexcept { }
61 
62       void
63       operator()(_Tp* __ptr) const
64       {
65 	static_assert(sizeof(_Tp)>0,
66 		      "can't delete pointer to incomplete type");
67 	delete __ptr;
68       }
69     };
70 
71   // _GLIBCXX_RESOLVE_LIB_DEFECTS
72   // DR 740 - omit specialization for array objects with a compile time length
73   /// Specialization, default_delete.
74   template<typename _Tp>
75     struct default_delete<_Tp[]>
76     {
77     private:
78       template<typename _Up>
79 	using __remove_cv = typename remove_cv<_Up>::type;
80 
81       // Like is_base_of<_Tp, _Up> but false if unqualified types are the same
82       template<typename _Up>
83 	using __is_derived_Tp
84 	  = __and_< is_base_of<_Tp, _Up>,
85 		    __not_<is_same<__remove_cv<_Tp>, __remove_cv<_Up>>> >;
86 
87     public:
88       constexpr default_delete() noexcept = default;
89 
90       template<typename _Up, typename = typename
91 	       enable_if<!__is_derived_Tp<_Up>::value>::type>
92         default_delete(const default_delete<_Up[]>&) noexcept { }
93 
94       void
95       operator()(_Tp* __ptr) const
96       {
97 	static_assert(sizeof(_Tp)>0,
98 		      "can't delete pointer to incomplete type");
99 	delete [] __ptr;
100       }
101 
102       template<typename _Up>
103 	typename enable_if<__is_derived_Tp<_Up>::value>::type
104 	operator()(_Up*) const = delete;
105     };
106 
107   /// 20.7.1.2 unique_ptr for single objects.
108   template <typename _Tp, typename _Dp = default_delete<_Tp> >
109     class unique_ptr
110     {
111       // use SFINAE to determine whether _Del::pointer exists
112       class _Pointer
113       {
114 	template<typename _Up>
115 	  static typename _Up::pointer __test(typename _Up::pointer*);
116 
117 	template<typename _Up>
118 	  static _Tp* __test(...);
119 
120 	typedef typename remove_reference<_Dp>::type _Del;
121 
122       public:
123 	typedef decltype(__test<_Del>(0)) type;
124       };
125 
126       typedef std::tuple<typename _Pointer::type, _Dp>  __tuple_type;
127       __tuple_type                                      _M_t;
128 
129     public:
130       typedef typename _Pointer::type   pointer;
131       typedef _Tp                       element_type;
132       typedef _Dp                       deleter_type;
133 
134       // Constructors.
135       constexpr unique_ptr() noexcept
136       : _M_t()
137       { static_assert(!is_pointer<deleter_type>::value,
138 		     "constructed with null function pointer deleter"); }
139 
140       explicit
141       unique_ptr(pointer __p) noexcept
142       : _M_t(__p, deleter_type())
143       { static_assert(!is_pointer<deleter_type>::value,
144 		     "constructed with null function pointer deleter"); }
145 
146       unique_ptr(pointer __p,
147 	  typename conditional<is_reference<deleter_type>::value,
148 	    deleter_type, const deleter_type&>::type __d) noexcept
149       : _M_t(__p, __d) { }
150 
151       unique_ptr(pointer __p,
152 	  typename remove_reference<deleter_type>::type&& __d) noexcept
153       : _M_t(std::move(__p), std::move(__d))
154       { static_assert(!std::is_reference<deleter_type>::value,
155 		      "rvalue deleter bound to reference"); }
156 
157       constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { }
158 
159       // Move constructors.
160       unique_ptr(unique_ptr&& __u) noexcept
161       : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter())) { }
162 
163       template<typename _Up, typename _Ep, typename = _Require<
164 	       is_convertible<typename unique_ptr<_Up, _Ep>::pointer, pointer>,
165 	       __not_<is_array<_Up>>,
166 	       typename conditional<is_reference<_Dp>::value,
167 				    is_same<_Ep, _Dp>,
168 				    is_convertible<_Ep, _Dp>>::type>>
169 	unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept
170 	: _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter()))
171 	{ }
172 
173 #if _GLIBCXX_USE_DEPRECATED
174       template<typename _Up, typename = _Require<
175 	       is_convertible<_Up*, _Tp*>, is_same<_Dp, default_delete<_Tp>>>>
176 	unique_ptr(auto_ptr<_Up>&& __u) noexcept;
177 #endif
178 
179       // Destructor.
180       ~unique_ptr() noexcept
181       {
182 	auto& __ptr = std::get<0>(_M_t);
183 	if (__ptr != nullptr)
184 	  get_deleter()(__ptr);
185 	__ptr = pointer();
186       }
187 
188       // Assignment.
189       unique_ptr&
190       operator=(unique_ptr&& __u) noexcept
191       {
192 	reset(__u.release());
193 	get_deleter() = std::forward<deleter_type>(__u.get_deleter());
194 	return *this;
195       }
196 
197       template<typename _Up, typename _Ep>
198 	typename enable_if< __and_<
199 	  is_convertible<typename unique_ptr<_Up, _Ep>::pointer, pointer>,
200 	  __not_<is_array<_Up>>
201 	  >::value,
202 	  unique_ptr&>::type
203 	operator=(unique_ptr<_Up, _Ep>&& __u) noexcept
204 	{
205 	  reset(__u.release());
206 	  get_deleter() = std::forward<_Ep>(__u.get_deleter());
207 	  return *this;
208 	}
209 
210       unique_ptr&
211       operator=(nullptr_t) noexcept
212       {
213 	reset();
214 	return *this;
215       }
216 
217       // Observers.
218       typename add_lvalue_reference<element_type>::type
219       operator*() const
220       {
221 	_GLIBCXX_DEBUG_ASSERT(get() != pointer());
222 	return *get();
223       }
224 
225       pointer
226       operator->() const noexcept
227       {
228 	_GLIBCXX_DEBUG_ASSERT(get() != pointer());
229 	return get();
230       }
231 
232       pointer
233       get() const noexcept
234       { return std::get<0>(_M_t); }
235 
236       deleter_type&
237       get_deleter() noexcept
238       { return std::get<1>(_M_t); }
239 
240       const deleter_type&
241       get_deleter() const noexcept
242       { return std::get<1>(_M_t); }
243 
244       explicit operator bool() const noexcept
245       { return get() == pointer() ? false : true; }
246 
247       // Modifiers.
248       pointer
249       release() noexcept
250       {
251 	pointer __p = get();
252 	std::get<0>(_M_t) = pointer();
253 	return __p;
254       }
255 
256       void
257       reset(pointer __p = pointer()) noexcept
258       {
259 	using std::swap;
260 	swap(std::get<0>(_M_t), __p);
261 	if (__p != pointer())
262 	  get_deleter()(__p);
263       }
264 
265       void
266       swap(unique_ptr& __u) noexcept
267       {
268 	using std::swap;
269 	swap(_M_t, __u._M_t);
270       }
271 
272       // Disable copy from lvalue.
273       unique_ptr(const unique_ptr&) = delete;
274       unique_ptr& operator=(const unique_ptr&) = delete;
275   };
276 
277   /// 20.7.1.3 unique_ptr for array objects with a runtime length
278   // [unique.ptr.runtime]
279   // _GLIBCXX_RESOLVE_LIB_DEFECTS
280   // DR 740 - omit specialization for array objects with a compile time length
281   template<typename _Tp, typename _Dp>
282     class unique_ptr<_Tp[], _Dp>
283     {
284       // use SFINAE to determine whether _Del::pointer exists
285       class _Pointer
286       {
287 	template<typename _Up>
288 	  static typename _Up::pointer __test(typename _Up::pointer*);
289 
290 	template<typename _Up>
291 	  static _Tp* __test(...);
292 
293 	typedef typename remove_reference<_Dp>::type _Del;
294 
295       public:
296 	typedef decltype(__test<_Del>(0)) type;
297       };
298 
299       typedef std::tuple<typename _Pointer::type, _Dp>  __tuple_type;
300       __tuple_type                                      _M_t;
301 
302       template<typename _Up>
303 	using __remove_cv = typename remove_cv<_Up>::type;
304 
305       // like is_base_of<_Tp, _Up> but false if unqualified types are the same
306       template<typename _Up>
307 	using __is_derived_Tp
308 	  = __and_< is_base_of<_Tp, _Up>,
309 		    __not_<is_same<__remove_cv<_Tp>, __remove_cv<_Up>>> >;
310 
311       template<typename _Up, typename _Ep,
312 	       typename _Tp_pointer = typename _Pointer::type,
313 	       typename _Up_pointer = typename unique_ptr<_Up, _Ep>::pointer>
314 	using __safe_conversion = __and_<
315 	    is_convertible<_Up_pointer, _Tp_pointer>,
316 	    is_array<_Up>,
317 	    __or_<__not_<is_pointer<_Up_pointer>>,
318 		  __not_<is_pointer<_Tp_pointer>>,
319 		  __not_<__is_derived_Tp<typename remove_extent<_Up>::type>>
320 	    >
321 	  >;
322 
323     public:
324       typedef typename _Pointer::type	pointer;
325       typedef _Tp		 	element_type;
326       typedef _Dp                       deleter_type;
327 
328       // Constructors.
329       constexpr unique_ptr() noexcept
330       : _M_t()
331       { static_assert(!std::is_pointer<deleter_type>::value,
332 		      "constructed with null function pointer deleter"); }
333 
334       explicit
335       unique_ptr(pointer __p) noexcept
336       : _M_t(__p, deleter_type())
337       { static_assert(!is_pointer<deleter_type>::value,
338 		      "constructed with null function pointer deleter"); }
339 
340       template<typename _Up, typename = _Require<is_pointer<pointer>,
341 	       is_convertible<_Up*, pointer>, __is_derived_Tp<_Up>>>
342 	explicit
343 	unique_ptr(_Up* __p) = delete;
344 
345       unique_ptr(pointer __p,
346 	  typename conditional<is_reference<deleter_type>::value,
347 	      deleter_type, const deleter_type&>::type __d) noexcept
348       : _M_t(__p, __d) { }
349 
350       unique_ptr(pointer __p, typename
351 		 remove_reference<deleter_type>::type&& __d) noexcept
352       : _M_t(std::move(__p), std::move(__d))
353       { static_assert(!is_reference<deleter_type>::value,
354 		      "rvalue deleter bound to reference"); }
355 
356       // Move constructor.
357       unique_ptr(unique_ptr&& __u) noexcept
358       : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter())) { }
359 
360       constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { }
361 
362       template<typename _Up, typename _Ep,
363 	       typename = _Require<__safe_conversion<_Up, _Ep>,
364 		 typename conditional<is_reference<_Dp>::value,
365 				      is_same<_Ep, _Dp>,
366 				      is_convertible<_Ep, _Dp>>::type
367 	       >>
368 	unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept
369 	: _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter()))
370 	{ }
371 
372       // Destructor.
373       ~unique_ptr()
374       {
375 	auto& __ptr = std::get<0>(_M_t);
376 	if (__ptr != nullptr)
377 	  get_deleter()(__ptr);
378 	__ptr = pointer();
379       }
380 
381       // Assignment.
382       unique_ptr&
383       operator=(unique_ptr&& __u) noexcept
384       {
385 	reset(__u.release());
386 	get_deleter() = std::forward<deleter_type>(__u.get_deleter());
387 	return *this;
388       }
389 
390       template<typename _Up, typename _Ep>
391 	typename
392 	enable_if<__safe_conversion<_Up, _Ep>::value, unique_ptr&>::type
393 	operator=(unique_ptr<_Up, _Ep>&& __u) noexcept
394 	{
395 	  reset(__u.release());
396 	  get_deleter() = std::forward<_Ep>(__u.get_deleter());
397 	  return *this;
398 	}
399 
400       unique_ptr&
401       operator=(nullptr_t) noexcept
402       {
403 	reset();
404 	return *this;
405       }
406 
407       // Observers.
408       typename std::add_lvalue_reference<element_type>::type
409       operator[](size_t __i) const
410       {
411 	_GLIBCXX_DEBUG_ASSERT(get() != pointer());
412 	return get()[__i];
413       }
414 
415       pointer
416       get() const noexcept
417       { return std::get<0>(_M_t); }
418 
419       deleter_type&
420       get_deleter() noexcept
421       { return std::get<1>(_M_t); }
422 
423       const deleter_type&
424       get_deleter() const noexcept
425       { return std::get<1>(_M_t); }
426 
427       explicit operator bool() const noexcept
428       { return get() == pointer() ? false : true; }
429 
430       // Modifiers.
431       pointer
432       release() noexcept
433       {
434 	pointer __p = get();
435 	std::get<0>(_M_t) = pointer();
436 	return __p;
437       }
438 
439       void
440       reset() noexcept
441       { reset(pointer()); }
442 
443       void
444       reset(pointer __p) noexcept
445       {
446 	using std::swap;
447 	swap(std::get<0>(_M_t), __p);
448 	if (__p != nullptr)
449 	  get_deleter()(__p);
450       }
451 
452       template<typename _Up, typename = _Require<is_pointer<pointer>,
453 	       is_convertible<_Up*, pointer>, __is_derived_Tp<_Up>>>
454 	void reset(_Up*) = delete;
455 
456       void
457       swap(unique_ptr& __u) noexcept
458       {
459 	using std::swap;
460 	swap(_M_t, __u._M_t);
461       }
462 
463       // Disable copy from lvalue.
464       unique_ptr(const unique_ptr&) = delete;
465       unique_ptr& operator=(const unique_ptr&) = delete;
466 
467       // Disable construction from convertible pointer types.
468       template<typename _Up, typename = _Require<is_pointer<pointer>,
469 	       is_convertible<_Up*, pointer>, __is_derived_Tp<_Up>>>
470 	unique_ptr(_Up*, typename
471 		   conditional<is_reference<deleter_type>::value,
472 		   deleter_type, const deleter_type&>::type) = delete;
473 
474       template<typename _Up, typename = _Require<is_pointer<pointer>,
475 	       is_convertible<_Up*, pointer>, __is_derived_Tp<_Up>>>
476 	unique_ptr(_Up*, typename
477 		   remove_reference<deleter_type>::type&&) = delete;
478     };
479 
480   template<typename _Tp, typename _Dp>
481     inline void
482     swap(unique_ptr<_Tp, _Dp>& __x,
483 	 unique_ptr<_Tp, _Dp>& __y) noexcept
484     { __x.swap(__y); }
485 
486   template<typename _Tp, typename _Dp,
487 	   typename _Up, typename _Ep>
488     inline bool
489     operator==(const unique_ptr<_Tp, _Dp>& __x,
490 	       const unique_ptr<_Up, _Ep>& __y)
491     { return __x.get() == __y.get(); }
492 
493   template<typename _Tp, typename _Dp>
494     inline bool
495     operator==(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept
496     { return !__x; }
497 
498   template<typename _Tp, typename _Dp>
499     inline bool
500     operator==(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept
501     { return !__x; }
502 
503   template<typename _Tp, typename _Dp,
504 	   typename _Up, typename _Ep>
505     inline bool
506     operator!=(const unique_ptr<_Tp, _Dp>& __x,
507 	       const unique_ptr<_Up, _Ep>& __y)
508     { return __x.get() != __y.get(); }
509 
510   template<typename _Tp, typename _Dp>
511     inline bool
512     operator!=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept
513     { return (bool)__x; }
514 
515   template<typename _Tp, typename _Dp>
516     inline bool
517     operator!=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept
518     { return (bool)__x; }
519 
520   template<typename _Tp, typename _Dp,
521 	   typename _Up, typename _Ep>
522     inline bool
523     operator<(const unique_ptr<_Tp, _Dp>& __x,
524 	      const unique_ptr<_Up, _Ep>& __y)
525     {
526       typedef typename
527 	std::common_type<typename unique_ptr<_Tp, _Dp>::pointer,
528 	                 typename unique_ptr<_Up, _Ep>::pointer>::type _CT;
529       return std::less<_CT>()(__x.get(), __y.get());
530     }
531 
532   template<typename _Tp, typename _Dp>
533     inline bool
534     operator<(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
535     { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(__x.get(),
536 								 nullptr); }
537 
538   template<typename _Tp, typename _Dp>
539     inline bool
540     operator<(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
541     { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(nullptr,
542 								 __x.get()); }
543 
544   template<typename _Tp, typename _Dp,
545 	   typename _Up, typename _Ep>
546     inline bool
547     operator<=(const unique_ptr<_Tp, _Dp>& __x,
548 	       const unique_ptr<_Up, _Ep>& __y)
549     { return !(__y < __x); }
550 
551   template<typename _Tp, typename _Dp>
552     inline bool
553     operator<=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
554     { return !(nullptr < __x); }
555 
556   template<typename _Tp, typename _Dp>
557     inline bool
558     operator<=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
559     { return !(__x < nullptr); }
560 
561   template<typename _Tp, typename _Dp,
562 	   typename _Up, typename _Ep>
563     inline bool
564     operator>(const unique_ptr<_Tp, _Dp>& __x,
565 	      const unique_ptr<_Up, _Ep>& __y)
566     { return (__y < __x); }
567 
568   template<typename _Tp, typename _Dp>
569     inline bool
570     operator>(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
571     { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(nullptr,
572 								 __x.get()); }
573 
574   template<typename _Tp, typename _Dp>
575     inline bool
576     operator>(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
577     { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(__x.get(),
578 								 nullptr); }
579 
580   template<typename _Tp, typename _Dp,
581 	   typename _Up, typename _Ep>
582     inline bool
583     operator>=(const unique_ptr<_Tp, _Dp>& __x,
584 	       const unique_ptr<_Up, _Ep>& __y)
585     { return !(__x < __y); }
586 
587   template<typename _Tp, typename _Dp>
588     inline bool
589     operator>=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
590     { return !(__x < nullptr); }
591 
592   template<typename _Tp, typename _Dp>
593     inline bool
594     operator>=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
595     { return !(nullptr < __x); }
596 
597   /// std::hash specialization for unique_ptr.
598   template<typename _Tp, typename _Dp>
599     struct hash<unique_ptr<_Tp, _Dp>>
600     : public __hash_base<size_t, unique_ptr<_Tp, _Dp>>
601     {
602       size_t
603       operator()(const unique_ptr<_Tp, _Dp>& __u) const noexcept
604       {
605 	typedef unique_ptr<_Tp, _Dp> _UP;
606 	return std::hash<typename _UP::pointer>()(__u.get());
607       }
608     };
609 
610   // @} group pointer_abstractions
611 
612 _GLIBCXX_END_NAMESPACE_VERSION
613 } // namespace
614 
615 #endif /* _UNIQUE_PTR_H */
616