#pragma once #include #include #include namespace extra2d { // ============================================================================ // 侵入式智能指针 // 参考 Cocos2d-x 的 IntrusivePtr 设计 // ============================================================================ template class IntrusivePtr { public: using element_type = T; // 默认构造函数 IntrusivePtr() : _ptr(nullptr) {} // 从原始指针构造 IntrusivePtr(T* p) : _ptr(p) { if (_ptr) { _ptr->addRef(); } } // 拷贝构造函数 IntrusivePtr(const IntrusivePtr& r) : _ptr(r._ptr) { if (_ptr) { _ptr->addRef(); } } // 从派生类拷贝构造 template IntrusivePtr(const IntrusivePtr& r) : _ptr(r.get()) { if (_ptr) { _ptr->addRef(); } } // 移动构造函数 IntrusivePtr(IntrusivePtr&& r) noexcept : _ptr(r.release()) {} // 从派生类移动构造 template IntrusivePtr(IntrusivePtr&& r) noexcept : _ptr(r.release()) {} // 析构函数 ~IntrusivePtr() { if (_ptr) { _ptr->release(); } } // 获取原始指针 T* get() const { return _ptr; } // 解引用操作符 T& operator*() const { return *_ptr; } // 箭头操作符 T* operator->() const { return _ptr; } // 转换为原始指针(隐式转换) operator T*() const { return _ptr; } // 赋值操作符 - 原始指针 IntrusivePtr& operator=(T* p) { reset(p); return *this; } // 赋值操作符 - 同类型 IntrusivePtr& operator=(const IntrusivePtr& r) { return *this = r._ptr; } // 赋值操作符 - 派生类 template IntrusivePtr& operator=(const IntrusivePtr& r) { return *this = r.get(); } // 移动赋值 IntrusivePtr& operator=(IntrusivePtr&& r) noexcept { IntrusivePtr(std::move(r)).swap(*this); return *this; } // 从派生类移动赋值 template IntrusivePtr& operator=(IntrusivePtr&& r) noexcept { IntrusivePtr(std::move(r)).swap(*this); return *this; } // 比较操作符 bool operator==(std::nullptr_t) const { return _ptr == nullptr; } bool operator==(T* r) const { return _ptr == r; } bool operator!=(std::nullptr_t) const { return _ptr != nullptr; } bool operator!=(T* r) const { return _ptr != r; } bool operator<(const IntrusivePtr& r) const { return _ptr < r._ptr; } // 重置指针 void reset() noexcept { if (_ptr) { _ptr->release(); } _ptr = nullptr; } void reset(T* p) { // 先增加新指针的引用计数,再释放旧指针 // 这样可以处理自赋值的情况 if (p) { p->addRef(); } if (_ptr) { _ptr->release(); } _ptr = p; } // 交换指针 void swap(T** pp) noexcept { T* p = _ptr; _ptr = *pp; *pp = p; } void swap(IntrusivePtr& r) noexcept { swap(&r._ptr); } // 释放指针所有权(不减少引用计数) T* release() { T* retVal = _ptr; _ptr = nullptr; return retVal; } private: T* _ptr; }; // ============================================================================ // 辅助函数 // ============================================================================ // 创建 IntrusivePtr 的便捷函数 template inline IntrusivePtr makePtr(Args&&... args) { return IntrusivePtr(new T(std::forward(args)...)); } } // namespace extra2d // ============================================================================ // std::hash 特化 // ============================================================================ namespace std { template struct hash> { size_t operator()(const extra2d::IntrusivePtr& val) const noexcept { return hash{}(val.get()); } }; } // namespace std