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