diff 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
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/foosdk/sdk/pfc/rcptr.h	Mon Jan 05 02:15:46 2026 -0500
@@ -0,0 +1,177 @@
+#pragma once
+
+namespace pfc {
+
+	struct _rcptr_null;
+	typedef _rcptr_null* t_rcptr_null;
+
+	static const t_rcptr_null rcptr_null = NULL;
+
+	class rc_container_base {
+	public:
+		long add_ref() throw() {
+			return ++m_counter;
+		}
+		long release() throw() {
+			long ret = --m_counter;
+			if (ret == 0) PFC_ASSERT_NO_EXCEPTION( delete this );
+			return ret;
+		}
+	protected:
+		virtual ~rc_container_base() {}
+	private:
+		refcounter m_counter;
+	};
+
+	template<typename t_object>
+	class rc_container_t : public rc_container_base {
+	public:
+		template<typename ... arg_t>
+        rc_container_t(arg_t && ... arg) : m_object(std::forward<arg_t>(arg) ...) {}
+
+		t_object m_object;
+	};
+
+	template<typename t_object>
+	class rcptr_t {
+	private:
+		typedef rcptr_t<t_object> t_self;
+		typedef rc_container_base t_container;
+		typedef rc_container_t<t_object> t_container_impl;
+	public:
+		rcptr_t(t_rcptr_null) throw() {_clear();}
+		rcptr_t() throw() {_clear();}
+		rcptr_t(const t_self & p_source) throw() {__init(p_source);}
+		t_self const & operator=(const t_self & p_source) throw() {__copy(p_source); return *this;}
+
+		template<typename t_source>
+		rcptr_t(const rcptr_t<t_source> & p_source) throw() {__init(p_source);}
+		template<typename t_source>
+		const t_self & operator=(const rcptr_t<t_source> & p_source) throw() {__copy(p_source); return *this;}
+
+		rcptr_t(t_self && p_source) throw() {_move(p_source);}
+		const t_self & operator=(t_self && p_source) throw() {release(); _move(p_source); return *this;}
+
+		const t_self & operator=(t_rcptr_null) throw() {release(); return *this;}
+
+/*		template<typename t_object_cast>
+		operator rcptr_t<t_object_cast>() const throw() {
+			rcptr_t<t_object_cast> temp;
+			if (is_valid()) temp.__set_from_cast(this->m_container,this->m_ptr);
+			return temp;
+		}*/
+
+		
+		template<typename t_other>
+		bool operator==(const rcptr_t<t_other> & p_other) const throw() {
+			return m_container == p_other.__container();
+		}
+
+		template<typename t_other>
+		bool operator!=(const rcptr_t<t_other> & p_other) const throw() {
+			return m_container != p_other.__container();
+		}
+
+		void __set_from_cast(t_container * p_container,t_object * p_ptr) throw() {
+			//addref first because in rare cases this is the same pointer as the one we currently own
+			if (p_container != NULL) p_container->add_ref();
+			release();
+			m_container = p_container;
+			m_ptr = p_ptr;
+		}
+
+		bool is_valid() const throw() {return m_container != NULL;}
+		bool is_empty() const throw() {return m_container == NULL;}
+
+
+		~rcptr_t() throw() {release();}
+
+		void release() throw() {
+			t_container * temp = m_container;
+			m_ptr = NULL;
+			m_container = NULL;
+			if (temp != NULL) temp->release();
+		}
+
+
+		template<typename t_object_cast>
+		rcptr_t<t_object_cast> static_cast_t() const throw() {
+			rcptr_t<t_object_cast> temp;
+			if (is_valid()) temp.__set_from_cast(this->m_container,static_cast<t_object_cast*>(this->m_ptr));
+			return temp;
+		}
+
+		void new_t() {
+			on_new(new t_container_impl());
+		}
+
+		template<typename ... arg_t>
+		void new_t(arg_t && ... arg) {
+            on_new(new t_container_impl(std::forward<arg_t>(arg) ...));
+		}
+
+		static t_self g_new_t() {
+			t_self temp;
+			temp.new_t();
+			return temp;
+		}
+
+		template<typename ... arg_t>
+		static t_self g_new_t(arg_t && ... arg) {
+			t_self temp;
+            temp.new_t(std::forward<arg_t>(arg) ...);
+			return temp;
+		}
+
+		t_object & operator*() const throw() {return *this->m_ptr;}
+
+		t_object * operator->() const throw() {return this->m_ptr;}
+
+
+		t_container * __container() const throw() {return m_container;}
+
+		// FOR INTERNAL USE ONLY
+		void _clear() throw() {m_container = NULL; m_ptr = NULL;}
+	private:
+
+		template<typename t_source>
+		void __init(const rcptr_t<t_source> & p_source) throw() {
+			m_container = p_source.__container();
+			m_ptr = &*p_source;
+			if (m_container != NULL) m_container->add_ref();
+		}
+		template<typename t_source>
+		void _move(rcptr_t<t_source> & p_source) throw() {
+			m_container = p_source.__container();
+			m_ptr = &*p_source;
+			p_source._clear();
+		}
+		template<typename t_source>
+		void __copy(const rcptr_t<t_source> & p_source) throw() {
+			__set_from_cast(p_source.__container(),&*p_source);
+		}
+		void on_new(t_container_impl * p_container) throw() {
+			this->release();
+			p_container->add_ref();
+			this->m_ptr = &p_container->m_object;
+			this->m_container = p_container;
+		}
+
+		t_container * m_container;
+		t_object * m_ptr;
+	};
+
+	template<typename t_object, typename ... arg_t>
+	rcptr_t<t_object> rcnew_t(arg_t && ... arg) {
+		rcptr_t<t_object> temp;
+        temp.new_t(std::forward<arg_t>(arg) ...);
+		return temp;		
+	}
+
+	class traits_rcptr : public traits_default {
+	public:
+		enum { realloc_safe = true, constructor_may_fail = false };
+	};
+
+	template<typename T> class traits_t<rcptr_t<T> > : public traits_rcptr {};
+}
\ No newline at end of file