blob: bdeda3cb9d55b8531639d99aaa0cef87d4e0f016 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
// Copyright (C) 2018 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
/**
* @brief A header file for the user input exception
* \file user_exception.hpp
*/
#pragma once
#include <memory>
#include <string>
#include <sstream>
#include <list>
#include <functional>
/**
* @def THROW_USER_EXCEPTION
* @brief A macro used to throw the exception with a notable description
*/
#define THROW_USER_EXCEPTION(exitCode) \
throw UserException(exitCode)
/**
* @class UserException
* @brief The UserException class implements an exception appearing as a result of user input
*/
class UserException : public std::exception {
mutable std::string errorDesc;
std::shared_ptr<std::stringstream> exception_stream;
int _exitCode;
public:
/**
* @brief A C++ std::exception API member
* @return An exception description with a file name and file line
*/
const char *what() const noexcept override {
if (errorDesc.empty() && exception_stream) {
errorDesc = exception_stream->str();
}
return errorDesc.c_str();
}
/**
* @brief A constructor. Creates a UserException object
*/
explicit UserException(int exitCode) : _exitCode(exitCode) {
}
UserException(int exitCode, std::string msg) : _exitCode(exitCode) {
*this << msg;
}
/**
* @brief A stream output operator to be used within exception
* @param arg Object for serialization in the exception message
*/
template<class T>
UserException &operator<<(const T &arg) {
if (!exception_stream) {
exception_stream.reset(new std::stringstream());
}
(*exception_stream) << arg;
return *this;
}
int exitCode() const { return _exitCode; }
};
class UserExceptions : public std::exception {
std::list<UserException> _list;
mutable std::string msg;
public:
UserExceptions &operator<<(const UserException &arg) {
_list.push_back(arg);
return *this;
}
const char *what() const noexcept override {
std::stringstream ss;
if (_list.size() == 1) {
ss << _list.back().what();
} else {
auto iter = _list.begin();
for (int i = 0; i < _list.size() - 1; i++) {
ss << "\t* " << (*iter++).what() << std::endl;
}
ss << "\t* " << _list.back().what();
}
msg = ss.str();
return msg.c_str();
}
const std::list<UserException>& list() const {
return _list;
}
bool empty() const { return _list.empty(); }
};
|