xref: /netbsd-src/external/bsd/elftosb/dist/common/smart_ptr.h (revision 993229b6fea628ff8b1fa09146c80b0cfb2768eb)
1 /*
2  *  smart_ptr.h
3  *  elftosb
4  *
5  *  Created by Chris Reed on 4/18/06.
6  *  Copyright 2006 __MyCompanyName__. All rights reserved.
7  *
8  */
9 #if !defined(_smart_ptr_h_)
10 #define _smart_ptr_h_
11 
12 /*!
13  * \brief Simple, standard smart pointer class.
14  *
15  * This class only supports the single-owner paradigm.
16  */
17 template <typename T>
18 class smart_ptr
19 {
20 public:
21 	typedef T data_type;
22 	typedef T * ptr_type;
23 	typedef const T * const_ptr_type;
24 	typedef T & ref_type;
25 	typedef const T & const_ref_type;
26 
27 	//! Default constuctor. Initialises with no pointer set.
smart_ptr()28 	smart_ptr() : _p(0) {}
29 
30 	//! This constructor takes a pointer to the object to be deleted.
smart_ptr(ptr_type p)31 	smart_ptr(ptr_type p) : _p(p) {}
32 
33 	//! Destructor. If an object (pointer) has been set, it will be deleted.
34 	//! Deletes the object using safe_delete().
~smart_ptr()35 	virtual ~smart_ptr() { safe_delete(); }
36 
37 	//! Return the current pointer value.
get()38 	ptr_type get() { return _p; }
39 
40 	//! Return the const form of the current pointer value.
get()41 	const_ptr_type get() const { return _p; }
42 
43 	//! Change the pointer value, or set if if the default constructor was used.
44 	//! If a pointer had previously been associated with the object, and \a p is
45 	//! different than that previous pointer, it will be deleted before taking
46 	//! ownership of \a p. If this is not desired, call reset() beforehand.
set(ptr_type p)47 	void set(ptr_type p)
48 	{
49 		if (_p && p != _p)
50 		{
51 			safe_delete();
52 		}
53 		_p = p;
54 	}
55 
56 	//! Dissociates any previously set pointer value without deleting it.
reset()57 	void reset() { _p = 0; }
58 
59 	//! Dissociates a previously set pointer value, deleting it at the same time.
clear()60 	void clear() { safe_delete(); }
61 
62 	//! Forces immediate deletion of the object. If you are planning on using
63 	//! this method, think about just using a normal pointer. It probably makes
64 	//! more sense.
safe_delete()65 	virtual void safe_delete()
66 	{
67 		if (_p)
68 		{
69 			delete _p;
70 			_p = 0;
71 		}
72 	}
73 
74 	//! \name Operators
75 	//@{
76 
77 	//! Makes the object transparent as the template type.
ptr_type()78 	operator ptr_type () { return _p; }
79 
80 	//! Const version of the pointer operator.
const_ptr_type()81 	operator const_ptr_type () const { return _p; }
82 
83 	//! Makes the object transparent as a reference of the template type.
ref_type()84 	operator ref_type () { return *_p; }
85 
86 	//! Const version of the reference operator.
const_ref_type()87 	operator const_ref_type () const { return *_p; }
88 
89 	//! Returns a boolean indicating whether the object has a pointer set or not.
90 	operator bool () const { return _p != 0; }
91 
92 	//! To allow setting the pointer directly. Equivalent to a call to set().
93 	smart_ptr<T> & operator = (const_ptr_type p)
94 	{
95 		set(const_cast<ptr_type>(p));
96 		return *this;
97 	}
98 
99 	//! Another operator to allow you to treat the object just like a pointer.
100 	ptr_type operator ->() { return _p; }
101 
102 	//! Another operator to allow you to treat the object just like a pointer.
103 	const_ptr_type operator ->() const { return _p; }
104 
105 //	//! Pointer dereferencing operator.
106 //	ref_type operator * () const { return *_p; }
107 //
108 //	//! Const version of the pointer dereference operator.
109 //	const_ref_type operator * () const { return *_p; }
110 
111 	//@}
112 
113 protected:
114 	ptr_type _p;	//!< The wrapped pointer.
115 };
116 
117 /*!
118  * \brief Simple, standard smart pointer class that uses the array delete operator.
119  *
120  * This class only supports the single-owner paradigm.
121  *
122  * This is almost entirely a copy of smart_ptr since the final C++ specification
123  * does not allow template subclass members to access members  of the parent that
124  * do not depend on the template parameter.
125  */
126 template <typename T>
127 class smart_array_ptr
128 {
129 public:
130 	typedef T data_type;
131 	typedef T * ptr_type;
132 	typedef const T * const_ptr_type;
133 	typedef T & ref_type;
134 	typedef const T & const_ref_type;
135 
136 	//! Default constuctor. Initialises with no pointer set.
smart_array_ptr()137 	smart_array_ptr() : _p(0) {}
138 
139 	//! This constructor takes a pointer to the object to be deleted.
smart_array_ptr(ptr_type p)140 	smart_array_ptr(ptr_type p) : _p(p) {}
141 
142 	//! Destructor. If an array has been set, it will be deleted.
143 	//! Deletes the array using safe_delete().
~smart_array_ptr()144 	virtual ~smart_array_ptr() { safe_delete(); }
145 
146 	//! Return the current pointer value.
get()147 	ptr_type get() { return _p; }
148 
149 	//! Return the const form of the current pointer value.
get()150 	const_ptr_type get() const { return _p; }
151 
152 	//! Change the pointer value, or set if if the default constructor was used.
153 	//! If a pointer had previously been associated with the object, and \a p is
154 	//! different than that previous pointer, it will be deleted before taking
155 	//! ownership of \a p. If this is not desired, call reset() beforehand.
set(ptr_type p)156 	void set(ptr_type p)
157 	{
158 		if (_p && p != _p)
159 		{
160 			safe_delete();
161 		}
162 		_p = p;
163 	}
164 
165 	//! Dissociates any previously set pointer value without deleting it.
reset()166 	void reset() { _p = 0; }
167 
168 	//! Dissociates a previously set pointer value, deleting it at the same time.
clear()169 	void clear() { safe_delete(); }
170 
171 	//! Forces immediate deletion of the object. If you are planning on using
172 	//! this method, think about just using a normal pointer. It probably makes
173 	//! more sense.
safe_delete()174 	virtual void safe_delete()
175 	{
176 		if (_p)
177 		{
178 			delete [] _p;
179 			_p = 0;
180 		}
181 	}
182 
183 	//! \name Operators
184 	//@{
185 
186 	//! Makes the object transparent as the template type.
ptr_type()187 	operator ptr_type () { return _p; }
188 
189 	//! Const version of the pointer operator.
const_ptr_type()190 	operator const_ptr_type () const { return _p; }
191 
192 	//! Makes the object transparent as a reference of the template type.
ref_type()193 	operator ref_type () { return *_p; }
194 
195 	//! Const version of the reference operator.
const_ref_type()196 	operator const_ref_type () const { return *_p; }
197 
198 	//! Returns a boolean indicating whether the object has a pointer set or not.
199 	operator bool () const { return _p != 0; }
200 
201 	//! To allow setting the pointer directly. Equivalent to a call to set().
202 	smart_array_ptr<T> & operator = (const_ptr_type p)
203 	{
204 		set(const_cast<ptr_type>(p));
205 		return *this;
206 	}
207 
208 	//! Another operator to allow you to treat the object just like a pointer.
209 	ptr_type operator ->() { return _p; }
210 
211 	//! Another operator to allow you to treat the object just like a pointer.
212 	const_ptr_type operator ->() const { return _p; }
213 
214 	//! Indexing operator.
215 	ref_type operator [] (unsigned index) { return _p[index]; }
216 
217 	//! Indexing operator.
218 	const_ref_type operator [] (unsigned index) const { return _p[index]; }
219 
220 //	//! Pointer dereferencing operator.
221 //	ref_type operator * () const { return *_p; }
222 //
223 //	//! Const version of the pointer dereference operator.
224 //	const_ref_type operator * () const { return *_p; }
225 
226 	//@}
227 
228 protected:
229 	ptr_type _p;	//!< The wrapped pointer.
230 };
231 
232 #endif // _smart_ptr_h_
233