Claw  1.7.3
smart_ptr.tpp
1 /*
2  CLAW - a C++ Library Absolutely Wonderful
3 
4  CLAW is a free library without any particular aim but being useful to
5  anyone.
6 
7  Copyright (C) 2005-2011 Julien Jorge
8 
9  This library is free software; you can redistribute it and/or
10  modify it under the terms of the GNU Lesser General Public
11  License as published by the Free Software Foundation; either
12  version 2.1 of the License, or (at your option) any later version.
13 
14  This library is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  Lesser General Public License for more details.
18 
19  You should have received a copy of the GNU Lesser General Public
20  License along with this library; if not, write to the Free Software
21  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 
23  contact: julien.jorge@gamned.org
24 */
25 /**
26  * \file smart_ptr.tpp
27  * \brief Implementation of the claw::memory::smart_ptr class.
28  * \author Julien Jorge
29  */
30 #include <cassert>
31 #include <cstdlib>
32 
33 /*----------------------------------------------------------------------------*/
34 /**
35  * \brief Default constructor.
36  */
37 template<typename T>
38 claw::memory::smart_ptr<T>::smart_ptr()
39  : m_ref_count(NULL), m_ptr(NULL)
40 {
41 
42 } // smart_ptr::smart_ptr()
43 
44 /*----------------------------------------------------------------------------*/
45 /**
46  * \brief Constructor from a pointer.
47  * \param data Pointer on the data.
48  *
49  * \b Warning: this constructor allows expressions like
50  *
51  * <tt>int a; smart_ptr<int> p(&a);</tt>
52  *
53  * Nevertheless, you should never fo that.
54  */
55 template<typename T>
56 claw::memory::smart_ptr<T>::smart_ptr( pointer data )
57  : m_ref_count(NULL), m_ptr(NULL)
58 {
59  if (data)
60  {
61  m_ref_count = new unsigned int(1);
62  m_ptr = data;
63  }
64 } // smart_ptr::smart_ptr() [pointer]
65 
66 /*----------------------------------------------------------------------------*/
67 /**
68  * \brief Copy constructor.
69  * \param that The smart_pointer to copy.
70  */
71 template<typename T>
72 claw::memory::smart_ptr<T>::smart_ptr( const self_type& that )
73 {
74  copy( that );
75 } // smart_ptr::smart_ptr() [copy]
76 
77 /*----------------------------------------------------------------------------*/
78 /**
79  * \brief Destructor. The memory is freed only if no more smart_ptr point on it.
80  */
81 template<typename T>
82 claw::memory::smart_ptr<T>::~smart_ptr()
83 {
84  release();
85 } // smart_ptr::~smart_ptr()
86 
87 /*----------------------------------------------------------------------------*/
88 /**
89  * \brief Assignment operator.
90  * \param that The smart_ptr to copy.
91  */
92 template<typename T>
93 typename claw::memory::smart_ptr<T>::self_type&
94 claw::memory::smart_ptr<T>::operator=( const self_type& that )
95 {
96  if ( &that != this )
97  {
98  release();
99  copy( that );
100  }
101 
102  return *this;
103 } // smart_ptr::operator=()
104 
105 /*----------------------------------------------------------------------------*/
106 /**
107  * \brief Equality operator.
108  * \param that The pointer to compare to.
109  * \return !(*this < that) && !(that < *this).
110  */
111 template<typename T>
112 bool claw::memory::smart_ptr<T>::operator==( const self_type& that ) const
113 {
114  return !(*this < that) && !(that < *this);
115 } // smart_ptr::operator==()
116 
117 /*----------------------------------------------------------------------------*/
118 /**
119  * \brief Disequality operator.
120  * \param that The pointer to compare to.
121  * \return (*this < that) || (that < *this).
122  */
123 template<typename T>
124 bool claw::memory::smart_ptr<T>::operator!=( const self_type& that ) const
125 {
126  return (*this < that) || (that < *this);
127 } // smart_ptr::operator!=()
128 
129 /*----------------------------------------------------------------------------*/
130 /**
131  * \brief "Less than" operator.
132  * \param that The pointer to compare to.
133  * \return True if the address pointed by \a this is lower than the address
134  * pointed by \a that.
135  */
136 template<typename T>
137 bool claw::memory::smart_ptr<T>::operator<( const self_type& that ) const
138 {
139  return m_ptr < that.m_ptr;
140 } // smart_ptr::operator<()
141 
142 /*----------------------------------------------------------------------------*/
143 /**
144  * \brief "Less or equal" operator.
145  * \param that The pointer to compare to.
146  * \return !(that < *this).
147  */
148 template<typename T>
149 bool claw::memory::smart_ptr<T>::operator<=( const self_type& that ) const
150 {
151  return !(that < *this);
152 } // smart_ptr::operator<=()
153 
154 /*----------------------------------------------------------------------------*/
155 /**
156  * \brief "Greater than" operator.
157  * \param that The pointer to compare to.
158  * \return \a that < *this.
159  */
160 template<typename T>
161 bool claw::memory::smart_ptr<T>::operator>( const self_type& that ) const
162 {
163  return that < *this;
164 } // smart_ptr::operator>()
165 
166 /*----------------------------------------------------------------------------*/
167 /**
168  * \brief "Greater or equal" operator.
169  * \param that The pointer to compare to.
170  * \return !(*this < that).
171  */
172 template<typename T>
173 bool claw::memory::smart_ptr<T>::operator>=( const self_type& that ) const
174 {
175  return !(*this < that);
176 } // smart_ptr::operator>=()
177 
178 /*----------------------------------------------------------------------------*/
179 /**
180  * \brief Dereference operator.
181  */
182 template<typename T>
183 typename claw::memory::smart_ptr<T>::pointer
184 claw::memory::smart_ptr<T>::operator->()
185 {
186  return m_ptr;
187 } // smart_ptr::operator->()
188 
189 /*----------------------------------------------------------------------------*/
190 /**
191  * \brief Dereference operator.
192  */
193 template<typename T>
194 typename claw::memory::smart_ptr<T>::pointer
195 claw::memory::smart_ptr<T>::operator->() const
196 {
197  return m_ptr;
198 } // smart_ptr::operator->()
199 
200 /*----------------------------------------------------------------------------*/
201 /**
202  * \brief Dereference operator.
203  */
204 template<typename T>
205 typename claw::memory::smart_ptr<T>::reference
206 claw::memory::smart_ptr<T>::operator*()
207 {
208  return *m_ptr;
209 } // smart_ptr::operator*()
210 
211 /*----------------------------------------------------------------------------*/
212 /**
213  * \brief Dereference operator.
214  */
215 template<typename T>
216 typename claw::memory::smart_ptr<T>::reference
217 claw::memory::smart_ptr<T>::operator*() const
218 {
219  return *m_ptr;
220 } // smart_ptr::operator*()
221 
222 /*----------------------------------------------------------------------------*/
223 /**
224  * \brief Copy a smart_ptr.
225  * \param that The smart_pointer to copy.
226  */
227 template<typename T>
228 void claw::memory::smart_ptr<T>::copy( const self_type& that )
229 {
230  assert( this != &that );
231 
232  m_ref_count = that.m_ref_count;
233  m_ptr = that.m_ptr;
234 
235  if (m_ref_count)
236  ++(*m_ref_count);
237 } // smart_ptr::copy()
238 
239 /*----------------------------------------------------------------------------*/
240 /**
241  * \brief Release the allocated memory.
242  *
243  * The memory is release only if no more smart_ptr point on it.
244  */
245 template<typename T>
246 void claw::memory::smart_ptr<T>::release()
247 {
248  if (m_ref_count)
249  if ( *m_ref_count )
250  {
251  --(*m_ref_count);
252 
253  if ( !(*m_ref_count) )
254  {
255  delete m_ptr;
256  delete m_ref_count;
257 
258  m_ref_count = NULL;
259  }
260 
261  m_ptr = NULL;
262  }
263 } // smart_ptr::release()