blob: fa3f9c06152126d073be815f40eceb476f9c0c0d [file] [log] [blame]
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001/*
2 * Copyright (c) 2016, 2017 ARM Limited.
3 *
4 * SPDX-License-Identifier: MIT
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to
8 * deal in the Software without restriction, including without limitation the
9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 * sell copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in all
14 * copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24#ifndef __ARM_COMPUTE_ERROR_H__
25#define __ARM_COMPUTE_ERROR_H__
26
Georgios Pinitas3faea252017-10-30 14:13:50 +000027#include <stdexcept>
28#include <string>
29
30namespace arm_compute
31{
32enum class ErrorCode
33{
34 OK, /**< No error */
35 RUNTIME_ERROR /**< Generic runtime error */
36};
37
38/** Error class */
39class Error
40{
41public:
42 /** Default Constructor **/
43 Error()
44 : _code(ErrorCode::OK), _description(" ")
45 {
46 }
47 /** Default Constructor
48 *
49 * @param error_status Error status.
50 * @param error_description Error description if error_status is not valid.
51 */
52 explicit Error(ErrorCode error_status, std::string error_description = " ")
53 : _code(error_status), _description(error_description)
54 {
55 }
56 /** Allow instances of this class to be copy constructed */
57 Error(const Error &) = default;
58 /** Allow instances of this class to be move constructed */
59 Error(Error &&) = default;
60 /** Allow instances of this class to be copy assigned */
61 Error &operator=(const Error &) = default;
62 /** Allow instances of this class to be move assigned */
63 Error &operator=(Error &&) = default;
64 /** Explicit bool conversion operator
65 *
66 * @return True if there is a valid error else false if status is OK.
67 */
68 explicit operator bool() const noexcept
69 {
70 return _code != ErrorCode::OK;
71 }
72 /** Gets error code
73 *
74 * @return Error code.
75 */
76 ErrorCode error_code() const
77 {
78 return _code;
79 }
80 /** Gets error description if any
81 *
82 * @return Error description.
83 */
84 std::string description() const
85 {
86 return _description;
87 }
88 /** Throws a runtime exception in case it contains a valid error status */
89 void throw_if_error()
90 {
91 if(bool(*this))
92 {
93 internal_throw_on_error();
94 }
95 }
96
97private:
98 /** Internal throwing function */
99 [[noreturn]] void internal_throw_on_error()
100 {
101 throw std::runtime_error(_description);
102 }
103
104private:
105 ErrorCode _code;
106 std::string _description;
107};
108
109/** Creates an error containing the error message
110 *
111 * @param[in] error_code Error code
112 * @param[in] function Function in which the error occurred.
113 * @param[in] file Name of the file where the error occurred.
114 * @param[in] line Line on which the error occurred.
115 * @param[in] msg Message to display before aborting.
116 * @param[in] ... Variable number of arguments of the message.
117 */
118Error create_error(ErrorCode error_code, const char *function, const char *file, const int line, const char *msg, ...);
119/** Print an error message then throw an std::runtime_error
120 *
121 * @param[in] function Function in which the error occurred.
122 * @param[in] file Name of the file where the error occurred.
123 * @param[in] line Line on which the error occurred.
124 * @param[in] msg Message to display before aborting.
125 * @param[in] ... Variable number of arguments of the message.
126 */
127[[noreturn]] void error(const char *function, const char *file, const int line, const char *msg, ...);
128}
129/** To avoid unused variables warnings
130 *
131 * This is useful if for example a variable is only used
132 * in debug builds and generates a warning in release builds.
133 *
134 * @param[in] var Variable which is unused.
135 */
136#define ARM_COMPUTE_UNUSED(var) (void)(var)
137
138/** Creates an error with a given message
139 *
140 * @param[in] error_code Error code.
141 * @param[in] ... Message to encapsulate.
142 */
143#define ARM_COMPUTE_CREATE_ERROR(error_code, ...) ::arm_compute::create_error(error_code, __func__, __FILE__, __LINE__, __VA_ARGS__) // NOLINT
144
145/** Creates an error on location with a given message
146 *
147 * @param[in] error_code Error code.
148 * @param[in] func Function in which the error occurred.
149 * @param[in] file File in which the error occurred.
150 * @param[in] line Line in which the error occurred.
151 * @param[in] ... Message to display before aborting.
152 */
153#define ARM_COMPUTE_CREATE_ERROR_LOC(error_code, func, file, line, ...) ::arm_compute::create_error(error_code, func, file, line, __VA_ARGS__) // NOLINT
154
155/** Checks if an error value is valid if not returns
156 *
157 * @param[in] error Error value to check
158 */
159#define ARM_COMPUTE_RETURN_ON_ERROR(error) \
160 do \
161 { \
162 if(bool(error)) \
163 { \
164 return error; \
165 } \
166 } while(false)
167
168/** Checks if an error value is valid if not throws an exception with the error
169 *
170 * @param[in] error Error value to check.
171 */
172#define ARM_COMPUTE_THROW_ON_ERROR(error) \
173 error.throw_if_error();
174
175/** If the condition is true, an error is returned
176 *
177 * @param[in] cond Condition to evaluate.
178 * @param[in] ... Error description message
179 */
180#define ARM_COMPUTE_RETURN_ERROR_ON_MSG(cond, ...) \
181 do \
182 { \
183 if(cond) \
184 { \
185 return ARM_COMPUTE_CREATE_ERROR(arm_compute::ErrorCode::RUNTIME_ERROR, __VA_ARGS__); \
186 } \
187 } while(false)
188
189/** If the condition is true, an error is thrown
190 *
191 * @param[in] cond Condition to evaluate.
192 * @param[in] func Function in which the error occurred.
193 * @param[in] file File in which the error occurred.
194 * @param[in] line Line in which the error occurred.
195 * @param[in] ... Error description message.
196 */
197#define ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG(cond, func, file, line, ...) \
198 do \
199 { \
200 if(cond) \
201 { \
202 return ARM_COMPUTE_CREATE_ERROR_LOC(arm_compute::ErrorCode::RUNTIME_ERROR, func, file, line, __VA_ARGS__); \
203 } \
204 } while(false)
205
206/** If the condition is true, an error is returned
207 *
208 * @param[in] cond Condition to evaluate
209 */
210#define ARM_COMPUTE_RETURN_ERROR_ON(cond) \
211 ARM_COMPUTE_RETURN_ERROR_ON_MSG(cond, #cond)
212
213/** If the condition is true, an error is returned
214 *
215 * @param[in] cond Condition to evaluate.
216 * @param[in] func Function in which the error occurred.
217 * @param[in] file File in which the error occurred.
218 * @param[in] line Line in which the error occurred.
219 */
220#define ARM_COMPUTE_RETURN_ERROR_ON_LOC(cond, func, file, line) \
221 ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG(cond, func, file, line, #cond)
222
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100223/** Print the given message then throw an std::runtime_error.
224 *
225 * @param[in] ... Message to display before aborting.
226 */
227#define ARM_COMPUTE_ERROR(...) ::arm_compute::error(__func__, __FILE__, __LINE__, __VA_ARGS__) // NOLINT
228
229/** Print the given message then throw an std::runtime_error.
230 *
231 * @param[in] func Function in which the error occurred.
232 * @param[in] file File in which the error occurred.
233 * @param[in] line Line in which the error occurred.
234 * @param[in] ... Message to display before aborting.
235 */
236#define ARM_COMPUTE_ERROR_LOC(func, file, line, ...) ::arm_compute::error(func, file, line, __VA_ARGS__) // NOLINT
237
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100238#ifdef ARM_COMPUTE_ASSERTS_ENABLED
Georgios Pinitas3faea252017-10-30 14:13:50 +0000239/** Checks if an error value is valid if not throws an exception with the error
240 *
241 * @param[in] error Error value to check.
242 */
Georgios Pinitasf9d3a0a2017-11-03 19:01:44 +0000243#define ARM_COMPUTE_ERROR_THROW_ON(error) \
Georgios Pinitas3faea252017-10-30 14:13:50 +0000244 error.throw_if_error();
245
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100246/** If the condition is true, the given message is printed and an exception is thrown
247 *
248 * @param[in] cond Condition to evaluate.
249 * @param[in] ... Message to print if cond is false.
250 */
251#define ARM_COMPUTE_ERROR_ON_MSG(cond, ...) \
252 do \
253 { \
254 if(cond) \
255 { \
256 ARM_COMPUTE_ERROR(__VA_ARGS__); \
257 } \
258 } while(0)
259
260/** If the condition is true, the given message is printed and an exception is thrown
261 *
262 * @param[in] cond Condition to evaluate.
263 * @param[in] func Function in which the error occurred.
264 * @param[in] file File in which the error occurred.
265 * @param[in] line Line in which the error occurred.
266 * @param[in] ... Message to print if cond is false.
267 */
268#define ARM_COMPUTE_ERROR_ON_LOC_MSG(cond, func, file, line, ...) \
269 do \
270 { \
271 if(cond) \
272 { \
273 ARM_COMPUTE_ERROR_LOC(func, file, line, __VA_ARGS__); \
274 } \
275 } while(0)
276
277/** If the condition is true, the given message is printed and an exception is thrown, otherwise value is returned
278 *
279 * @param[in] cond Condition to evaluate.
280 * @param[in] val Value to be returned.
281 * @param[in] msg Message to print if cond is false.
282 */
283#define ARM_COMPUTE_CONST_ON_ERROR(cond, val, msg) (cond) ? throw std::logic_error(msg) : val;
284#else /* ARM_COMPUTE_ASSERTS_ENABLED */
Georgios Pinitasf9d3a0a2017-11-03 19:01:44 +0000285#define ARM_COMPUTE_ERROR_THROW_ON(error)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100286#define ARM_COMPUTE_ERROR_ON_MSG(cond, ...)
287#define ARM_COMPUTE_ERROR_ON_LOC_MSG(cond, func, file, line, ...)
288#define ARM_COMPUTE_CONST_ON_ERROR(cond, val, msg) val
289#endif /* ARM_COMPUTE_ASSERTS_ENABLED */
290
291/** If the condition is true then an error message is printed and an exception thrown
292 *
Georgios Pinitas3faea252017-10-30 14:13:50 +0000293 * @param[in] cond Condition to evaluate.
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100294 */
295#define ARM_COMPUTE_ERROR_ON(cond) \
296 ARM_COMPUTE_ERROR_ON_MSG(cond, #cond)
297
298/** If the condition is true then an error message is printed and an exception thrown
299 *
Georgios Pinitas3faea252017-10-30 14:13:50 +0000300 * @param[in] cond Condition to evaluate.
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100301 * @param[in] func Function in which the error occurred.
302 * @param[in] file File in which the error occurred.
303 * @param[in] line Line in which the error occurred.
304 */
305#define ARM_COMPUTE_ERROR_ON_LOC(cond, func, file, line) \
306 ARM_COMPUTE_ERROR_ON_LOC_MSG(cond, func, file, line, #cond)
307
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100308#endif /* __ARM_COMPUTE_ERROR_H__ */