7 #ifndef TREELITE_LOGGING_H_ 8 #define TREELITE_LOGGING_H_ 24 struct Error :
public std::runtime_error {
25 explicit Error(
const std::string& s) : std::runtime_error(s) {}
28 template <
typename X,
typename Y>
29 std::unique_ptr<std::string> LogCheckFormat(
const X& x,
const Y& y) {
30 std::ostringstream os;
31 os <<
" (" << x <<
" vs. " << y <<
") ";
33 return std::make_unique<std::string>(os.str());
36 #if defined(__GNUC__) || defined(__clang__) 37 #define TREELITE_ALWAYS_INLINE inline __attribute__((__always_inline__)) 38 #elif defined(_MSC_VER) 39 #define TREELITE_ALWAYS_INLINE __forceinline 41 #define TREELITE_ALWAYS_INLINE inline 44 #define DEFINE_CHECK_FUNC(name, op) \ 45 template <typename X, typename Y> \ 46 TREELITE_ALWAYS_INLINE std::unique_ptr<std::string> LogCheck##name(const X& x, const Y& y) { \ 47 if (x op y) return nullptr; \ 48 return LogCheckFormat(x, y); \ 50 TREELITE_ALWAYS_INLINE std::unique_ptr<std::string> LogCheck##name(int x, int y) { \ 51 return LogCheck##name<int, int>(x, y); \ 54 #pragma GCC diagnostic push 55 #pragma GCC diagnostic ignored "-Wsign-compare" 56 DEFINE_CHECK_FUNC(_LT, <)
57 DEFINE_CHECK_FUNC(_GT, >)
58 DEFINE_CHECK_FUNC(_LE, <=)
59 DEFINE_CHECK_FUNC(_GE, >=)
60 DEFINE_CHECK_FUNC(_EQ, ==)
61 DEFINE_CHECK_FUNC(_NE, !=)
62 #pragma GCC diagnostic pop 65 #define TREELITE_CHECK_BINARY_OP(name, op, x, y) \ 66 if (auto __treelite__log__err = ::treelite::LogCheck##name(x, y)) \ 67 ::treelite::LogMessageFatal(__FILE__, __LINE__).stream() \ 68 << "Check failed: " << #x " " #op " " #y << *__treelite__log__err << ": " 69 #define TREELITE_CHECK(x) \ 71 ::treelite::LogMessageFatal(__FILE__, __LINE__).stream() \ 72 << "Check failed: " #x << ": " 73 #define TREELITE_CHECK_LT(x, y) TREELITE_CHECK_BINARY_OP(_LT, <, x, y) 74 #define TREELITE_CHECK_GT(x, y) TREELITE_CHECK_BINARY_OP(_GT, >, x, y) 75 #define TREELITE_CHECK_LE(x, y) TREELITE_CHECK_BINARY_OP(_LE, <=, x, y) 76 #define TREELITE_CHECK_GE(x, y) TREELITE_CHECK_BINARY_OP(_GE, >=, x, y) 77 #define TREELITE_CHECK_EQ(x, y) TREELITE_CHECK_BINARY_OP(_EQ, ==, x, y) 78 #define TREELITE_CHECK_NE(x, y) TREELITE_CHECK_BINARY_OP(_NE, !=, x, y) 80 #define TREELITE_LOG_INFO ::treelite::LogMessage(__FILE__, __LINE__) 81 #define TREELITE_LOG_ERROR TREELITE_LOG_INFO 82 #define TREELITE_LOG_FATAL ::treelite::LogMessageFatal(__FILE__, __LINE__) 83 #define TREELITE_LOG(severity) TREELITE_LOG_##severity.stream() 90 #endif // defined(_MSC_VER) 92 const char* HumanDate() {
94 _strtime_s(buffer_,
sizeof(buffer_));
95 #else // defined(_MSC_VER) 96 time_t time_value = std::time(
nullptr);
100 pnow = localtime_r(&time_value, &now);
101 #else // !defined(_WIN32) 102 pnow = std::localtime(&time_value);
103 #endif // !defined(_WIN32) 104 std::snprintf(buffer_,
sizeof(buffer_),
"%02d:%02d:%02d",
105 pnow->tm_hour, pnow->tm_min, pnow->tm_sec);
106 #endif // defined(_MSC_VER) 117 log_stream_ <<
"[" << pretty_date_.HumanDate() <<
"] " << file <<
":" << line <<
": ";
122 std::ostringstream& stream() {
126 throw Error(log_stream_.str());
130 std::ostringstream log_stream_;
137 log_stream_ <<
"[" <<
DateLogger().HumanDate() <<
"] " << file <<
":" 141 Log(log_stream_.str());
143 std::ostream& stream() {
return log_stream_; }
144 static void Log(
const std::string& msg);
147 std::ostringstream log_stream_;
152 using Callback = void (*)(
const char*);
154 : log_callback_([] (
const char* msg) { std::cerr << msg << std::endl; }) {}
155 inline void Register(Callback log_callback) {
156 this->log_callback_ = log_callback;
158 inline Callback Get()
const {
159 return log_callback_;
162 Callback log_callback_;
169 #endif // TREELITE_LOGGING_H_
Exception class that will be thrown by Treelite.
Helper class for thread-local storage.