fork download
  1. #include <iostream>
  2. #include <type_traits>
  3.  
  4. template<typename TF, typename Tag>
  5. void write_debug_output( std::ostream & out, TF&& f, Tag ) {
  6. out << f;
  7. }
  8.  
  9. struct tracer {
  10. template<typename T>
  11. struct tag { struct type {}; };
  12.  
  13. std::ostream & out;
  14. tracer( std::ostream & out, char const * file, int line )
  15. : out( out ) {
  16. out << file << ":" << line << ": ";
  17. }
  18. ~tracer() {
  19. out << std::endl;
  20. }
  21.  
  22. template<typename TF, typename ... TR>
  23. void write( TF&& f, TR&& ... rest ) {
  24. typename tag<
  25. typename std::remove_cv<
  26. typename std::remove_reference<TF>::type
  27. >::type
  28. >::type t;
  29. write_debug_output( out, std::forward<TF>(f), t );
  30. out << " ";
  31. write( std::forward<TR>(rest)... );
  32. }
  33. template<typename TF>
  34. void write( TF&& f ) {
  35. typename tag<
  36. typename std::remove_cv<
  37. typename std::remove_reference<TF>::type
  38. >::type
  39. >::type t;
  40. write_debug_output( out, std::forward<TF>(f), t );
  41. }
  42. void write() {
  43. //handle the empty params case
  44. }
  45. };
  46.  
  47. #define TRACE(...) tracer( std::cout, __FILE__, __LINE__ ).write( __VA_ARGS__ )
  48.  
  49. #define TRACE_OUTPUT(match_type) \
  50. template<typename TF> \
  51. void write_debug_output( std::ostream & out, TF && f, tracer::tag<match_type>::type )
  52.  
  53. struct my_object { };
  54. TRACE_OUTPUT(my_object) {
  55. out << "my_object f is a "
  56. << (std::is_const<typename std::remove_reference<TF>::type>::value ? "const " : "" )
  57. << (std::is_lvalue_reference<TF>::value ? "lvalue" : "rvalue");
  58. }
  59.  
  60. struct other_object {
  61. int val;
  62. };
  63. TRACE_OUTPUT(other_object) {
  64. out << "val=" << f.val;
  65. }
  66.  
  67. int main()
  68. {
  69. my_object const a;
  70. TRACE(a);
  71. TRACE("CONST",a);
  72. my_object b;
  73. TRACE("MUTABLE",b);
  74. TRACE("RVALUE", my_object() );
  75. TRACE( 123, 5.5 );
  76. TRACE();
  77. TRACE( "other", other_object{14} );
  78. }
  79.  
Success #stdin #stdout 0s 3300KB
stdin
Standard input is empty
stdout
prog.cpp:70: my_object f is a const lvalue
prog.cpp:71: CONST my_object f is a const lvalue
prog.cpp:73: MUTABLE my_object f is a lvalue
prog.cpp:74: RVALUE my_object f is a rvalue
prog.cpp:75: 123 5.5
prog.cpp:76: 
prog.cpp:77: other val=14