aboutsummaryrefslogtreecommitdiff
path: root/src/FbTk/RefCount.hh
diff options
context:
space:
mode:
Diffstat (limited to 'src/FbTk/RefCount.hh')
-rw-r--r--src/FbTk/RefCount.hh129
1 files changed, 129 insertions, 0 deletions
diff --git a/src/FbTk/RefCount.hh b/src/FbTk/RefCount.hh
new file mode 100644
index 0000000..737ee1b
--- /dev/null
+++ b/src/FbTk/RefCount.hh
@@ -0,0 +1,129 @@
1// RefCount.hh for FbTk - Fluxbox Toolkit
2// Copyright (c) 2002 Henrik Kinnunen (fluxgen at users.sourceforge.net)
3//
4// Permission is hereby granted, free of charge, to any person obtaining a
5// copy of this software and associated documentation files (the "Software"),
6// to deal in the Software without restriction, including without limitation
7// the rights to use, copy, modify, merge, publish, distribute, sublicense,
8// and/or sell copies of the Software, and to permit persons to whom the
9// Software is furnished to do so, subject to the following conditions:
10//
11// The above copyright notice and this permission notice shall be included in
12// all copies or substantial portions of the Software.
13//
14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20// DEALINGS IN THE SOFTWARE.
21
22#ifndef FBTK_REFCOUNT_HH
23#define FBTK_REFCOUNT_HH
24
25namespace FbTk {
26
27/// holds a pointer with reference counting, similar to std:auto_ptr
28template <typename Pointer>
29class RefCount {
30public:
31 RefCount();
32 explicit RefCount(Pointer *p);
33 explicit RefCount(RefCount<Pointer> &copy);
34 RefCount(const RefCount<Pointer> &copy);
35 ~RefCount();
36 RefCount<Pointer> &operator = (const RefCount<Pointer> &copy);
37 RefCount<Pointer> &operator = (Pointer *p);
38 Pointer *operator * () const { return get(); }
39 Pointer *operator -> () const { return get(); }
40 Pointer *get() const { return m_data; }
41 /// @return number of referenses
42 unsigned int usedBy() const { return (m_refcount != 0 ? *m_refcount : 0); }
43private:
44 /// increase referense count
45 void incRefCount();
46 /// decrease referense count
47 void decRefCount();
48 Pointer *m_data; ///< data holder
49 mutable unsigned int *m_refcount; ///< holds reference counting
50};
51
52// implementation
53
54template <typename Pointer>
55RefCount<Pointer>::RefCount():m_data(0), m_refcount(new unsigned int(0)) {
56
57}
58
59template <typename Pointer>
60RefCount<Pointer>::RefCount(RefCount<Pointer> &copy):
61 m_data(copy.m_data),
62 m_refcount(copy.m_refcount) {
63 incRefCount();
64}
65
66template <typename Pointer>
67RefCount<Pointer>::RefCount(Pointer *p):m_data(p), m_refcount(new unsigned int(0)) {
68 incRefCount();
69}
70
71template <typename Pointer>
72RefCount<Pointer>::RefCount(const RefCount<Pointer> &copy):
73 m_data(copy.m_data),
74 m_refcount(copy.m_refcount) {
75 incRefCount();
76}
77
78template <typename Pointer>
79RefCount<Pointer>::~RefCount() {
80 decRefCount();
81}
82
83template <typename Pointer>
84RefCount<Pointer> &RefCount<Pointer>::operator = (const RefCount<Pointer> &copy) {
85 decRefCount(); // dec current ref count
86 m_refcount = copy.m_refcount; // set new ref count
87 m_data = copy.m_data; // set new data pointer
88 incRefCount(); // inc new ref count
89 return *this;
90}
91
92template <typename Pointer>
93RefCount<Pointer> &RefCount<Pointer>::operator = (Pointer *p) {
94 decRefCount();
95 m_data = p; // set data pointer
96 m_refcount = new unsigned int(0); // create new counter
97 incRefCount();
98 return *this;
99}
100
101template <typename Pointer>
102void RefCount<Pointer>::decRefCount() {
103 if (m_refcount == 0)
104 return;
105 if (*m_refcount == 0) { // already zero, then delete refcount
106 delete m_refcount;
107 m_refcount = 0;
108 return;
109 }
110 (*m_refcount)--;
111 if (*m_refcount == 0) { // destroy m_data and m_refcount if nobody else is using this
112 if (m_data != 0)
113 delete m_data;
114 m_data = 0;
115 delete m_refcount;
116 m_refcount = 0;
117 }
118}
119
120template <typename Pointer>
121void RefCount<Pointer>::incRefCount() {
122 if (m_refcount == 0)
123 return;
124 (*m_refcount)++;
125}
126
127}; // end namespace FbTk
128
129#endif // FBTK_REFCOUNT_HH