128 lines
4.4 KiB
C++
128 lines
4.4 KiB
C++
/*************************************************************************
|
|
* Copyright (C) [2023-2024] by Cambricon, Inc.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
*************************************************************************/
|
|
#ifndef CSRC_COMMON_STACK_EXCEPTION_H_
|
|
#define CSRC_COMMON_STACK_EXCEPTION_H_
|
|
|
|
#include <sstream>
|
|
#include <stdexcept>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
namespace tmo {
|
|
namespace stack_exception {
|
|
/** Call-stack entry datastructure. */
|
|
struct entry {
|
|
/** Default constructor that clears all fields. */
|
|
entry() : line(0) {}
|
|
|
|
std::string file; ///< filename
|
|
size_t line; ///< line number
|
|
std::string function; ///< name of function or method
|
|
|
|
/** Serialize entry into a text string. */
|
|
std::string to_string() const {
|
|
std::ostringstream os;
|
|
os << file;
|
|
if (line > 0) {
|
|
os << ":" << line;
|
|
}
|
|
os << " @" << function;
|
|
return os.str();
|
|
}
|
|
};
|
|
|
|
/** Stack-trace base class, for retrieving the current call-stack. */
|
|
class call_stack {
|
|
public:
|
|
/** Stack-trace consructor.
|
|
\param num_discard - number of stack entries to discard at the top. */
|
|
call_stack(const size_t num_discard = 0);
|
|
|
|
virtual ~call_stack() throw();
|
|
|
|
/** Serializes the entire call-stack into a text string. */
|
|
std::string to_string() const {
|
|
std::ostringstream os;
|
|
for (size_t i = 0; i < stack.size(); i++)
|
|
os << stack[i].to_string() << std::endl;
|
|
return os.str();
|
|
}
|
|
|
|
/** Call stack. */
|
|
std::vector<entry> stack;
|
|
};
|
|
|
|
/** Abstract base-class for all stack-augmented exception classes.
|
|
* Enables catching of all stack-augmented exception classes. */
|
|
class stack_exception_base : public call_stack {
|
|
public:
|
|
stack_exception_base(const bool _show_stack) : call_stack(2), show_stack(_show_stack) {}
|
|
virtual ~stack_exception_base() throw() {}
|
|
|
|
virtual const char *what() const throw() = 0;
|
|
|
|
/// flag to indicate if stack-trace is included in what() messages
|
|
bool show_stack;
|
|
};
|
|
|
|
/** Template for stack-augmented exception classes. */
|
|
template <class T>
|
|
class stack_exception : public T, public stack_exception_base {
|
|
public:
|
|
stack_exception(const std::string &msg) : T(msg), stack_exception_base(true) {}
|
|
virtual ~stack_exception() throw() {}
|
|
|
|
stack_exception(const char *file, int line, const char *pretty_function, const std::string &msg)
|
|
: T(msg), stack_exception_base(true) {
|
|
entry e;
|
|
e.file = file;
|
|
e.line = line;
|
|
e.function = pretty_function;
|
|
stack.insert(stack.begin(), e);
|
|
}
|
|
|
|
virtual const char *what() const throw() {
|
|
if (show_stack) {
|
|
// concatenate message with stack trace
|
|
buffer = "[" + std::string(T::what()) + "]\n" + stack_exception::to_string();
|
|
return buffer.c_str();
|
|
} else {
|
|
return T::what();
|
|
}
|
|
}
|
|
|
|
private:
|
|
mutable std::string buffer;
|
|
};
|
|
/** Stack-augmented exception classes for all std::exception classes. */
|
|
// typedef stack_exception<std::runtime_error> TmoException;
|
|
// typedef stack_exception<std::range_error> stack_range_error;
|
|
// typedef stack_exception<std::overflow_error> stack_overflow_error;
|
|
// typedef stack_exception<std::underflow_error> stack_underflow_error;
|
|
// typedef stack_exception<std::logic_error> stack_logic_error;
|
|
// typedef stack_exception<std::domain_error> stack_domain_error;
|
|
// typedef stack_exception<std::invalid_argument> stack_invalid_argument;
|
|
// typedef stack_exception<std::length_error> stack_length_error;
|
|
// typedef stack_exception<std::out_of_range> stack_out_of_range;
|
|
} // namespace stack_exception
|
|
|
|
class _TmoException : public stack_exception::stack_exception<std::runtime_error> {
|
|
public:
|
|
_TmoException(const std::string &msg) : stack_exception<std::runtime_error>(msg) {}
|
|
_TmoException(const char *file, int line, const char *pretty_function, const std::string &msg)
|
|
: stack_exception<std::runtime_error>(file, line, pretty_function, msg) {}
|
|
};
|
|
#define TmoException(msg) tmo::_TmoException(__FILE__, __LINE__, __PRETTY_FUNCTION__, msg)
|
|
} // namespace tmo
|
|
|
|
#endif // CSRC_COMMON_STACK_EXCEPTION_H_
|