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 {
253 etl::ifunction<const etl::exception&>* p = static_cast<etl::ifunction<const etl::exception&>*>(object);
254 p->operator()(e);
255 }
256 };
257} // namespace etl
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 Index>
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 Index>
278 assert_function_ptr_t assert_handler<Index>::assert_function_ptr = assert_handler<Index>::default_assert;
279 } // namespace private_error_handler
280
281 //***************************************************************************
284 //***************************************************************************
285 inline 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} // namespace etl
290#endif
291
292//***************************************************************************
304//***************************************************************************
305#if defined(ETL_NO_CHECKS)
306 #define ETL_ASSERT(b, e) static_cast<void>(sizeof(b)) // Does nothing.
307 #define ETL_ASSERT_OR_RETURN(b, e) static_cast<void>(sizeof(b)) // Does nothing.
308 #define ETL_ASSERT_OR_RETURN_VALUE(b, e, v) static_cast<void>(sizeof(b)) // Does nothing.
309
310 #define ETL_ASSERT_FAIL(e) ETL_DO_NOTHING // Does nothing.
311 #define ETL_ASSERT_FAIL_AND_RETURN(e) ETL_DO_NOTHING // Does nothing.
312 #define ETL_ASSERT_FAIL_AND_RETURN_VALUE(e, v) ETL_DO_NOTHING // Does nothing.
313#elif defined(ETL_USE_ASSERT_FUNCTION)
314 #define ETL_ASSERT(b, e) \
315 do { \
316 if (!(b)) ETL_UNLIKELY \
317 { \
318 etl::private_error_handler::assert_handler<0>::assert_function_ptr((e)); \
319 } \
320 } while (false) // If the condition fails, calls the assert function
321 #define ETL_ASSERT_OR_RETURN(b, e) \
322 do { \
323 if (!(b)) ETL_UNLIKELY \
324 { \
325 etl::private_error_handler::assert_handler<0>::assert_function_ptr((e)); \
326 return; \
327 } \
328 } while (false) // If the condition fails, calls the assert function and return
329 #define ETL_ASSERT_OR_RETURN_VALUE(b, e, v) \
330 do { \
331 if (!(b)) ETL_UNLIKELY \
332 { \
333 etl::private_error_handler::assert_handler<0>::assert_function_ptr((e)); \
334 return (v); \
335 } \
336 } while (false) // If the condition fails, calls the assert function and
337 // return a value
338
339 #define ETL_ASSERT_FAIL(e) \
340 do { \
341 etl::private_error_handler::assert_handler<0>::assert_function_ptr((e)); \
342 } while (false) // Calls the assert function
343 #define ETL_ASSERT_FAIL_AND_RETURN(e) \
344 do { \
345 etl::private_error_handler::assert_handler<0>::assert_function_ptr((e)); \
346 return; \
347 } while (false) // Calls the assert function and return
348 #define ETL_ASSERT_FAIL_AND_RETURN_VALUE(e, v) \
349 do { \
350 etl::private_error_handler::assert_handler<0>::assert_function_ptr((e)); \
351 return (v); \
352 } while (false) // Calls the assert function and return a value
353#elif ETL_USING_EXCEPTIONS
354 #if defined(ETL_LOG_ERRORS)
355 #define ETL_ASSERT(b, e) \
356 do { \
357 if (!(b)) ETL_UNLIKELY \
358 { \
359 etl::error_handler::error((e)); \
360 throw((e)); \
361 } \
362 } while (false) // If the condition fails, calls the error handler then
363 // throws an exception.
364 #define ETL_ASSERT_OR_RETURN(b, e) \
365 do { \
366 if (!(b)) ETL_UNLIKELY \
367 { \
368 etl::error_handler::error((e)); \
369 throw((e)); \
370 return; \
371 } \
372 } while (false) // If the condition fails, calls the error handler then
373 // throws an exception.
374 #define ETL_ASSERT_OR_RETURN_VALUE(b, e, v) \
375 do { \
376 if (!(b)) ETL_UNLIKELY \
377 { \
378 etl::error_handler::error((e)); \
379 throw((e)); \
380 return (v); \
381 } \
382 } while (false) // If the condition fails, calls the error handler then
383 // throws an exception.
384
385 #define ETL_ASSERT_FAIL(e) \
386 do { \
387 etl::error_handler::error((e)); \
388 throw((e)); \
389 } while (false) // Calls the error handler then throws an exception.
390 #define ETL_ASSERT_FAIL_AND_RETURN(e) \
391 do { \
392 etl::error_handler::error((e)); \
393 throw((e)); \
394 return; \
395 } while (false) // Calls the error handler then throws an exception.
396 #define ETL_ASSERT_FAIL_AND_RETURN_VALUE(e, v) \
397 do { \
398 etl::error_handler::error((e)); \
399 throw((e)); \
400 return (v); \
401 } while (false) // Calls the error handler then throws an exception.
402 #else
403 #define ETL_ASSERT(b, e) \
404 do { \
405 if (!(b)) ETL_UNLIKELY \
406 { \
407 throw((e)); \
408 } \
409 } while (false) // If the condition fails, throws an exception.
410 #define ETL_ASSERT_OR_RETURN(b, e) \
411 do { \
412 if (!(b)) ETL_UNLIKELY \
413 { \
414 throw((e)); \
415 } \
416 } while (false) // If the condition fails, throws an exception.
417 #define ETL_ASSERT_OR_RETURN_VALUE(b, e, v) \
418 do { \
419 if (!(b)) ETL_UNLIKELY \
420 { \
421 throw((e)); \
422 } \
423 } while (false) // If the condition fails, throws an exception.
424
425 #define ETL_ASSERT_FAIL(e) \
426 do { \
427 throw((e)); \
428 } while (false) // Throws an exception.
429 #define ETL_ASSERT_FAIL_AND_RETURN(e) \
430 do { \
431 throw((e)); \
432 } while (false) // Throws an exception.
433 #define ETL_ASSERT_FAIL_AND_RETURN_VALUE(e, v) \
434 do { \
435 throw((e)); \
436 } while (false) // Throws an exception.
437 #endif
438#else
439 #if defined(ETL_LOG_ERRORS)
440 #define ETL_ASSERT(b, e) \
441 do { \
442 if (!(b)) ETL_UNLIKELY \
443 { \
444 etl::error_handler::error((e)); \
445 } \
446 } while (false) // If the condition fails, calls the error handler
447 #define ETL_ASSERT_OR_RETURN(b, e) \
448 do { \
449 if (!(b)) ETL_UNLIKELY \
450 { \
451 etl::error_handler::error((e)); \
452 return; \
453 } \
454 } while (false) // If the condition fails, calls the error handler and return
455 #define ETL_ASSERT_OR_RETURN_VALUE(b, e, v) \
456 do { \
457 if (!(b)) ETL_UNLIKELY \
458 { \
459 etl::error_handler::error((e)); \
460 return (v); \
461 } \
462 } while (false) // If the condition fails, calls the error handler and
463 // return a value
464
465 #define ETL_ASSERT_FAIL(e) \
466 do { \
467 etl::error_handler::error((e)); \
468 } while (false) // Calls the error handler
469 #define ETL_ASSERT_FAIL_AND_RETURN(e) \
470 do { \
471 etl::error_handler::error((e)); \
472 return; \
473 } while (false) // Calls the error handler and return
474 #define ETL_ASSERT_FAIL_AND_RETURN_VALUE(e, v) \
475 do { \
476 etl::error_handler::error((e)); \
477 return (v); \
478 } while (false) // Calls the error handler and return a value
479 #else
480 #if ETL_IS_DEBUG_BUILD
481 #define ETL_ASSERT(b, e) assert((b)) // If the condition fails, asserts.
482 #define ETL_ASSERT_OR_RETURN(b, e) \
483 do { \
484 if (!(b)) ETL_UNLIKELY \
485 { \
486 assert(false); \
487 return; \
488 } \
489 } while (false) // If the condition fails, asserts and return.
490 #define ETL_ASSERT_OR_RETURN_VALUE(b, e, v) \
491 do { \
492 if (!(b)) ETL_UNLIKELY \
493 { \
494 assert(false); \
495 return (v); \
496 } \
497 } while (false) // If the condition fails, asserts and return a value.
498
499 #define ETL_ASSERT_FAIL(e) assert(false) // Asserts.
500 #define ETL_ASSERT_FAIL_AND_RETURN(e) \
501 do { \
502 assert(false); \
503 return; \
504 } while (false) // Asserts.
505 #define ETL_ASSERT_FAIL_AND_RETURN_VALUE(e, v) \
506 do { \
507 assert(false); \
508 return (v); \
509 } while (false) // Asserts.
510 #else
511 #define ETL_ASSERT(b, e) static_cast<void>(sizeof(b)) // Does nothing.
512 #define ETL_ASSERT_OR_RETURN(b, e) \
513 do { \
514 if (!(b)) ETL_UNLIKELY \
515 return; \
516 } while (false) // Returns.
517 #define ETL_ASSERT_OR_RETURN_VALUE(b, e, v) \
518 do { \
519 if (!(b)) ETL_UNLIKELY \
520 return (v); \
521 } while (false) // Returns a value.
522
523 #define ETL_ASSERT_FAIL(e) ETL_DO_NOTHING // Does nothing.
524 #define ETL_ASSERT_FAIL_AND_RETURN(e) \
525 do { \
526 return; \
527 } while (false) // Returns.
528 #define ETL_ASSERT_FAIL_AND_RETURN_VALUE(e, v) \
529 do { \
530 return (v); \
531 } while (false) // Returns a value.
532 #endif
533 #endif
534#endif
535
536//*************************************
537#if defined(ETL_CHECK_PUSH_POP)
538 #define ETL_ASSERT_CHECK_PUSH_POP(b, e) ETL_ASSERT(b, e)
539 #define ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(b, e) ETL_ASSERT_OR_RETURN(b, e)
540#else
541 #define ETL_ASSERT_CHECK_PUSH_POP(b, e)
542 #define ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(b, e)
543#endif
544
545//*************************************
546#ifdef ETL_CHECK_INDEX_OPERATOR
547 #define ETL_CHECKING_INDEX_OPERATOR 1
548 #define ETL_NOT_CHECKING_INDEX_OPERATOR 0
549 #define ETL_ASSERT_CHECK_INDEX_OPERATOR(b, e) ETL_ASSERT(b, e)
550#else
551 #define ETL_CHECKING_INDEX_OPERATOR 0
552 #define ETL_NOT_CHECKING_INDEX_OPERATOR 1
553 #define ETL_ASSERT_CHECK_INDEX_OPERATOR(b, e)
554#endif
555
556//*************************************
557#ifdef ETL_CHECK_EXTRA
558 #define ETL_CHECKING_EXTRA 1
559 #define ETL_NOT_CHECKING_EXTRA 0
560 #define ETL_ASSERT_CHECK_EXTRA(b, e) ETL_ASSERT(b, e)
561#else
562 #define ETL_CHECKING_EXTRA 0
563 #define ETL_NOT_CHECKING_EXTRA 1
564 #define ETL_ASSERT_CHECK_EXTRA(b, e)
565#endif
566
567//*************************************
568#if defined(ETL_VERBOSE_ERRORS)
569 // include everything, file name, line number, verbose text
570 #define ETL_ERROR(e) (e(__FILE__, __LINE__))
571 #define ETL_ERROR_WITH_VALUE(e, v) (e(__FILE__, __LINE__, (v)))
572 #define ETL_ERROR_TEXT(verbose_text, terse_text) (verbose_text)
573 #define ETL_ERROR_GENERIC(text) (etl::exception((text), __FILE__, __LINE__))
574#elif defined(ETL_MINIMAL_ERRORS)
575 // include nothing, no file name, no line number, no text
576 #define ETL_ERROR(e) (e("", -1))
577 #define ETL_ERROR_WITH_VALUE(e, v) (e("", -1, (v)))
578 #define ETL_ERROR_TEXT(verbose_text, terse_text) ("")
579 #define ETL_ERROR_GENERIC(text) (etl::exception("", "", -1))
580#else
581 // include only terse text, no file name, no line number
582 #define ETL_ERROR(e) (e("", -1))
583 #define ETL_ERROR_WITH_VALUE(e, v) (e("", -1, (v)))
584 #define ETL_ERROR_TEXT(verbose_text, terse_text) (terse_text)
585 #define ETL_ERROR_GENERIC(text) (etl::exception((text), "", -1))
586#endif
587
588#endif
bitset_ext
Definition absolute.h:40