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