summaryrefslogtreecommitdiff
path: root/inference-engine/samples/validation_app/user_exception.hpp
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(); }
};