OSDN Git Service

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