Embedded Template Library 1.0
Loading...
Searching...
No Matches
error_handler.h
Go to the documentation of this file.
1
3
4/******************************************************************************
5The MIT License(MIT)
6
7Embedded Template Library.
8https://github.com/ETLCPP/etl
9https://www.etlcpp.com
10
11Copyright(c) 2014 John Wellbelove
12
13Permission is hereby granted, free of charge, to any person obtaining a copy
14of this software and associated documentation files(the "Software"), to deal
15in the Software without restriction, including without limitation the rights
16to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
17copies of the Software, and to permit persons to whom the Software is
18furnished to do so, subject to the following conditions :
19
20The above copyright notice and this permission notice shall be included in all
21copies or substantial portions of the Software.
22
23THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
26AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29SOFTWARE.
30******************************************************************************/
31
32#ifndef ETL_ERROR_HANDLER_INCLUDED
33#define ETL_ERROR_HANDLER_INCLUDED
34
38
39#include "platform.h"
40#include "exception.h"
41#include "function.h"
42#include "nullptr.h"
43
44#include <assert.h>
45
46#if defined(ETL_LOG_ERRORS) || defined(ETL_IN_UNIT_TEST)
47namespace etl
48{
49 //***************************************************************************
52 //***************************************************************************
53 class error_handler
54 {
55 public:
56
57 //*************************************************************************
59 //*************************************************************************
60 struct free_function : public etl::function<void, const etl::exception&>
61 {
62 explicit free_function(void (*p_function_)(const etl::exception&))
63 : etl::function<void, const etl::exception&>(p_function_)
64 {
65 }
66 };
67
68 //*************************************************************************
70 //*************************************************************************
71 template <typename TObject>
72 struct member_function : public etl::function<TObject, const etl::exception&>
73 {
74 member_function(TObject& object_, void(TObject::*p_function_)(const etl::exception&))
75 : etl::function<TObject, const etl::exception&>(object_, p_function_)
76 {
77 }
78 };
79
80 //*****************************************************************************
83 //*****************************************************************************
84 static void set_callback(ifunction<const etl::exception&>& f)
85 {
86 create((void*)(&f), ifunction_stub);
87 }
88
89 //*************************************************************************
91 //*************************************************************************
92 template <void(*Method)(const etl::exception&)>
93 static void set_callback()
94 {
95 create(ETL_NULLPTR, function_stub<Method>);
96 }
97
98 //*************************************************************************
100 //*************************************************************************
101 template <typename T, void(T::* Method)(const etl::exception&)>
102 static void set_callback(T& instance)
103 {
104 create((void*)(&instance), method_stub<T, Method>);
105 }
106
107 //*************************************************************************
109 //*************************************************************************
110 template <typename T, void(T::* Method)(const etl::exception&) const>
111 static void set_callback(const T& instance)
112 {
113 create((void*)(&instance), const_method_stub<T, Method>);
114 }
115
116 //*************************************************************************
118 //*************************************************************************
119 template <typename T, T& Instance, void(T::* Method)(const etl::exception&)>
120 static void set_callback()
121 {
122 create(method_instance_stub<T, Instance, Method>);
123 }
124
125 //*************************************************************************
127 //*************************************************************************
128 template <typename T, T const& Instance, void(T::* Method)(const etl::exception&) const>
129 static void set_callback()
130 {
131 create(const_method_instance_stub<T, Instance, Method>);
132 }
133
134 //*****************************************************************************
137 //*****************************************************************************
138 static void error(const etl::exception& e)
139 {
140 invocation_element& invocation = get_invocation_element();
141
142 if (invocation.stub != ETL_NULLPTR)
143 {
144 (*invocation.stub)(invocation.object, e);
145 }
146 }
147
148 private:
149
150 typedef void(*stub_type)(void* object, const etl::exception&);
151
152 //*************************************************************************
154 //*************************************************************************
155 struct invocation_element
156 {
157 //***********************************************************************
158 invocation_element()
159 : object(ETL_NULLPTR)
160 , stub(ETL_NULLPTR)
161 {
162 }
163
164 //***********************************************************************
165 void* object;
166 stub_type stub;
167 };
168
169 //*************************************************************************
171 //*************************************************************************
172 static invocation_element& get_invocation_element()
173 {
174 static invocation_element invocation;
175
176 return invocation;
177 }
178
179 //*************************************************************************
181 //*************************************************************************
182 static void create(void* object, stub_type stub)
183 {
184 invocation_element& invocation = get_invocation_element();
185
186 invocation.object = object;
187 invocation.stub = stub;
188 }
189
190 //*************************************************************************
192 //*************************************************************************
193 static void create(stub_type stub)
194 {
195 invocation_element& invocation = get_invocation_element();
196
197 invocation.object = ETL_NULLPTR;
198 invocation.stub = stub;
199 }
200
201 //*************************************************************************
203 //*************************************************************************
204 template <typename T, void(T::* Method)(const etl::exception&)>
205 static void method_stub(void* object, const etl::exception& e)
206 {
207 T* p = static_cast<T*>(object);
208 return (p->*Method)(e);
209 }
210
211 //*************************************************************************
213 //*************************************************************************
214 template <typename T, void(T::* Method)(const etl::exception&) const>
215 static void const_method_stub(void* object, const etl::exception& e)
216 {
217 T* const p = static_cast<T*>(object);
218 return (p->*Method)(e);
219 }
220
221 //*************************************************************************
223 //*************************************************************************
224 template <typename T, T& Instance, void(T::* Method)(const etl::exception&)>
225 static void method_instance_stub(void*, const etl::exception& e)
226 {
227 return (Instance.*Method)(e);
228 }
229
230 //*************************************************************************
232 //*************************************************************************
233 template <typename T, const T& Instance, void(T::* Method)(const etl::exception&) const>
234 static void const_method_instance_stub(void*, const etl::exception& e)
235 {
236 (Instance.*Method)(e);
237 }
238
239 //*************************************************************************
241 //*************************************************************************
242 template <void(*Method)(const etl::exception&)>
243 static void function_stub(void*, const etl::exception& e)
244 {
245 (Method)(e);
246 }
247
248 //*************************************************************************
250 //*************************************************************************
251 static void ifunction_stub(void* object, const etl::exception& e)
252 {
254 p->operator()(e);
255 }
256 };
257}
258#elif defined(ETL_USE_ASSERT_FUNCTION)
259namespace etl
260{
261 namespace private_error_handler
262 {
263 typedef void(*assert_function_ptr_t)(const etl::exception&);
264
265 // Stores the assert function pointer and default assert function.
266 template <size_t N>
267 struct assert_handler
268 {
269 static assert_function_ptr_t assert_function_ptr;
270
271 static void default_assert(const etl::exception&)
272 {
273 assert(false);
274 }
275 };
276
277 template <size_t N>
278 assert_function_ptr_t assert_handler<N>::assert_function_ptr = assert_handler<N>::default_assert;
279 }
280
281 //***************************************************************************
284 //***************************************************************************
285 void set_assert_function(etl::private_error_handler::assert_function_ptr_t afptr)
286 {
287 etl::private_error_handler::assert_handler<0>::assert_function_ptr = afptr;
288 }
289}
290#endif
291
292//***************************************************************************
302//***************************************************************************
303#if defined(ETL_NO_CHECKS)
304 #define ETL_ASSERT(b, e) ETL_DO_NOTHING // Does nothing.
305 #define ETL_ASSERT_OR_RETURN(b, e) ETL_DO_NOTHING // Does nothing.
306 #define ETL_ASSERT_OR_RETURN_VALUE(b, e, v) ETL_DO_NOTHING // Does nothing.
307
308 #define ETL_ASSERT_FAIL(e) ETL_DO_NOTHING // Does nothing.
309 #define ETL_ASSERT_FAIL_AND_RETURN(e) ETL_DO_NOTHING // Does nothing.
310 #define ETL_ASSERT_FAIL_AND_RETURN_VALUE(e, v) ETL_DO_NOTHING // Does nothing.
311#elif defined(ETL_USE_ASSERT_FUNCTION)
312 #define ETL_ASSERT(b, e) {if(!(b)) {etl::private_error_handler::assert_handler<0>::assert_function_ptr((e));}} // If the condition fails, calls the assert function
313 #define ETL_ASSERT_OR_RETURN(b, e) {if(!(b)) {etl::private_error_handler::assert_handler<0>::assert_function_ptr((e)); return;}} // If the condition fails, calls the assert function and return
314 #define ETL_ASSERT_OR_RETURN_VALUE(b, e, v) {if(!(b)) {etl::private_error_handler::assert_handler<0>::assert_function_ptr((e)); return (v);}} // If the condition fails, calls the assert function and return a value
315
316 #define ETL_ASSERT_FAIL(e) {etl::private_error_handler::assert_handler<0>::assert_function_ptr((e));} // Calls the assert function
317 #define ETL_ASSERT_FAIL_AND_RETURN(e) {etl::private_error_handler::assert_handler<0>::assert_function_ptr((e)); return;} // Calls the assert function and return
318 #define ETL_ASSERT_FAIL_AND_RETURN_VALUE(e, v) {etl::private_error_handler::assert_handler<0>::assert_function_ptr((e)); return (v);} // Calls the assert function and return a value
319#elif ETL_USING_EXCEPTIONS
320 #if defined(ETL_LOG_ERRORS)
321 #define ETL_ASSERT(b, e) {if (!(b)) {etl::error_handler::error((e)); throw((e));}} // If the condition fails, calls the error handler then throws an exception.
322 #define ETL_ASSERT_OR_RETURN(b, e) {if (!(b)) {etl::error_handler::error((e)); throw((e)); return;}} // If the condition fails, calls the error handler then throws an exception.
323 #define ETL_ASSERT_OR_RETURN_VALUE(b, e, v) {if (!(b)) {etl::error_handler::error((e)); throw((e)); return(v);}} // If the condition fails, calls the error handler then throws an exception.
324
325 #define ETL_ASSERT_FAIL(e) {etl::error_handler::error((e)); throw((e));} // Calls the error handler then throws an exception.
326 #define ETL_ASSERT_FAIL_AND_RETURN(e) {etl::error_handler::error((e)); throw((e)); return;} // Calls the error handler then throws an exception.
327 #define ETL_ASSERT_FAIL_AND_RETURN_VALUE(e, v) {etl::error_handler::error((e)); throw((e)); return(v);} // Calls the error handler then throws an exception.
328 #else
329 #define ETL_ASSERT(b, e) {if (!(b)) {throw((e));}} // If the condition fails, throws an exception.
330 #define ETL_ASSERT_OR_RETURN(b, e) {if (!(b)) {throw((e));}} // If the condition fails, throws an exception.
331 #define ETL_ASSERT_OR_RETURN_VALUE(b, e, v) {if (!(b)) {throw((e));}} // If the condition fails, throws an exception.
332
333 #define ETL_ASSERT_FAIL(e) {throw((e));} // Throws an exception.
334 #define ETL_ASSERT_FAIL_AND_RETURN(e) {throw((e));} // Throws an exception.
335 #define ETL_ASSERT_FAIL_AND_RETURN_VALUE(e, v) {throw((e));} // Throws an exception.
336 #endif
337#else
338 #if defined(ETL_LOG_ERRORS)
339 #define ETL_ASSERT(b, e) {if(!(b)) {etl::error_handler::error((e));}} // If the condition fails, calls the error handler
340 #define ETL_ASSERT_OR_RETURN(b, e) {if(!(b)) {etl::error_handler::error((e)); return;}} // If the condition fails, calls the error handler and return
341 #define ETL_ASSERT_OR_RETURN_VALUE(b, e, v) {if(!(b)) {etl::error_handler::error((e)); return (v);}} // If the condition fails, calls the error handler and return a value
342
343 #define ETL_ASSERT_FAIL(e) {etl::error_handler::error((e));} // Calls the error handler
344 #define ETL_ASSERT_FAIL_AND_RETURN(e) {etl::error_handler::error((e)); return;} // Calls the error handler and return
345 #define ETL_ASSERT_FAIL_AND_RETURN_VALUE(e, v) {etl::error_handler::error((e)); return (v);} // Calls the error handler and return a value
346 #else
347 #if ETL_IS_DEBUG_BUILD
348 #define ETL_ASSERT(b, e) assert((b)) // If the condition fails, asserts.
349 #define ETL_ASSERT_OR_RETURN(b, e) {if (!(b)) {assert(false); return;}} // If the condition fails, asserts and return.
350 #define ETL_ASSERT_OR_RETURN_VALUE(b, e, v) {if (!(b)) {assert(false); return(v);}} // If the condition fails, asserts and return a value.
351
352 #define ETL_ASSERT_FAIL(e) assert(false) // Asserts.
353 #define ETL_ASSERT_FAIL_AND_RETURN(e) {assert(false); return;} // Asserts.
354 #define ETL_ASSERT_FAIL_AND_RETURN_VALUE(e, v) {assert(false); return(v);} // Asserts.
355 #else
356 #define ETL_ASSERT(b, e) // Does nothing.
357 #define ETL_ASSERT_OR_RETURN(b, e) {if (!(b)) return;} // Returns.
358 #define ETL_ASSERT_OR_RETURN_VALUE(b, e, v) {if (!(b)) return(v);} // Returns a value.
359
360 #define ETL_ASSERT_FAIL(e) // Does nothing.
361 #define ETL_ASSERT_FAIL_AND_RETURN(e) {return;} // Returns.
362 #define ETL_ASSERT_FAIL_AND_RETURN_VALUE(e, v) {return(v);} // Returns a value.
363 #endif
364 #endif
365#endif
366
367#if defined(ETL_VERBOSE_ERRORS)
368 #define ETL_ERROR(e) (e(__FILE__, __LINE__)) // Make an exception with the file name and line number.
369 #define ETL_ERROR_WITH_VALUE(e, v) (e(__FILE__, __LINE__, (v))) // Make an exception with the file name, line number and value.
370#else
371 #define ETL_ERROR(e) (e("", __LINE__)) // Make an exception with the line number.
372 #define ETL_ERROR_WITH_VALUE(e, v) (e("", __LINE__, (v))) // Make an exception with the file name, line number and value.
373#endif
374
375#if defined(ETL_VERBOSE_ERRORS)
376 #define ETL_ERROR_TEXT(verbose_text, terse_text) (verbose_text) // Use the verbose text.
377#else
378 #define ETL_ERROR_TEXT(verbose_text, terse_text) (terse_text) // Use the terse text.
379#endif
380
381#endif
382
Definition exception.h:47
Definition function.h:94
bitset_ext
Definition absolute.h:38
T * create(Args &&... args)
Creates the object from a type. Variadic parameter constructor.
Definition variant_pool_generator.h:348
pair holds two objects of arbitrary type
Definition utility.h:164
ETL_CONSTEXPR pair()
Default constructor.
Definition utility.h:176