1 //===-- CleanUp.h -----------------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #ifndef liblldb_CleanUp_h_
11 #define liblldb_CleanUp_h_
13 #include "lldb/lldb-public.h"
15 namespace lldb_utility {
17 //----------------------------------------------------------------------
18 // Templated class that guarantees that a cleanup callback function will
19 // be called. The cleanup function will be called once under the
20 // following conditions:
21 // - when the object goes out of scope
22 // - when the user explicitly calls clean.
23 // - the current value will be cleaned up when a new value is set using
24 // set(T value) as long as the current value hasn't already been cleaned.
26 // This class is designed to be used with simple types for type T (like
27 // file descriptors, opaque handles, pointers, etc). If more complex
28 // type T objects are desired, we need to probably specialize this class
29 // to take "const T&" for all input T parameters. Yet if a type T is
30 // complex already it might be better to build the cleanup funcionality
33 // The cleanup function must take one argument that is of type T.
34 // The calback function return type is R. The return value is currently
35 // needed for "CallbackType". If there is an easy way to get around the
36 // need for the return value we can change this class.
38 // The two template parameters are:
39 // T - The variable type of value that will be stored and used as the
40 // sole argument for the cleanup callback.
41 // R - The return type for the cleanup function.
44 // // Use with file handles that get opened where you want to close
45 // // them. Below we use "int open(const char *path, int oflag, ...)"
46 // // which returns an integer file descriptor. -1 is the invalid file
47 // // descriptor so to make an object that will call "int close(int fd)"
48 // // automatically we can use:
50 // CleanUp <int, int> fd(open("/tmp/a.txt", O_RDONLY, 0), -1, close);
52 // // malloc/free example
53 // CleanUp <void *, void> malloced_bytes(malloc(32), NULL, free);
54 //----------------------------------------------------------------------
55 template <typename T, typename R = void>
60 typedef R (*CallbackType)(value_type);
62 //----------------------------------------------------------------------
63 // Constructor that sets the current value only. No values are
64 // considered to be invalid and the cleanup function will be called
65 // regardless of the value of m_current_value.
66 //----------------------------------------------------------------------
67 CleanUp (value_type value, CallbackType callback) :
68 m_current_value (value),
70 m_callback (callback),
71 m_callback_called (false),
72 m_invalid_value_is_valid (false)
76 //----------------------------------------------------------------------
77 // Constructor that sets the current value and also the invalid value.
78 // The cleanup function will be called on "m_value" as long as it isn't
79 // equal to "m_invalid_value".
80 //----------------------------------------------------------------------
81 CleanUp (value_type value, value_type invalid, CallbackType callback) :
82 m_current_value (value),
83 m_invalid_value (invalid),
84 m_callback (callback),
85 m_callback_called (false),
86 m_invalid_value_is_valid (true)
90 //----------------------------------------------------------------------
91 // Automatically cleanup when this object goes out of scope.
92 //----------------------------------------------------------------------
98 //----------------------------------------------------------------------
99 // Access the value stored in this class
100 //----------------------------------------------------------------------
103 return m_current_value;
106 //----------------------------------------------------------------------
107 // Access the value stored in this class
108 //----------------------------------------------------------------------
112 return m_current_value;
115 //----------------------------------------------------------------------
116 // Reset the owned value to "value". If a current value is valid and
117 // the cleanup callback hasn't been called, the previous value will
118 // be cleaned up (see void CleanUp::clean()).
119 //----------------------------------------------------------------------
121 set (const value_type value)
123 // Cleanup the current value if needed
125 // Now set the new value and mark our callback as not called
126 m_callback_called = false;
127 m_current_value = value;
130 //----------------------------------------------------------------------
131 // Checks is "m_current_value" is valid. The value is considered valid
132 // no invalid value was supplied during construction of this object or
133 // if an invalid value was supplied and "m_current_value" is not equal
134 // to "m_invalid_value".
136 // Returns true if "m_current_value" is valid, false otherwise.
137 //----------------------------------------------------------------------
141 if (m_invalid_value_is_valid)
142 return m_current_value != m_invalid_value;
146 //----------------------------------------------------------------------
147 // This function will call the cleanup callback provided in the
148 // constructor one time if the value is considered valid (See is_valid()).
149 // This function sets m_callback_called to true so we don't call the
150 // cleanup callback multiple times on the same value.
151 //----------------------------------------------------------------------
155 if (m_callback && !m_callback_called)
157 m_callback_called = true;
159 m_callback(m_current_value);
163 //----------------------------------------------------------------------
164 // Cancels the cleanup that would have been called on "m_current_value"
165 // if it was valid. This function can be used to release the value
166 // contained in this object so ownership can be transfered to the caller.
167 //----------------------------------------------------------------------
171 m_callback_called = true;
172 return m_current_value;
176 value_type m_current_value;
177 const value_type m_invalid_value;
178 CallbackType m_callback;
179 bool m_callback_called;
180 bool m_invalid_value_is_valid;
182 // Outlaw default constructor, copy constructor and the assignment operator
183 DISALLOW_COPY_AND_ASSIGN (CleanUp);
186 template <typename T, typename R, typename A0>
190 typedef T value_type;
191 typedef R (*CallbackType)(value_type, A0);
193 //----------------------------------------------------------------------
194 // Constructor that sets the current value only. No values are
195 // considered to be invalid and the cleanup function will be called
196 // regardless of the value of m_current_value.
197 //----------------------------------------------------------------------
198 CleanUp2 (value_type value, CallbackType callback, A0 arg) :
199 m_current_value (value),
201 m_callback (callback),
202 m_callback_called (false),
203 m_invalid_value_is_valid (false),
208 //----------------------------------------------------------------------
209 // Constructor that sets the current value and also the invalid value.
210 // The cleanup function will be called on "m_value" as long as it isn't
211 // equal to "m_invalid_value".
212 //----------------------------------------------------------------------
213 CleanUp2 (value_type value, value_type invalid, CallbackType callback, A0 arg) :
214 m_current_value (value),
215 m_invalid_value (invalid),
216 m_callback (callback),
217 m_callback_called (false),
218 m_invalid_value_is_valid (true),
223 //----------------------------------------------------------------------
224 // Automatically cleanup when this object goes out of scope.
225 //----------------------------------------------------------------------
231 //----------------------------------------------------------------------
232 // Access the value stored in this class
233 //----------------------------------------------------------------------
236 return m_current_value;
239 //----------------------------------------------------------------------
240 // Access the value stored in this class
241 //----------------------------------------------------------------------
245 return m_current_value;
248 //----------------------------------------------------------------------
249 // Reset the owned value to "value". If a current value is valid and
250 // the cleanup callback hasn't been called, the previous value will
251 // be cleaned up (see void CleanUp::clean()).
252 //----------------------------------------------------------------------
254 set (const value_type value)
256 // Cleanup the current value if needed
258 // Now set the new value and mark our callback as not called
259 m_callback_called = false;
260 m_current_value = value;
263 //----------------------------------------------------------------------
264 // Checks is "m_current_value" is valid. The value is considered valid
265 // no invalid value was supplied during construction of this object or
266 // if an invalid value was supplied and "m_current_value" is not equal
267 // to "m_invalid_value".
269 // Returns true if "m_current_value" is valid, false otherwise.
270 //----------------------------------------------------------------------
274 if (m_invalid_value_is_valid)
275 return m_current_value != m_invalid_value;
279 //----------------------------------------------------------------------
280 // This function will call the cleanup callback provided in the
281 // constructor one time if the value is considered valid (See is_valid()).
282 // This function sets m_callback_called to true so we don't call the
283 // cleanup callback multiple times on the same value.
284 //----------------------------------------------------------------------
288 if (m_callback && !m_callback_called)
290 m_callback_called = true;
292 m_callback(m_current_value, m_argument);
296 //----------------------------------------------------------------------
297 // Cancels the cleanup that would have been called on "m_current_value"
298 // if it was valid. This function can be used to release the value
299 // contained in this object so ownership can be transfered to the caller.
300 //----------------------------------------------------------------------
304 m_callback_called = true;
305 return m_current_value;
309 value_type m_current_value;
310 const value_type m_invalid_value;
311 CallbackType m_callback;
312 bool m_callback_called;
313 bool m_invalid_value_is_valid;
316 // Outlaw default constructor, copy constructor and the assignment operator
317 DISALLOW_COPY_AND_ASSIGN (CleanUp2);
320 } // namespace lldb_utility
322 #endif // #ifndef liblldb_CleanUp_h_