Anthony Barbier | 6ff3b19 | 2017-09-04 18:44:23 +0100 | [diff] [blame] | 1 | /* |
Michalis Spyrou | 7c60c99 | 2019-10-10 14:33:47 +0100 | [diff] [blame] | 2 | * Copyright (c) 2016-2019 ARM Limited. |
Anthony Barbier | 6ff3b19 | 2017-09-04 18:44:23 +0100 | [diff] [blame] | 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 | */ |
Michalis Spyrou | f464337 | 2019-11-29 16:17:13 +0000 | [diff] [blame] | 24 | #ifndef ARM_COMPUTE_ERROR_H |
| 25 | #define ARM_COMPUTE_ERROR_H |
Anthony Barbier | 6ff3b19 | 2017-09-04 18:44:23 +0100 | [diff] [blame] | 26 | |
Michalis Spyrou | 7c60c99 | 2019-10-10 14:33:47 +0100 | [diff] [blame] | 27 | #include <array> |
Georgios Pinitas | 3faea25 | 2017-10-30 14:13:50 +0000 | [diff] [blame] | 28 | #include <string> |
| 29 | |
| 30 | namespace arm_compute |
| 31 | { |
Georgios Pinitas | d8734b5 | 2017-12-22 15:27:52 +0000 | [diff] [blame] | 32 | /** Ignores unused arguments |
| 33 | * |
| 34 | * @tparam T Argument types |
Alex Gilday | c357c47 | 2018-03-21 13:54:09 +0000 | [diff] [blame] | 35 | * |
| 36 | * @param[in] ... Ignored arguments |
Georgios Pinitas | d8734b5 | 2017-12-22 15:27:52 +0000 | [diff] [blame] | 37 | */ |
| 38 | template <typename... T> |
| 39 | inline void ignore_unused(T &&...) |
| 40 | { |
| 41 | } |
| 42 | |
| 43 | /** Available error codes */ |
Georgios Pinitas | 3faea25 | 2017-10-30 14:13:50 +0000 | [diff] [blame] | 44 | enum class ErrorCode |
| 45 | { |
Vidhya Sudhan Loganathan | 76c8564 | 2018-05-25 13:53:02 +0100 | [diff] [blame] | 46 | OK, /**< No error */ |
| 47 | RUNTIME_ERROR, /**< Generic runtime error */ |
| 48 | UNSUPPORTED_EXTENSION_USE /**< Unsupported extension used*/ |
Georgios Pinitas | 3faea25 | 2017-10-30 14:13:50 +0000 | [diff] [blame] | 49 | }; |
| 50 | |
Georgios Pinitas | 631c41a | 2017-12-06 11:53:03 +0000 | [diff] [blame] | 51 | /** Status class */ |
| 52 | class Status |
Georgios Pinitas | 3faea25 | 2017-10-30 14:13:50 +0000 | [diff] [blame] | 53 | { |
| 54 | public: |
| 55 | /** Default Constructor **/ |
Georgios Pinitas | 631c41a | 2017-12-06 11:53:03 +0000 | [diff] [blame] | 56 | Status() |
| 57 | : _code(ErrorCode::OK), _error_description(" ") |
Georgios Pinitas | 3faea25 | 2017-10-30 14:13:50 +0000 | [diff] [blame] | 58 | { |
| 59 | } |
| 60 | /** Default Constructor |
| 61 | * |
| 62 | * @param error_status Error status. |
Georgios Pinitas | 631c41a | 2017-12-06 11:53:03 +0000 | [diff] [blame] | 63 | * @param error_description (Optional) Error description if error_status is not valid. |
Georgios Pinitas | 3faea25 | 2017-10-30 14:13:50 +0000 | [diff] [blame] | 64 | */ |
Georgios Pinitas | 631c41a | 2017-12-06 11:53:03 +0000 | [diff] [blame] | 65 | explicit Status(ErrorCode error_status, std::string error_description = " ") |
| 66 | : _code(error_status), _error_description(error_description) |
Georgios Pinitas | 3faea25 | 2017-10-30 14:13:50 +0000 | [diff] [blame] | 67 | { |
| 68 | } |
| 69 | /** Allow instances of this class to be copy constructed */ |
Georgios Pinitas | 631c41a | 2017-12-06 11:53:03 +0000 | [diff] [blame] | 70 | Status(const Status &) = default; |
Georgios Pinitas | 3faea25 | 2017-10-30 14:13:50 +0000 | [diff] [blame] | 71 | /** Allow instances of this class to be move constructed */ |
Georgios Pinitas | 631c41a | 2017-12-06 11:53:03 +0000 | [diff] [blame] | 72 | Status(Status &&) = default; |
Georgios Pinitas | 3faea25 | 2017-10-30 14:13:50 +0000 | [diff] [blame] | 73 | /** Allow instances of this class to be copy assigned */ |
Georgios Pinitas | 631c41a | 2017-12-06 11:53:03 +0000 | [diff] [blame] | 74 | Status &operator=(const Status &) = default; |
Georgios Pinitas | 3faea25 | 2017-10-30 14:13:50 +0000 | [diff] [blame] | 75 | /** Allow instances of this class to be move assigned */ |
Georgios Pinitas | 631c41a | 2017-12-06 11:53:03 +0000 | [diff] [blame] | 76 | Status &operator=(Status &&) = default; |
Georgios Pinitas | 3faea25 | 2017-10-30 14:13:50 +0000 | [diff] [blame] | 77 | /** Explicit bool conversion operator |
| 78 | * |
Georgios Pinitas | 631c41a | 2017-12-06 11:53:03 +0000 | [diff] [blame] | 79 | * @return True if there is no error else false |
Georgios Pinitas | 3faea25 | 2017-10-30 14:13:50 +0000 | [diff] [blame] | 80 | */ |
| 81 | explicit operator bool() const noexcept |
| 82 | { |
Georgios Pinitas | 631c41a | 2017-12-06 11:53:03 +0000 | [diff] [blame] | 83 | return _code == ErrorCode::OK; |
Georgios Pinitas | 3faea25 | 2017-10-30 14:13:50 +0000 | [diff] [blame] | 84 | } |
| 85 | /** Gets error code |
| 86 | * |
| 87 | * @return Error code. |
| 88 | */ |
| 89 | ErrorCode error_code() const |
| 90 | { |
| 91 | return _code; |
| 92 | } |
| 93 | /** Gets error description if any |
| 94 | * |
| 95 | * @return Error description. |
| 96 | */ |
Georgios Pinitas | 631c41a | 2017-12-06 11:53:03 +0000 | [diff] [blame] | 97 | std::string error_description() const |
Georgios Pinitas | 3faea25 | 2017-10-30 14:13:50 +0000 | [diff] [blame] | 98 | { |
Georgios Pinitas | 631c41a | 2017-12-06 11:53:03 +0000 | [diff] [blame] | 99 | return _error_description; |
Georgios Pinitas | 3faea25 | 2017-10-30 14:13:50 +0000 | [diff] [blame] | 100 | } |
| 101 | /** Throws a runtime exception in case it contains a valid error status */ |
Diego Lopez Recas | 35ceeb2 | 2017-12-04 18:56:10 +0000 | [diff] [blame] | 102 | void throw_if_error() const |
Georgios Pinitas | 3faea25 | 2017-10-30 14:13:50 +0000 | [diff] [blame] | 103 | { |
Georgios Pinitas | 631c41a | 2017-12-06 11:53:03 +0000 | [diff] [blame] | 104 | if(!bool(*this)) |
Georgios Pinitas | 3faea25 | 2017-10-30 14:13:50 +0000 | [diff] [blame] | 105 | { |
| 106 | internal_throw_on_error(); |
| 107 | } |
| 108 | } |
| 109 | |
| 110 | private: |
| 111 | /** Internal throwing function */ |
Diego Lopez Recas | 35ceeb2 | 2017-12-04 18:56:10 +0000 | [diff] [blame] | 112 | [[noreturn]] void internal_throw_on_error() const; |
Georgios Pinitas | 3faea25 | 2017-10-30 14:13:50 +0000 | [diff] [blame] | 113 | |
| 114 | private: |
| 115 | ErrorCode _code; |
Georgios Pinitas | 631c41a | 2017-12-06 11:53:03 +0000 | [diff] [blame] | 116 | std::string _error_description; |
Georgios Pinitas | 3faea25 | 2017-10-30 14:13:50 +0000 | [diff] [blame] | 117 | }; |
| 118 | |
| 119 | /** Creates an error containing the error message |
| 120 | * |
| 121 | * @param[in] error_code Error code |
Georgios Pinitas | 3faea25 | 2017-10-30 14:13:50 +0000 | [diff] [blame] | 122 | * @param[in] msg Message to display before aborting. |
Georgios Pinitas | 631c41a | 2017-12-06 11:53:03 +0000 | [diff] [blame] | 123 | * |
| 124 | * @return status containing the error |
Georgios Pinitas | 3faea25 | 2017-10-30 14:13:50 +0000 | [diff] [blame] | 125 | */ |
Michalis Spyrou | 7c60c99 | 2019-10-10 14:33:47 +0100 | [diff] [blame] | 126 | Status create_error(ErrorCode error_code, std::string msg); |
| 127 | |
| 128 | /** Creates an error and the error message |
Georgios Pinitas | 3faea25 | 2017-10-30 14:13:50 +0000 | [diff] [blame] | 129 | * |
Michalis Spyrou | 7c60c99 | 2019-10-10 14:33:47 +0100 | [diff] [blame] | 130 | * @param[in] error_code Error code |
| 131 | * @param[in] func Function in which the error occurred. |
| 132 | * @param[in] file File in which the error occurred. |
| 133 | * @param[in] line Line in which the error occurred. |
| 134 | * @param[in] msg Message to display before aborting. |
| 135 | * |
| 136 | * @return status containing the error |
Georgios Pinitas | 3faea25 | 2017-10-30 14:13:50 +0000 | [diff] [blame] | 137 | */ |
Michalis Spyrou | 7c60c99 | 2019-10-10 14:33:47 +0100 | [diff] [blame] | 138 | Status create_error_msg(ErrorCode error_code, const char *func, const char *file, int line, const char *msg); |
| 139 | /** Throw an std::runtime_error |
| 140 | * |
| 141 | * @param[in] err Error status |
| 142 | */ |
| 143 | [[noreturn]] void throw_error(Status err); |
Georgios Pinitas | 3faea25 | 2017-10-30 14:13:50 +0000 | [diff] [blame] | 144 | } |
| 145 | /** To avoid unused variables warnings |
| 146 | * |
| 147 | * This is useful if for example a variable is only used |
| 148 | * in debug builds and generates a warning in release builds. |
| 149 | * |
Georgios Pinitas | d8734b5 | 2017-12-22 15:27:52 +0000 | [diff] [blame] | 150 | * @param[in] ... Variables which are unused. |
Georgios Pinitas | 3faea25 | 2017-10-30 14:13:50 +0000 | [diff] [blame] | 151 | */ |
Anthony Barbier | c8e84b5 | 2018-07-17 16:48:42 +0100 | [diff] [blame] | 152 | #define ARM_COMPUTE_UNUSED(...) ::arm_compute::ignore_unused(__VA_ARGS__) // NOLINT |
Georgios Pinitas | 3faea25 | 2017-10-30 14:13:50 +0000 | [diff] [blame] | 153 | |
| 154 | /** Creates an error with a given message |
| 155 | * |
| 156 | * @param[in] error_code Error code. |
Michalis Spyrou | 7c60c99 | 2019-10-10 14:33:47 +0100 | [diff] [blame] | 157 | * @param[in] msg Message to encapsulate. |
Georgios Pinitas | 3faea25 | 2017-10-30 14:13:50 +0000 | [diff] [blame] | 158 | */ |
Michalis Spyrou | 7c60c99 | 2019-10-10 14:33:47 +0100 | [diff] [blame] | 159 | #define ARM_COMPUTE_CREATE_ERROR(error_code, msg) arm_compute::create_error_msg(error_code, __func__, __FILE__, __LINE__, msg) |
Georgios Pinitas | 3faea25 | 2017-10-30 14:13:50 +0000 | [diff] [blame] | 160 | |
| 161 | /** Creates an error on location with a given message |
| 162 | * |
| 163 | * @param[in] error_code Error code. |
| 164 | * @param[in] func Function in which the error occurred. |
| 165 | * @param[in] file File in which the error occurred. |
| 166 | * @param[in] line Line in which the error occurred. |
Michalis Spyrou | 7c60c99 | 2019-10-10 14:33:47 +0100 | [diff] [blame] | 167 | * @param[in] msg Message to display before aborting. |
Georgios Pinitas | 3faea25 | 2017-10-30 14:13:50 +0000 | [diff] [blame] | 168 | */ |
Michalis Spyrou | 7c60c99 | 2019-10-10 14:33:47 +0100 | [diff] [blame] | 169 | #define ARM_COMPUTE_CREATE_ERROR_LOC(error_code, func, file, line, msg) arm_compute::create_error_msg(error_code, func, file, line, msg) |
| 170 | |
| 171 | /** Creates an error on location with a given message. Accepts a message format |
| 172 | * and a variable list of arguments matching the format description. |
| 173 | * |
| 174 | * @param[in] error_code Error code. |
| 175 | * @param[in] func Function in which the error occurred. |
| 176 | * @param[in] file File in which the error occurred. |
| 177 | * @param[in] line Line in which the error occurred. |
| 178 | * @param[in] msg Error description message format. |
| 179 | * @param[in] ... List of arguments matching the format description. |
| 180 | */ |
| 181 | #define ARM_COMPUTE_CREATE_ERROR_LOC_VAR(error_code, func, file, line, msg, ...) \ |
| 182 | do \ |
| 183 | { \ |
| 184 | std::array<char, 512> out{ 0 }; \ |
| 185 | int offset = snprintf(out.data(), out.size(), "in %s %s:%d: ", func, file, line); \ |
| 186 | snprintf(out.data() + offset, out.size() - offset, msg, __VA_ARGS__); \ |
| 187 | arm_compute::create_error(error_code, std::string(out.data())); \ |
| 188 | } while(false) |
Georgios Pinitas | 3faea25 | 2017-10-30 14:13:50 +0000 | [diff] [blame] | 189 | |
Vidhya Sudhan Loganathan | 3ca9786 | 2018-04-23 08:20:04 +0100 | [diff] [blame] | 190 | /** An error is returned with the given description. |
| 191 | * |
| 192 | * @param[in] ... Error description message. |
| 193 | */ |
| 194 | #define ARM_COMPUTE_RETURN_ERROR_MSG(...) \ |
| 195 | do \ |
| 196 | { \ |
| 197 | return ARM_COMPUTE_CREATE_ERROR(arm_compute::ErrorCode::RUNTIME_ERROR, __VA_ARGS__); \ |
| 198 | } while(false) |
| 199 | |
Georgios Pinitas | 631c41a | 2017-12-06 11:53:03 +0000 | [diff] [blame] | 200 | /** Checks if a status contains an error and returns it |
Georgios Pinitas | 3faea25 | 2017-10-30 14:13:50 +0000 | [diff] [blame] | 201 | * |
Georgios Pinitas | 631c41a | 2017-12-06 11:53:03 +0000 | [diff] [blame] | 202 | * @param[in] status Status value to check |
Georgios Pinitas | 3faea25 | 2017-10-30 14:13:50 +0000 | [diff] [blame] | 203 | */ |
Georgios Pinitas | 631c41a | 2017-12-06 11:53:03 +0000 | [diff] [blame] | 204 | #define ARM_COMPUTE_RETURN_ON_ERROR(status) \ |
| 205 | do \ |
| 206 | { \ |
| 207 | if(!bool(status)) \ |
| 208 | { \ |
| 209 | return status; \ |
| 210 | } \ |
Georgios Pinitas | 3faea25 | 2017-10-30 14:13:50 +0000 | [diff] [blame] | 211 | } while(false) |
| 212 | |
| 213 | /** Checks if an error value is valid if not throws an exception with the error |
| 214 | * |
| 215 | * @param[in] error Error value to check. |
| 216 | */ |
| 217 | #define ARM_COMPUTE_THROW_ON_ERROR(error) \ |
| 218 | error.throw_if_error(); |
| 219 | |
Michalis Spyrou | 7c60c99 | 2019-10-10 14:33:47 +0100 | [diff] [blame] | 220 | /** If the condition is true, an error is returned. Accepts a message format |
| 221 | * and a variable list of arguments matching the format description. |
| 222 | * |
| 223 | * @param[in] cond Condition to evaluate. |
| 224 | * @param[in] msg Error description message format. |
| 225 | * @param[in] ... List of arguments matching the format description. |
| 226 | */ |
| 227 | #define ARM_COMPUTE_RETURN_ERROR_ON_MSG_VAR(cond, msg, ...) \ |
| 228 | do \ |
| 229 | { \ |
| 230 | if(cond) \ |
| 231 | { \ |
| 232 | std::array<char, 512> out{ 0 }; \ |
| 233 | int offset = snprintf(out.data(), out.size(), "in %s %s:%d: ", __func__, __FILE__, __LINE__); \ |
| 234 | snprintf(out.data() + offset, out.size() - offset, msg, __VA_ARGS__); \ |
| 235 | return arm_compute::create_error(arm_compute::ErrorCode::RUNTIME_ERROR, std::string(out.data())); \ |
| 236 | } \ |
| 237 | } while(false) |
| 238 | |
Georgios Pinitas | 3faea25 | 2017-10-30 14:13:50 +0000 | [diff] [blame] | 239 | /** If the condition is true, an error is returned |
| 240 | * |
| 241 | * @param[in] cond Condition to evaluate. |
Michalis Spyrou | 7c60c99 | 2019-10-10 14:33:47 +0100 | [diff] [blame] | 242 | * @param[in] msg Error description message |
Georgios Pinitas | 3faea25 | 2017-10-30 14:13:50 +0000 | [diff] [blame] | 243 | */ |
Michalis Spyrou | 7c60c99 | 2019-10-10 14:33:47 +0100 | [diff] [blame] | 244 | #define ARM_COMPUTE_RETURN_ERROR_ON_MSG(cond, msg) \ |
| 245 | do \ |
| 246 | { \ |
| 247 | if(cond) \ |
| 248 | { \ |
| 249 | return arm_compute::create_error_msg(arm_compute::ErrorCode::RUNTIME_ERROR, __func__, __FILE__, __LINE__, msg); \ |
| 250 | } \ |
Georgios Pinitas | 3faea25 | 2017-10-30 14:13:50 +0000 | [diff] [blame] | 251 | } while(false) |
| 252 | |
Michalis Spyrou | 7c60c99 | 2019-10-10 14:33:47 +0100 | [diff] [blame] | 253 | /** If the condition is true, an error is thrown. Accepts a message format |
| 254 | * and a variable list of arguments matching the format description. |
Georgios Pinitas | 3faea25 | 2017-10-30 14:13:50 +0000 | [diff] [blame] | 255 | * |
| 256 | * @param[in] cond Condition to evaluate. |
| 257 | * @param[in] func Function in which the error occurred. |
| 258 | * @param[in] file File in which the error occurred. |
| 259 | * @param[in] line Line in which the error occurred. |
Michalis Spyrou | 7c60c99 | 2019-10-10 14:33:47 +0100 | [diff] [blame] | 260 | * @param[in] msg Error description message format. |
| 261 | * @param[in] ... List of arguments matching the format description. |
Georgios Pinitas | 3faea25 | 2017-10-30 14:13:50 +0000 | [diff] [blame] | 262 | */ |
Michalis Spyrou | 7c60c99 | 2019-10-10 14:33:47 +0100 | [diff] [blame] | 263 | #define ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG_VAR(cond, func, file, line, msg, ...) \ |
| 264 | do \ |
| 265 | { \ |
| 266 | if(cond) \ |
| 267 | { \ |
| 268 | std::array<char, 512> out{ 0 }; \ |
| 269 | int offset = snprintf(out.data(), out.size(), "in %s %s:%d: ", func, file, line); \ |
| 270 | snprintf(out.data() + offset, out.size() - offset, msg, __VA_ARGS__); \ |
| 271 | return arm_compute::create_error(ErrorCode::RUNTIME_ERROR, std::string(out.data())); \ |
| 272 | } \ |
| 273 | } while(false) |
| 274 | |
| 275 | /** If the condition is true, an error is thrown. |
| 276 | * |
| 277 | * @param[in] cond Condition to evaluate. |
| 278 | * @param[in] func Function in which the error occurred. |
| 279 | * @param[in] file File in which the error occurred. |
| 280 | * @param[in] line Line in which the error occurred. |
| 281 | * @param[in] msg Message to display. |
| 282 | */ |
| 283 | #define ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG(cond, func, file, line, msg) \ |
| 284 | do \ |
| 285 | { \ |
| 286 | if(cond) \ |
| 287 | { \ |
| 288 | return arm_compute::create_error_msg(ErrorCode::RUNTIME_ERROR, func, file, line, msg); \ |
| 289 | } \ |
Georgios Pinitas | 3faea25 | 2017-10-30 14:13:50 +0000 | [diff] [blame] | 290 | } while(false) |
| 291 | |
| 292 | /** If the condition is true, an error is returned |
| 293 | * |
| 294 | * @param[in] cond Condition to evaluate |
| 295 | */ |
| 296 | #define ARM_COMPUTE_RETURN_ERROR_ON(cond) \ |
| 297 | ARM_COMPUTE_RETURN_ERROR_ON_MSG(cond, #cond) |
| 298 | |
| 299 | /** If the condition is true, an error is returned |
| 300 | * |
| 301 | * @param[in] cond Condition to evaluate. |
| 302 | * @param[in] func Function in which the error occurred. |
| 303 | * @param[in] file File in which the error occurred. |
| 304 | * @param[in] line Line in which the error occurred. |
| 305 | */ |
| 306 | #define ARM_COMPUTE_RETURN_ERROR_ON_LOC(cond, func, file, line) \ |
| 307 | ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG(cond, func, file, line, #cond) |
| 308 | |
Anthony Barbier | 6ff3b19 | 2017-09-04 18:44:23 +0100 | [diff] [blame] | 309 | /** Print the given message then throw an std::runtime_error. |
| 310 | * |
Michalis Spyrou | 7c60c99 | 2019-10-10 14:33:47 +0100 | [diff] [blame] | 311 | * @param[in] func Function in which the error occurred. |
| 312 | * @param[in] file File in which the error occurred. |
| 313 | * @param[in] line Line in which the error occurred. |
| 314 | * @param[in] msg Message to display. |
Anthony Barbier | 6ff3b19 | 2017-09-04 18:44:23 +0100 | [diff] [blame] | 315 | */ |
Michalis Spyrou | 7c60c99 | 2019-10-10 14:33:47 +0100 | [diff] [blame] | 316 | #define ARM_COMPUTE_THROW_ERROR(func, file, line, msg) \ |
| 317 | do \ |
| 318 | { \ |
| 319 | arm_compute::throw_error(arm_compute::create_error_msg(arm_compute::ErrorCode::RUNTIME_ERROR, func, file, line, msg)); \ |
| 320 | } while(false) |
| 321 | |
| 322 | /** Print the given message then throw an std::runtime_error. Accepts a message format |
| 323 | * and a variable list of arguments matching the format description. |
| 324 | * |
| 325 | * @param[in] func Function in which the error occurred. |
| 326 | * @param[in] file File in which the error occurred. |
| 327 | * @param[in] line Line in which the error occurred. |
| 328 | * @param[in] msg Error description message format. |
| 329 | * @param[in] ... List of arguments matching the format description. |
| 330 | */ |
| 331 | #define ARM_COMPUTE_THROW_ERROR_VAR(func, file, line, msg, ...) \ |
| 332 | do \ |
| 333 | { \ |
| 334 | std::array<char, 512> out{ 0 }; \ |
| 335 | int offset = snprintf(out.data(), out.size(), "in %s %s:%d: ", func, file, line); \ |
| 336 | snprintf(out.data() + offset, out.size() - offset, msg, __VA_ARGS__); \ |
| 337 | arm_compute::throw_error(arm_compute::Status(arm_compute::ErrorCode::RUNTIME_ERROR, std::string(out.data()))); \ |
| 338 | } while(false) |
| 339 | |
| 340 | /** Print the given message then throw an std::runtime_error. Accepts a message format |
| 341 | * and a variable list of arguments matching the format description. |
| 342 | * |
| 343 | * @param[in] msg Error description message format. |
| 344 | * @param[in] ... List of arguments matching the format description. |
| 345 | */ |
| 346 | #define ARM_COMPUTE_ERROR_VAR(msg, ...) ARM_COMPUTE_THROW_ERROR_VAR(__func__, __FILE__, __LINE__, msg, __VA_ARGS__) |
| 347 | |
| 348 | /** Print the given message then throw an std::runtime_error. |
| 349 | * |
| 350 | * @param[in] msg Message to display. |
| 351 | */ |
| 352 | #define ARM_COMPUTE_ERROR(msg) ARM_COMPUTE_THROW_ERROR(__func__, __FILE__, __LINE__, msg) |
| 353 | |
| 354 | /** Print the given message then throw an std::runtime_error. Accepts a message format |
| 355 | * and a variable list of arguments matching the format description. |
| 356 | * |
| 357 | * @param[in] func Function in which the error occurred. |
| 358 | * @param[in] file File in which the error occurred. |
| 359 | * @param[in] line Line in which the error occurred. |
| 360 | * @param[in] msg Error description message format. |
| 361 | * @param[in] ... List of arguments matching the format description. |
| 362 | */ |
| 363 | #define ARM_COMPUTE_ERROR_LOC_VAR(func, file, line, msg, ...) ARM_COMPUTE_THROW_ERROR_VAR(func, file, line, msg, __VA_ARGS__) // NOLINT |
Anthony Barbier | 6ff3b19 | 2017-09-04 18:44:23 +0100 | [diff] [blame] | 364 | |
| 365 | /** Print the given message then throw an std::runtime_error. |
| 366 | * |
| 367 | * @param[in] func Function in which the error occurred. |
| 368 | * @param[in] file File in which the error occurred. |
| 369 | * @param[in] line Line in which the error occurred. |
Michalis Spyrou | 7c60c99 | 2019-10-10 14:33:47 +0100 | [diff] [blame] | 370 | * @param[in] msg Message to display. |
Anthony Barbier | 6ff3b19 | 2017-09-04 18:44:23 +0100 | [diff] [blame] | 371 | */ |
Michalis Spyrou | 7c60c99 | 2019-10-10 14:33:47 +0100 | [diff] [blame] | 372 | #define ARM_COMPUTE_ERROR_LOC(func, file, line, msg) ARM_COMPUTE_THROW_ERROR(func, file, line, msg) // NOLINT |
Anthony Barbier | 6ff3b19 | 2017-09-04 18:44:23 +0100 | [diff] [blame] | 373 | |
Georgios Pinitas | 6ed43b5 | 2018-07-12 17:34:22 +0100 | [diff] [blame] | 374 | /** If the condition is true, the given message is printed and program exits |
| 375 | * |
| 376 | * @param[in] cond Condition to evaluate. |
Michalis Spyrou | 7c60c99 | 2019-10-10 14:33:47 +0100 | [diff] [blame] | 377 | * @param[in] msg Message to display. |
Georgios Pinitas | 6ed43b5 | 2018-07-12 17:34:22 +0100 | [diff] [blame] | 378 | */ |
Michalis Spyrou | 7c60c99 | 2019-10-10 14:33:47 +0100 | [diff] [blame] | 379 | #define ARM_COMPUTE_EXIT_ON_MSG(cond, msg) \ |
| 380 | do \ |
| 381 | { \ |
| 382 | if(cond) \ |
| 383 | { \ |
| 384 | ARM_COMPUTE_ERROR(msg); \ |
| 385 | } \ |
| 386 | } while(false) |
| 387 | |
| 388 | /** If the condition is true, the given message is printed and program exits. Accepts a message format |
| 389 | * and a variable list of arguments matching the format description. |
| 390 | * |
| 391 | * @param[in] cond Condition to evaluate. |
| 392 | * @param[in] msg Error description message format. |
| 393 | * @param[in] ... List of arguments matching the format description. |
| 394 | */ |
| 395 | #define ARM_COMPUTE_EXIT_ON_MSG_VAR(cond, msg, ...) \ |
| 396 | do \ |
| 397 | { \ |
| 398 | if(cond) \ |
| 399 | { \ |
| 400 | ARM_COMPUTE_ERROR_VAR(msg, __VA_ARGS__); \ |
| 401 | } \ |
Georgios Pinitas | 6ed43b5 | 2018-07-12 17:34:22 +0100 | [diff] [blame] | 402 | } while(false) |
| 403 | |
Anthony Barbier | 6ff3b19 | 2017-09-04 18:44:23 +0100 | [diff] [blame] | 404 | #ifdef ARM_COMPUTE_ASSERTS_ENABLED |
Georgios Pinitas | 631c41a | 2017-12-06 11:53:03 +0000 | [diff] [blame] | 405 | /** Checks if a status value is valid if not throws an exception with the error |
Georgios Pinitas | 3faea25 | 2017-10-30 14:13:50 +0000 | [diff] [blame] | 406 | * |
Georgios Pinitas | 631c41a | 2017-12-06 11:53:03 +0000 | [diff] [blame] | 407 | * @param[in] status Status value to check. |
Georgios Pinitas | 3faea25 | 2017-10-30 14:13:50 +0000 | [diff] [blame] | 408 | */ |
Georgios Pinitas | 631c41a | 2017-12-06 11:53:03 +0000 | [diff] [blame] | 409 | #define ARM_COMPUTE_ERROR_THROW_ON(status) \ |
| 410 | status.throw_if_error() |
Georgios Pinitas | 3faea25 | 2017-10-30 14:13:50 +0000 | [diff] [blame] | 411 | |
Anthony Barbier | 6ff3b19 | 2017-09-04 18:44:23 +0100 | [diff] [blame] | 412 | /** If the condition is true, the given message is printed and an exception is thrown |
| 413 | * |
| 414 | * @param[in] cond Condition to evaluate. |
Michalis Spyrou | 7c60c99 | 2019-10-10 14:33:47 +0100 | [diff] [blame] | 415 | * @param[in] msg Message to display. |
Anthony Barbier | 6ff3b19 | 2017-09-04 18:44:23 +0100 | [diff] [blame] | 416 | */ |
Michalis Spyrou | 7c60c99 | 2019-10-10 14:33:47 +0100 | [diff] [blame] | 417 | #define ARM_COMPUTE_ERROR_ON_MSG(cond, msg) \ |
| 418 | ARM_COMPUTE_EXIT_ON_MSG(cond, msg) |
Anthony Barbier | 6ff3b19 | 2017-09-04 18:44:23 +0100 | [diff] [blame] | 419 | |
Michalis Spyrou | 7c60c99 | 2019-10-10 14:33:47 +0100 | [diff] [blame] | 420 | /** If the condition is true, the given message is printed and an exception is thrown. Accepts a message format |
| 421 | * and a variable list of arguments matching the format description. |
| 422 | * |
| 423 | * @param[in] cond Condition to evaluate. |
| 424 | * @param[in] msg Error description message format. |
| 425 | * @param[in] ... List of arguments matching the format description. |
| 426 | */ |
| 427 | #define ARM_COMPUTE_ERROR_ON_MSG_VAR(cond, msg, ...) \ |
| 428 | ARM_COMPUTE_EXIT_ON_MSG_VAR(cond, msg, __VA_ARGS__) |
| 429 | |
| 430 | /** If the condition is true, the given message is printed and an exception is thrown. |
Anthony Barbier | 6ff3b19 | 2017-09-04 18:44:23 +0100 | [diff] [blame] | 431 | * |
| 432 | * @param[in] cond Condition to evaluate. |
| 433 | * @param[in] func Function in which the error occurred. |
| 434 | * @param[in] file File in which the error occurred. |
| 435 | * @param[in] line Line in which the error occurred. |
| 436 | * @param[in] ... Message to print if cond is false. |
| 437 | */ |
Michalis Spyrou | 7c60c99 | 2019-10-10 14:33:47 +0100 | [diff] [blame] | 438 | #define ARM_COMPUTE_ERROR_ON_LOC_MSG(cond, func, file, line, ...) \ |
| 439 | do \ |
| 440 | { \ |
| 441 | if(cond) \ |
| 442 | { \ |
| 443 | ARM_COMPUTE_ERROR_LOC_VAR(func, file, line, __VA_ARGS__); \ |
| 444 | } \ |
Georgios Pinitas | 6ed43b5 | 2018-07-12 17:34:22 +0100 | [diff] [blame] | 445 | } while(false) |
Anthony Barbier | 6ff3b19 | 2017-09-04 18:44:23 +0100 | [diff] [blame] | 446 | |
| 447 | /** If the condition is true, the given message is printed and an exception is thrown, otherwise value is returned |
| 448 | * |
| 449 | * @param[in] cond Condition to evaluate. |
| 450 | * @param[in] val Value to be returned. |
| 451 | * @param[in] msg Message to print if cond is false. |
| 452 | */ |
| 453 | #define ARM_COMPUTE_CONST_ON_ERROR(cond, val, msg) (cond) ? throw std::logic_error(msg) : val; |
| 454 | #else /* ARM_COMPUTE_ASSERTS_ENABLED */ |
Georgios Pinitas | 631c41a | 2017-12-06 11:53:03 +0000 | [diff] [blame] | 455 | #define ARM_COMPUTE_ERROR_THROW_ON(status) |
Michalis Spyrou | 7c60c99 | 2019-10-10 14:33:47 +0100 | [diff] [blame] | 456 | #define ARM_COMPUTE_ERROR_ON_MSG(cond, msg) |
| 457 | #define ARM_COMPUTE_ERROR_ON_MSG_VAR(cond, msg, ...) |
Anthony Barbier | 6ff3b19 | 2017-09-04 18:44:23 +0100 | [diff] [blame] | 458 | #define ARM_COMPUTE_ERROR_ON_LOC_MSG(cond, func, file, line, ...) |
| 459 | #define ARM_COMPUTE_CONST_ON_ERROR(cond, val, msg) val |
| 460 | #endif /* ARM_COMPUTE_ASSERTS_ENABLED */ |
| 461 | |
| 462 | /** If the condition is true then an error message is printed and an exception thrown |
| 463 | * |
Georgios Pinitas | 3faea25 | 2017-10-30 14:13:50 +0000 | [diff] [blame] | 464 | * @param[in] cond Condition to evaluate. |
Anthony Barbier | 6ff3b19 | 2017-09-04 18:44:23 +0100 | [diff] [blame] | 465 | */ |
| 466 | #define ARM_COMPUTE_ERROR_ON(cond) \ |
| 467 | ARM_COMPUTE_ERROR_ON_MSG(cond, #cond) |
| 468 | |
| 469 | /** If the condition is true then an error message is printed and an exception thrown |
| 470 | * |
Georgios Pinitas | 3faea25 | 2017-10-30 14:13:50 +0000 | [diff] [blame] | 471 | * @param[in] cond Condition to evaluate. |
Anthony Barbier | 6ff3b19 | 2017-09-04 18:44:23 +0100 | [diff] [blame] | 472 | * @param[in] func Function in which the error occurred. |
| 473 | * @param[in] file File in which the error occurred. |
| 474 | * @param[in] line Line in which the error occurred. |
| 475 | */ |
| 476 | #define ARM_COMPUTE_ERROR_ON_LOC(cond, func, file, line) \ |
Michalis Spyrou | 7c60c99 | 2019-10-10 14:33:47 +0100 | [diff] [blame] | 477 | ARM_COMPUTE_ERROR_ON_LOC_MSG(cond, func, file, line, "%s", #cond) |
Anthony Barbier | 6ff3b19 | 2017-09-04 18:44:23 +0100 | [diff] [blame] | 478 | |
Michalis Spyrou | 323ce0f | 2018-11-30 16:30:43 +0000 | [diff] [blame] | 479 | #ifndef ARM_COMPUTE_EXCEPTIONS_DISABLED |
| 480 | #define ARM_COMPUTE_THROW(ex) throw(ex) |
| 481 | #else /* ARM_COMPUTE_EXCEPTIONS_DISABLED */ |
| 482 | #define ARM_COMPUTE_THROW(ex) (ex), std::abort() |
| 483 | #endif /* ARM_COMPUTE_EXCEPTIONS_DISABLED */ |
| 484 | |
Michalis Spyrou | f464337 | 2019-11-29 16:17:13 +0000 | [diff] [blame] | 485 | #endif /* ARM_COMPUTE_ERROR_H */ |