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