#ifndef DYNINST_DYNCOMPAT_SHARED_PTR_HPP #define DYNINST_DYNCOMPAT_SHARED_PTR_HPP #include #include #include #include #ifndef DYNCOMPAT_NOEXCEPT #define DYNCOMPAT_NOEXCEPT noexcept #endif namespace dyncompat { template void checked_delete(T* ptr) DYNCOMPAT_NOEXCEPT; template class shared_ptr : public std::shared_ptr { using base = std::shared_ptr; public: using element_type = typename base::element_type; shared_ptr() DYNCOMPAT_NOEXCEPT = default; shared_ptr(std::nullptr_t) DYNCOMPAT_NOEXCEPT : base(nullptr) {} shared_ptr(const shared_ptr&) DYNCOMPAT_NOEXCEPT = default; shared_ptr(shared_ptr&&) DYNCOMPAT_NOEXCEPT = default; template >> shared_ptr(Integer value) : base(nullptr) { assert(value == 0); (void)value; } shared_ptr(const base& other) DYNCOMPAT_NOEXCEPT : base(other) {} shared_ptr(base&& other) DYNCOMPAT_NOEXCEPT : base(std::move(other)) {} template shared_ptr(const shared_ptr& other) DYNCOMPAT_NOEXCEPT : base(other) {} template shared_ptr(shared_ptr&& other) DYNCOMPAT_NOEXCEPT : base(std::move(other)) {} explicit shared_ptr(T* ptr) : base(ptr, &dyncompat::checked_delete) {} template explicit shared_ptr(U* ptr) : base(ptr, &dyncompat::checked_delete) {} template shared_ptr(U* ptr, Deleter deleter) : base(ptr, deleter) {} template shared_ptr(U* ptr, Deleter deleter, Allocator alloc) : base(ptr, deleter, alloc) {} template explicit shared_ptr(const std::weak_ptr& other) : base(other) {} template shared_ptr(const shared_ptr& other, T* ptr) DYNCOMPAT_NOEXCEPT : base(other, ptr) {} shared_ptr& operator=(const shared_ptr&) DYNCOMPAT_NOEXCEPT = default; shared_ptr& operator=(shared_ptr&&) DYNCOMPAT_NOEXCEPT = default; template >> shared_ptr& operator=(Integer value) { assert(value == 0); (void)value; base::reset(); return *this; } shared_ptr& operator=(const base& other) DYNCOMPAT_NOEXCEPT { base::operator=(other); return *this; } shared_ptr& operator=(base&& other) DYNCOMPAT_NOEXCEPT { base::operator=(std::move(other)); return *this; } template shared_ptr& operator=(const shared_ptr& other) DYNCOMPAT_NOEXCEPT { base::operator=(other); return *this; } template shared_ptr& operator=(shared_ptr&& other) DYNCOMPAT_NOEXCEPT { base::operator=(std::move(other)); return *this; } void reset() DYNCOMPAT_NOEXCEPT { base::reset(); } template void reset(U* ptr) { base::reset(ptr, &dyncompat::checked_delete); } template void reset(U* ptr, Deleter deleter) { base::reset(ptr, deleter); } template void reset(U* ptr, Deleter deleter, Allocator alloc) { base::reset(ptr, deleter, alloc); } }; template class weak_ptr : public std::weak_ptr { using base = std::weak_ptr; public: weak_ptr() DYNCOMPAT_NOEXCEPT = default; weak_ptr(const weak_ptr&) DYNCOMPAT_NOEXCEPT = default; weak_ptr(weak_ptr&&) DYNCOMPAT_NOEXCEPT = default; weak_ptr(const base& other) DYNCOMPAT_NOEXCEPT : base(other) {} weak_ptr(base&& other) DYNCOMPAT_NOEXCEPT : base(std::move(other)) {} template weak_ptr(const shared_ptr& other) DYNCOMPAT_NOEXCEPT : base(other) {} template weak_ptr(const weak_ptr& other) DYNCOMPAT_NOEXCEPT : base(other) {} weak_ptr& operator=(const weak_ptr&) DYNCOMPAT_NOEXCEPT = default; weak_ptr& operator=(weak_ptr&&) DYNCOMPAT_NOEXCEPT = default; weak_ptr& operator=(const base& other) DYNCOMPAT_NOEXCEPT { base::operator=(other); return *this; } weak_ptr& operator=(base&& other) DYNCOMPAT_NOEXCEPT { base::operator=(std::move(other)); return *this; } template weak_ptr& operator=(const shared_ptr& other) DYNCOMPAT_NOEXCEPT { base::operator=(other); return *this; } template weak_ptr& operator=(const weak_ptr& other) DYNCOMPAT_NOEXCEPT { base::operator=(other); return *this; } shared_ptr lock() const DYNCOMPAT_NOEXCEPT { return shared_ptr(base::lock()); } }; template class enable_shared_from_this : public std::enable_shared_from_this { public: shared_ptr shared_from_this() { return shared_ptr(std::enable_shared_from_this::shared_from_this()); } shared_ptr shared_from_this() const { return shared_ptr(std::enable_shared_from_this::shared_from_this()); } weak_ptr weak_from_this() DYNCOMPAT_NOEXCEPT { return std::enable_shared_from_this::weak_from_this(); } weak_ptr weak_from_this() const DYNCOMPAT_NOEXCEPT { return std::enable_shared_from_this::weak_from_this(); } }; template shared_ptr const_pointer_cast(const shared_ptr& ptr) DYNCOMPAT_NOEXCEPT { return shared_ptr(std::const_pointer_cast(static_cast&>(ptr))); } template shared_ptr dynamic_pointer_cast(const shared_ptr& ptr) DYNCOMPAT_NOEXCEPT { return shared_ptr(std::dynamic_pointer_cast(static_cast&>(ptr))); } template shared_ptr reinterpret_pointer_cast(const shared_ptr& ptr) DYNCOMPAT_NOEXCEPT { return shared_ptr(std::reinterpret_pointer_cast(static_cast&>(ptr))); } template shared_ptr static_pointer_cast(const shared_ptr& ptr) DYNCOMPAT_NOEXCEPT { return shared_ptr(std::static_pointer_cast(static_cast&>(ptr))); } template void checked_delete(T* ptr) DYNCOMPAT_NOEXCEPT { delete ptr; } } // namespace dyncompat #endif