diff --git a/src/mrw/checkcxx11.hxx b/src/mrw/checkcxx11.hxx index f4899c8..26aecd7 100644 --- a/src/mrw/checkcxx11.hxx +++ b/src/mrw/checkcxx11.hxx @@ -50,15 +50,370 @@ # ifdef MRW__OLD_PRE11_COMPILER # if __cplusplus<200300L -# include -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 class shared_ptr: public boost::shared_ptr { + namespace std { + // there is no std::shared_ptr in pre C++11 compilers, so we use the + // one copied from newer gcc + template + 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 + 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 class shared_ptr : public __shared_ptr<_Tp> { + public: + constexpr shared_ptr() noexcept: __shared_ptr<_Tp>() { } + shared_ptr(const shared_ptr&) noexcept = default; + template explicit shared_ptr(_Tp1* __p) + : __shared_ptr<_Tp>(__p) { } + template + shared_ptr(_Tp1* __p, _Deleter __d) + : __shared_ptr<_Tp>(__p, __d) { } + template + shared_ptr(nullptr_t __p, _Deleter __d) + : __shared_ptr<_Tp>(__p, __d) { } + template + shared_ptr(_Tp1* __p, _Deleter __d, _Alloc __a) + : __shared_ptr<_Tp>(__p, __d, std::move(__a)) { } + template + shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a) + : __shared_ptr<_Tp>(__p, __d, std::move(__a)) { } + template + shared_ptr(const shared_ptr<_Tp1>& __r, _Tp* __p) noexcept + : __shared_ptr<_Tp>(__r, __p) { } + template::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::value>::type> + shared_ptr(shared_ptr<_Tp1>&& __r) noexcept + : __shared_ptr<_Tp>(std::move(__r)) { } + template + explicit shared_ptr(const weak_ptr<_Tp1>& __r) + : __shared_ptr<_Tp>(__r) { } + template + 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 + 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 + shared_ptr& operator=(shared_ptr<_Tp1>&& __r) noexcept { + this->__shared_ptr<_Tp>::operator=(std::move(__r)); + return *this; + } + template + shared_ptr& operator=(std::unique_ptr<_Tp1, _Del>&& __r) { + this->__shared_ptr<_Tp>::operator=(std::move(__r)); + return *this; + } + private: + template + shared_ptr(_Sp_make_shared_tag __tag, const _Alloc& __a, + _Args&&... __args) + : __shared_ptr<_Tp>(__tag, __a, + std::forward<_Args>(__args)...) { } + template + friend shared_ptr<_Tp1> + allocate_shared(const _Alloc& __a, _Args&&... __args); + }; + template + inline bool operator==(const shared_ptr<_Tp1>& __a, + const shared_ptr<_Tp2>& __b) noexcept { + return __a.get() == __b.get(); + } + template + inline bool operator==(const shared_ptr<_Tp>& __a, + nullptr_t) noexcept { + return !__a; + } + template + inline bool operator==(nullptr_t, + const shared_ptr<_Tp>& __a) noexcept { + return !__a; + } + template + inline bool operator!=(const shared_ptr<_Tp1>& __a, + const shared_ptr<_Tp2>& __b) noexcept { + return __a.get() != __b.get(); + } + template + inline bool operator!=(const shared_ptr<_Tp>& __a, + nullptr_t) noexcept { + return (bool)__a; + } + template + inline bool operator!=(nullptr_t, + const shared_ptr<_Tp>& __a) noexcept { + return (bool)__a; + } + template + 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 + inline bool + operator<(const shared_ptr<_Tp>& __a, nullptr_t) noexcept + { return std::less<_Tp*>()(__a.get(), nullptr); } + + template + inline bool + operator<(nullptr_t, const shared_ptr<_Tp>& __a) noexcept + { return std::less<_Tp*>()(nullptr, __a.get()); } + + template + inline bool + operator<=(const shared_ptr<_Tp1>& __a, + const shared_ptr<_Tp2>& __b) noexcept + { return !(__b < __a); } + + template + inline bool + operator<=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept + { return !(nullptr < __a); } + + template + inline bool + operator<=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept + { return !(__a < nullptr); } + + template + inline bool + operator>(const shared_ptr<_Tp1>& __a, + const shared_ptr<_Tp2>& __b) noexcept + { return (__b < __a); } + + template + inline bool + operator>(const shared_ptr<_Tp>& __a, nullptr_t) noexcept + { return std::less<_Tp*>()(nullptr, __a.get()); } + + template + inline bool + operator>(nullptr_t, const shared_ptr<_Tp>& __a) noexcept + { return std::less<_Tp*>()(__a.get(), nullptr); } + + template + inline bool + operator>=(const shared_ptr<_Tp1>& __a, + const shared_ptr<_Tp2>& __b) noexcept + { return !(__a < __b); } + + template + inline bool + operator>=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept + { return !(__a < nullptr); } + + template + inline bool + operator>=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept + { return !(nullptr < __a); } + + template + struct less> : public _Sp_less> + { }; + + // 20.7.2.2.8 shared_ptr specialized algorithms. + template + inline void + swap(shared_ptr<_Tp>& __a, shared_ptr<_Tp>& __b) noexcept + { __a.swap(__b); } + + // 20.7.2.2.9 shared_ptr casts. + template + inline shared_ptr<_Tp> + static_pointer_cast(const shared_ptr<_Tp1>& __r) noexcept + { return shared_ptr<_Tp>(__r, static_cast<_Tp*>(__r.get())); } + + template + inline shared_ptr<_Tp> + const_pointer_cast(const shared_ptr<_Tp1>& __r) noexcept + { return shared_ptr<_Tp>(__r, const_cast<_Tp*>(__r.get())); } + + template + 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 + class weak_ptr : public __weak_ptr<_Tp> + { public: - explicit shared_ptr(): boost::shared_ptr() {} - explicit shared_ptr(T* p): boost::shared_ptr(p) {} - }; + constexpr weak_ptr() noexcept + : __weak_ptr<_Tp>() { } + + template::value>::type> + weak_ptr(const weak_ptr<_Tp1>& __r) noexcept + : __weak_ptr<_Tp>(__r) { } + + template::value>::type> + weak_ptr(const shared_ptr<_Tp1>& __r) noexcept + : __weak_ptr<_Tp>(__r) { } + + template + weak_ptr& + operator=(const weak_ptr<_Tp1>& __r) noexcept + { + this->__weak_ptr<_Tp>::operator=(__r); + return *this; + } + + template + 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 + inline void + swap(weak_ptr<_Tp>& __a, weak_ptr<_Tp>& __b) noexcept + { __a.swap(__b); } + + + /// Primary template owner_less + template + struct owner_less; + + /// Partial specialization of owner_less for shared_ptr. + template + struct owner_less> + : public _Sp_owner_less, weak_ptr<_Tp>> + { }; + + /// Partial specialization of owner_less for weak_ptr. + template + struct owner_less> + : public _Sp_owner_less, shared_ptr<_Tp>> + { }; + + /** + * @brief Base class allowing use of member function shared_from_this. + */ + template + 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 + shared_from_this() const + { return shared_ptr(this->_M_weak_this); } + + private: + template + void + _M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const noexcept + { _M_weak_this._M_assign(__p, __n); } + + template + 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 + 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 + 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 + struct hash> + : public __hash_base> + { + size_t + operator()(const shared_ptr<_Tp>& __s) const noexcept + { return std::hash<_Tp*>()(__s.get()); } + }; // auto_ptr is deprecated in favour of unique_ptr, simulate unique_ptr template class unique_ptr: public std::auto_ptr { public: