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