7 #ifndef TREELITE_LOGGING_H_ 8 #define TREELITE_LOGGING_H_ 21 template <
typename X,
typename Y>
22 std::unique_ptr<std::string> LogCheckFormat(
const X& x,
const Y& y) {
23 std::ostringstream os;
24 os <<
" (" << x <<
" vs. " << y <<
") ";
26 return std::make_unique<std::string>(os.str());
29 #if defined(__GNUC__) || defined(__clang__) 30 #define TREELITE_ALWAYS_INLINE inline __attribute__((__always_inline__)) 31 #elif defined(_MSC_VER) 32 #define TREELITE_ALWAYS_INLINE __forceinline 34 #define TREELITE_ALWAYS_INLINE inline 37 #define DEFINE_CHECK_FUNC(name, op) \ 38 template <typename X, typename Y> \ 39 TREELITE_ALWAYS_INLINE std::unique_ptr<std::string> LogCheck##name(const X& x, const Y& y) { \ 40 if (x op y) return nullptr; \ 41 return LogCheckFormat(x, y); \ 43 TREELITE_ALWAYS_INLINE std::unique_ptr<std::string> LogCheck##name(int x, int y) { \ 44 return LogCheck##name<int, int>(x, y); \ 47 #pragma GCC diagnostic push 48 #pragma GCC diagnostic ignored "-Wsign-compare" 49 DEFINE_CHECK_FUNC(_LT, <)
50 DEFINE_CHECK_FUNC(_GT, >)
51 DEFINE_CHECK_FUNC(_LE, <=)
52 DEFINE_CHECK_FUNC(_GE, >=)
53 DEFINE_CHECK_FUNC(_EQ, ==)
54 DEFINE_CHECK_FUNC(_NE, !=)
55 #pragma GCC diagnostic pop 58 #define TREELITE_CHECK_BINARY_OP(name, op, x, y) \ 59 if (auto __treelite__log__err = ::treelite::LogCheck##name(x, y)) \ 60 ::treelite::LogMessageFatal(__FILE__, __LINE__).stream() \ 61 << "Check failed: " << #x " " #op " " #y << *__treelite__log__err << ": " 62 #define TREELITE_CHECK(x) \ 64 ::treelite::LogMessageFatal(__FILE__, __LINE__).stream() \ 65 << "Check failed: " #x << ": " 66 #define TREELITE_CHECK_LT(x, y) TREELITE_CHECK_BINARY_OP(_LT, <, x, y) 67 #define TREELITE_CHECK_GT(x, y) TREELITE_CHECK_BINARY_OP(_GT, >, x, y) 68 #define TREELITE_CHECK_LE(x, y) TREELITE_CHECK_BINARY_OP(_LE, <=, x, y) 69 #define TREELITE_CHECK_GE(x, y) TREELITE_CHECK_BINARY_OP(_GE, >=, x, y) 70 #define TREELITE_CHECK_EQ(x, y) TREELITE_CHECK_BINARY_OP(_EQ, ==, x, y) 71 #define TREELITE_CHECK_NE(x, y) TREELITE_CHECK_BINARY_OP(_NE, !=, x, y) 73 #define TREELITE_LOG_INFO ::treelite::LogMessage(__FILE__, __LINE__) 74 #define TREELITE_LOG_ERROR TREELITE_LOG_INFO 75 #define TREELITE_LOG_FATAL ::treelite::LogMessageFatal(__FILE__, __LINE__) 76 #define TREELITE_LOG(severity) TREELITE_LOG_##severity.stream() 83 #endif // defined(_MSC_VER) 85 const char* HumanDate() {
87 _strtime_s(buffer_,
sizeof(buffer_));
88 #else // defined(_MSC_VER) 89 time_t time_value = std::time(
nullptr);
93 pnow = localtime_r(&time_value, &now);
94 #else // !defined(_WIN32) 95 pnow = std::localtime(&time_value);
96 #endif // !defined(_WIN32) 97 std::snprintf(buffer_,
sizeof(buffer_),
"%02d:%02d:%02d",
98 pnow->tm_hour, pnow->tm_min, pnow->tm_sec);
99 #endif // defined(_MSC_VER) 110 log_stream_ <<
"[" << pretty_date_.HumanDate() <<
"] " << file <<
":" << line <<
": ";
115 std::ostringstream& stream() {
119 throw Error(log_stream_.str());
123 std::ostringstream log_stream_;
130 log_stream_ <<
"[" <<
DateLogger().HumanDate() <<
"] " << file <<
":" 134 Log(log_stream_.str());
136 std::ostream& stream() {
return log_stream_; }
137 static void Log(
const std::string& msg);
140 std::ostringstream log_stream_;
145 using Callback = void (*)(
const char*);
147 : log_callback_([] (
const char* msg) { std::cerr << msg << std::endl; }) {}
148 inline void Register(Callback log_callback) {
149 this->log_callback_ = log_callback;
151 inline Callback Get()
const {
152 return log_callback_;
155 Callback log_callback_;
162 #endif // TREELITE_LOGGING_H_
Exception class that will be thrown by Treelite.
Exception class used throughout the Treelite codebase.
Helper class for thread-local storage.