Advertisement
Guest User

logger

a guest
Apr 2nd, 2020
66
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.02 KB | None | 0 0
  1. #include <array>
  2. #include <boost\preprocessor.hpp>
  3. #include <cstdint>
  4. #include <string>
  5. #include <vector>
  6.  
  7. namespace logger {
  8.  
  9. thread_local std::uint32_t t_indent{ 0 };
  10. thread_local char t_string_buffer[ 64*1024 ];
  11.  
  12. struct indent_guard {
  13.     enum {
  14.         indent = 4,
  15.     };
  16.  
  17.     inline indent_guard( )
  18.     {
  19.         t_indent += indent;
  20.     }
  21.  
  22.     inline ~indent_guard( )
  23.     {
  24.         t_indent -= indent;
  25.     }
  26. }; // struct indent_guard
  27.  
  28. inline void log(char const* const string)
  29. {
  30.     static thread_local char t_indent_buffer[ 64*1024 ];
  31.     static thread_local bool s_first_time = true;
  32.     if ( s_first_time ) {
  33.         s_first_time = false;
  34.         std::fill( t_indent_buffer, t_indent_buffer + sizeof(t_indent_buffer)/sizeof(t_indent_buffer[0]), ' ' );
  35.     }
  36.  
  37.     auto& end_of_indent = t_indent_buffer[ t_indent ];
  38.     end_of_indent = '\0';
  39.     printf("%s%s\n", t_indent_buffer, string);
  40.     end_of_indent = ' ';
  41. }
  42.  
  43. template < typename T >
  44. inline char* append_using_to_string( char* const string, T const& number )
  45. {
  46.     auto const& cpp_string = std::to_string( number );
  47.     auto const cpp_string_length = cpp_string.length( );
  48.     memcpy( string, cpp_string.c_str(), cpp_string_length*sizeof(char) );
  49.     return string + cpp_string_length;
  50. }
  51.  
  52. inline char* append( char* const string, int const number )
  53. {
  54.     return append_using_to_string( string, number );
  55. }
  56.  
  57. inline char* append( char* const string, long const number )
  58. {
  59.     return append_using_to_string( string, number );
  60. }
  61.  
  62. inline char* append( char* const string, long long const number )
  63. {
  64.     return append_using_to_string( string, number );
  65. }
  66.  
  67. inline char* append( char* const string, unsigned int const number )
  68. {
  69.     return append_using_to_string( string, number );
  70. }
  71.  
  72. inline char* append( char* const string, unsigned long const number )
  73. {
  74.     return append_using_to_string( string, number );
  75. }
  76.  
  77. inline char* append( char* const string, unsigned long long const number )
  78. {
  79.     return append_using_to_string( string, number );
  80. }
  81.  
  82. inline char* append( char* const string, float const number )
  83. {
  84.     return append_using_to_string( string, number );
  85. }
  86.  
  87. inline char* append( char* const string, double const number )
  88. {
  89.     return append_using_to_string( string, number );
  90. }
  91.  
  92. inline char* append( char* const string, long double const number )
  93. {
  94.     return append_using_to_string( string, number );
  95. }
  96.  
  97. inline char* append( char* const string, void const* const pointer )
  98. {
  99.     return string + sprintf( string, "0x%p", pointer );
  100. }
  101.  
  102. template < typename T >
  103. inline char* append( char* string, std::vector< T > const& container )
  104. {
  105.     *string++ = '{';
  106.     *string++ = ' ';
  107.     for ( std::size_t index = 0, count = container.size(); index < count; ++index ) {
  108.         if ( index ) {
  109.             *string++ = ',';
  110.             *string++ = ' ';
  111.         }
  112.  
  113.         string = append( string, index );
  114.         *string++ = ':';
  115.         string = append( string, container[index] );
  116.     }
  117.  
  118.     *string++ = '}';
  119.     return string;
  120. }
  121.  
  122. inline char* log_parameters( char* output, bool const is_first )
  123. {
  124.     std::ignore = output;
  125.     std::ignore = is_first;
  126.     return output;
  127. }
  128.  
  129. template < typename T, typename... Arguments >
  130. inline char* log_parameters( char* output, bool const is_first, char const* const argument_string, T const& argument, Arguments&&... arguments )
  131. {
  132.     if ( !is_first ) {
  133.         *output++ = ',';
  134.         *output++ = ' ';
  135.     }
  136.  
  137.     for ( char const* i = argument_string; *i; ++i, ++output )
  138.         *output = *i;
  139.  
  140.     *output++ = ':';
  141.    
  142.     return log_parameters( append( output, argument ), false, std::forward< Arguments >( arguments )... );
  143. }
  144.  
  145. template < typename... Arguments >
  146. inline void log_function_call( char const* const function_name, Arguments&&... arguments )
  147. {
  148.     char* first = t_string_buffer;
  149.     for ( char const* i = function_name; *i; ++i, ++first )
  150.         *first = *i;
  151.  
  152.     *first++ = '(';
  153.     *first++ = ' ';
  154.  
  155.     char* current = log_parameters( first, true, std::forward< Arguments >( arguments )... );
  156.     if ( current != first )
  157.         *current++ = ' ';
  158.  
  159.     *current++ = ')';
  160.     *current++ = '\0';
  161.     logger::log( t_string_buffer );
  162. }
  163.  
  164. } // namespace logger
  165.  
  166. #define LOGGER_NAMED_PARAMETERS_HELPER_1( variable ) \
  167.     BOOST_PP_STRINGIZE( variable ), ( variable )
  168.  
  169. #define LOGGER_NAMED_PARAMETERS_HELPER_2( r, d, variable ) \
  170.     , LOGGER_NAMED_PARAMETERS_HELPER_1( variable )
  171.  
  172. #define LOGGER_NAMED_PARAMETERS_SEQUENCE( sequence ) \
  173.     LOGGER_NAMED_PARAMETERS_HELPER_1( BOOST_PP_SEQ_HEAD(sequence) ) \
  174.     BOOST_PP_SEQ_FOR_EACH( LOGGER_NAMED_PARAMETERS_HELPER_2,,BOOST_PP_SEQ_TAIL(sequence) )
  175.  
  176. #define LOGGER_NAMED_PARAMETERS( ... ) \
  177.     LOGGER_NAMED_PARAMETERS_SEQUENCE( BOOST_PP_VARIADIC_TO_SEQ( __VA_ARGS__ ) )
  178.  
  179. #define LOG_FUNCTION_CALL( function, ... ) \
  180.     ::logger::log_function_call( #function, LOGGER_NAMED_PARAMETERS( __VA_ARGS__ ) );   \
  181.     ::logger::indent_guard BOOST_PP_CAT( indent_guard, __LINE__ );                      \
  182.     (void)0
  183.  
  184. std::uint64_t fib( std::uint32_t const n )
  185. {
  186.     LOG_FUNCTION_CALL( fib, n, &fib );
  187.     LOG_FUNCTION_CALL( fib, n );
  188.  
  189.     return n > 2 ? fib(n-1) + fib(n-2) : 1;
  190. }
  191.  
  192. int main()
  193. {
  194.     printf( "result: %llu\n", fib( 8 ) );
  195.  
  196.     std::vector< int > test{ 10, 20, 30 };
  197.     LOG_FUNCTION_CALL( fib, test );
  198.     return 0;
  199. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement