Changed implementation of logging macros.
We have observed some strange performance-related behavior as described here: https://stackoverflow.com/questions/29652787/adding-stringstream-cout-hurts-performance-even-when-the-code-is-never-called This set of changes addresses this problem. The old macros would simply expand the logging code in place, whereas we now have logging functions and the macros call these. Overall I believe it is tidier.
This commit is contained in:
@ -116,40 +116,26 @@ freely, subject to the following restrictions:
|
||||
* ...
|
||||
*/
|
||||
#ifdef POLYVOX_THROW_ENABLED
|
||||
namespace PolyVox
|
||||
{
|
||||
template< typename ExceptionType, typename ... Args >
|
||||
void polyvox_throw(Args const& ... messageArgs)
|
||||
{
|
||||
std::string message = Impl::argListToString(messageArgs...);
|
||||
#ifdef POLYVOX_LOG_ERROR_ENABLED
|
||||
PolyVox::Impl::getLoggerInstance()->logErrorMessage(message);
|
||||
#endif
|
||||
throw ExceptionType(message);
|
||||
}
|
||||
|
||||
#define POLYVOX_THROW_IF(condition, type, message) \
|
||||
/* We use the do...while(0) construct in our macros (for reasons see here: http://stackoverflow.com/a/154138) \
|
||||
but Visual Studio gives unhelpful 'conditional expression is constant' warnings. The recommended solution \
|
||||
(http://stackoverflow.com/a/1946485) is to disable these warnings. */ \
|
||||
POLYVOX_MSC_WARNING_PUSH \
|
||||
POLYVOX_DISABLE_MSC_WARNING(4127) \
|
||||
do \
|
||||
{ \
|
||||
if ((condition)) \
|
||||
{ \
|
||||
std::stringstream ss; \
|
||||
ss << message; \
|
||||
PolyVox::Impl::getLoggerInstance()->logErrorMessage(ss.str()); \
|
||||
throw type(ss.str()); \
|
||||
} \
|
||||
} while(0) \
|
||||
POLYVOX_MSC_WARNING_POP
|
||||
|
||||
#define POLYVOX_THROW(type, message) \
|
||||
/* We use the do...while(0) construct in our macros (for reasons see here: http://stackoverflow.com/a/154138) \
|
||||
but Visual Studio gives unhelpful 'conditional expression is constant' warnings. The recommended solution \
|
||||
(http://stackoverflow.com/a/1946485) is to disable these warnings. */ \
|
||||
POLYVOX_MSC_WARNING_PUSH \
|
||||
POLYVOX_DISABLE_MSC_WARNING(4127) \
|
||||
do \
|
||||
{ \
|
||||
std::stringstream ss; \
|
||||
ss << message; \
|
||||
PolyVox::Impl::getLoggerInstance()->logErrorMessage(ss.str()); \
|
||||
throw type(ss.str()); \
|
||||
} while(0) \
|
||||
POLYVOX_MSC_WARNING_POP
|
||||
|
||||
template< typename ExceptionType, typename ... Args >
|
||||
void polyvox_throw_if(bool condition, Args const& ... messageArgs)
|
||||
{
|
||||
if(condition) { polyvox_throw<ExceptionType>(messageArgs...); }
|
||||
}
|
||||
}
|
||||
#define POLYVOX_THROW(type, ...) PolyVox::polyvox_throw<type>(__VA_ARGS__)
|
||||
#define POLYVOX_THROW_IF(condition, type, ...) PolyVox::polyvox_throw_if<type>(condition, __VA_ARGS__)
|
||||
#else
|
||||
namespace PolyVox
|
||||
{
|
||||
|
@ -81,270 +81,152 @@ namespace PolyVox
|
||||
{
|
||||
Impl::getLoggerInstance() = pLogger;
|
||||
}
|
||||
|
||||
namespace Impl
|
||||
{
|
||||
// Used for building the log messages - convert a list of variables into a string.
|
||||
// Based on second approach here: http://stackoverflow.com/a/25386444/2337254
|
||||
template< typename ... Args >
|
||||
std::string argListToString(const Args& ... args)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
int a[] = { 0, ((void)(oss << args), 0) ... };
|
||||
(void)a; // Prevent warnings about unused param
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
// Log trace message
|
||||
template< typename ... Args >
|
||||
void logTraceMessage(Args const& ... messageArgs)
|
||||
{
|
||||
std::string message = argListToString(messageArgs...);
|
||||
PolyVox::Impl::getLoggerInstance()->logTraceMessage(message);
|
||||
}
|
||||
|
||||
template< typename ... Args >
|
||||
void logTraceMessageIf(bool condition, Args const& ... messageArgs)
|
||||
{
|
||||
if (condition) { logTraceMessage(messageArgs...); }
|
||||
}
|
||||
|
||||
// Log debug message
|
||||
template< typename ... Args >
|
||||
void logDebugMessage(Args const& ... messageArgs)
|
||||
{
|
||||
std::string message = argListToString(messageArgs...);
|
||||
PolyVox::Impl::getLoggerInstance()->logDebugMessage(message);
|
||||
}
|
||||
|
||||
template< typename ... Args >
|
||||
void logDebugMessageIf(bool condition, Args const& ... messageArgs)
|
||||
{
|
||||
if (condition) { logDebugMessage(messageArgs...); }
|
||||
}
|
||||
|
||||
// Log info message
|
||||
template< typename ... Args >
|
||||
void logInfoMessage(Args const& ... messageArgs)
|
||||
{
|
||||
std::string message = argListToString(messageArgs...);
|
||||
PolyVox::Impl::getLoggerInstance()->logInfoMessage(message);
|
||||
}
|
||||
|
||||
template< typename ... Args >
|
||||
void logInfoMessageIf(bool condition, Args const& ... messageArgs)
|
||||
{
|
||||
if (condition) { logInfoMessage(messageArgs...); }
|
||||
}
|
||||
|
||||
// Log warning message
|
||||
template< typename ... Args >
|
||||
void logWarningMessage(Args const& ... messageArgs)
|
||||
{
|
||||
std::string message = argListToString(messageArgs...);
|
||||
PolyVox::Impl::getLoggerInstance()->logWarningMessage(message);
|
||||
}
|
||||
|
||||
template< typename ... Args >
|
||||
void logWarningMessageIf(bool condition, Args const& ... messageArgs)
|
||||
{
|
||||
if (condition) { logWarningMessage(messageArgs...); }
|
||||
}
|
||||
|
||||
// Log error message
|
||||
template< typename ... Args >
|
||||
void logErrorMessage(Args const& ... messageArgs)
|
||||
{
|
||||
std::string message = argListToString(messageArgs...);
|
||||
PolyVox::Impl::getLoggerInstance()->logErrorMessage(message);
|
||||
}
|
||||
|
||||
template< typename ... Args >
|
||||
void logErrorMessageIf(bool condition, Args const& ... messageArgs)
|
||||
{
|
||||
if (condition) { logErrorMessage(messageArgs...); }
|
||||
}
|
||||
|
||||
// Log fatal message
|
||||
template< typename ... Args >
|
||||
void logFatalMessage(Args const& ... messageArgs)
|
||||
{
|
||||
std::string message = argListToString(messageArgs...);
|
||||
PolyVox::Impl::getLoggerInstance()->logFatalMessage(message);
|
||||
}
|
||||
|
||||
template< typename ... Args >
|
||||
void logFatalMessageIf(bool condition, Args const& ... messageArgs)
|
||||
{
|
||||
if (condition) { logFatalMessage(messageArgs...); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef POLYVOX_LOG_TRACE_ENABLED
|
||||
|
||||
#define POLYVOX_LOG_TRACE(message) \
|
||||
/* We use the do...while(0) construct in our macros (for reasons see here: http://stackoverflow.com/a/154138) \
|
||||
but Visual Studio gives unhelpful 'conditional expression is constant' warnings. The recommended solution \
|
||||
(http://stackoverflow.com/a/1946485) is to disable these warnings. */ \
|
||||
POLYVOX_MSC_WARNING_PUSH \
|
||||
POLYVOX_DISABLE_MSC_WARNING(4127) \
|
||||
do \
|
||||
{ \
|
||||
std::stringstream ss; \
|
||||
ss << message; \
|
||||
PolyVox::Impl::getLoggerInstance()->logTraceMessage(ss.str()); \
|
||||
} while(0) \
|
||||
POLYVOX_MSC_WARNING_POP
|
||||
|
||||
#define POLYVOX_LOG_TRACE_IF(condition, message) \
|
||||
/* We use the do...while(0) construct in our macros (for reasons see here: http://stackoverflow.com/a/154138) \
|
||||
but Visual Studio gives unhelpful 'conditional expression is constant' warnings. The recommended solution \
|
||||
(http://stackoverflow.com/a/1946485) is to disable these warnings. */ \
|
||||
POLYVOX_MSC_WARNING_PUSH \
|
||||
POLYVOX_DISABLE_MSC_WARNING(4127) \
|
||||
do \
|
||||
{ \
|
||||
if ((condition)) \
|
||||
{ \
|
||||
std::stringstream ss; \
|
||||
ss << message; \
|
||||
PolyVox::Impl::getLoggerInstance()->logTraceMessage(ss.str()); \
|
||||
} \
|
||||
} while(0) \
|
||||
POLYVOX_MSC_WARNING_POP
|
||||
|
||||
#define POLYVOX_LOG_TRACE(...) PolyVox::Impl::logTraceMessage(__VA_ARGS__)
|
||||
#define POLYVOX_LOG_TRACE_IF(condition, ...) PolyVox::Impl::logTraceMessageIf(condition, __VA_ARGS__)
|
||||
#else
|
||||
|
||||
// We don't bother with the do...while(0) construct here as we're not executing multiple statements
|
||||
// We also don't bother with forcing variables to be 'used'. If this causes a problem then calling
|
||||
// code can just force them to be used itself in addition to calling the logging macro. Basically
|
||||
// we just want to reduce the chance of extra code being generated.
|
||||
#define POLYVOX_LOG_TRACE(message)
|
||||
#define POLYVOX_LOG_TRACE_IF(condition, message)
|
||||
|
||||
#define POLYVOX_LOG_TRACE(...)
|
||||
#define POLYVOX_LOG_TRACE_IF(condition, ...)
|
||||
#endif
|
||||
|
||||
#ifdef POLYVOX_LOG_DEBUG_ENABLED
|
||||
|
||||
#define POLYVOX_LOG_DEBUG(message) \
|
||||
/* We use the do...while(0) construct in our macros (for reasons see here: http://stackoverflow.com/a/154138) \
|
||||
but Visual Studio gives unhelpful 'conditional expression is constant' warnings. The recommended solution \
|
||||
(http://stackoverflow.com/a/1946485) is to disable these warnings. */ \
|
||||
POLYVOX_MSC_WARNING_PUSH \
|
||||
POLYVOX_DISABLE_MSC_WARNING(4127) \
|
||||
do \
|
||||
{ \
|
||||
std::stringstream ss; \
|
||||
ss << message; \
|
||||
PolyVox::Impl::getLoggerInstance()->logDebugMessage(ss.str()); \
|
||||
} while(0) \
|
||||
POLYVOX_MSC_WARNING_POP
|
||||
|
||||
#define POLYVOX_LOG_DEBUG_IF(condition, message) \
|
||||
/* We use the do...while(0) construct in our macros (for reasons see here: http://stackoverflow.com/a/154138) \
|
||||
but Visual Studio gives unhelpful 'conditional expression is constant' warnings. The recommended solution \
|
||||
(http://stackoverflow.com/a/1946485) is to disable these warnings. */ \
|
||||
POLYVOX_MSC_WARNING_PUSH \
|
||||
POLYVOX_DISABLE_MSC_WARNING(4127) \
|
||||
do \
|
||||
{ \
|
||||
if ((condition)) \
|
||||
{ \
|
||||
std::stringstream ss; \
|
||||
ss << message; \
|
||||
PolyVox::Impl::getLoggerInstance()->logDebugMessage(ss.str()); \
|
||||
} \
|
||||
} while(0) \
|
||||
POLYVOX_MSC_WARNING_POP
|
||||
|
||||
#define POLYVOX_LOG_DEBUG(...) PolyVox::Impl::logDebugMessage(__VA_ARGS__)
|
||||
#define POLYVOX_LOG_DEBUG_IF(condition, ...) PolyVox::Impl::logDebugMessageIf(condition, __VA_ARGS__)
|
||||
#else
|
||||
|
||||
// We don't bother with the do...while(0) construct here as we're not executing multiple statements
|
||||
// We also don't bother with forcing variables to be 'used'. If this causes a problem then calling
|
||||
// code can just force them to be used itself in addition to calling the logging macro. Basically
|
||||
// we just want to reduce the chance of extra code being generated.
|
||||
#define POLYVOX_LOG_DEBUG(message)
|
||||
#define POLYVOX_LOG_DEBUG_IF(condition, message)
|
||||
|
||||
#define POLYVOX_LOG_DEBUG(...)
|
||||
#define POLYVOX_LOG_DEBUG_IF(condition, ...)
|
||||
#endif
|
||||
|
||||
#ifdef POLYVOX_LOG_INFO_ENABLED
|
||||
|
||||
#define POLYVOX_LOG_INFO(message) \
|
||||
/* We use the do...while(0) construct in our macros (for reasons see here: http://stackoverflow.com/a/154138) \
|
||||
but Visual Studio gives unhelpful 'conditional expression is constant' warnings. The recommended solution \
|
||||
(http://stackoverflow.com/a/1946485) is to disable these warnings. */ \
|
||||
POLYVOX_MSC_WARNING_PUSH \
|
||||
POLYVOX_DISABLE_MSC_WARNING(4127) \
|
||||
do \
|
||||
{ \
|
||||
std::stringstream ss; \
|
||||
ss << message; \
|
||||
PolyVox::Impl::getLoggerInstance()->logInfoMessage(ss.str()); \
|
||||
} while(0) \
|
||||
POLYVOX_MSC_WARNING_POP
|
||||
|
||||
#define POLYVOX_LOG_INFO_IF(condition, message) \
|
||||
/* We use the do...while(0) construct in our macros (for reasons see here: http://stackoverflow.com/a/154138) \
|
||||
but Visual Studio gives unhelpful 'conditional expression is constant' warnings. The recommended solution \
|
||||
(http://stackoverflow.com/a/1946485) is to disable these warnings. */ \
|
||||
POLYVOX_MSC_WARNING_PUSH \
|
||||
POLYVOX_DISABLE_MSC_WARNING(4127) \
|
||||
do \
|
||||
{ \
|
||||
if ((condition)) \
|
||||
{ \
|
||||
std::stringstream ss; \
|
||||
ss << message; \
|
||||
PolyVox::Impl::getLoggerInstance()->logInfoMessage(ss.str()); \
|
||||
} \
|
||||
} while(0) \
|
||||
POLYVOX_MSC_WARNING_POP
|
||||
|
||||
#define POLYVOX_LOG_INFO(...) PolyVox::Impl::logInfoMessage(__VA_ARGS__)
|
||||
#define POLYVOX_LOG_INFO_IF(condition, ...) PolyVox::Impl::logInfoMessageIf(condition, __VA_ARGS__)
|
||||
#else
|
||||
|
||||
// We don't bother with the do...while(0) construct here as we're not executing multiple statements
|
||||
// We also don't bother with forcing variables to be 'used'. If this causes a problem then calling
|
||||
// code can just force them to be used itself in addition to calling the logging macro. Basically
|
||||
// we just want to reduce the chance of extra code being generated.
|
||||
#define POLYVOX_LOG_INFO(message)
|
||||
#define POLYVOX_LOG_INFO_IF(condition, message)
|
||||
|
||||
#define POLYVOX_LOG_INFO(...)
|
||||
#define POLYVOX_LOG_INFO_IF(condition, ...)
|
||||
#endif
|
||||
|
||||
#ifdef POLYVOX_LOG_WARNING_ENABLED
|
||||
|
||||
#define POLYVOX_LOG_WARNING(message) \
|
||||
/* We use the do...while(0) construct in our macros (for reasons see here: http://stackoverflow.com/a/154138) \
|
||||
but Visual Studio gives unhelpful 'conditional expression is constant' warnings. The recommended solution \
|
||||
(http://stackoverflow.com/a/1946485) is to disable these warnings. */ \
|
||||
POLYVOX_MSC_WARNING_PUSH \
|
||||
POLYVOX_DISABLE_MSC_WARNING(4127) \
|
||||
do \
|
||||
{ \
|
||||
std::stringstream ss; \
|
||||
ss << message; \
|
||||
PolyVox::Impl::getLoggerInstance()->logWarningMessage(ss.str()); \
|
||||
} while(0) \
|
||||
POLYVOX_MSC_WARNING_POP
|
||||
|
||||
#define POLYVOX_LOG_WARNING_IF(condition, message) \
|
||||
/* We use the do...while(0) construct in our macros (for reasons see here: http://stackoverflow.com/a/154138) \
|
||||
but Visual Studio gives unhelpful 'conditional expression is constant' warnings. The recommended solution \
|
||||
(http://stackoverflow.com/a/1946485) is to disable these warnings. */ \
|
||||
POLYVOX_MSC_WARNING_PUSH \
|
||||
POLYVOX_DISABLE_MSC_WARNING(4127) \
|
||||
do \
|
||||
{ \
|
||||
if ((condition)) \
|
||||
{ \
|
||||
std::stringstream ss; \
|
||||
ss << message; \
|
||||
PolyVox::Impl::getLoggerInstance()->logWarningMessage(ss.str()); \
|
||||
} \
|
||||
} while(0) \
|
||||
POLYVOX_MSC_WARNING_POP
|
||||
|
||||
#define POLYVOX_LOG_WARNING(...) PolyVox::Impl::logWarningMessage(__VA_ARGS__)
|
||||
#define POLYVOX_LOG_WARNING_IF(condition, ...) PolyVox::Impl::logWarningMessageIf(condition, __VA_ARGS__)
|
||||
#else
|
||||
|
||||
// We don't bother with the do...while(0) construct here as we're not executing multiple statements
|
||||
// We also don't bother with forcing variables to be 'used'. If this causes a problem then calling
|
||||
// code can just force them to be used itself in addition to calling the logging macro. Basically
|
||||
// we just want to reduce the chance of extra code being generated.
|
||||
#define POLYVOX_LOG_WARNING(message)
|
||||
#define POLYVOX_LOG_WARNING_IF(condition, message)
|
||||
|
||||
#define POLYVOX_LOG_WARNING(...)
|
||||
#define POLYVOX_LOG_WARNING_IF(condition, ...)
|
||||
#endif
|
||||
|
||||
#ifdef POLYVOX_LOG_ERROR_ENABLED
|
||||
|
||||
#define POLYVOX_LOG_ERROR(message) \
|
||||
/* We use the do...while(0) construct in our macros (for reasons see here: http://stackoverflow.com/a/154138) \
|
||||
but Visual Studio gives unhelpful 'conditional expression is constant' warnings. The recommended solution \
|
||||
(http://stackoverflow.com/a/1946485) is to disable these warnings. */ \
|
||||
POLYVOX_MSC_WARNING_PUSH \
|
||||
POLYVOX_DISABLE_MSC_WARNING(4127) \
|
||||
do \
|
||||
{ \
|
||||
std::stringstream ss; \
|
||||
ss << message; \
|
||||
PolyVox::Impl::getLoggerInstance()->logErrorMessage(ss.str()); \
|
||||
} while(0) \
|
||||
POLYVOX_MSC_WARNING_POP
|
||||
|
||||
#define POLYVOX_LOG_ERROR_IF(condition, message) \
|
||||
/* We use the do...while(0) construct in our macros (for reasons see here: http://stackoverflow.com/a/154138) \
|
||||
but Visual Studio gives unhelpful 'conditional expression is constant' warnings. The recommended solution \
|
||||
(http://stackoverflow.com/a/1946485) is to disable these warnings. */ \
|
||||
POLYVOX_MSC_WARNING_PUSH \
|
||||
POLYVOX_DISABLE_MSC_WARNING(4127) \
|
||||
do \
|
||||
{ \
|
||||
if ((condition)) \
|
||||
{ \
|
||||
std::stringstream ss; \
|
||||
ss << message; \
|
||||
PolyVox::Impl::getLoggerInstance()->logErrorMessage(ss.str()); \
|
||||
} \
|
||||
} while(0) \
|
||||
POLYVOX_MSC_WARNING_POP
|
||||
|
||||
#define POLYVOX_LOG_ERROR(...) PolyVox::Impl::logErrorMessage(__VA_ARGS__)
|
||||
#define POLYVOX_LOG_ERROR_IF(condition, ...) PolyVox::Impl::logErrorMessageIf(condition, __VA_ARGS__)
|
||||
#else
|
||||
|
||||
// We don't bother with the do...while(0) construct here as we're not executing multiple statements
|
||||
// We also don't bother with forcing variables to be 'used'. If this causes a problem then calling
|
||||
// code can just force them to be used itself in addition to calling the logging macro. Basically
|
||||
// we just want to reduce the chance of extra code being generated.
|
||||
#define POLYVOX_LOG_ERROR(message)
|
||||
#define POLYVOX_LOG_ERROR_IF(condition, message)
|
||||
|
||||
#define POLYVOX_LOG_ERROR(...)
|
||||
#define POLYVOX_LOG_ERROR_IF(condition, ...)
|
||||
#endif
|
||||
|
||||
#ifdef POLYVOX_LOG_FATAL_ENABLED
|
||||
|
||||
#define POLYVOX_LOG_FATAL(message) \
|
||||
/* We use the do...while(0) construct in our macros (for reasons see here: http://stackoverflow.com/a/154138) \
|
||||
but Visual Studio gives unhelpful 'conditional expression is constant' warnings. The recommended solution \
|
||||
(http://stackoverflow.com/a/1946485) is to disable these warnings. */ \
|
||||
POLYVOX_MSC_WARNING_PUSH \
|
||||
POLYVOX_DISABLE_MSC_WARNING(4127) \
|
||||
do \
|
||||
{ \
|
||||
std::stringstream ss; \
|
||||
ss << message; \
|
||||
PolyVox::Impl::getLoggerInstance()->logFatalMessage(ss.str()); \
|
||||
} while(0) \
|
||||
POLYVOX_MSC_WARNING_POP
|
||||
|
||||
#define POLYVOX_LOG_FATAL_IF(condition, message) \
|
||||
/* We use the do...while(0) construct in our macros (for reasons see here: http://stackoverflow.com/a/154138) \
|
||||
but Visual Studio gives unhelpful 'conditional expression is constant' warnings. The recommended solution \
|
||||
(http://stackoverflow.com/a/1946485) is to disable these warnings. */ \
|
||||
POLYVOX_MSC_WARNING_PUSH \
|
||||
POLYVOX_DISABLE_MSC_WARNING(4127) \
|
||||
do \
|
||||
{ \
|
||||
if ((condition)) \
|
||||
{ \
|
||||
std::stringstream ss; \
|
||||
ss << message; \
|
||||
PolyVox::Impl::getLoggerInstance()->logFatalMessage(ss.str()); \
|
||||
} \
|
||||
} while(0) \
|
||||
POLYVOX_MSC_WARNING_POP
|
||||
|
||||
#define POLYVOX_LOG_FATAL(...) PolyVox::Impl::logFatalMessage(__VA_ARGS__)
|
||||
#define POLYVOX_LOG_FATAL_IF(condition, ...) PolyVox::Impl::logFatalMessageIf(condition, __VA_ARGS__)
|
||||
#else
|
||||
|
||||
// We don't bother with the do...while(0) construct here as we're not executing multiple statements
|
||||
// We also don't bother with forcing variables to be 'used'. If this causes a problem then calling
|
||||
// code can just force them to be used itself in addition to calling the logging macro. Basically
|
||||
// we just want to reduce the chance of extra code being generated.
|
||||
#define POLYVOX_LOG_FATAL(message)
|
||||
#define POLYVOX_LOG_FATAL_IF(condition, message)
|
||||
|
||||
#define POLYVOX_LOG_FATAL(...)
|
||||
#define POLYVOX_LOG_FATAL_IF(condition, ...)
|
||||
#endif
|
||||
|
||||
#endif //__PolyVox_Logging_H__
|
Reference in New Issue
Block a user