Mercurial > foo_out_sdl
comparison foosdk/sdk/pfc/rcptr.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 namespace pfc { | |
| 4 | |
| 5 struct _rcptr_null; | |
| 6 typedef _rcptr_null* t_rcptr_null; | |
| 7 | |
| 8 static const t_rcptr_null rcptr_null = NULL; | |
| 9 | |
| 10 class rc_container_base { | |
| 11 public: | |
| 12 long add_ref() throw() { | |
| 13 return ++m_counter; | |
| 14 } | |
| 15 long release() throw() { | |
| 16 long ret = --m_counter; | |
| 17 if (ret == 0) PFC_ASSERT_NO_EXCEPTION( delete this ); | |
| 18 return ret; | |
| 19 } | |
| 20 protected: | |
| 21 virtual ~rc_container_base() {} | |
| 22 private: | |
| 23 refcounter m_counter; | |
| 24 }; | |
| 25 | |
| 26 template<typename t_object> | |
| 27 class rc_container_t : public rc_container_base { | |
| 28 public: | |
| 29 template<typename ... arg_t> | |
| 30 rc_container_t(arg_t && ... arg) : m_object(std::forward<arg_t>(arg) ...) {} | |
| 31 | |
| 32 t_object m_object; | |
| 33 }; | |
| 34 | |
| 35 template<typename t_object> | |
| 36 class rcptr_t { | |
| 37 private: | |
| 38 typedef rcptr_t<t_object> t_self; | |
| 39 typedef rc_container_base t_container; | |
| 40 typedef rc_container_t<t_object> t_container_impl; | |
| 41 public: | |
| 42 rcptr_t(t_rcptr_null) throw() {_clear();} | |
| 43 rcptr_t() throw() {_clear();} | |
| 44 rcptr_t(const t_self & p_source) throw() {__init(p_source);} | |
| 45 t_self const & operator=(const t_self & p_source) throw() {__copy(p_source); return *this;} | |
| 46 | |
| 47 template<typename t_source> | |
| 48 rcptr_t(const rcptr_t<t_source> & p_source) throw() {__init(p_source);} | |
| 49 template<typename t_source> | |
| 50 const t_self & operator=(const rcptr_t<t_source> & p_source) throw() {__copy(p_source); return *this;} | |
| 51 | |
| 52 rcptr_t(t_self && p_source) throw() {_move(p_source);} | |
| 53 const t_self & operator=(t_self && p_source) throw() {release(); _move(p_source); return *this;} | |
| 54 | |
| 55 const t_self & operator=(t_rcptr_null) throw() {release(); return *this;} | |
| 56 | |
| 57 /* template<typename t_object_cast> | |
| 58 operator rcptr_t<t_object_cast>() const throw() { | |
| 59 rcptr_t<t_object_cast> temp; | |
| 60 if (is_valid()) temp.__set_from_cast(this->m_container,this->m_ptr); | |
| 61 return temp; | |
| 62 }*/ | |
| 63 | |
| 64 | |
| 65 template<typename t_other> | |
| 66 bool operator==(const rcptr_t<t_other> & p_other) const throw() { | |
| 67 return m_container == p_other.__container(); | |
| 68 } | |
| 69 | |
| 70 template<typename t_other> | |
| 71 bool operator!=(const rcptr_t<t_other> & p_other) const throw() { | |
| 72 return m_container != p_other.__container(); | |
| 73 } | |
| 74 | |
| 75 void __set_from_cast(t_container * p_container,t_object * p_ptr) throw() { | |
| 76 //addref first because in rare cases this is the same pointer as the one we currently own | |
| 77 if (p_container != NULL) p_container->add_ref(); | |
| 78 release(); | |
| 79 m_container = p_container; | |
| 80 m_ptr = p_ptr; | |
| 81 } | |
| 82 | |
| 83 bool is_valid() const throw() {return m_container != NULL;} | |
| 84 bool is_empty() const throw() {return m_container == NULL;} | |
| 85 | |
| 86 | |
| 87 ~rcptr_t() throw() {release();} | |
| 88 | |
| 89 void release() throw() { | |
| 90 t_container * temp = m_container; | |
| 91 m_ptr = NULL; | |
| 92 m_container = NULL; | |
| 93 if (temp != NULL) temp->release(); | |
| 94 } | |
| 95 | |
| 96 | |
| 97 template<typename t_object_cast> | |
| 98 rcptr_t<t_object_cast> static_cast_t() const throw() { | |
| 99 rcptr_t<t_object_cast> temp; | |
| 100 if (is_valid()) temp.__set_from_cast(this->m_container,static_cast<t_object_cast*>(this->m_ptr)); | |
| 101 return temp; | |
| 102 } | |
| 103 | |
| 104 void new_t() { | |
| 105 on_new(new t_container_impl()); | |
| 106 } | |
| 107 | |
| 108 template<typename ... arg_t> | |
| 109 void new_t(arg_t && ... arg) { | |
| 110 on_new(new t_container_impl(std::forward<arg_t>(arg) ...)); | |
| 111 } | |
| 112 | |
| 113 static t_self g_new_t() { | |
| 114 t_self temp; | |
| 115 temp.new_t(); | |
| 116 return temp; | |
| 117 } | |
| 118 | |
| 119 template<typename ... arg_t> | |
| 120 static t_self g_new_t(arg_t && ... arg) { | |
| 121 t_self temp; | |
| 122 temp.new_t(std::forward<arg_t>(arg) ...); | |
| 123 return temp; | |
| 124 } | |
| 125 | |
| 126 t_object & operator*() const throw() {return *this->m_ptr;} | |
| 127 | |
| 128 t_object * operator->() const throw() {return this->m_ptr;} | |
| 129 | |
| 130 | |
| 131 t_container * __container() const throw() {return m_container;} | |
| 132 | |
| 133 // FOR INTERNAL USE ONLY | |
| 134 void _clear() throw() {m_container = NULL; m_ptr = NULL;} | |
| 135 private: | |
| 136 | |
| 137 template<typename t_source> | |
| 138 void __init(const rcptr_t<t_source> & p_source) throw() { | |
| 139 m_container = p_source.__container(); | |
| 140 m_ptr = &*p_source; | |
| 141 if (m_container != NULL) m_container->add_ref(); | |
| 142 } | |
| 143 template<typename t_source> | |
| 144 void _move(rcptr_t<t_source> & p_source) throw() { | |
| 145 m_container = p_source.__container(); | |
| 146 m_ptr = &*p_source; | |
| 147 p_source._clear(); | |
| 148 } | |
| 149 template<typename t_source> | |
| 150 void __copy(const rcptr_t<t_source> & p_source) throw() { | |
| 151 __set_from_cast(p_source.__container(),&*p_source); | |
| 152 } | |
| 153 void on_new(t_container_impl * p_container) throw() { | |
| 154 this->release(); | |
| 155 p_container->add_ref(); | |
| 156 this->m_ptr = &p_container->m_object; | |
| 157 this->m_container = p_container; | |
| 158 } | |
| 159 | |
| 160 t_container * m_container; | |
| 161 t_object * m_ptr; | |
| 162 }; | |
| 163 | |
| 164 template<typename t_object, typename ... arg_t> | |
| 165 rcptr_t<t_object> rcnew_t(arg_t && ... arg) { | |
| 166 rcptr_t<t_object> temp; | |
| 167 temp.new_t(std::forward<arg_t>(arg) ...); | |
| 168 return temp; | |
| 169 } | |
| 170 | |
| 171 class traits_rcptr : public traits_default { | |
| 172 public: | |
| 173 enum { realloc_safe = true, constructor_may_fail = false }; | |
| 174 }; | |
| 175 | |
| 176 template<typename T> class traits_t<rcptr_t<T> > : public traits_rcptr {}; | |
| 177 } |
