00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #ifndef _UNIQUE_PTR_H
00031 #define _UNIQUE_PTR_H 1
00032
00033 #ifndef __GXX_EXPERIMENTAL_CXX0X__
00034 # include <c++0x_warning.h>
00035 #endif
00036
00037 #include <bits/c++config.h>
00038 #include <debug/debug.h>
00039 #include <type_traits>
00040 #include <utility>
00041 #include <tuple>
00042
00043 _GLIBCXX_BEGIN_NAMESPACE(std)
00044
00045
00046
00047
00048
00049
00050
00051 template<typename _Tp>
00052 struct default_delete
00053 {
00054 default_delete() { }
00055
00056 template<typename _Up>
00057 default_delete(const default_delete<_Up>&) { }
00058
00059 void
00060 operator()(_Tp* __ptr) const
00061 {
00062 static_assert(sizeof(_Tp)>0,
00063 "can't delete pointer to incomplete type");
00064 delete __ptr;
00065 }
00066 };
00067
00068
00069
00070
00071 template<typename _Tp>
00072 struct default_delete<_Tp[]>
00073 {
00074 void
00075 operator()(_Tp* __ptr) const
00076 {
00077 static_assert(sizeof(_Tp)>0,
00078 "can't delete pointer to incomplete type");
00079 delete [] __ptr;
00080 }
00081 };
00082
00083
00084 template <typename _Tp, typename _Tp_Deleter = default_delete<_Tp> >
00085 class unique_ptr
00086 {
00087 typedef std::tuple<_Tp*, _Tp_Deleter> __tuple_type;
00088 typedef _Tp* unique_ptr::* __unspecified_pointer_type;
00089
00090 public:
00091 typedef _Tp* pointer;
00092 typedef _Tp element_type;
00093 typedef _Tp_Deleter deleter_type;
00094
00095
00096 unique_ptr()
00097 : _M_t(pointer(), deleter_type())
00098 { static_assert(!std::is_pointer<deleter_type>::value,
00099 "constructed with null function pointer deleter"); }
00100
00101 explicit
00102 unique_ptr(pointer __p)
00103 : _M_t(__p, deleter_type())
00104 { static_assert(!std::is_pointer<deleter_type>::value,
00105 "constructed with null function pointer deleter"); }
00106
00107 unique_ptr(pointer __p,
00108 typename std::conditional<std::is_reference<deleter_type>::value,
00109 deleter_type, const deleter_type&>::type __d)
00110 : _M_t(__p, __d) { }
00111
00112 unique_ptr(pointer __p,
00113 typename std::remove_reference<deleter_type>::type&& __d)
00114 : _M_t(std::move(__p), std::move(__d))
00115 { static_assert(!std::is_reference<deleter_type>::value,
00116 "rvalue deleter bound to reference"); }
00117
00118
00119 unique_ptr(unique_ptr&& __u)
00120 : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter())) { }
00121
00122 template<typename _Up, typename _Up_Deleter>
00123 unique_ptr(unique_ptr<_Up, _Up_Deleter>&& __u)
00124 : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter()))
00125 { }
00126
00127
00128 ~unique_ptr() { reset(); }
00129
00130
00131 unique_ptr&
00132 operator=(unique_ptr&& __u)
00133 {
00134 reset(__u.release());
00135 get_deleter() = std::move(__u.get_deleter());
00136 return *this;
00137 }
00138
00139 template<typename _Up, typename _Up_Deleter>
00140 unique_ptr&
00141 operator=(unique_ptr<_Up, _Up_Deleter>&& __u)
00142 {
00143 reset(__u.release());
00144 get_deleter() = std::move(__u.get_deleter());
00145 return *this;
00146 }
00147
00148 unique_ptr&
00149 operator=(__unspecified_pointer_type)
00150 {
00151 reset();
00152 return *this;
00153 }
00154
00155
00156 typename std::add_lvalue_reference<element_type>::type operator*() const
00157 {
00158 _GLIBCXX_DEBUG_ASSERT(get() != 0);
00159 return *get();
00160 }
00161
00162 pointer
00163 operator->() const
00164 {
00165 _GLIBCXX_DEBUG_ASSERT(get() != 0);
00166 return get();
00167 }
00168
00169 pointer
00170 get() const
00171 { return std::get<0>(_M_t); }
00172
00173 typename std::add_lvalue_reference<deleter_type>::type
00174 get_deleter()
00175 { return std::get<1>(_M_t); }
00176
00177 typename std::add_lvalue_reference<
00178 typename std::add_const<deleter_type>::type
00179 >::type
00180 get_deleter() const
00181 { return std::get<1>(_M_t); }
00182
00183 explicit operator bool() const
00184 { return get() == 0 ? false : true; }
00185
00186
00187 pointer
00188 release()
00189 {
00190 pointer __p = get();
00191 std::get<0>(_M_t) = 0;
00192 return __p;
00193 }
00194
00195 void
00196 reset(pointer __p = pointer())
00197 {
00198 if (__p != get())
00199 {
00200 get_deleter()(get());
00201 std::get<0>(_M_t) = __p;
00202 }
00203 }
00204
00205 void
00206 swap(unique_ptr& __u)
00207 {
00208 using std::swap;
00209 swap(_M_t, __u._M_t);
00210 }
00211
00212
00213 unique_ptr(const unique_ptr&) = delete;
00214
00215 template<typename _Up, typename _Up_Deleter>
00216 unique_ptr(const unique_ptr<_Up, _Up_Deleter>&) = delete;
00217
00218 unique_ptr& operator=(const unique_ptr&) = delete;
00219
00220 template<typename _Up, typename _Up_Deleter>
00221 unique_ptr& operator=(const unique_ptr<_Up, _Up_Deleter>&) = delete;
00222
00223 private:
00224 __tuple_type _M_t;
00225 };
00226
00227
00228
00229
00230
00231 template<typename _Tp, typename _Tp_Deleter>
00232 class unique_ptr<_Tp[], _Tp_Deleter>
00233 {
00234 typedef std::tuple<_Tp*, _Tp_Deleter> __tuple_type;
00235 typedef _Tp* unique_ptr::* __unspecified_pointer_type;
00236
00237 public:
00238 typedef _Tp* pointer;
00239 typedef _Tp element_type;
00240 typedef _Tp_Deleter deleter_type;
00241
00242
00243 unique_ptr()
00244 : _M_t(pointer(), deleter_type())
00245 { static_assert(!std::is_pointer<deleter_type>::value,
00246 "constructed with null function pointer deleter"); }
00247
00248 explicit
00249 unique_ptr(pointer __p)
00250 : _M_t(__p, deleter_type())
00251 { static_assert(!std::is_pointer<deleter_type>::value,
00252 "constructed with null function pointer deleter"); }
00253
00254 unique_ptr(pointer __p,
00255 typename std::conditional<std::is_reference<deleter_type>::value,
00256 deleter_type, const deleter_type&>::type __d)
00257 : _M_t(__p, __d) { }
00258
00259 unique_ptr(pointer __p,
00260 typename std::remove_reference<deleter_type>::type && __d)
00261 : _M_t(std::move(__p), std::move(__d))
00262 { static_assert(!std::is_reference<deleter_type>::value,
00263 "rvalue deleter bound to reference"); }
00264
00265
00266 unique_ptr(unique_ptr&& __u)
00267 : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter())) { }
00268
00269 template<typename _Up, typename _Up_Deleter>
00270 unique_ptr(unique_ptr<_Up, _Up_Deleter>&& __u)
00271 : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter()))
00272 { }
00273
00274
00275 ~unique_ptr() { reset(); }
00276
00277
00278 unique_ptr&
00279 operator=(unique_ptr&& __u)
00280 {
00281 reset(__u.release());
00282 get_deleter() = std::move(__u.get_deleter());
00283 return *this;
00284 }
00285
00286 template<typename _Up, typename _Up_Deleter>
00287 unique_ptr&
00288 operator=(unique_ptr<_Up, _Up_Deleter>&& __u)
00289 {
00290 reset(__u.release());
00291 get_deleter() = std::move(__u.get_deleter());
00292 return *this;
00293 }
00294
00295 unique_ptr&
00296 operator=(__unspecified_pointer_type)
00297 {
00298 reset();
00299 return *this;
00300 }
00301
00302
00303 typename std::add_lvalue_reference<element_type>::type
00304 operator[](size_t __i) const
00305 {
00306 _GLIBCXX_DEBUG_ASSERT(get() != 0);
00307 return get()[__i];
00308 }
00309
00310 pointer
00311 get() const
00312 { return std::get<0>(_M_t); }
00313
00314 typename std::add_lvalue_reference<deleter_type>::type
00315 get_deleter()
00316 { return std::get<1>(_M_t); }
00317
00318 typename std::add_lvalue_reference<
00319 typename std::add_const<deleter_type>::type
00320 >::type
00321 get_deleter() const
00322 { return std::get<1>(_M_t); }
00323
00324 explicit operator bool() const
00325 { return get() == 0 ? false : true; }
00326
00327
00328 pointer
00329 release()
00330 {
00331 pointer __p = get();
00332 std::get<0>(_M_t) = 0;
00333 return __p;
00334 }
00335
00336 void
00337 reset(pointer __p = pointer())
00338 {
00339 if (__p != get())
00340 {
00341 get_deleter()(get());
00342 std::get<0>(_M_t) = __p;
00343 }
00344 }
00345
00346
00347 template<typename _Up>
00348 void reset(_Up) = delete;
00349
00350 void
00351 swap(unique_ptr& __u)
00352 {
00353 using std::swap;
00354 swap(_M_t, __u._M_t);
00355 }
00356
00357
00358 unique_ptr(const unique_ptr&) = delete;
00359 unique_ptr& operator=(const unique_ptr&) = delete;
00360
00361
00362
00363 template<typename _Up>
00364 unique_ptr(_Up*, typename
00365 std::conditional<std::is_reference<deleter_type>::value,
00366 deleter_type, const deleter_type&>::type,
00367 typename std::enable_if<std::is_convertible<_Up*,
00368 pointer>::value>::type* = 0) = delete;
00369
00370 template<typename _Up>
00371 unique_ptr(_Up*, typename std::remove_reference<deleter_type>::type&&,
00372 typename std::enable_if<std::is_convertible<_Up*,
00373 pointer>::value>::type* = 0) = delete;
00374
00375 template<typename _Up>
00376 explicit
00377 unique_ptr(_Up*, typename std::enable_if<std::is_convertible<_Up*,
00378 pointer>::value>::type* = 0) = delete;
00379
00380 private:
00381 __tuple_type _M_t;
00382 };
00383
00384 template<typename _Tp, typename _Tp_Deleter>
00385 inline void
00386 swap(unique_ptr<_Tp, _Tp_Deleter>& __x,
00387 unique_ptr<_Tp, _Tp_Deleter>& __y)
00388 { __x.swap(__y); }
00389
00390 template<typename _Tp, typename _Tp_Deleter,
00391 typename _Up, typename _Up_Deleter>
00392 inline bool
00393 operator==(const unique_ptr<_Tp, _Tp_Deleter>& __x,
00394 const unique_ptr<_Up, _Up_Deleter>& __y)
00395 { return __x.get() == __y.get(); }
00396
00397 template<typename _Tp, typename _Tp_Deleter,
00398 typename _Up, typename _Up_Deleter>
00399 inline bool
00400 operator!=(const unique_ptr<_Tp, _Tp_Deleter>& __x,
00401 const unique_ptr<_Up, _Up_Deleter>& __y)
00402 { return !(__x.get() == __y.get()); }
00403
00404 template<typename _Tp, typename _Tp_Deleter,
00405 typename _Up, typename _Up_Deleter>
00406 inline bool
00407 operator<(const unique_ptr<_Tp, _Tp_Deleter>& __x,
00408 const unique_ptr<_Up, _Up_Deleter>& __y)
00409 { return __x.get() < __y.get(); }
00410
00411 template<typename _Tp, typename _Tp_Deleter,
00412 typename _Up, typename _Up_Deleter>
00413 inline bool
00414 operator<=(const unique_ptr<_Tp, _Tp_Deleter>& __x,
00415 const unique_ptr<_Up, _Up_Deleter>& __y)
00416 { return !(__y.get() < __x.get()); }
00417
00418 template<typename _Tp, typename _Tp_Deleter,
00419 typename _Up, typename _Up_Deleter>
00420 inline bool
00421 operator>(const unique_ptr<_Tp, _Tp_Deleter>& __x,
00422 const unique_ptr<_Up, _Up_Deleter>& __y)
00423 { return __y.get() < __x.get(); }
00424
00425 template<typename _Tp, typename _Tp_Deleter,
00426 typename _Up, typename _Up_Deleter>
00427 inline bool
00428 operator>=(const unique_ptr<_Tp, _Tp_Deleter>& __x,
00429 const unique_ptr<_Up, _Up_Deleter>& __y)
00430 { return !(__x.get() < __y.get()); }
00431
00432
00433
00434 _GLIBCXX_END_NAMESPACE
00435
00436 #endif