#ifndef OPENPOSE_UTILITIES_ERROR_AND_LOG_HPP #define OPENPOSE_UTILITIES_ERROR_AND_LOG_HPP #include // std::stringstream #include #include #include #include namespace op { OP_API void setMainThread(); OP_API std::string getThreadId(); OP_API bool getIfInMainThreadOrEmpty(); OP_API bool getIfNotInMainThreadOrEmpty(); template std::string tToString(const T& message) { // Message -> ostringstream std::ostringstream oss; oss << message; // ostringstream -> std::string return oss.str(); } /** * Differences between different kind of errors: * - error() is a normal error in the code. * - errorWorker() is an error that occurred on a thread. Therefore, the machine will stop the threads, go back * to the main thread, and then throw the error. * - errorDestructor() is an error that occurred on a destructor. Exception on destructors provokes core dumped, * so we simply output an error message via std::cerr. */ // Error management - How to use: // error(message, __LINE__, __FUNCTION__, __FILE__); OP_API void error( const std::string& message, const int line = -1, const std::string& function = "", const std::string& file = ""); template inline void error( const T& message, const int line = -1, const std::string& function = "", const std::string& file = "") { error(tToString(message), line, function, file); } // Worker error management OP_API void checkWorkerErrors(); OP_API void errorWorker( const std::string& message, const int line = -1, const std::string& function = "", const std::string& file = ""); template inline void errorWorker( const T& message, const int line = -1, const std::string& function = "", const std::string& file = "") { errorWorker(tToString(message), line, function, file); } // Destructor error management OP_API void errorDestructor( const std::string& message, const int line = -1, const std::string& function = "", const std::string& file = ""); template inline void errorDestructor( const T& message, const int line = -1, const std::string& function = "", const std::string& file = "") { errorDestructor(tToString(message), line, function, file); } // Printing info - How to use: // It will print info if desiredPriority >= sPriorityThreshold // opLog(message, desiredPriority, __LINE__, __FUNCTION__, __FILE__); OP_API void opLog( const std::string& message, const Priority priority = Priority::Max, const int line = -1, const std::string& function = "", const std::string& file = ""); template inline void opLog( const T& message, const Priority priority = Priority::Max, const int line = -1, const std::string& function = "", const std::string& file = "") { opLog(tToString(message), priority, line, function, file); } // If only desired on debug mode (no computational cost at all on release mode): // It will print info if desiredPriority >= sPriorityThreshold // opLogIfDebug(message, desiredPriority, __LINE__, __FUNCTION__, __FILE__); template inline void opLogIfDebug( const T& message, const Priority priority = Priority::Max, const int line = -1, const std::string& function = "", const std::string& file = "") { #ifndef NDEBUG opLog(message, priority, line, function, file); #else UNUSED(message); UNUSED(priority); UNUSED(line); UNUSED(function); UNUSED(file); #endif } // This class is thread-safe namespace ConfigureError { OP_API std::vector getErrorModes(); OP_API void setErrorModes(const std::vector& errorModes); } // This class is not fully thread-safe namespace ConfigureLog { OP_API Priority getPriorityThreshold(); OP_API const std::vector& getLogModes(); // This function is not thread-safe. It must be run at the beginning OP_API void setPriorityThreshold(const Priority priorityThreshold); // This function is not thread-safe. It must be run at the beginning OP_API void setLogModes(const std::vector& loggingModes); } } #endif // OPENPOSE_UTILITIES_ERROR_AND_LOG_HPP