Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <array>
- #include <boost\preprocessor.hpp>
- #include <cstdint>
- #include <string>
- #include <vector>
- namespace logger {
- thread_local std::uint32_t t_indent{ 0 };
- thread_local char t_string_buffer[ 64*1024 ];
- struct indent_guard {
- enum {
- indent = 4,
- };
- inline indent_guard( )
- {
- t_indent += indent;
- }
- inline ~indent_guard( )
- {
- t_indent -= indent;
- }
- }; // struct indent_guard
- inline void log(char const* const string)
- {
- static thread_local char t_indent_buffer[ 64*1024 ];
- static thread_local bool s_first_time = true;
- if ( s_first_time ) {
- s_first_time = false;
- std::fill( t_indent_buffer, t_indent_buffer + sizeof(t_indent_buffer)/sizeof(t_indent_buffer[0]), ' ' );
- }
- auto& end_of_indent = t_indent_buffer[ t_indent ];
- end_of_indent = '\0';
- printf("%s%s\n", t_indent_buffer, string);
- end_of_indent = ' ';
- }
- template < typename T >
- inline char* append_using_to_string( char* const string, T const& number )
- {
- auto const& cpp_string = std::to_string( number );
- auto const cpp_string_length = cpp_string.length( );
- memcpy( string, cpp_string.c_str(), cpp_string_length*sizeof(char) );
- return string + cpp_string_length;
- }
- inline char* append( char* const string, int const number )
- {
- return append_using_to_string( string, number );
- }
- inline char* append( char* const string, long const number )
- {
- return append_using_to_string( string, number );
- }
- inline char* append( char* const string, long long const number )
- {
- return append_using_to_string( string, number );
- }
- inline char* append( char* const string, unsigned int const number )
- {
- return append_using_to_string( string, number );
- }
- inline char* append( char* const string, unsigned long const number )
- {
- return append_using_to_string( string, number );
- }
- inline char* append( char* const string, unsigned long long const number )
- {
- return append_using_to_string( string, number );
- }
- inline char* append( char* const string, float const number )
- {
- return append_using_to_string( string, number );
- }
- inline char* append( char* const string, double const number )
- {
- return append_using_to_string( string, number );
- }
- inline char* append( char* const string, long double const number )
- {
- return append_using_to_string( string, number );
- }
- inline char* append( char* const string, void const* const pointer )
- {
- return string + sprintf( string, "0x%p", pointer );
- }
- template < typename T >
- inline char* append( char* string, std::vector< T > const& container )
- {
- *string++ = '{';
- *string++ = ' ';
- for ( std::size_t index = 0, count = container.size(); index < count; ++index ) {
- if ( index ) {
- *string++ = ',';
- *string++ = ' ';
- }
- string = append( string, index );
- *string++ = ':';
- string = append( string, container[index] );
- }
- *string++ = '}';
- return string;
- }
- inline char* log_parameters( char* output, bool const is_first )
- {
- std::ignore = output;
- std::ignore = is_first;
- return output;
- }
- template < typename T, typename... Arguments >
- inline char* log_parameters( char* output, bool const is_first, char const* const argument_string, T const& argument, Arguments&&... arguments )
- {
- if ( !is_first ) {
- *output++ = ',';
- *output++ = ' ';
- }
- for ( char const* i = argument_string; *i; ++i, ++output )
- *output = *i;
- *output++ = ':';
- return log_parameters( append( output, argument ), false, std::forward< Arguments >( arguments )... );
- }
- template < typename... Arguments >
- inline void log_function_call( char const* const function_name, Arguments&&... arguments )
- {
- char* first = t_string_buffer;
- for ( char const* i = function_name; *i; ++i, ++first )
- *first = *i;
- *first++ = '(';
- *first++ = ' ';
- char* current = log_parameters( first, true, std::forward< Arguments >( arguments )... );
- if ( current != first )
- *current++ = ' ';
- *current++ = ')';
- *current++ = '\0';
- logger::log( t_string_buffer );
- }
- } // namespace logger
- #define LOGGER_NAMED_PARAMETERS_HELPER_1( variable ) \
- BOOST_PP_STRINGIZE( variable ), ( variable )
- #define LOGGER_NAMED_PARAMETERS_HELPER_2( r, d, variable ) \
- , LOGGER_NAMED_PARAMETERS_HELPER_1( variable )
- #define LOGGER_NAMED_PARAMETERS_SEQUENCE( sequence ) \
- LOGGER_NAMED_PARAMETERS_HELPER_1( BOOST_PP_SEQ_HEAD(sequence) ) \
- BOOST_PP_SEQ_FOR_EACH( LOGGER_NAMED_PARAMETERS_HELPER_2,,BOOST_PP_SEQ_TAIL(sequence) )
- #define LOGGER_NAMED_PARAMETERS( ... ) \
- LOGGER_NAMED_PARAMETERS_SEQUENCE( BOOST_PP_VARIADIC_TO_SEQ( __VA_ARGS__ ) )
- #define LOG_FUNCTION_CALL( function, ... ) \
- ::logger::log_function_call( #function, LOGGER_NAMED_PARAMETERS( __VA_ARGS__ ) ); \
- ::logger::indent_guard BOOST_PP_CAT( indent_guard, __LINE__ ); \
- (void)0
- std::uint64_t fib( std::uint32_t const n )
- {
- LOG_FUNCTION_CALL( fib, n, &fib );
- LOG_FUNCTION_CALL( fib, n );
- return n > 2 ? fib(n-1) + fib(n-2) : 1;
- }
- int main()
- {
- printf( "result: %llu\n", fib( 8 ) );
- std::vector< int > test{ 10, 20, 30 };
- LOG_FUNCTION_CALL( fib, test );
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement