#include #include #include using namespace std; namespace dbc { class Error { public: const string message; Error(string m) : message{m} {} Error(const char *m) : message{m} {} }; class CheckError : public Error {}; class SentinelError : public Error {}; class PreCondError : public Error {}; class PostCondError : public Error {}; void log(const string &message, std::source_location loc = std::source_location::current()) { fmt::print("[{}:{}:{}] {}\n", loc.file_name(), loc.function_name(), loc.line(), message); } void sentinel(const string &message, std::source_location loc = std::source_location::current()) { string err = fmt::format("[SENTINEL! {}:{}:{}:{}] {}\n", loc.file_name(), loc.function_name(), loc.line(), loc.column(), message); throw SentinelError{err}; } void pre(const string &message, std::function tester, std::source_location loc = std::source_location::current()) { if(!tester()) { string err = fmt::format("[PRE! {}:{}:{}:{}] {}\n", loc.file_name(), loc.function_name(), loc.line(), loc.column(), message); throw PreCondError{err}; } } void post(const string &message, std::function tester, std::source_location loc = std::source_location::current()) { if(!tester()) { string err = fmt::format("[POST! {}:{}:{}:{}] {}\n", loc.file_name(), loc.function_name(), loc.line(), loc.column(), message); throw PostCondError{err}; } } void check(bool test, const string &message, std::source_location loc = std::source_location::current()) { if(!test) { string err = fmt::format("[CHECK! {}:{}:{}:{}] {}\n", loc.file_name(), loc.function_name(), loc.line(), loc.column(), message); throw CheckError{err}; } } }