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 }