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 class NullStream {
40 public:
41  template <class T>
42  NullStream& operator<<(const T&) noexcept {
43  return *this;
44  }
45 
46  NullStream& operator<<(std::ostream& (*)(std::ostream&)) noexcept {
47  return *this;
48  }
49 };
50 
51 #define IE_ASSERT(EXPRESSION) \
52  assert((EXPRESSION)); \
53  NullStream()
54 #endif // NDEBUG
55 
56 namespace InferenceEngine {
57 enum StatusCode : int;
58 namespace details {
59 
60 /**
61  * @brief The InferenceEngineException class implements the main Inference Engine exception
62  */
63 class INFERENCE_ENGINE_API_CLASS(InferenceEngineException): public std::exception {
64  mutable std::string errorDesc;
65  StatusCode status_code = static_cast<StatusCode>(0);
66  std::string _file;
67  int _line;
68  std::shared_ptr<std::stringstream> exception_stream;
69  bool save_to_status_code = false;
70 
71 public:
72  /**
73  * @brief A C++ std::exception API member
74  * @return An exception description with a file name and file line
75  */
76  const char* what() const noexcept override {
77  if (errorDesc.empty() && exception_stream) {
78  errorDesc = exception_stream->str();
79 #ifndef NDEBUG
80  errorDesc += "\n" + _file + ":" + std::to_string(_line);
81 #endif
82  }
83  return errorDesc.c_str();
84  }
85 
86  /**
87  * @brief A constructor. Creates an InferenceEngineException object from a specific file and line
88  * @param filename File where exception has been thrown
89  * @param line Line of the exception emitter
90  */
91  InferenceEngineException(const std::string& filename, const int line): _file(filename), _line(line) {}
92 
93  /**
94  * @brief noexcept required for copy ctor
95  * @details The C++ Standard, [except.throw], paragraph 3 [ISO/IEC 14882-2014]
96  */
97  InferenceEngineException(const InferenceEngineException& that) noexcept {
98  errorDesc = that.errorDesc;
99  status_code = that.status_code;
100  _file = that._file;
101  _line = that._line;
102  exception_stream = that.exception_stream;
103  }
104 
105  /**
106  * @brief A stream output operator to be used within exception
107  * @param arg Object for serialization in the exception message
108  */
109  template <class T>
110  InferenceEngineException& operator<<(const T& arg) {
111  if (save_to_status_code) {
112  auto can_convert = status_code_assign(arg);
113  save_to_status_code = false;
114  if (can_convert.second) {
115  this->status_code = can_convert.first;
116  return *this;
117  }
118  }
119  if (!exception_stream) {
120  exception_stream.reset(new std::stringstream());
121  }
122  (*exception_stream) << arg;
123  return *this;
124  }
125 
126  /**
127  * @brief Manipulator to indicate that next item has to be converted to StatusCode to save
128  * @param iex InferenceEngineException object
129  */
130  friend InferenceEngineException& as_status(InferenceEngineException& iex) {
131  iex.save_to_status_code = true;
132  return iex;
133  }
134 
135  /**
136  * @brief A stream output operator to catch InferenceEngineException manipulators
137  * @param manip InferenceEngineException manipulator to call
138  */
139  InferenceEngineException& operator<<(InferenceEngineException& (*manip)(InferenceEngineException&)) {
140  return manip(*this);
141  }
142 
143  /** @brief Check if it has StatusCode value */
144  bool hasStatus() const {
145  return this->status_code == 0 ? false : true;
146  }
147 
148  /** @brief Get StatusCode value */
149  StatusCode getStatus() const {
150  return this->status_code;
151  }
152 
153  ~InferenceEngineException() noexcept override;
154 
155 private:
156  std::pair<StatusCode, bool> status_code_assign(const StatusCode& status) {
157  return {status, true};
158  }
159 
160  template <typename T>
161  std::pair<StatusCode, bool> status_code_assign(const T&) {
162  return {static_cast<StatusCode>(0), false};
163  }
164 };
165 
166 InferenceEngineException& as_status(InferenceEngineException& iex);
167 
168 static_assert(std::is_nothrow_copy_constructible<InferenceEngineException>::value,
169  "InferenceEngineException must be nothrow copy constructible");
170 } // namespace details
171 } // namespace InferenceEngine
Inference Engine API.
Definition: ie_argmax_layer.hpp:15
StatusCode
This enum contains codes for all possible return values of the interface functions.
Definition: ie_common.h:216
The macro defines a symbol import/export mechanism essential for Microsoft Windows(R) OS...
Definition: ie_exception.hpp:39