#include <string>#include <thread>#include <iostream>#include <type_traits>#include <cxxabi.h>#include <memory>#define OPENVPN_RC_DEBUG#if defined(_MSC_VER) && defined(_M_X64) typedef long long olong; typedef unsigned long long oulong;#else typedef long olong; typedef unsigned long oulong;#endifinline std::string cxx_demangle(const char *mangled_name){ int status; std::unique_ptr<char[]> realname; realname.reset(abi::__cxa_demangle(mangled_name, 0, 0, &status)); if (!status) return std::string(realname.get()); else return "DEMANGLE_ERROR";}template <typename R>inline void intrusive_ptr_add_ref(R *p) noexcept{#ifdef OPENVPN_RC_DEBUG std::cout << "ADD REF " << cxx_demangle(typeid(p).name()) << std::endl;#endif ++p->refcount_;}template <typename R>inline void intrusive_ptr_release(R *p) noexcept{ if (--p->refcount_ == 0) {#ifdef OPENVPN_RC_DEBUG std::cout << "DEL OBJ " << cxx_demangle(typeid(p).name()) << std::endl;#endif delete p; } else {#ifdef OPENVPN_RC_DEBUG std::cout << "REL REF " << cxx_demangle(typeid(p).name()) << std::endl;#endif }}class thread_unsafe_refcount{public: thread_unsafe_refcount() noexcept : rc(olong(0)) { } void operator++() noexcept { ++rc; } olong operator--() noexcept { return --rc; } bool inc_if_nonzero() noexcept { if (rc) { ++rc; return true; } else return false; } olong use_count() const noexcept { return rc; } static constexpr bool is_thread_safe() { return false; }private: thread_unsafe_refcount(const thread_unsafe_refcount&) = delete; thread_unsafe_refcount& operator=(const thread_unsafe_refcount&) = delete; olong rc;};// The smart pointer classtemplate <typename T>class RCPtr{public: typedef T element_type; RCPtr() noexcept : px(nullptr) { } RCPtr(T* p, const bool add_ref=true) noexcept : px(p) { if (px && add_ref) intrusive_ptr_add_ref(px); } RCPtr(const RCPtr& rhs) noexcept : px(rhs.px) { if (px) intrusive_ptr_add_ref(px); } RCPtr(RCPtr&& rhs) noexcept : px(rhs.px) { rhs.px = nullptr; } template <typename U> RCPtr(const RCPtr<U>& rhs) noexcept : px(rhs.get()) { if (px) intrusive_ptr_add_ref(px); } ~RCPtr() { if (px) intrusive_ptr_release(px); } RCPtr& operator=(const RCPtr& rhs) noexcept { RCPtr(rhs).swap(*this); return *this; } RCPtr& operator=(RCPtr&& rhs) noexcept { RCPtr(std::move(rhs)).swap(*this); return *this; } void reset() noexcept { RCPtr().swap(*this); } void reset(T* rhs) noexcept { RCPtr(rhs).swap(*this); } void swap(RCPtr& rhs) noexcept { std::swap(px, rhs.px); } T* get() const noexcept { return px; } T& operator*() const noexcept { return *px; } T* operator->() const noexcept { return px; } explicit operator bool() const noexcept { return px != nullptr; } bool operator==(const RCPtr& rhs) const { return px == rhs.px; } bool operator!=(const RCPtr& rhs) const { return px != rhs.px; } template <typename U> RCPtr<U> static_pointer_cast() const noexcept { return RCPtr<U>(static_cast<U*>(px)); } template <typename U> RCPtr<U> dynamic_pointer_cast() const noexcept { return RCPtr<U>(dynamic_cast<U*>(px)); }private: T* px;};// Reference count base class for objects tracked by RCPtr.// Disallows copying and assignment.template <typename RCImpl> // RCImpl = thread_safe_refcount or thread_unsafe_refcountclass RC{public: typedef RCPtr<RC> Ptr; RC() noexcept {} virtual ~RC() {} olong use_count() const noexcept { return refcount_.use_count(); } static constexpr bool is_thread_safe() { return RCImpl::is_thread_safe(); }private: RC(const RC&) = delete; RC& operator=(const RC&) = delete; template <typename R> friend void intrusive_ptr_add_ref(R* p) noexcept; template <typename R> friend void intrusive_ptr_release(R* p) noexcept; RCImpl refcount_;};class Monster : public RC<thread_unsafe_refcount> { std::string name; int blood;public: typedef RCPtr<Monster> Ptr; Monster(std::string n, int b=100) : name(n), blood(b) {} void fight(int n) {blood-=n;}};int main(int argc, char* argv[]) { Monster::Ptr m_p(new Monster("vampire")); std::cout << m_p->use_count() << std::endl; Monster::Ptr m_p2 = m_p; //RCPtr<Monster> m1_p(&m1); return 0;}