|
|
|
@ -50,370 +50,15 @@ |
|
|
|
|
|
|
|
|
|
# ifdef MRW__OLD_PRE11_COMPILER |
|
|
|
|
# if __cplusplus<200300L |
|
|
|
|
namespace std { |
|
|
|
|
// there is no std::shared_ptr in pre C++11 compilers, so we use the
|
|
|
|
|
// one copied from newer gcc
|
|
|
|
|
template<typename _Ch, typename _Tr, typename _Tp, _Lock_policy _Lp> |
|
|
|
|
inline std::basic_ostream<_Ch, _Tr>& |
|
|
|
|
operator<<(std::basic_ostream<_Ch, _Tr>& __os, |
|
|
|
|
const __shared_ptr<_Tp, _Lp>& __p) |
|
|
|
|
{ |
|
|
|
|
__os << __p.get(); |
|
|
|
|
return __os; |
|
|
|
|
} |
|
|
|
|
template<typename _Del, typename _Tp, _Lock_policy _Lp> |
|
|
|
|
inline _Del* |
|
|
|
|
get_deleter(const __shared_ptr<_Tp, _Lp>& __p) noexcept |
|
|
|
|
{ |
|
|
|
|
#ifdef __GXX_RTTI |
|
|
|
|
return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del))); |
|
|
|
|
#else |
|
|
|
|
return 0; |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
template<typename _Tp> class shared_ptr : public __shared_ptr<_Tp> { |
|
|
|
|
public: |
|
|
|
|
constexpr shared_ptr() noexcept: __shared_ptr<_Tp>() { } |
|
|
|
|
shared_ptr(const shared_ptr&) noexcept = default; |
|
|
|
|
template<typename _Tp1> explicit shared_ptr(_Tp1* __p) |
|
|
|
|
: __shared_ptr<_Tp>(__p) { } |
|
|
|
|
template<typename _Tp1, typename _Deleter> |
|
|
|
|
shared_ptr(_Tp1* __p, _Deleter __d) |
|
|
|
|
: __shared_ptr<_Tp>(__p, __d) { } |
|
|
|
|
template<typename _Deleter> |
|
|
|
|
shared_ptr(nullptr_t __p, _Deleter __d) |
|
|
|
|
: __shared_ptr<_Tp>(__p, __d) { } |
|
|
|
|
template<typename _Tp1, typename _Deleter, typename _Alloc> |
|
|
|
|
shared_ptr(_Tp1* __p, _Deleter __d, _Alloc __a) |
|
|
|
|
: __shared_ptr<_Tp>(__p, __d, std::move(__a)) { } |
|
|
|
|
template<typename _Deleter, typename _Alloc> |
|
|
|
|
shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a) |
|
|
|
|
: __shared_ptr<_Tp>(__p, __d, std::move(__a)) { } |
|
|
|
|
template<typename _Tp1> |
|
|
|
|
shared_ptr(const shared_ptr<_Tp1>& __r, _Tp* __p) noexcept |
|
|
|
|
: __shared_ptr<_Tp>(__r, __p) { } |
|
|
|
|
template<typename _Tp1, typename = typename |
|
|
|
|
std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type> |
|
|
|
|
shared_ptr(const shared_ptr<_Tp1>& __r) noexcept |
|
|
|
|
: __shared_ptr<_Tp>(__r) { } |
|
|
|
|
shared_ptr(shared_ptr&& __r) noexcept |
|
|
|
|
: __shared_ptr<_Tp>(std::move(__r)) { } |
|
|
|
|
template<typename _Tp1, typename = typename |
|
|
|
|
std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type> |
|
|
|
|
shared_ptr(shared_ptr<_Tp1>&& __r) noexcept |
|
|
|
|
: __shared_ptr<_Tp>(std::move(__r)) { } |
|
|
|
|
template<typename _Tp1> |
|
|
|
|
explicit shared_ptr(const weak_ptr<_Tp1>& __r) |
|
|
|
|
: __shared_ptr<_Tp>(__r) { } |
|
|
|
|
template<typename _Tp1, typename _Del> |
|
|
|
|
shared_ptr(std::unique_ptr<_Tp1, _Del>&& __r) |
|
|
|
|
: __shared_ptr<_Tp>(std::move(__r)) { } |
|
|
|
|
constexpr shared_ptr(nullptr_t __p) noexcept |
|
|
|
|
: __shared_ptr<_Tp>(__p) { } |
|
|
|
|
shared_ptr& operator=(const shared_ptr&) noexcept = default; |
|
|
|
|
template<typename _Tp1> |
|
|
|
|
shared_ptr& operator=(const shared_ptr<_Tp1>& __r) noexcept { |
|
|
|
|
this->__shared_ptr<_Tp>::operator=(__r); |
|
|
|
|
return *this; |
|
|
|
|
} |
|
|
|
|
shared_ptr& operator=(shared_ptr&& __r) noexcept { |
|
|
|
|
this->__shared_ptr<_Tp>::operator=(std::move(__r)); |
|
|
|
|
return *this; |
|
|
|
|
} |
|
|
|
|
template<class _Tp1> |
|
|
|
|
shared_ptr& operator=(shared_ptr<_Tp1>&& __r) noexcept { |
|
|
|
|
this->__shared_ptr<_Tp>::operator=(std::move(__r)); |
|
|
|
|
return *this; |
|
|
|
|
} |
|
|
|
|
template<typename _Tp1, typename _Del> |
|
|
|
|
shared_ptr& operator=(std::unique_ptr<_Tp1, _Del>&& __r) { |
|
|
|
|
this->__shared_ptr<_Tp>::operator=(std::move(__r)); |
|
|
|
|
return *this; |
|
|
|
|
} |
|
|
|
|
private: |
|
|
|
|
template<typename _Alloc, typename... _Args> |
|
|
|
|
shared_ptr(_Sp_make_shared_tag __tag, const _Alloc& __a, |
|
|
|
|
_Args&&... __args) |
|
|
|
|
: __shared_ptr<_Tp>(__tag, __a, |
|
|
|
|
std::forward<_Args>(__args)...) { } |
|
|
|
|
template<typename _Tp1, typename _Alloc, typename... _Args> |
|
|
|
|
friend shared_ptr<_Tp1> |
|
|
|
|
allocate_shared(const _Alloc& __a, _Args&&... __args); |
|
|
|
|
}; |
|
|
|
|
template<typename _Tp1, typename _Tp2> |
|
|
|
|
inline bool operator==(const shared_ptr<_Tp1>& __a, |
|
|
|
|
const shared_ptr<_Tp2>& __b) noexcept { |
|
|
|
|
return __a.get() == __b.get(); |
|
|
|
|
} |
|
|
|
|
template<typename _Tp> |
|
|
|
|
inline bool operator==(const shared_ptr<_Tp>& __a, |
|
|
|
|
nullptr_t) noexcept { |
|
|
|
|
return !__a; |
|
|
|
|
} |
|
|
|
|
template<typename _Tp> |
|
|
|
|
inline bool operator==(nullptr_t, |
|
|
|
|
const shared_ptr<_Tp>& __a) noexcept { |
|
|
|
|
return !__a; |
|
|
|
|
} |
|
|
|
|
template<typename _Tp1, typename _Tp2> |
|
|
|
|
inline bool operator!=(const shared_ptr<_Tp1>& __a, |
|
|
|
|
const shared_ptr<_Tp2>& __b) noexcept { |
|
|
|
|
return __a.get() != __b.get(); |
|
|
|
|
} |
|
|
|
|
template<typename _Tp> |
|
|
|
|
inline bool operator!=(const shared_ptr<_Tp>& __a, |
|
|
|
|
nullptr_t) noexcept { |
|
|
|
|
return (bool)__a; |
|
|
|
|
} |
|
|
|
|
template<typename _Tp> |
|
|
|
|
inline bool operator!=(nullptr_t, |
|
|
|
|
const shared_ptr<_Tp>& __a) noexcept { |
|
|
|
|
return (bool)__a; |
|
|
|
|
} |
|
|
|
|
template<typename _Tp1, typename _Tp2> |
|
|
|
|
inline bool operator<(const shared_ptr<_Tp1>& __a, |
|
|
|
|
const shared_ptr<_Tp2>& __b) noexcept { |
|
|
|
|
typedef typename std::common_type<_Tp1*, _Tp2*>::type _CT; |
|
|
|
|
return std::less<_CT>()(__a.get(), __b.get()); |
|
|
|
|
} |
|
|
|
|
template<typename _Tp> |
|
|
|
|
inline bool |
|
|
|
|
operator<(const shared_ptr<_Tp>& __a, nullptr_t) noexcept |
|
|
|
|
{ return std::less<_Tp*>()(__a.get(), nullptr); } |
|
|
|
|
|
|
|
|
|
template<typename _Tp> |
|
|
|
|
inline bool |
|
|
|
|
operator<(nullptr_t, const shared_ptr<_Tp>& __a) noexcept |
|
|
|
|
{ return std::less<_Tp*>()(nullptr, __a.get()); } |
|
|
|
|
|
|
|
|
|
template<typename _Tp1, typename _Tp2> |
|
|
|
|
inline bool |
|
|
|
|
operator<=(const shared_ptr<_Tp1>& __a, |
|
|
|
|
const shared_ptr<_Tp2>& __b) noexcept |
|
|
|
|
{ return !(__b < __a); } |
|
|
|
|
|
|
|
|
|
template<typename _Tp> |
|
|
|
|
inline bool |
|
|
|
|
operator<=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept |
|
|
|
|
{ return !(nullptr < __a); } |
|
|
|
|
|
|
|
|
|
template<typename _Tp> |
|
|
|
|
inline bool |
|
|
|
|
operator<=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept |
|
|
|
|
{ return !(__a < nullptr); } |
|
|
|
|
|
|
|
|
|
template<typename _Tp1, typename _Tp2> |
|
|
|
|
inline bool |
|
|
|
|
operator>(const shared_ptr<_Tp1>& __a, |
|
|
|
|
const shared_ptr<_Tp2>& __b) noexcept |
|
|
|
|
{ return (__b < __a); } |
|
|
|
|
|
|
|
|
|
template<typename _Tp> |
|
|
|
|
inline bool |
|
|
|
|
operator>(const shared_ptr<_Tp>& __a, nullptr_t) noexcept |
|
|
|
|
{ return std::less<_Tp*>()(nullptr, __a.get()); } |
|
|
|
|
|
|
|
|
|
template<typename _Tp> |
|
|
|
|
inline bool |
|
|
|
|
operator>(nullptr_t, const shared_ptr<_Tp>& __a) noexcept |
|
|
|
|
{ return std::less<_Tp*>()(__a.get(), nullptr); } |
|
|
|
|
|
|
|
|
|
template<typename _Tp1, typename _Tp2> |
|
|
|
|
inline bool |
|
|
|
|
operator>=(const shared_ptr<_Tp1>& __a, |
|
|
|
|
const shared_ptr<_Tp2>& __b) noexcept |
|
|
|
|
{ return !(__a < __b); } |
|
|
|
|
|
|
|
|
|
template<typename _Tp> |
|
|
|
|
inline bool |
|
|
|
|
operator>=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept |
|
|
|
|
{ return !(__a < nullptr); } |
|
|
|
|
|
|
|
|
|
template<typename _Tp> |
|
|
|
|
inline bool |
|
|
|
|
operator>=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept |
|
|
|
|
{ return !(nullptr < __a); } |
|
|
|
|
|
|
|
|
|
template<typename _Tp> |
|
|
|
|
struct less<shared_ptr<_Tp>> : public _Sp_less<shared_ptr<_Tp>> |
|
|
|
|
{ }; |
|
|
|
|
|
|
|
|
|
// 20.7.2.2.8 shared_ptr specialized algorithms.
|
|
|
|
|
template<typename _Tp> |
|
|
|
|
inline void |
|
|
|
|
swap(shared_ptr<_Tp>& __a, shared_ptr<_Tp>& __b) noexcept |
|
|
|
|
{ __a.swap(__b); } |
|
|
|
|
|
|
|
|
|
// 20.7.2.2.9 shared_ptr casts.
|
|
|
|
|
template<typename _Tp, typename _Tp1> |
|
|
|
|
inline shared_ptr<_Tp> |
|
|
|
|
static_pointer_cast(const shared_ptr<_Tp1>& __r) noexcept |
|
|
|
|
{ return shared_ptr<_Tp>(__r, static_cast<_Tp*>(__r.get())); } |
|
|
|
|
|
|
|
|
|
template<typename _Tp, typename _Tp1> |
|
|
|
|
inline shared_ptr<_Tp> |
|
|
|
|
const_pointer_cast(const shared_ptr<_Tp1>& __r) noexcept |
|
|
|
|
{ return shared_ptr<_Tp>(__r, const_cast<_Tp*>(__r.get())); } |
|
|
|
|
|
|
|
|
|
template<typename _Tp, typename _Tp1> |
|
|
|
|
inline shared_ptr<_Tp> |
|
|
|
|
dynamic_pointer_cast(const shared_ptr<_Tp1>& __r) noexcept |
|
|
|
|
{ |
|
|
|
|
if (_Tp* __p = dynamic_cast<_Tp*>(__r.get())) |
|
|
|
|
return shared_ptr<_Tp>(__r, __p); |
|
|
|
|
return shared_ptr<_Tp>(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief A smart pointer with weak semantics. |
|
|
|
|
* |
|
|
|
|
* With forwarding constructors and assignment operators. |
|
|
|
|
*/ |
|
|
|
|
template<typename _Tp> |
|
|
|
|
class weak_ptr : public __weak_ptr<_Tp> |
|
|
|
|
{ |
|
|
|
|
# include <boost/shared_ptr.hpp> |
|
|
|
|
namespace std { |
|
|
|
|
// there is no std::shared_ptr in pre C++11 compilers, so we use the
|
|
|
|
|
// one from the boost library as a 1:1 replacement
|
|
|
|
|
template <typename T> class shared_ptr: public boost::shared_ptr<T> { |
|
|
|
|
public: |
|
|
|
|
constexpr weak_ptr() noexcept |
|
|
|
|
: __weak_ptr<_Tp>() { } |
|
|
|
|
|
|
|
|
|
template<typename _Tp1, typename = typename |
|
|
|
|
std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type> |
|
|
|
|
weak_ptr(const weak_ptr<_Tp1>& __r) noexcept |
|
|
|
|
: __weak_ptr<_Tp>(__r) { } |
|
|
|
|
|
|
|
|
|
template<typename _Tp1, typename = typename |
|
|
|
|
std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type> |
|
|
|
|
weak_ptr(const shared_ptr<_Tp1>& __r) noexcept |
|
|
|
|
: __weak_ptr<_Tp>(__r) { } |
|
|
|
|
|
|
|
|
|
template<typename _Tp1> |
|
|
|
|
weak_ptr& |
|
|
|
|
operator=(const weak_ptr<_Tp1>& __r) noexcept |
|
|
|
|
{ |
|
|
|
|
this->__weak_ptr<_Tp>::operator=(__r); |
|
|
|
|
return *this; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
template<typename _Tp1> |
|
|
|
|
weak_ptr& |
|
|
|
|
operator=(const shared_ptr<_Tp1>& __r) noexcept |
|
|
|
|
{ |
|
|
|
|
this->__weak_ptr<_Tp>::operator=(__r); |
|
|
|
|
return *this; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
shared_ptr<_Tp> |
|
|
|
|
lock() const noexcept |
|
|
|
|
{ |
|
|
|
|
#ifdef __GTHREADS |
|
|
|
|
if (this->expired()) |
|
|
|
|
return shared_ptr<_Tp>(); |
|
|
|
|
|
|
|
|
|
__try |
|
|
|
|
{ |
|
|
|
|
return shared_ptr<_Tp>(*this); |
|
|
|
|
} |
|
|
|
|
__catch(const bad_weak_ptr&) |
|
|
|
|
{ |
|
|
|
|
return shared_ptr<_Tp>(); |
|
|
|
|
} |
|
|
|
|
#else |
|
|
|
|
return this->expired() ? shared_ptr<_Tp>() : shared_ptr<_Tp>(*this); |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// 20.7.2.3.6 weak_ptr specialized algorithms.
|
|
|
|
|
template<typename _Tp> |
|
|
|
|
inline void |
|
|
|
|
swap(weak_ptr<_Tp>& __a, weak_ptr<_Tp>& __b) noexcept |
|
|
|
|
{ __a.swap(__b); } |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Primary template owner_less
|
|
|
|
|
template<typename _Tp> |
|
|
|
|
struct owner_less; |
|
|
|
|
|
|
|
|
|
/// Partial specialization of owner_less for shared_ptr.
|
|
|
|
|
template<typename _Tp> |
|
|
|
|
struct owner_less<shared_ptr<_Tp>> |
|
|
|
|
: public _Sp_owner_less<shared_ptr<_Tp>, weak_ptr<_Tp>> |
|
|
|
|
{ }; |
|
|
|
|
|
|
|
|
|
/// Partial specialization of owner_less for weak_ptr.
|
|
|
|
|
template<typename _Tp> |
|
|
|
|
struct owner_less<weak_ptr<_Tp>> |
|
|
|
|
: public _Sp_owner_less<weak_ptr<_Tp>, shared_ptr<_Tp>> |
|
|
|
|
{ }; |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Base class allowing use of member function shared_from_this. |
|
|
|
|
*/ |
|
|
|
|
template<typename _Tp> |
|
|
|
|
class enable_shared_from_this |
|
|
|
|
{ |
|
|
|
|
protected: |
|
|
|
|
constexpr enable_shared_from_this() noexcept { } |
|
|
|
|
|
|
|
|
|
enable_shared_from_this(const enable_shared_from_this&) noexcept { } |
|
|
|
|
|
|
|
|
|
enable_shared_from_this& |
|
|
|
|
operator=(const enable_shared_from_this&) noexcept |
|
|
|
|
{ return *this; } |
|
|
|
|
|
|
|
|
|
~enable_shared_from_this() { } |
|
|
|
|
|
|
|
|
|
public: |
|
|
|
|
shared_ptr<_Tp> |
|
|
|
|
shared_from_this() |
|
|
|
|
{ return shared_ptr<_Tp>(this->_M_weak_this); } |
|
|
|
|
|
|
|
|
|
shared_ptr<const _Tp> |
|
|
|
|
shared_from_this() const |
|
|
|
|
{ return shared_ptr<const _Tp>(this->_M_weak_this); } |
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
template<typename _Tp1> |
|
|
|
|
void |
|
|
|
|
_M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const noexcept |
|
|
|
|
{ _M_weak_this._M_assign(__p, __n); } |
|
|
|
|
|
|
|
|
|
template<typename _Tp1> |
|
|
|
|
friend void |
|
|
|
|
__enable_shared_from_this_helper(const __shared_count<>& __pn, |
|
|
|
|
const enable_shared_from_this* __pe, |
|
|
|
|
const _Tp1* __px) noexcept |
|
|
|
|
{ |
|
|
|
|
if (__pe != 0) |
|
|
|
|
__pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
mutable weak_ptr<_Tp> _M_weak_this; |
|
|
|
|
}; |
|
|
|
|
template<typename _Tp, typename _Alloc, typename... _Args> |
|
|
|
|
inline shared_ptr<_Tp> |
|
|
|
|
allocate_shared(const _Alloc& __a, _Args&&... __args) |
|
|
|
|
{ |
|
|
|
|
return shared_ptr<_Tp>(_Sp_make_shared_tag(), __a, |
|
|
|
|
std::forward<_Args>(__args)...); |
|
|
|
|
} |
|
|
|
|
template<typename _Tp, typename... _Args> |
|
|
|
|
inline shared_ptr<_Tp> |
|
|
|
|
make_shared(_Args&&... __args) |
|
|
|
|
{ |
|
|
|
|
typedef typename std::remove_const<_Tp>::type _Tp_nc; |
|
|
|
|
return std::allocate_shared<_Tp>(std::allocator<_Tp_nc>(), |
|
|
|
|
std::forward<_Args>(__args)...); |
|
|
|
|
} |
|
|
|
|
template<typename _Tp> |
|
|
|
|
struct hash<shared_ptr<_Tp>> |
|
|
|
|
: public __hash_base<size_t, shared_ptr<_Tp>> |
|
|
|
|
{ |
|
|
|
|
size_t |
|
|
|
|
operator()(const shared_ptr<_Tp>& __s) const noexcept |
|
|
|
|
{ return std::hash<_Tp*>()(__s.get()); } |
|
|
|
|
}; |
|
|
|
|
explicit shared_ptr(): boost::shared_ptr<T>() {} |
|
|
|
|
explicit shared_ptr(T* p): boost::shared_ptr<T>(p) {} |
|
|
|
|
}; |
|
|
|
|
// auto_ptr is deprecated in favour of unique_ptr, simulate unique_ptr
|
|
|
|
|
template <typename T> class unique_ptr: public std::auto_ptr<T> { |
|
|
|
|
public: |
|
|
|
|