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"
16 namespace lldb_utility {
18 //----------------------------------------------------------------------
19 // Templated class that guarantees that a cleanup callback function will
20 // be called. The cleanup function will be called once under the
21 // following conditions:
22 // - when the object goes out of scope
23 // - when the user explicitly calls clean.
24 // - the current value will be cleaned up when a new value is set using
25 // set(T value) as long as the current value hasn't already been cleaned.
27 // This class is designed to be used with simple types for type T (like
28 // file descriptors, opaque handles, pointers, etc). If more complex
29 // type T objects are desired, we need to probably specialize this class
30 // to take "const T&" for all input T parameters. Yet if a type T is
31 // complex already it might be better to build the cleanup functionality
34 // The cleanup function must take one argument that is of type T.
35 // The calback function return type is R. The return value is currently
36 // needed for "CallbackType". If there is an easy way to get around the
37 // need for the return value we can change this class.
39 // The two template parameters are:
40 // T - The variable type of value that will be stored and used as the
41 // sole argument for the cleanup callback.
42 // R - The return type for the cleanup function.
45 // // Use with file handles that get opened where you want to close
46 // // them. Below we use "int open(const char *path, int oflag, ...)"
47 // // which returns an integer file descriptor. -1 is the invalid file
48 // // descriptor so to make an object that will call "int close(int fd)"
49 // // automatically we can use:
51 // CleanUp <int, int> fd(open("/tmp/a.txt", O_RDONLY, 0), -1, close);
53 // // malloc/free example
54 // CleanUp <void *, void> malloced_bytes(malloc(32), NULL, free);
55 //----------------------------------------------------------------------
56 template <typename T, typename R = void>
61 typedef std::function<R(value_type)> CallbackType;
63 //----------------------------------------------------------------------
64 // Constructor that sets the current value only. No values are
65 // considered to be invalid and the cleanup function will be called
66 // regardless of the value of m_current_value.
67 //----------------------------------------------------------------------
68 CleanUp (value_type value, CallbackType callback) :
69 m_current_value (value),
71 m_callback (callback),
72 m_callback_called (false),
73 m_invalid_value_is_valid (false)
77 //----------------------------------------------------------------------
78 // Constructor that sets the current value and also the invalid value.
79 // The cleanup function will be called on "m_value" as long as it isn't
80 // equal to "m_invalid_value".
81 //----------------------------------------------------------------------
82 CleanUp (value_type value, value_type invalid, CallbackType callback) :
83 m_current_value (value),
84 m_invalid_value (invalid),
85 m_callback (callback),
86 m_callback_called (false),
87 m_invalid_value_is_valid (true)
91 //----------------------------------------------------------------------
92 // Automatically cleanup when this object goes out of scope.
93 //----------------------------------------------------------------------
99 //----------------------------------------------------------------------
100 // Access the value stored in this class
101 //----------------------------------------------------------------------
104 return m_current_value;
107 //----------------------------------------------------------------------
108 // Access the value stored in this class
109 //----------------------------------------------------------------------
113 return m_current_value;
116 //----------------------------------------------------------------------
117 // Reset the owned value to "value". If a current value is valid and
118 // the cleanup callback hasn't been called, the previous value will
119 // be cleaned up (see void CleanUp::clean()).
120 //----------------------------------------------------------------------
122 set (const value_type value)
124 // Cleanup the current value if needed
126 // Now set the new value and mark our callback as not called
127 m_callback_called = false;
128 m_current_value = value;
131 //----------------------------------------------------------------------
132 // Checks is "m_current_value" is valid. The value is considered valid
133 // no invalid value was supplied during construction of this object or
134 // if an invalid value was supplied and "m_current_value" is not equal
135 // to "m_invalid_value".
137 // Returns true if "m_current_value" is valid, false otherwise.
138 //----------------------------------------------------------------------
142 if (m_invalid_value_is_valid)
143 return m_current_value != m_invalid_value;
147 //----------------------------------------------------------------------
148 // This function will call the cleanup callback provided in the
149 // constructor one time if the value is considered valid (See is_valid()).
150 // This function sets m_callback_called to true so we don't call the
151 // cleanup callback multiple times on the same value.
152 //----------------------------------------------------------------------
156 if (m_callback && !m_callback_called)
158 m_callback_called = true;
160 m_callback(m_current_value);
164 //----------------------------------------------------------------------
165 // Cancels the cleanup that would have been called on "m_current_value"
166 // if it was valid. This function can be used to release the value
167 // contained in this object so ownership can be transferred to the caller.
168 //----------------------------------------------------------------------
172 m_callback_called = true;
173 return m_current_value;
177 value_type m_current_value;
178 const value_type m_invalid_value;
179 CallbackType m_callback;
180 bool m_callback_called;
181 bool m_invalid_value_is_valid;
183 // Outlaw default constructor, copy constructor and the assignment operator
184 DISALLOW_COPY_AND_ASSIGN (CleanUp);
187 template <typename T, typename R, typename A0>
191 typedef T value_type;
192 typedef std::function<R(value_type,A0)> CallbackType;
194 //----------------------------------------------------------------------
195 // Constructor that sets the current value only. No values are
196 // considered to be invalid and the cleanup function will be called
197 // regardless of the value of m_current_value.
198 //----------------------------------------------------------------------
199 CleanUp2 (value_type value, CallbackType callback, A0 arg) :
200 m_current_value (value),
202 m_callback (callback),
203 m_callback_called (false),
204 m_invalid_value_is_valid (false),
209 //----------------------------------------------------------------------
210 // Constructor that sets the current value and also the invalid value.
211 // The cleanup function will be called on "m_value" as long as it isn't
212 // equal to "m_invalid_value".
213 //----------------------------------------------------------------------
214 CleanUp2 (value_type value, value_type invalid, CallbackType callback, A0 arg) :
215 m_current_value (value),
216 m_invalid_value (invalid),
217 m_callback (callback),
218 m_callback_called (false),
219 m_invalid_value_is_valid (true),
224 //----------------------------------------------------------------------
225 // Automatically cleanup when this object goes out of scope.
226 //----------------------------------------------------------------------
232 //----------------------------------------------------------------------
233 // Access the value stored in this class
234 //----------------------------------------------------------------------
237 return m_current_value;
240 //----------------------------------------------------------------------
241 // Access the value stored in this class
242 //----------------------------------------------------------------------
246 return m_current_value;
249 //----------------------------------------------------------------------
250 // Reset the owned value to "value". If a current value is valid and
251 // the cleanup callback hasn't been called, the previous value will
252 // be cleaned up (see void CleanUp::clean()).
253 //----------------------------------------------------------------------
255 set (const value_type value)
257 // Cleanup the current value if needed
259 // Now set the new value and mark our callback as not called
260 m_callback_called = false;
261 m_current_value = value;
264 //----------------------------------------------------------------------
265 // Checks is "m_current_value" is valid. The value is considered valid
266 // no invalid value was supplied during construction of this object or
267 // if an invalid value was supplied and "m_current_value" is not equal
268 // to "m_invalid_value".
270 // Returns true if "m_current_value" is valid, false otherwise.
271 //----------------------------------------------------------------------
275 if (m_invalid_value_is_valid)
276 return m_current_value != m_invalid_value;
280 //----------------------------------------------------------------------
281 // This function will call the cleanup callback provided in the
282 // constructor one time if the value is considered valid (See is_valid()).
283 // This function sets m_callback_called to true so we don't call the
284 // cleanup callback multiple times on the same value.
285 //----------------------------------------------------------------------
289 if (m_callback && !m_callback_called)
291 m_callback_called = true;
293 m_callback(m_current_value, m_argument);
297 //----------------------------------------------------------------------
298 // Cancels the cleanup that would have been called on "m_current_value"
299 // if it was valid. This function can be used to release the value
300 // contained in this object so ownership can be transferred to the caller.
301 //----------------------------------------------------------------------
305 m_callback_called = true;
306 return m_current_value;
310 value_type m_current_value;
311 const value_type m_invalid_value;
312 CallbackType m_callback;
313 bool m_callback_called;
314 bool m_invalid_value_is_valid;
317 // Outlaw default constructor, copy constructor and the assignment operator
318 DISALLOW_COPY_AND_ASSIGN (CleanUp2);
321 } // namespace lldb_utility
323 #endif // #ifndef liblldb_CleanUp_h_