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