]> icculus.org git repositories - divverent/netradiant.git/blob - libs/generic/referencecounted.h
initial
[divverent/netradiant.git] / libs / generic / referencecounted.h
1 /*
2 Copyright (C) 2001-2006, William Joseph.
3 All Rights Reserved.
4
5 This file is part of GtkRadiant.
6
7 GtkRadiant is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 GtkRadiant is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GtkRadiant; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20 */
21
22 #if !defined(INCLUDED_GENERIC_REFERENCECOUNTED_H)
23 #define INCLUDED_GENERIC_REFERENCECOUNTED_H
24
25 /// \file
26 /// \brief 'smart' pointers and references. 
27
28 #include <algorithm>
29
30 template<typename Type>
31 class IncRefDecRefCounter
32 {
33 public:
34   void increment(Type& value)
35   {
36     value.IncRef();
37   }
38   void decrement(Type& value)
39   {
40     value.DecRef();
41   }
42 };
43
44 /// \brief A smart-pointer that uses a counter stored in the object pointed-to.
45 template<typename Type, typename Counter = IncRefDecRefCounter<Type> >
46 class SmartPointer : public Counter
47 {
48   Type* m_value;
49 public:
50
51   SmartPointer(const SmartPointer& other)
52     : m_value(other.m_value)
53   {
54     Counter::increment(*m_value);
55   }
56   explicit SmartPointer(Type* value)
57     : m_value(value)
58   {
59     Counter::increment(*m_value);
60   }
61   ~SmartPointer()
62   {
63     Counter::decrement(*m_value);
64   }
65   SmartPointer& operator=(const SmartPointer& other)
66   {
67     SmartPointer temp(other);
68     temp.swap(*this);
69     return *this;
70   }
71   SmartPointer& operator=(Type* value)
72   {
73     SmartPointer temp(value);
74     temp.swap(*this);
75     return *this;
76   }
77   void swap(SmartPointer& other)
78   {
79     std::swap(m_value, other.m_value);
80   }
81
82   operator Type*() const
83   {
84     return m_value;
85   }
86   Type& operator*() const
87   {
88     return *m_value;
89   }
90   Type* operator->() const
91   {
92     return m_value;
93   }
94   Type* get() const
95   {
96     return m_value;
97   }
98 };
99
100 template<typename Type>
101 inline bool operator<(const SmartPointer<Type>& self, const SmartPointer<Type>& other)
102 {
103   return self.get() < other.get();
104 }
105 template<typename Type>
106 inline bool operator==(const SmartPointer<Type>& self, const SmartPointer<Type>& other)
107 {
108   return self.get() == other.get();
109 }
110 template<typename Type>
111 inline bool operator!=(const SmartPointer<Type>& self, const SmartPointer<Type>& other)
112 {
113   return !::operator==(self, other);
114 }
115
116 namespace std
117 {
118   /// \brief Swaps the values of \p self and \p other.
119   /// Overloads std::swap().
120   template<typename Type>
121   inline void swap(SmartPointer<Type>& self, SmartPointer<Type>& other)
122   {
123     self.swap(other);
124   }
125 }
126
127
128 /// \brief A smart-reference that uses a counter stored in the object pointed-to.
129 template<typename Type, typename Counter = IncRefDecRefCounter<Type> >
130 class SmartReference : public Counter
131 {
132   Type* m_value;
133 public:
134
135   SmartReference(const SmartReference& other)
136     : m_value(other.m_value)
137   {
138     Counter::increment(*m_value);
139   }
140   explicit SmartReference(Type& value)
141     : m_value(&value)
142   {
143     Counter::increment(*m_value);
144   }
145   ~SmartReference()
146   {
147     Counter::decrement(*m_value);
148   }
149   SmartReference& operator=(const SmartReference& other)
150   {
151     SmartReference temp(other);
152     temp.swap(*this);
153     return *this;
154   }
155   SmartReference& operator=(Type& value)
156   {
157     SmartReference temp(value);
158     temp.swap(*this);
159     return *this;
160   }
161   void swap(SmartReference& other)
162   {
163     std::swap(m_value, other.m_value);
164   }
165
166   operator Type&() const
167   {
168     return *m_value;
169   }
170   Type& get() const
171   {
172     return *m_value;
173   }
174   Type* get_pointer() const
175   {
176     return m_value;
177   }
178 };
179
180 template<typename Type>
181 inline bool operator<(const SmartReference<Type>& self, const SmartReference<Type>& other)
182 {
183   return self.get() < other.get();
184 }
185 template<typename Type>
186 inline bool operator==(const SmartReference<Type>& self, const SmartReference<Type>& other)
187 {
188   return self.get() == other.get();
189 }
190 template<typename Type>
191 inline bool operator!=(const SmartReference<Type>& self, const SmartReference<Type>& other)
192 {
193   return !::operator==(self, other);
194 }
195
196 namespace std
197 {
198   /// \brief Swaps the values of \p self and \p other.
199   /// Overloads std::swap().
200   template<typename Type>
201   inline void swap(SmartReference<Type>& self, SmartReference<Type>& other)
202   {
203     self.swap(other);
204   }
205 }
206
207 #endif