/*! * Copyright 2014 by Contributors * \file utils.h * \brief simple utils to support the code * \author Tianqi Chen */ #ifndef XGBOOST_UTILS_UTILS_H_ #define XGBOOST_UTILS_UTILS_H_ #define _CRT_SECURE_NO_WARNINGS #include #include #include #include #include #ifndef XGBOOST_STRICT_CXX98_ #include #endif #if !defined(__GNUC__) #define fopen64 std::fopen #endif #ifdef _MSC_VER // NOTE: sprintf_s is not equivalent to snprintf, // they are equivalent when success, which is sufficient for our case #define snprintf sprintf_s #define vsnprintf vsprintf_s #else #ifdef _FILE_OFFSET_BITS #if _FILE_OFFSET_BITS == 32 #pragma message("Warning: FILE OFFSET BITS defined to be 32 bit") #endif #endif #ifdef __APPLE__ #define off64_t off_t #define fopen64 std::fopen #endif extern "C" { #include } #endif #ifdef _MSC_VER typedef unsigned char uint8_t; typedef unsigned __int16 uint16_t; typedef unsigned __int32 uint32_t; typedef unsigned __int64 uint64_t; typedef __int64 int64_t; #else #include #endif namespace xgboost { /*! \brief namespace for helper utils of the project */ namespace utils { /*! \brief error message buffer length */ const int kPrintBuffer = 1 << 12; #ifndef XGBOOST_CUSTOMIZE_MSG_ /*! * \brief handling of Assert error, caused by inappropriate input * \param msg error message */ inline void HandleAssertError(const char *msg) { fprintf(stderr, "AssertError:%s\n", msg); exit(-1); } /*! * \brief handling of Check error, caused by inappropriate input * \param msg error message */ inline void HandleCheckError(const char *msg) { throw std::runtime_error(msg); } inline void HandlePrint(const char *msg) { printf("%s", msg); } #else #ifndef XGBOOST_STRICT_CXX98_ // include declarations, some one must implement this void HandleAssertError(const char *msg); void HandleCheckError(const char *msg); void HandlePrint(const char *msg); #endif #endif #ifdef XGBOOST_STRICT_CXX98_ // these function pointers are to be assigned extern "C" void (*Printf)(const char *fmt, ...); extern "C" int (*SPrintf)(char *buf, size_t size, const char *fmt, ...); extern "C" void (*Assert)(int exp, const char *fmt, ...); extern "C" void (*Check)(int exp, const char *fmt, ...); extern "C" void (*Error)(const char *fmt, ...); #else /*! \brief printf, print message to the console */ inline void Printf(const char *fmt, ...) { std::string msg(kPrintBuffer, '\0'); va_list args; va_start(args, fmt); vsnprintf(&msg[0], kPrintBuffer, fmt, args); va_end(args); HandlePrint(msg.c_str()); } /*! \brief portable version of snprintf */ inline int SPrintf(char *buf, size_t size, const char *fmt, ...) { va_list args; va_start(args, fmt); int ret = vsnprintf(buf, size, fmt, args); va_end(args); return ret; } /*! \brief assert an condition is true, use this to handle debug information */ inline void Assert(bool exp, const char *fmt, ...) { if (!exp) { std::string msg(kPrintBuffer, '\0'); va_list args; va_start(args, fmt); vsnprintf(&msg[0], kPrintBuffer, fmt, args); va_end(args); HandleAssertError(msg.c_str()); } } /*!\brief same as assert, but this is intended to be used as message for user*/ inline void Check(bool exp, const char *fmt, ...) { if (!exp) { std::string msg(kPrintBuffer, '\0'); va_list args; va_start(args, fmt); vsnprintf(&msg[0], kPrintBuffer, fmt, args); va_end(args); HandleCheckError(msg.c_str()); } } /*! \brief report error message, same as check */ inline void Error(const char *fmt, ...) { { std::string msg(kPrintBuffer, '\0'); va_list args; va_start(args, fmt); vsnprintf(&msg[0], kPrintBuffer, fmt, args); va_end(args); HandleCheckError(msg.c_str()); } } #endif /*! \brief replace fopen, report error when the file open fails */ inline std::FILE *FopenCheck(const char *fname, const char *flag) { std::FILE *fp = fopen64(fname, flag); Check(fp != NULL, "can not open file \"%s\"\n", fname); return fp; } } // namespace utils // easy utils that can be directly accessed in xgboost /*! \brief get the beginning address of a vector */ template inline T *BeginPtr(std::vector &vec) { // NOLINT(*) if (vec.size() == 0) { return NULL; } else { return &vec[0]; } } /*! \brief get the beginning address of a vector */ template inline const T *BeginPtr(const std::vector &vec) { if (vec.size() == 0) { return NULL; } else { return &vec[0]; } } inline char* BeginPtr(std::string &str) { // NOLINT(*) if (str.length() == 0) return NULL; return &str[0]; } inline const char* BeginPtr(const std::string &str) { if (str.length() == 0) return NULL; return &str[0]; } } // namespace xgboost #endif // XGBOOST_UTILS_UTILS_H_