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
00085
00086 class _Pointer
00087 {
00088 template<typename _Up>
00089 static typename _Up::pointer __test(typename _Up::pointer*);
00090
00091 template<typename _Up>
00092 static _Tp* __test(...);
00093
00094 typedef typename remove_reference<_Tp_Deleter>::type _Del;
00095
00096 public:
00097 typedef decltype( __test<_Del>(0) ) type;
00098 };
00099
00100 public:
00101 typedef typename _Pointer::type pointer;
00102 typedef _Tp element_type;
00103 typedef _Tp_Deleter deleter_type;
00104
00105
00106 unique_ptr()
00107 : _M_t(pointer(), deleter_type())
00108 { static_assert(!std::is_pointer<deleter_type>::value,
00109 "constructed with null function pointer deleter"); }
00110
00111 explicit
00112 unique_ptr(pointer __p)
00113 : _M_t(__p, deleter_type())
00114 { static_assert(!std::is_pointer<deleter_type>::value,
00115 "constructed with null function pointer deleter"); }
00116
00117 unique_ptr(pointer __p,
00118 typename std::conditional<std::is_reference<deleter_type>::value,
00119 deleter_type, const deleter_type&>::type __d)
00120 : _M_t(__p, __d) { }
00121
00122 unique_ptr(pointer __p,
00123 typename std::remove_reference<deleter_type>::type&& __d)
00124 : _M_t(std::move(__p), std::move(__d))
00125 { static_assert(!std::is_reference<deleter_type>::value,
00126 "rvalue deleter bound to reference"); }
00127
00128 unique_ptr(nullptr_t)
00129 : _M_t(pointer(), deleter_type())
00130 { }
00131
00132
00133 unique_ptr(unique_ptr&& __u)
00134 : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter())) { }
00135
00136 template<typename _Up, typename _Up_Deleter>
00137 unique_ptr(unique_ptr<_Up, _Up_Deleter>&& __u)
00138 : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter()))
00139 { }
00140
00141
00142 ~unique_ptr() { reset(); }
00143
00144
00145 unique_ptr&
00146 operator=(unique_ptr&& __u)
00147 {
00148 reset(__u.release());
00149 get_deleter() = std::move(__u.get_deleter());
00150 return *this;
00151 }
00152
00153 template<typename _Up, typename _Up_Deleter>
00154 unique_ptr&
00155 operator=(unique_ptr<_Up, _Up_Deleter>&& __u)
00156 {
00157 reset(__u.release());
00158 get_deleter() = std::move(__u.get_deleter());
00159 return *this;
00160 }
00161
00162 unique_ptr&
00163 operator=(nullptr_t)
00164 {
00165 reset();
00166 return *this;
00167 }
00168
00169
00170 typename std::add_lvalue_reference<element_type>::type
00171 operator*() const
00172 {
00173 _GLIBCXX_DEBUG_ASSERT(get() != pointer());
00174 return *get();
00175 }
00176
00177 pointer
00178 operator->() const
00179 {
00180 _GLIBCXX_DEBUG_ASSERT(get() != pointer());
00181 return get();
00182 }
00183
00184 pointer
00185 get() const
00186 { return std::get<0>(_M_t); }
00187
00188 deleter_type&
00189 get_deleter()
00190 { return std::get<1>(_M_t); }
00191
00192 const deleter_type&
00193 get_deleter() const
00194 { return std::get<1>(_M_t); }
00195
00196 explicit operator bool() const
00197 { return get() == pointer() ? false : true; }
00198
00199
00200 pointer
00201 release()
00202 {
00203 pointer __p = get();
00204 std::get<0>(_M_t) = pointer();
00205 return __p;
00206 }
00207
00208 void
00209 reset(pointer __p = pointer())
00210 {
00211 using std::swap;
00212 swap(std::get<0>(_M_t), __p);
00213 if (__p != pointer())
00214 get_deleter()(__p);
00215 }
00216
00217 void
00218 swap(unique_ptr& __u)
00219 {
00220 using std::swap;
00221 swap(_M_t, __u._M_t);
00222 }
00223
00224
00225 unique_ptr(const unique_ptr&) = delete;
00226 unique_ptr& operator=(const unique_ptr&) = delete;
00227
00228 private:
00229 __tuple_type _M_t;
00230 };
00231
00232
00233
00234
00235
00236 template<typename _Tp, typename _Tp_Deleter>
00237 class unique_ptr<_Tp[], _Tp_Deleter>
00238 {
00239 typedef std::tuple<_Tp*, _Tp_Deleter> __tuple_type;
00240
00241 public:
00242 typedef _Tp* pointer;
00243 typedef _Tp element_type;
00244 typedef _Tp_Deleter deleter_type;
00245
00246
00247 unique_ptr()
00248 : _M_t(pointer(), deleter_type())
00249 { static_assert(!std::is_pointer<deleter_type>::value,
00250 "constructed with null function pointer deleter"); }
00251
00252 explicit
00253 unique_ptr(pointer __p)
00254 : _M_t(__p, deleter_type())
00255 { static_assert(!std::is_pointer<deleter_type>::value,
00256 "constructed with null function pointer deleter"); }
00257
00258 unique_ptr(pointer __p,
00259 typename std::conditional<std::is_reference<deleter_type>::value,
00260 deleter_type, const deleter_type&>::type __d)
00261 : _M_t(__p, __d) { }
00262
00263 unique_ptr(pointer __p,
00264 typename std::remove_reference<deleter_type>::type && __d)
00265 : _M_t(std::move(__p), std::move(__d))
00266 { static_assert(!std::is_reference<deleter_type>::value,
00267 "rvalue deleter bound to reference"); }
00268
00269
00270 unique_ptr(nullptr_t)
00271 : _M_t(pointer(), deleter_type())
00272 { }
00273
00274
00275 unique_ptr(unique_ptr&& __u)
00276 : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter())) { }
00277
00278 template<typename _Up, typename _Up_Deleter>
00279 unique_ptr(unique_ptr<_Up, _Up_Deleter>&& __u)
00280 : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter()))
00281 { }
00282
00283
00284 ~unique_ptr() { reset(); }
00285
00286
00287 unique_ptr&
00288 operator=(unique_ptr&& __u)
00289 {
00290 reset(__u.release());
00291 get_deleter() = std::move(__u.get_deleter());
00292 return *this;
00293 }
00294
00295 template<typename _Up, typename _Up_Deleter>
00296 unique_ptr&
00297 operator=(unique_ptr<_Up, _Up_Deleter>&& __u)
00298 {
00299 reset(__u.release());
00300 get_deleter() = std::move(__u.get_deleter());
00301 return *this;
00302 }
00303
00304 unique_ptr&
00305 operator=(nullptr_t)
00306 {
00307 reset();
00308 return *this;
00309 }
00310
00311
00312 typename std::add_lvalue_reference<element_type>::type
00313 operator[](size_t __i) const
00314 {
00315 _GLIBCXX_DEBUG_ASSERT(get() != pointer());
00316 return get()[__i];
00317 }
00318
00319 pointer
00320 get() const
00321 { return std::get<0>(_M_t); }
00322
00323 deleter_type&
00324 get_deleter()
00325 { return std::get<1>(_M_t); }
00326
00327 const deleter_type&
00328 get_deleter() const
00329 { return std::get<1>(_M_t); }
00330
00331 explicit operator bool() const
00332 { return get() == pointer() ? false : true; }
00333
00334
00335 pointer
00336 release()
00337 {
00338 pointer __p = get();
00339 std::get<0>(_M_t) = pointer();
00340 return __p;
00341 }
00342
00343 void
00344 reset(pointer __p = pointer())
00345 {
00346 using std::swap;
00347 swap(std::get<0>(_M_t), __p);
00348 if (__p != nullptr)
00349 get_deleter()(__p);
00350 }
00351
00352 void
00353 reset(nullptr_t)
00354 {
00355 pointer __p = get();
00356 std::get<0>(_M_t) = pointer();
00357 if (__p != nullptr)
00358 get_deleter()(__p);
00359 }
00360
00361
00362 template<typename _Up>
00363 void reset(_Up) = delete;
00364
00365 void
00366 swap(unique_ptr& __u)
00367 {
00368 using std::swap;
00369 swap(_M_t, __u._M_t);
00370 }
00371
00372
00373 unique_ptr(const unique_ptr&) = delete;
00374 unique_ptr& operator=(const unique_ptr&) = delete;
00375
00376
00377
00378 template<typename _Up>
00379 unique_ptr(_Up*, typename
00380 std::conditional<std::is_reference<deleter_type>::value,
00381 deleter_type, const deleter_type&>::type,
00382 typename std::enable_if<std::is_convertible<_Up*,
00383 pointer>::value>::type* = 0) = delete;
00384
00385 template<typename _Up>
00386 unique_ptr(_Up*, typename std::remove_reference<deleter_type>::type&&,
00387 typename std::enable_if<std::is_convertible<_Up*,
00388 pointer>::value>::type* = 0) = delete;
00389
00390 template<typename _Up>
00391 explicit
00392 unique_ptr(_Up*, typename std::enable_if<std::is_convertible<_Up*,
00393 pointer>::value>::type* = 0) = delete;
00394
00395 private:
00396 __tuple_type _M_t;
00397 };
00398
00399 template<typename _Tp, typename _Tp_Deleter>
00400 inline void
00401 swap(unique_ptr<_Tp, _Tp_Deleter>& __x,
00402 unique_ptr<_Tp, _Tp_Deleter>& __y)
00403 { __x.swap(__y); }
00404
00405 template<typename _Tp, typename _Tp_Deleter,
00406 typename _Up, typename _Up_Deleter>
00407 inline bool
00408 operator==(const unique_ptr<_Tp, _Tp_Deleter>& __x,
00409 const unique_ptr<_Up, _Up_Deleter>& __y)
00410 { return __x.get() == __y.get(); }
00411
00412 template<typename _Tp, typename _Tp_Deleter,
00413 typename _Up, typename _Up_Deleter>
00414 inline bool
00415 operator!=(const unique_ptr<_Tp, _Tp_Deleter>& __x,
00416 const unique_ptr<_Up, _Up_Deleter>& __y)
00417 { return !(__x.get() == __y.get()); }
00418
00419 template<typename _Tp, typename _Tp_Deleter,
00420 typename _Up, typename _Up_Deleter>
00421 inline bool
00422 operator<(const unique_ptr<_Tp, _Tp_Deleter>& __x,
00423 const unique_ptr<_Up, _Up_Deleter>& __y)
00424 { return __x.get() < __y.get(); }
00425
00426 template<typename _Tp, typename _Tp_Deleter,
00427 typename _Up, typename _Up_Deleter>
00428 inline bool
00429 operator<=(const unique_ptr<_Tp, _Tp_Deleter>& __x,
00430 const unique_ptr<_Up, _Up_Deleter>& __y)
00431 { return !(__y.get() < __x.get()); }
00432
00433 template<typename _Tp, typename _Tp_Deleter,
00434 typename _Up, typename _Up_Deleter>
00435 inline bool
00436 operator>(const unique_ptr<_Tp, _Tp_Deleter>& __x,
00437 const unique_ptr<_Up, _Up_Deleter>& __y)
00438 { return __y.get() < __x.get(); }
00439
00440 template<typename _Tp, typename _Tp_Deleter,
00441 typename _Up, typename _Up_Deleter>
00442 inline bool
00443 operator>=(const unique_ptr<_Tp, _Tp_Deleter>& __x,
00444 const unique_ptr<_Up, _Up_Deleter>& __y)
00445 { return !(__x.get() < __y.get()); }
00446
00447
00448 template<typename _Tp, typename _Tp_Deleter>
00449 struct hash<unique_ptr<_Tp, _Tp_Deleter>>
00450 : public std::unary_function<unique_ptr<_Tp, _Tp_Deleter>, size_t>
00451 {
00452 size_t
00453 operator()(const unique_ptr<_Tp, _Tp_Deleter>& __u) const
00454 {
00455 typedef unique_ptr<_Tp, _Tp_Deleter> _UP;
00456 return std::hash<typename _UP::pointer>()(__u.get());
00457 }
00458 };
00459
00460
00461
00462 _GLIBCXX_END_NAMESPACE
00463
00464 #endif