Mercurial > foo_out_sdl
comparison foosdk/sdk/pfc/ref_counter.h @ 1:20d02a178406 default tip
*: check in everything else
yay
| author | Paper <paper@tflc.us> |
|---|---|
| date | Mon, 05 Jan 2026 02:15:46 -0500 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 0:e9bb126753e7 | 1:20d02a178406 |
|---|---|
| 1 #pragma once | |
| 2 | |
| 3 #include "traits.h" | |
| 4 #include "lockless.h" | |
| 5 #include "primitives.h" | |
| 6 | |
| 7 namespace pfc { | |
| 8 | |
| 9 class NOVTABLE refcounted_object_root | |
| 10 { | |
| 11 public: | |
| 12 void refcount_add_ref() throw() {++m_counter;} | |
| 13 void refcount_release() throw() {if (--m_counter == 0) delete this;} | |
| 14 void _refcount_release_temporary() throw() {--m_counter;}//for internal use only! | |
| 15 protected: | |
| 16 refcounted_object_root() {} | |
| 17 virtual ~refcounted_object_root() {} | |
| 18 private: | |
| 19 refcounter m_counter; | |
| 20 }; | |
| 21 | |
| 22 template<typename T> | |
| 23 class refcounted_object_ptr_t { | |
| 24 private: | |
| 25 typedef refcounted_object_ptr_t<T> t_self; | |
| 26 public: | |
| 27 inline refcounted_object_ptr_t() throw() : m_ptr(NULL) {} | |
| 28 inline refcounted_object_ptr_t(T* p_ptr) throw() : m_ptr(NULL) {copy(p_ptr);} | |
| 29 inline refcounted_object_ptr_t(const t_self & p_source) throw() : m_ptr(NULL) {copy(p_source);} | |
| 30 inline refcounted_object_ptr_t(t_self && p_source) throw() { m_ptr = p_source.m_ptr; p_source.m_ptr = NULL; } | |
| 31 | |
| 32 template<typename t_source> | |
| 33 inline refcounted_object_ptr_t(t_source * p_ptr) throw() : m_ptr(NULL) {copy(p_ptr);} | |
| 34 | |
| 35 template<typename t_source> | |
| 36 inline refcounted_object_ptr_t(const refcounted_object_ptr_t<t_source> & p_source) throw() : m_ptr(NULL) {copy(p_source);} | |
| 37 | |
| 38 inline ~refcounted_object_ptr_t() throw() {if (m_ptr != NULL) m_ptr->refcount_release();} | |
| 39 | |
| 40 template<typename t_source> | |
| 41 inline void copy(t_source * p_ptr) throw() { | |
| 42 T* torel = pfc::replace_t(m_ptr,pfc::safe_ptr_cast<T>(p_ptr)); | |
| 43 if (m_ptr != NULL) m_ptr->refcount_add_ref(); | |
| 44 if (torel != NULL) torel->refcount_release(); | |
| 45 | |
| 46 } | |
| 47 | |
| 48 template<typename t_source> | |
| 49 inline void copy(const refcounted_object_ptr_t<t_source> & p_source) throw() {copy(p_source.get_ptr());} | |
| 50 | |
| 51 | |
| 52 inline const t_self & operator=(const t_self & p_source) throw() {copy(p_source); return *this;} | |
| 53 inline const t_self & operator=(t_self && p_source) throw() {attach(p_source.detach()); return *this;} | |
| 54 inline const t_self & operator=(T * p_ptr) throw() {copy(p_ptr); return *this;} | |
| 55 | |
| 56 template<typename t_source> inline t_self & operator=(const refcounted_object_ptr_t<t_source> & p_source) throw() {copy(p_source); return *this;} | |
| 57 template<typename t_source> inline t_self & operator=(t_source * p_ptr) throw() {copy(p_ptr); return *this;} | |
| 58 | |
| 59 inline void release() throw() { | |
| 60 T * temp = pfc::replace_t(m_ptr,(T*)NULL); | |
| 61 if (temp != NULL) temp->refcount_release(); | |
| 62 } | |
| 63 | |
| 64 | |
| 65 inline T& operator*() const throw() {return *m_ptr;} | |
| 66 | |
| 67 inline T* operator->() const throw() {PFC_ASSERT(m_ptr != NULL);return m_ptr;} | |
| 68 | |
| 69 inline T* get_ptr() const throw() {return m_ptr;} | |
| 70 | |
| 71 inline bool is_valid() const throw() {return m_ptr != NULL;} | |
| 72 inline bool is_empty() const throw() {return m_ptr == NULL;} | |
| 73 | |
| 74 inline bool operator==(const t_self & p_item) const throw() {return m_ptr == p_item.get_ptr();} | |
| 75 inline bool operator!=(const t_self & p_item) const throw() {return m_ptr != p_item.get_ptr();} | |
| 76 inline bool operator>(const t_self & p_item) const throw() {return m_ptr > p_item.get_ptr();} | |
| 77 inline bool operator<(const t_self & p_item) const throw() {return m_ptr < p_item.get_ptr();} | |
| 78 | |
| 79 | |
| 80 inline T* _duplicate_ptr() const throw()//should not be used ! temporary ! | |
| 81 { | |
| 82 if (m_ptr) m_ptr->refcount_add_ref(); | |
| 83 return m_ptr; | |
| 84 } | |
| 85 | |
| 86 inline T* detach() throw() {//should not be used ! temporary ! | |
| 87 T* ret = m_ptr; | |
| 88 m_ptr = 0; | |
| 89 return ret; | |
| 90 } | |
| 91 | |
| 92 inline void attach(T * p_ptr) throw() {//should not be used ! temporary ! | |
| 93 release(); | |
| 94 m_ptr = p_ptr; | |
| 95 } | |
| 96 inline t_self & operator<<(t_self & p_source) throw() {attach(p_source.detach());return *this;} | |
| 97 inline t_self & operator>>(t_self & p_dest) throw() {p_dest.attach(detach());return *this;} | |
| 98 private: | |
| 99 T* m_ptr; | |
| 100 }; | |
| 101 | |
| 102 template<typename T> | |
| 103 class traits_t<refcounted_object_ptr_t<T> > : public traits_default { | |
| 104 public: | |
| 105 enum { realloc_safe = true, constructor_may_fail = false}; | |
| 106 }; | |
| 107 | |
| 108 }; |
