]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - include/lldb/Utility/CleanUp.h
Vendor import of lldb trunk r290819:
[FreeBSD/FreeBSD.git] / 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 #include <functional>
15
16 namespace lldb_utility {
17
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.
26 //
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
32 // into T.
33 //
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.
38 //
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.
43 //
44 // EXAMPLES
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:
50 //
51 //  CleanUp <int, int> fd(open("/tmp/a.txt", O_RDONLY, 0), -1, close);
52 //
53 //  // malloc/free example
54 //  CleanUp <void *, void> malloced_bytes(malloc(32), NULL, free);
55 //----------------------------------------------------------------------
56 template <typename T, typename R = void> class CleanUp {
57 public:
58   typedef T value_type;
59   typedef std::function<R(value_type)> CallbackType;
60
61   //----------------------------------------------------------------------
62   // Constructor that sets the current value only. No values are
63   // considered to be invalid and the cleanup function will be called
64   // regardless of the value of m_current_value.
65   //----------------------------------------------------------------------
66   CleanUp(value_type value, CallbackType callback)
67       : m_current_value(value), m_invalid_value(), m_callback(callback),
68         m_callback_called(false), m_invalid_value_is_valid(false) {}
69
70   //----------------------------------------------------------------------
71   // Constructor that sets the current value and also the invalid value.
72   // The cleanup function will be called on "m_value" as long as it isn't
73   // equal to "m_invalid_value".
74   //----------------------------------------------------------------------
75   CleanUp(value_type value, value_type invalid, CallbackType callback)
76       : m_current_value(value), m_invalid_value(invalid), m_callback(callback),
77         m_callback_called(false), m_invalid_value_is_valid(true) {}
78
79   //----------------------------------------------------------------------
80   // Automatically cleanup when this object goes out of scope.
81   //----------------------------------------------------------------------
82   ~CleanUp() { clean(); }
83
84   //----------------------------------------------------------------------
85   // Access the value stored in this class
86   //----------------------------------------------------------------------
87   value_type get() { return m_current_value; }
88
89   //----------------------------------------------------------------------
90   // Access the value stored in this class
91   //----------------------------------------------------------------------
92   const value_type get() const { return m_current_value; }
93
94   //----------------------------------------------------------------------
95   // Reset the owned value to "value". If a current value is valid and
96   // the cleanup callback hasn't been called, the previous value will
97   // be cleaned up (see void CleanUp::clean()).
98   //----------------------------------------------------------------------
99   void set(const value_type value) {
100     // Cleanup the current value if needed
101     clean();
102     // Now set the new value and mark our callback as not called
103     m_callback_called = false;
104     m_current_value = value;
105   }
106
107   //----------------------------------------------------------------------
108   // Checks is "m_current_value" is valid. The value is considered valid
109   // no invalid value was supplied during construction of this object or
110   // if an invalid value was supplied and "m_current_value" is not equal
111   // to "m_invalid_value".
112   //
113   // Returns true if "m_current_value" is valid, false otherwise.
114   //----------------------------------------------------------------------
115   bool is_valid() const {
116     if (m_invalid_value_is_valid)
117       return m_current_value != m_invalid_value;
118     return true;
119   }
120
121   //----------------------------------------------------------------------
122   // This function will call the cleanup callback provided in the
123   // constructor one time if the value is considered valid (See is_valid()).
124   // This function sets m_callback_called to true so we don't call the
125   // cleanup callback multiple times on the same value.
126   //----------------------------------------------------------------------
127   void clean() {
128     if (m_callback && !m_callback_called) {
129       m_callback_called = true;
130       if (is_valid())
131         m_callback(m_current_value);
132     }
133   }
134
135   //----------------------------------------------------------------------
136   // Cancels the cleanup that would have been called on "m_current_value"
137   // if it was valid. This function can be used to release the value
138   // contained in this object so ownership can be transferred to the caller.
139   //----------------------------------------------------------------------
140   value_type release() {
141     m_callback_called = true;
142     return m_current_value;
143   }
144
145 private:
146   value_type m_current_value;
147   const value_type m_invalid_value;
148   CallbackType m_callback;
149   bool m_callback_called;
150   bool m_invalid_value_is_valid;
151
152   // Outlaw default constructor, copy constructor and the assignment operator
153   DISALLOW_COPY_AND_ASSIGN(CleanUp);
154 };
155
156 template <typename T, typename R, typename A0> class CleanUp2 {
157 public:
158   typedef T value_type;
159   typedef std::function<R(value_type, A0)> CallbackType;
160
161   //----------------------------------------------------------------------
162   // Constructor that sets the current value only. No values are
163   // considered to be invalid and the cleanup function will be called
164   // regardless of the value of m_current_value.
165   //----------------------------------------------------------------------
166   CleanUp2(value_type value, CallbackType callback, A0 arg)
167       : m_current_value(value), m_invalid_value(), m_callback(callback),
168         m_callback_called(false), m_invalid_value_is_valid(false),
169         m_argument(arg) {}
170
171   //----------------------------------------------------------------------
172   // Constructor that sets the current value and also the invalid value.
173   // The cleanup function will be called on "m_value" as long as it isn't
174   // equal to "m_invalid_value".
175   //----------------------------------------------------------------------
176   CleanUp2(value_type value, value_type invalid, CallbackType callback, A0 arg)
177       : m_current_value(value), m_invalid_value(invalid), m_callback(callback),
178         m_callback_called(false), m_invalid_value_is_valid(true),
179         m_argument(arg) {}
180
181   //----------------------------------------------------------------------
182   // Automatically cleanup when this object goes out of scope.
183   //----------------------------------------------------------------------
184   ~CleanUp2() { clean(); }
185
186   //----------------------------------------------------------------------
187   // Access the value stored in this class
188   //----------------------------------------------------------------------
189   value_type get() { return m_current_value; }
190
191   //----------------------------------------------------------------------
192   // Access the value stored in this class
193   //----------------------------------------------------------------------
194   const value_type get() const { return m_current_value; }
195
196   //----------------------------------------------------------------------
197   // Reset the owned value to "value". If a current value is valid and
198   // the cleanup callback hasn't been called, the previous value will
199   // be cleaned up (see void CleanUp::clean()).
200   //----------------------------------------------------------------------
201   void set(const value_type value) {
202     // Cleanup the current value if needed
203     clean();
204     // Now set the new value and mark our callback as not called
205     m_callback_called = false;
206     m_current_value = value;
207   }
208
209   //----------------------------------------------------------------------
210   // Checks is "m_current_value" is valid. The value is considered valid
211   // no invalid value was supplied during construction of this object or
212   // if an invalid value was supplied and "m_current_value" is not equal
213   // to "m_invalid_value".
214   //
215   // Returns true if "m_current_value" is valid, false otherwise.
216   //----------------------------------------------------------------------
217   bool is_valid() const {
218     if (m_invalid_value_is_valid)
219       return m_current_value != m_invalid_value;
220     return true;
221   }
222
223   //----------------------------------------------------------------------
224   // This function will call the cleanup callback provided in the
225   // constructor one time if the value is considered valid (See is_valid()).
226   // This function sets m_callback_called to true so we don't call the
227   // cleanup callback multiple times on the same value.
228   //----------------------------------------------------------------------
229   void clean() {
230     if (m_callback && !m_callback_called) {
231       m_callback_called = true;
232       if (is_valid())
233         m_callback(m_current_value, m_argument);
234     }
235   }
236
237   //----------------------------------------------------------------------
238   // Cancels the cleanup that would have been called on "m_current_value"
239   // if it was valid. This function can be used to release the value
240   // contained in this object so ownership can be transferred to the caller.
241   //----------------------------------------------------------------------
242   value_type release() {
243     m_callback_called = true;
244     return m_current_value;
245   }
246
247 private:
248   value_type m_current_value;
249   const value_type m_invalid_value;
250   CallbackType m_callback;
251   bool m_callback_called;
252   bool m_invalid_value_is_valid;
253   A0 m_argument;
254
255   // Outlaw default constructor, copy constructor and the assignment operator
256   DISALLOW_COPY_AND_ASSIGN(CleanUp2);
257 };
258
259 } // namespace lldb_utility
260
261 #endif // #ifndef liblldb_CleanUp_h_