]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/llvm/tools/lldb/include/lldb/Utility/CleanUp.h
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / llvm / tools / lldb / include / lldb / Utility / CleanUp.h
1 //===-- CleanUp.h -----------------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #ifndef liblldb_CleanUp_h_
11 #define liblldb_CleanUp_h_
12
13 #include "lldb/lldb-public.h"
14
15 namespace lldb_utility {
16
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.
25 //
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 
31 // into T.
32 //
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.
37 //
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.
42 //
43 // EXAMPLES
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:
49 //
50 //  CleanUp <int, int> fd(open("/tmp/a.txt", O_RDONLY, 0), -1, close);
51 //
52 //  // malloc/free example
53 //  CleanUp <void *, void> malloced_bytes(malloc(32), NULL, free);
54 //----------------------------------------------------------------------
55 template <typename T, typename R = void>
56 class CleanUp
57 {
58 public:
59     typedef T value_type;
60     typedef R (*CallbackType)(value_type);
61
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),
69         m_invalid_value (),
70         m_callback (callback),
71         m_callback_called (false),
72         m_invalid_value_is_valid (false)
73     {
74     }
75
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)
87     {
88     }
89
90     //----------------------------------------------------------------------
91     // Automatically cleanup when this object goes out of scope.
92     //----------------------------------------------------------------------
93     ~CleanUp ()
94     {
95         clean();
96     }
97
98     //----------------------------------------------------------------------
99     // Access the value stored in this class
100     //----------------------------------------------------------------------
101     value_type get() 
102     {
103         return m_current_value; 
104     }
105
106     //----------------------------------------------------------------------
107     // Access the value stored in this class
108     //----------------------------------------------------------------------
109     const value_type
110     get() const 
111     {
112         return m_current_value; 
113     }
114
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     //----------------------------------------------------------------------
120     void 
121     set (const value_type value)
122     {
123         // Cleanup the current value if needed
124         clean ();
125         // Now set the new value and mark our callback as not called
126         m_callback_called = false;
127         m_current_value = value;
128     }
129
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".
135     //
136     // Returns true if "m_current_value" is valid, false otherwise.
137     //----------------------------------------------------------------------
138     bool 
139     is_valid() const 
140     {
141         if (m_invalid_value_is_valid)
142             return m_current_value != m_invalid_value; 
143         return true;
144     }
145
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     //----------------------------------------------------------------------
152     void 
153     clean()
154     {
155         if (m_callback && !m_callback_called)
156         {
157             m_callback_called = true;
158             if (is_valid())
159                 m_callback(m_current_value);
160         }
161     }
162
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     //----------------------------------------------------------------------
168     value_type
169     release ()
170     {
171         m_callback_called = true;
172         return m_current_value;
173     }
174
175 private:
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;
181
182     // Outlaw default constructor, copy constructor and the assignment operator
183     DISALLOW_COPY_AND_ASSIGN (CleanUp);                 
184 };
185     
186 template <typename T, typename R, typename A0>
187 class CleanUp2
188 {
189 public:
190     typedef T value_type;
191     typedef R (*CallbackType)(value_type, A0);
192     
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),
200     m_invalid_value (),
201     m_callback (callback),
202     m_callback_called (false),
203     m_invalid_value_is_valid (false),
204     m_argument(arg)
205     {
206     }
207     
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),
219     m_argument(arg)
220     {
221     }
222     
223     //----------------------------------------------------------------------
224     // Automatically cleanup when this object goes out of scope.
225     //----------------------------------------------------------------------
226     ~CleanUp2 ()
227     {
228         clean();
229     }
230     
231     //----------------------------------------------------------------------
232     // Access the value stored in this class
233     //----------------------------------------------------------------------
234     value_type get() 
235     {
236         return m_current_value; 
237     }
238     
239     //----------------------------------------------------------------------
240     // Access the value stored in this class
241     //----------------------------------------------------------------------
242     const value_type
243     get() const 
244     {
245         return m_current_value; 
246     }
247     
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     //----------------------------------------------------------------------
253     void 
254     set (const value_type value)
255     {
256         // Cleanup the current value if needed
257         clean ();
258         // Now set the new value and mark our callback as not called
259         m_callback_called = false;
260         m_current_value = value;
261     }
262     
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".
268     //
269     // Returns true if "m_current_value" is valid, false otherwise.
270     //----------------------------------------------------------------------
271     bool 
272     is_valid() const 
273     {
274         if (m_invalid_value_is_valid)
275             return m_current_value != m_invalid_value; 
276         return true;
277     }
278     
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     //----------------------------------------------------------------------
285     void 
286     clean()
287     {
288         if (m_callback && !m_callback_called)
289         {
290             m_callback_called = true;
291             if (is_valid())
292                 m_callback(m_current_value, m_argument);
293         }
294     }
295     
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     //----------------------------------------------------------------------
301     value_type
302     release ()
303     {
304         m_callback_called = true;
305         return m_current_value;
306     }
307     
308 private:
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;
314     A0              m_argument;
315     
316     // Outlaw default constructor, copy constructor and the assignment operator
317     DISALLOW_COPY_AND_ASSIGN (CleanUp2);                 
318 };
319
320 } // namespace lldb_utility
321
322 #endif // #ifndef liblldb_CleanUp_h_