blob: 97dbba3fabc90545a26325858e7d826fb1a72398 [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
Anthony Barbier7068f992017-10-26 15:23:08 +010027#include <stdarg.h>
Georgios Pinitas3faea252017-10-30 14:13:50 +000028#include <string>
29
30namespace arm_compute
31{
32enum class ErrorCode
33{
34 OK, /**< No error */
35 RUNTIME_ERROR /**< Generic runtime error */
36};
37
Georgios Pinitas631c41a2017-12-06 11:53:03 +000038/** Status class */
39class Status
Georgios Pinitas3faea252017-10-30 14:13:50 +000040{
41public:
42 /** Default Constructor **/
Georgios Pinitas631c41a2017-12-06 11:53:03 +000043 Status()
44 : _code(ErrorCode::OK), _error_description(" ")
Georgios Pinitas3faea252017-10-30 14:13:50 +000045 {
46 }
47 /** Default Constructor
48 *
49 * @param error_status Error status.
Georgios Pinitas631c41a2017-12-06 11:53:03 +000050 * @param error_description (Optional) Error description if error_status is not valid.
Georgios Pinitas3faea252017-10-30 14:13:50 +000051 */
Georgios Pinitas631c41a2017-12-06 11:53:03 +000052 explicit Status(ErrorCode error_status, std::string error_description = " ")
53 : _code(error_status), _error_description(error_description)
Georgios Pinitas3faea252017-10-30 14:13:50 +000054 {
55 }
56 /** Allow instances of this class to be copy constructed */
Georgios Pinitas631c41a2017-12-06 11:53:03 +000057 Status(const Status &) = default;
Georgios Pinitas3faea252017-10-30 14:13:50 +000058 /** Allow instances of this class to be move constructed */
Georgios Pinitas631c41a2017-12-06 11:53:03 +000059 Status(Status &&) = default;
Georgios Pinitas3faea252017-10-30 14:13:50 +000060 /** Allow instances of this class to be copy assigned */
Georgios Pinitas631c41a2017-12-06 11:53:03 +000061 Status &operator=(const Status &) = default;
Georgios Pinitas3faea252017-10-30 14:13:50 +000062 /** Allow instances of this class to be move assigned */
Georgios Pinitas631c41a2017-12-06 11:53:03 +000063 Status &operator=(Status &&) = default;
Georgios Pinitas3faea252017-10-30 14:13:50 +000064 /** Explicit bool conversion operator
65 *
Georgios Pinitas631c41a2017-12-06 11:53:03 +000066 * @return True if there is no error else false
Georgios Pinitas3faea252017-10-30 14:13:50 +000067 */
68 explicit operator bool() const noexcept
69 {
Georgios Pinitas631c41a2017-12-06 11:53:03 +000070 return _code == ErrorCode::OK;
Georgios Pinitas3faea252017-10-30 14:13:50 +000071 }
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 */
Georgios Pinitas631c41a2017-12-06 11:53:03 +000084 std::string error_description() const
Georgios Pinitas3faea252017-10-30 14:13:50 +000085 {
Georgios Pinitas631c41a2017-12-06 11:53:03 +000086 return _error_description;
Georgios Pinitas3faea252017-10-30 14:13:50 +000087 }
88 /** Throws a runtime exception in case it contains a valid error status */
89 void throw_if_error()
90 {
Georgios Pinitas631c41a2017-12-06 11:53:03 +000091 if(!bool(*this))
Georgios Pinitas3faea252017-10-30 14:13:50 +000092 {
93 internal_throw_on_error();
94 }
95 }
96
97private:
98 /** Internal throwing function */
Anthony Barbier83f82652017-12-01 17:13:51 +000099 [[noreturn]] void internal_throw_on_error();
Georgios Pinitas3faea252017-10-30 14:13:50 +0000100
101private:
102 ErrorCode _code;
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000103 std::string _error_description;
Georgios Pinitas3faea252017-10-30 14:13:50 +0000104};
105
Anthony Barbier7068f992017-10-26 15:23:08 +0100106/** Creates an error containing the error message from variable argument list
107 *
108 * @param[in] error_code Error code
109 * @param[in] function Function in which the error occurred.
110 * @param[in] file Name of the file where the error occurred.
111 * @param[in] line Line on which the error occurred.
112 * @param[in] msg Message to display before aborting.
113 * @param[in] args Variable argument list of the message.
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000114 *
115 * @return status containing the error
Anthony Barbier7068f992017-10-26 15:23:08 +0100116 */
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000117Status create_error_va_list(ErrorCode error_code, const char *function, const char *file, const int line, const char *msg, va_list args);
Georgios Pinitas3faea252017-10-30 14:13:50 +0000118/** Creates an error containing the error message
119 *
120 * @param[in] error_code Error code
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.
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000126 *
127 * @return status containing the error
Georgios Pinitas3faea252017-10-30 14:13:50 +0000128 */
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000129Status create_error(ErrorCode error_code, const char *function, const char *file, const int line, const char *msg, ...);
Georgios Pinitas3faea252017-10-30 14:13:50 +0000130/** Print an error message then throw an std::runtime_error
131 *
132 * @param[in] function Function in which the error occurred.
133 * @param[in] file Name of the file where the error occurred.
134 * @param[in] line Line on which the error occurred.
135 * @param[in] msg Message to display before aborting.
136 * @param[in] ... Variable number of arguments of the message.
137 */
138[[noreturn]] void error(const char *function, const char *file, const int line, const char *msg, ...);
139}
140/** To avoid unused variables warnings
141 *
142 * This is useful if for example a variable is only used
143 * in debug builds and generates a warning in release builds.
144 *
145 * @param[in] var Variable which is unused.
146 */
147#define ARM_COMPUTE_UNUSED(var) (void)(var)
148
149/** Creates an error with a given message
150 *
151 * @param[in] error_code Error code.
152 * @param[in] ... Message to encapsulate.
153 */
154#define ARM_COMPUTE_CREATE_ERROR(error_code, ...) ::arm_compute::create_error(error_code, __func__, __FILE__, __LINE__, __VA_ARGS__) // NOLINT
155
156/** Creates an error on location with a given message
157 *
158 * @param[in] error_code Error code.
159 * @param[in] func Function in which the error occurred.
160 * @param[in] file File in which the error occurred.
161 * @param[in] line Line in which the error occurred.
162 * @param[in] ... Message to display before aborting.
163 */
164#define ARM_COMPUTE_CREATE_ERROR_LOC(error_code, func, file, line, ...) ::arm_compute::create_error(error_code, func, file, line, __VA_ARGS__) // NOLINT
165
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000166/** Checks if a status contains an error and returns it
Georgios Pinitas3faea252017-10-30 14:13:50 +0000167 *
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000168 * @param[in] status Status value to check
Georgios Pinitas3faea252017-10-30 14:13:50 +0000169 */
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000170#define ARM_COMPUTE_RETURN_ON_ERROR(status) \
171 do \
172 { \
173 if(!bool(status)) \
174 { \
175 return status; \
176 } \
Georgios Pinitas3faea252017-10-30 14:13:50 +0000177 } while(false)
178
179/** Checks if an error value is valid if not throws an exception with the error
180 *
181 * @param[in] error Error value to check.
182 */
183#define ARM_COMPUTE_THROW_ON_ERROR(error) \
184 error.throw_if_error();
185
186/** If the condition is true, an error is returned
187 *
188 * @param[in] cond Condition to evaluate.
189 * @param[in] ... Error description message
190 */
191#define ARM_COMPUTE_RETURN_ERROR_ON_MSG(cond, ...) \
192 do \
193 { \
194 if(cond) \
195 { \
196 return ARM_COMPUTE_CREATE_ERROR(arm_compute::ErrorCode::RUNTIME_ERROR, __VA_ARGS__); \
197 } \
198 } while(false)
199
200/** If the condition is true, an error is thrown
201 *
202 * @param[in] cond Condition to evaluate.
203 * @param[in] func Function in which the error occurred.
204 * @param[in] file File in which the error occurred.
205 * @param[in] line Line in which the error occurred.
206 * @param[in] ... Error description message.
207 */
208#define ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG(cond, func, file, line, ...) \
209 do \
210 { \
211 if(cond) \
212 { \
213 return ARM_COMPUTE_CREATE_ERROR_LOC(arm_compute::ErrorCode::RUNTIME_ERROR, func, file, line, __VA_ARGS__); \
214 } \
215 } while(false)
216
217/** If the condition is true, an error is returned
218 *
219 * @param[in] cond Condition to evaluate
220 */
221#define ARM_COMPUTE_RETURN_ERROR_ON(cond) \
222 ARM_COMPUTE_RETURN_ERROR_ON_MSG(cond, #cond)
223
224/** If the condition is true, an error is returned
225 *
226 * @param[in] cond Condition to evaluate.
227 * @param[in] func Function in which the error occurred.
228 * @param[in] file File in which the error occurred.
229 * @param[in] line Line in which the error occurred.
230 */
231#define ARM_COMPUTE_RETURN_ERROR_ON_LOC(cond, func, file, line) \
232 ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG(cond, func, file, line, #cond)
233
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100234/** Print the given message then throw an std::runtime_error.
235 *
236 * @param[in] ... Message to display before aborting.
237 */
238#define ARM_COMPUTE_ERROR(...) ::arm_compute::error(__func__, __FILE__, __LINE__, __VA_ARGS__) // NOLINT
239
240/** Print the given message then throw an std::runtime_error.
241 *
242 * @param[in] func Function in which the error occurred.
243 * @param[in] file File in which the error occurred.
244 * @param[in] line Line in which the error occurred.
245 * @param[in] ... Message to display before aborting.
246 */
247#define ARM_COMPUTE_ERROR_LOC(func, file, line, ...) ::arm_compute::error(func, file, line, __VA_ARGS__) // NOLINT
248
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100249#ifdef ARM_COMPUTE_ASSERTS_ENABLED
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000250/** Checks if a status value is valid if not throws an exception with the error
Georgios Pinitas3faea252017-10-30 14:13:50 +0000251 *
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000252 * @param[in] status Status value to check.
Georgios Pinitas3faea252017-10-30 14:13:50 +0000253 */
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000254#define ARM_COMPUTE_ERROR_THROW_ON(status) \
255 status.throw_if_error()
Georgios Pinitas3faea252017-10-30 14:13:50 +0000256
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100257/** If the condition is true, the given message is printed and an exception is thrown
258 *
259 * @param[in] cond Condition to evaluate.
260 * @param[in] ... Message to print if cond is false.
261 */
262#define ARM_COMPUTE_ERROR_ON_MSG(cond, ...) \
263 do \
264 { \
265 if(cond) \
266 { \
267 ARM_COMPUTE_ERROR(__VA_ARGS__); \
268 } \
269 } while(0)
270
271/** If the condition is true, the given message is printed and an exception is thrown
272 *
273 * @param[in] cond Condition to evaluate.
274 * @param[in] func Function in which the error occurred.
275 * @param[in] file File in which the error occurred.
276 * @param[in] line Line in which the error occurred.
277 * @param[in] ... Message to print if cond is false.
278 */
279#define ARM_COMPUTE_ERROR_ON_LOC_MSG(cond, func, file, line, ...) \
280 do \
281 { \
282 if(cond) \
283 { \
284 ARM_COMPUTE_ERROR_LOC(func, file, line, __VA_ARGS__); \
285 } \
286 } while(0)
287
288/** If the condition is true, the given message is printed and an exception is thrown, otherwise value is returned
289 *
290 * @param[in] cond Condition to evaluate.
291 * @param[in] val Value to be returned.
292 * @param[in] msg Message to print if cond is false.
293 */
294#define ARM_COMPUTE_CONST_ON_ERROR(cond, val, msg) (cond) ? throw std::logic_error(msg) : val;
295#else /* ARM_COMPUTE_ASSERTS_ENABLED */
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000296#define ARM_COMPUTE_ERROR_THROW_ON(status)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100297#define ARM_COMPUTE_ERROR_ON_MSG(cond, ...)
298#define ARM_COMPUTE_ERROR_ON_LOC_MSG(cond, func, file, line, ...)
299#define ARM_COMPUTE_CONST_ON_ERROR(cond, val, msg) val
300#endif /* ARM_COMPUTE_ASSERTS_ENABLED */
301
302/** If the condition is true then an error message is printed and an exception thrown
303 *
Georgios Pinitas3faea252017-10-30 14:13:50 +0000304 * @param[in] cond Condition to evaluate.
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100305 */
306#define ARM_COMPUTE_ERROR_ON(cond) \
307 ARM_COMPUTE_ERROR_ON_MSG(cond, #cond)
308
309/** If the condition is true then an error message is printed and an exception thrown
310 *
Georgios Pinitas3faea252017-10-30 14:13:50 +0000311 * @param[in] cond Condition to evaluate.
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100312 * @param[in] func Function in which the error occurred.
313 * @param[in] file File in which the error occurred.
314 * @param[in] line Line in which the error occurred.
315 */
316#define ARM_COMPUTE_ERROR_ON_LOC(cond, func, file, line) \
317 ARM_COMPUTE_ERROR_ON_LOC_MSG(cond, func, file, line, #cond)
318
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100319#endif /* __ARM_COMPUTE_ERROR_H__ */