ie_exception.hpp
Go to the documentation of this file.
1 // Copyright (C) 2018-2020 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
3 //
4 
5 /**
6  * @brief A header file for the main Inference Engine exception
7  *
8  * @file ie_exception.hpp
9  */
10 #pragma once
11 
12 #include <ie_api.h>
13 
14 #include <functional>
15 #include <memory>
16 #include <sstream>
17 #include <string>
18 #include <utility>
19 #include <vector>
20 
21 /**
22  * @def THROW_IE_EXCEPTION
23  * @brief A macro used to throw the exception with a notable description
24  */
25 #define THROW_IE_EXCEPTION throw InferenceEngine::details::InferenceEngineException(__FILE__, __LINE__)
26 
27 /**
28  * @def IE_ASSERT
29  * @brief Uses assert() function if NDEBUG is not defined, InferenceEngine exception otherwise
30  */
31 #ifdef NDEBUG
32 #define IE_ASSERT(EXPRESSION) \
33  if (!(EXPRESSION)) \
34  throw InferenceEngine::details::InferenceEngineException(__FILE__, __LINE__) \
35  << "AssertionFailed: " << #EXPRESSION // NOLINT
36 #else
37 #include <cassert>
38 
39 /**
40  * @private
41  */
42 class NullStream {
43 public:
44  template <class T>
45  NullStream& operator<<(const T&) noexcept {
46  return *this;
47  }
48 
49  NullStream& operator<<(std::ostream& (*)(std::ostream&)) noexcept {
50  return *this;
51  }
52 };
53 
54 #define IE_ASSERT(EXPRESSION) \
55  assert((EXPRESSION)); \
56  NullStream()
57 #endif // NDEBUG
58 
59 namespace InferenceEngine {
60 enum StatusCode : int;
61 namespace details {
62 
63 /**
64  * @brief The InferenceEngineException class implements the main Inference Engine exception
65  */
66 class INFERENCE_ENGINE_API_CLASS(InferenceEngineException): public std::exception {
67  mutable std::string errorDesc;
68  StatusCode status_code = static_cast<StatusCode>(0);
69  std::string _file;
70  int _line;
71  std::shared_ptr<std::stringstream> exception_stream;
72  bool save_to_status_code = false;
73 
74 public:
75  /**
76  * @brief A C++ std::exception API member
77  * @return An exception description with a file name and file line
78  */
79  const char* what() const noexcept override {
80  if (errorDesc.empty() && exception_stream) {
81  errorDesc = exception_stream->str();
82 #ifndef NDEBUG
83  errorDesc += "\n" + _file + ":" + std::to_string(_line);
84 #endif
85  }
86  return errorDesc.c_str();
87  }
88 
89  /**
90  * @brief A constructor. Creates an InferenceEngineException object from a specific file and line
91  * @param filename File where exception has been thrown
92  * @param line Line of the exception emitter
93  * @param message Exception message
94  */
95  InferenceEngineException(const std::string& filename, const int line, const std::string& message = "") noexcept;
96 
97  /**
98  * @brief noexcept required for copy ctor
99  * @details The C++ Standard, [except.throw], paragraph 3 [ISO/IEC 14882-2014]
100  */
101  InferenceEngineException(const InferenceEngineException& that) noexcept;
102 
103  /**
104  * @brief A stream output operator to be used within exception
105  * @param arg Object for serialization in the exception message
106  */
107  template <class T>
108  InferenceEngineException& operator<<(const T& arg) {
109  if (save_to_status_code) {
110  auto can_convert = status_code_assign(arg);
111  save_to_status_code = false;
112  if (can_convert.second) {
113  this->status_code = can_convert.first;
114  return *this;
115  }
116  }
117  if (!exception_stream) {
118  exception_stream.reset(new std::stringstream());
119  }
120  (*exception_stream) << arg;
121  return *this;
122  }
123 
124  /**
125  * @brief Manipulator to indicate that next item has to be converted to StatusCode to save
126  * @param iex InferenceEngineException object
127  */
128  friend InferenceEngineException& as_status(InferenceEngineException& iex) {
129  iex.save_to_status_code = true;
130  return iex;
131  }
132 
133  /**
134  * @brief A stream output operator to catch InferenceEngineException manipulators
135  * @param manip InferenceEngineException manipulator to call
136  */
137  InferenceEngineException& operator<<(InferenceEngineException& (*manip)(InferenceEngineException&)) {
138  return manip(*this);
139  }
140 
141  /** @brief Check if it has StatusCode value */
142  bool hasStatus() const {
143  return this->status_code == 0 ? false : true;
144  }
145 
146  /** @brief Get StatusCode value */
147  StatusCode getStatus() const {
148  return this->status_code;
149  }
150 
151  ~InferenceEngineException() noexcept override;
152 
153 private:
154  std::pair<StatusCode, bool> status_code_assign(const StatusCode& status) {
155  return {status, true};
156  }
157 
158  template <typename T>
159  std::pair<StatusCode, bool> status_code_assign(const T&) {
160  return {static_cast<StatusCode>(0), false};
161  }
162 };
163 
164 InferenceEngineException& as_status(InferenceEngineException& iex);
165 
166 static_assert(std::is_nothrow_copy_constructible<InferenceEngineException>::value,
167  "InferenceEngineException must be nothrow copy constructible");
168 } // namespace details
169 } // namespace InferenceEngine
Definition: cldnn_config.hpp:16
The macro defines a symbol import/export mechanism essential for Microsoft Windows(R) OS...