Embedded Template Library  1.0
error_handler.h
Go to the documentation of this file.
1 
3 
4 /******************************************************************************
5 The MIT License(MIT)
6 
7 Embedded Template Library.
8 https://github.com/ETLCPP/etl
9 https://www.etlcpp.com
10 
11 Copyright(c) 2014 jwellbelove
12 
13 Permission is hereby granted, free of charge, to any person obtaining a copy
14 of this software and associated documentation files(the "Software"), to deal
15 in the Software without restriction, including without limitation the rights
16 to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
17 copies of the Software, and to permit persons to whom the Software is
18 furnished to do so, subject to the following conditions :
19 
20 The above copyright notice and this permission notice shall be included in all
21 copies or substantial portions of the Software.
22 
23 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
26 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29 SOFTWARE.
30 ******************************************************************************/
31 
32 #ifndef ETL_ERROR_HANDLER_INCLUDED
33 #define ETL_ERROR_HANDLER_INCLUDED
34 
38 
39 #include <assert.h>
40 
41 #include "platform.h"
42 #include "exception.h"
43 #include "function.h"
44 #include "nullptr.h"
45 
46 #if defined(ETL_LOG_ERRORS) || defined(ETL_IN_UNIT_TEST)
47 namespace 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 #endif
259 
260 //***************************************************************************
269 //***************************************************************************
270 #if defined(ETL_NO_CHECKS)
271  #define ETL_ASSERT(b, e) // Does nothing.
272  #define ETL_ALWAYS_ASSERT(e) // Does nothing.
273 #elif defined(ETL_THROW_EXCEPTIONS)
274  #if defined(ETL_LOG_ERRORS)
275  #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.
276  #define ETL_ALWAYS_ASSERT(e) {etl::error_handler::error((e)); throw((e));} // Calls the error handler then throws an exception.
277  #else
278  #define ETL_ASSERT(b, e) {if (!(b)) {throw((e));}} // If the condition fails, throws an exception.
279  #define ETL_ALWAYS_ASSERT(e) {throw((e));} // Throws an exception.
280  #endif
281 #else
282  #if defined(ETL_LOG_ERRORS)
283  #define ETL_ASSERT(b, e) {if(!(b)) {etl::error_handler::error((e));}} // If the condition fails, calls the error handler
284  #define ETL_ALWAYS_ASSERT(e) {etl::error_handler::error((e));} // Calls the error handler
285  #else
286  #if defined(NDEBUG)
287  #define ETL_ASSERT(b, e) // Does nothing.
288  #define ETL_ALWAYS_ASSERT(e) // Does nothing.
289  #else
290  #define ETL_ASSERT(b, e) assert((b)) // If the condition fails, asserts.
291  #define ETL_ALWAYS_ASSERT(e) assert(false) // Asserts.
292  #endif
293  #endif
294 #endif
295 
296 #if defined(ETL_VERBOSE_ERRORS)
297  #define ETL_ERROR(e) (e(__FILE__, __LINE__)) // Make an exception with the file name and line number.
298 #else
299  #define ETL_ERROR(e) (e("", __LINE__)) // Make an exception with the line number.
300 #endif
301 
302 #if defined(ETL_VERBOSE_ERRORS)
303  #define ETL_ERROR_TEXT(verbose_text, terse_text) (verbose_text) // Use the verbose text.
304 #else
305  #define ETL_ERROR_TEXT(verbose_text, terse_text) (terse_text) // Use the terse text.
306 #endif
307 
308 #endif
309 
Definition: exception.h:47
Definition: function.h:94
Definition: function.h:54
Definition: absolute.h:37