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.hh128
1 files changed, 128 insertions, 0 deletions
diff --git a/src/FbTk/RefCount.hh b/src/FbTk/RefCount.hh
new file mode 100644
index 0000000..0fd889b
--- /dev/null
+++ b/src/FbTk/RefCount.hh
@@ -0,0 +1,128 @@
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}
99
100template <typename Pointer>
101void RefCount<Pointer>::decRefCount() {
102 if (m_refcount == 0)
103 return;
104 if (*m_refcount == 0) { // already zero, then delete refcount
105 delete m_refcount;
106 m_refcount = 0;
107 return;
108 }
109 (*m_refcount)--;
110 if (*m_refcount == 0) { // destroy m_data and m_refcount if nobody else is using this
111 if (m_data != 0)
112 delete m_data;
113 m_data = 0;
114 delete m_refcount;
115 m_refcount = 0;
116 }
117}
118
119template <typename Pointer>
120void RefCount<Pointer>::incRefCount() {
121 if (m_refcount == 0)
122 return;
123 (*m_refcount)++;
124}
125
126}; // end namespace FbTk
127
128#endif // FBTK_REFCOUNT_HH