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