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