gcc50/csu: Skip depends step to avoid possible race
[dragonfly.git] / contrib / gcc-4.4 / libstdc++-v3 / include / bits / unique_ptr.h
1 // unique_ptr implementation -*- C++ -*-
2
3 // Copyright (C) 2008, 2009 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 unique_ptr.h
26  *  This is an internal header file, included by other library headers.
27  *  You should not attempt to use it directly.
28  */
29
30 #ifndef _UNIQUE_PTR_H
31 #define _UNIQUE_PTR_H 1
32
33 #ifndef __GXX_EXPERIMENTAL_CXX0X__
34 # include <c++0x_warning.h>
35 #endif
36
37 #include <bits/c++config.h>
38 #include <debug/debug.h>
39 #include <type_traits>
40 #include <utility>
41 #include <tuple>
42
43 _GLIBCXX_BEGIN_NAMESPACE(std)
44
45   /**
46    * @addtogroup pointer_abstractions
47    * @{
48    */
49
50   /// Primary template, default_delete.
51   template<typename _Tp> 
52     struct default_delete
53       {
54         default_delete() { }
55
56         template<typename _Up>
57           default_delete(const default_delete<_Up>&) { }
58
59         void
60         operator()(_Tp* __ptr) const
61         {
62           static_assert(sizeof(_Tp)>0,
63                         "can't delete pointer to incomplete type");
64           delete __ptr;
65         }
66     };
67
68   // _GLIBCXX_RESOLVE_LIB_DEFECTS
69   // DR 740 - omit specialization for array objects with a compile time length
70   /// Specialization, default_delete.
71   template<typename _Tp> 
72     struct default_delete<_Tp[]>
73     {
74       void
75       operator()(_Tp* __ptr) const
76       {
77         static_assert(sizeof(_Tp)>0,
78                       "can't delete pointer to incomplete type");
79         delete [] __ptr;
80       }
81     };
82
83   /// 20.7.12.2 unique_ptr for single objects.
84   template <typename _Tp, typename _Tp_Deleter = default_delete<_Tp> > 
85     class unique_ptr
86     {
87       typedef std::tuple<_Tp*, _Tp_Deleter>  __tuple_type;
88       typedef __tuple_type unique_ptr::*     __unspecified_bool_type;
89       typedef _Tp* unique_ptr::*             __unspecified_pointer_type;
90
91     public:
92       typedef _Tp*               pointer;
93       typedef _Tp                element_type;      
94       typedef _Tp_Deleter        deleter_type;
95
96       // Constructors.
97       unique_ptr()
98       : _M_t(pointer(), deleter_type())
99       { static_assert(!std::is_pointer<deleter_type>::value,
100                       "constructed with null function pointer deleter"); }
101
102       explicit
103       unique_ptr(pointer __p)
104       : _M_t(__p, deleter_type())
105       { static_assert(!std::is_pointer<deleter_type>::value,
106                      "constructed with null function pointer deleter"); }
107
108       unique_ptr(pointer __p,
109           typename std::conditional<std::is_reference<deleter_type>::value, 
110             deleter_type, const deleter_type&>::type __d)
111       : _M_t(__p, __d) { }
112
113       unique_ptr(pointer __p,
114           typename std::remove_reference<deleter_type>::type&& __d)
115       : _M_t(std::move(__p), std::move(__d))
116       { static_assert(!std::is_reference<deleter_type>::value, 
117                       "rvalue deleter bound to reference"); }
118
119       // Move constructors.
120       unique_ptr(unique_ptr&& __u) 
121       : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter())) { }
122
123       template<typename _Up, typename _Up_Deleter> 
124         unique_ptr(unique_ptr<_Up, _Up_Deleter>&& __u) 
125         : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter()))
126         { }
127
128       // Destructor.
129       ~unique_ptr() { reset(); }
130     
131       // Assignment.
132       unique_ptr&
133       operator=(unique_ptr&& __u)
134       { 
135         reset(__u.release()); 
136         get_deleter() = std::move(__u.get_deleter()); 
137         return *this;
138       }
139
140       template<typename _Up, typename _Up_Deleter> 
141         unique_ptr&
142         operator=(unique_ptr<_Up, _Up_Deleter>&& __u)
143         {
144           reset(__u.release()); 
145           get_deleter() = std::move(__u.get_deleter()); 
146           return *this;
147         }
148
149       unique_ptr&
150       operator=(__unspecified_pointer_type) 
151       {
152         reset();
153         return *this;
154       }
155
156       // Observers.
157       typename std::add_lvalue_reference<element_type>::type operator*() const
158       {
159         _GLIBCXX_DEBUG_ASSERT(get() != 0);
160         return *get();
161       }
162
163       pointer
164       operator->() const
165       {
166         _GLIBCXX_DEBUG_ASSERT(get() != 0);
167         return get();
168       }
169
170       pointer
171       get() const
172       { return std::get<0>(_M_t); }
173
174       typename std::add_lvalue_reference<deleter_type>::type
175       get_deleter()
176       { return std::get<1>(_M_t); }
177
178       typename std::add_lvalue_reference<
179           typename std::add_const<deleter_type>::type
180               >::type
181       get_deleter() const
182       { return std::get<1>(_M_t); }
183
184       operator __unspecified_bool_type () const
185       { return get() == 0 ? 0 : &unique_ptr::_M_t; }
186
187       // Modifiers.
188       pointer
189       release() 
190       {
191         pointer __p = get();
192         std::get<0>(_M_t) = 0;
193         return __p;
194       }
195
196       void
197       reset(pointer __p = pointer())
198       {
199         if (__p != get())
200           {
201             get_deleter()(get());
202             std::get<0>(_M_t) = __p;
203           }
204       }
205
206       void
207       swap(unique_ptr&& __u)
208       {
209         using std::swap;
210         swap(_M_t, __u._M_t);
211       }
212
213       // Disable copy from lvalue.
214       unique_ptr(const unique_ptr&) = delete;
215
216       template<typename _Up, typename _Up_Deleter> 
217         unique_ptr(const unique_ptr<_Up, _Up_Deleter>&) = delete;
218
219       unique_ptr& operator=(const unique_ptr&) = delete;
220
221       template<typename _Up, typename _Up_Deleter> 
222         unique_ptr& operator=(const unique_ptr<_Up, _Up_Deleter>&) = delete;
223
224     private:
225       __tuple_type _M_t;
226   };
227  
228   /// 20.7.12.3 unique_ptr for array objects with a runtime length
229   // [unique.ptr.runtime]
230   // _GLIBCXX_RESOLVE_LIB_DEFECTS
231   // DR 740 - omit specialization for array objects with a compile time length
232   template<typename _Tp, typename _Tp_Deleter> 
233     class unique_ptr<_Tp[], _Tp_Deleter>
234     {
235       typedef std::tuple<_Tp*, _Tp_Deleter>  __tuple_type;
236       typedef __tuple_type unique_ptr::*     __unspecified_bool_type;
237       typedef _Tp* unique_ptr::*             __unspecified_pointer_type;
238
239     public:
240       typedef _Tp*               pointer;
241       typedef _Tp                element_type;      
242       typedef _Tp_Deleter        deleter_type;
243
244       // Constructors.
245       unique_ptr()
246       : _M_t(pointer(), deleter_type())
247       { static_assert(!std::is_pointer<deleter_type>::value,
248                       "constructed with null function pointer deleter"); }
249
250       explicit
251       unique_ptr(pointer __p)
252       : _M_t(__p, deleter_type())
253       { static_assert(!std::is_pointer<deleter_type>::value,
254                       "constructed with null function pointer deleter"); }
255
256       unique_ptr(pointer __p,
257           typename std::conditional<std::is_reference<deleter_type>::value, 
258               deleter_type, const deleter_type&>::type __d) 
259       : _M_t(__p, __d) { }
260
261       unique_ptr(pointer __p,
262                  typename std::remove_reference<deleter_type>::type && __d)
263       : _M_t(std::move(__p), std::move(__d))
264       { static_assert(!std::is_reference<deleter_type>::value, 
265                       "rvalue deleter bound to reference"); }
266
267       // Move constructors.
268       unique_ptr(unique_ptr&& __u) 
269       : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter())) { }
270
271       template<typename _Up, typename _Up_Deleter> 
272         unique_ptr(unique_ptr<_Up, _Up_Deleter>&& __u) 
273         : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter()))
274         { }
275
276       // Destructor.
277       ~unique_ptr() { reset(); }
278
279       // Assignment.
280       unique_ptr&
281       operator=(unique_ptr&& __u)
282       {
283         reset(__u.release());
284         get_deleter() = std::move(__u.get_deleter()); 
285         return *this; 
286       }
287
288       template<typename _Up, typename _Up_Deleter> 
289         unique_ptr&
290         operator=(unique_ptr<_Up, _Up_Deleter>&& __u)
291         {
292           reset(__u.release());
293           get_deleter() = std::move(__u.get_deleter()); 
294           return *this;
295         }
296
297       unique_ptr&
298       operator=(__unspecified_pointer_type)
299       {
300         reset();
301         return *this;
302       }
303
304       // Observers.
305       typename std::add_lvalue_reference<element_type>::type 
306       operator[](size_t __i) const 
307       {
308         _GLIBCXX_DEBUG_ASSERT(get() != 0);
309         return get()[__i];
310       }
311
312       pointer
313       get() const
314       { return std::get<0>(_M_t); }
315
316       typename std::add_lvalue_reference<deleter_type>::type 
317       get_deleter()
318       { return std::get<1>(_M_t); }
319
320       typename std::add_lvalue_reference<
321           typename std::add_const<deleter_type>::type
322               >::type 
323       get_deleter() const
324       { return std::get<1>(_M_t); }    
325
326       operator __unspecified_bool_type () const 
327       { return get() == 0 ? 0 : &unique_ptr::_M_t; }
328     
329       // Modifiers.
330       pointer
331       release() 
332       {
333         pointer __p = get();
334         std::get<0>(_M_t) = 0;
335         return __p;
336       }
337
338       void
339       reset(pointer __p = pointer()) 
340       {
341         if (__p != get())
342         {
343           get_deleter()(get());
344           std::get<0>(_M_t) = __p;
345         }
346       }
347
348       // DR 821.
349       template<typename _Up>
350         void reset(_Up) = delete;
351
352       void
353       swap(unique_ptr&& __u)
354       {
355         using std::swap;
356         swap(_M_t, __u._M_t);
357       }
358
359       // Disable copy from lvalue.
360       unique_ptr(const unique_ptr&) = delete;
361       unique_ptr& operator=(const unique_ptr&) = delete;
362
363       // Disable construction from convertible pointer types.
364       // (N2315 - 20.6.5.3.1)
365       template<typename _Up>
366         unique_ptr(_Up*, typename
367                    std::conditional<std::is_reference<deleter_type>::value,
368                    deleter_type, const deleter_type&>::type,
369                    typename std::enable_if<std::is_convertible<_Up*, 
370                    pointer>::value>::type* = 0) = delete;
371
372       template<typename _Up>
373         unique_ptr(_Up*, typename std::remove_reference<deleter_type>::type&&,
374                    typename std::enable_if<std::is_convertible<_Up*, 
375                    pointer>::value>::type* = 0) = delete;
376
377       template<typename _Up>
378         explicit
379         unique_ptr(_Up*, typename std::enable_if<std::is_convertible<_Up*, 
380                    pointer>::value>::type* = 0) = delete;
381
382     private:
383       __tuple_type _M_t;
384   };
385   
386   template<typename _Tp, typename _Tp_Deleter> 
387     inline void
388     swap(unique_ptr<_Tp, _Tp_Deleter>& __x,
389          unique_ptr<_Tp, _Tp_Deleter>& __y)
390     { __x.swap(__y); }
391
392   template<typename _Tp, typename _Tp_Deleter> 
393     inline void
394     swap(unique_ptr<_Tp, _Tp_Deleter>&& __x,
395          unique_ptr<_Tp, _Tp_Deleter>& __y)
396     { __x.swap(__y); }
397
398   template<typename _Tp, typename _Tp_Deleter> 
399     inline void
400     swap(unique_ptr<_Tp, _Tp_Deleter>& __x,
401          unique_ptr<_Tp, _Tp_Deleter>&& __y)
402     { __x.swap(__y); }
403   
404   template<typename _Tp, typename _Tp_Deleter,
405            typename _Up, typename _Up_Deleter>
406     inline bool
407     operator==(const unique_ptr<_Tp, _Tp_Deleter>& __x,
408                const unique_ptr<_Up, _Up_Deleter>& __y)
409     { return __x.get() == __y.get(); }
410
411   template<typename _Tp, typename _Tp_Deleter,
412            typename _Up, typename _Up_Deleter>
413     inline bool
414     operator!=(const unique_ptr<_Tp, _Tp_Deleter>& __x,
415                const unique_ptr<_Up, _Up_Deleter>& __y)
416     { return !(__x.get() == __y.get()); }
417
418   template<typename _Tp, typename _Tp_Deleter,
419            typename _Up, typename _Up_Deleter>
420     inline bool
421     operator<(const unique_ptr<_Tp, _Tp_Deleter>& __x,
422               const unique_ptr<_Up, _Up_Deleter>& __y)
423     { return __x.get() < __y.get(); }
424
425   template<typename _Tp, typename _Tp_Deleter,
426            typename _Up, typename _Up_Deleter>
427     inline bool
428     operator<=(const unique_ptr<_Tp, _Tp_Deleter>& __x,
429                const unique_ptr<_Up, _Up_Deleter>& __y)
430     { return !(__y.get() < __x.get()); }
431
432   template<typename _Tp, typename _Tp_Deleter,
433            typename _Up, typename _Up_Deleter>
434     inline bool
435     operator>(const unique_ptr<_Tp, _Tp_Deleter>& __x,
436               const unique_ptr<_Up, _Up_Deleter>& __y)
437     { return __y.get() < __x.get(); }
438
439   template<typename _Tp, typename _Tp_Deleter,
440            typename _Up, typename _Up_Deleter>
441     inline bool
442     operator>=(const unique_ptr<_Tp, _Tp_Deleter>& __x,
443                const unique_ptr<_Up, _Up_Deleter>& __y)
444     { return !(__x.get() < __y.get()); }
445
446   // @} group pointer_abstractions
447
448 _GLIBCXX_END_NAMESPACE
449
450 #endif /* _UNIQUE_PTR_H */