@ -19,6 +19,9 @@
# include <vector>
# include "absl/functional/any_invocable.h"
# include "absl/strings/str_cat.h"
# include "absl/strings/str_format.h"
# include "absl/strings/string_view.h"
namespace grpc_core {
namespace dump_args_detail {
@ -39,17 +42,62 @@ class DumpArgs {
do_these_things ( { AddDumper ( & args ) . . . } ) ;
}
friend std : : ostream & operator < < ( std : : ostream & out , const DumpArgs & args ) ;
template < typename Sink >
friend void AbslStringify ( Sink & sink , const DumpArgs & dumper ) {
CustomSinkImpl < Sink > custom_sink ( sink ) ;
dumper . Stringify ( custom_sink ) ;
}
friend std : : ostream & operator < < ( std : : ostream & out , const DumpArgs & dumper ) {
return out < < absl : : StrCat ( dumper ) ;
}
private :
class CustomSink {
public :
virtual void Append ( absl : : string_view x ) = 0 ;
protected :
~ CustomSink ( ) = default ;
} ;
template < typename Sink >
class CustomSinkImpl final : public CustomSink {
public :
explicit CustomSinkImpl ( Sink & sink ) : sink_ ( sink ) { }
void Append ( absl : : string_view x ) override { sink_ . Append ( x ) ; }
private :
Sink & sink_ ;
} ;
template < typename T >
int AddDumper ( T * p ) {
arg_dumpers_ . push_back ( [ p ] ( std : : ostream & os ) { os < < * p ; } ) ;
arg_dumpers_ . push_back (
[ p ] ( CustomSink & os ) { os . Append ( absl : : StrCat ( * p ) ) ; } ) ;
return 0 ;
}
int AddDumper ( void * * p ) {
arg_dumpers_ . push_back (
[ p ] ( CustomSink & os ) { os . Append ( absl : : StrFormat ( " %p " , * p ) ) ; } ) ;
return 0 ;
}
template < typename T >
int AddDumper ( T * * p ) {
return AddDumper ( reinterpret_cast < void * * > ( p ) ) ;
}
template < typename T >
int AddDumper ( T * const * p ) {
return AddDumper ( const_cast < T * * > ( p ) ) ;
}
void Stringify ( CustomSink & sink ) const ;
const char * arg_string_ ;
std : : vector < absl : : AnyInvocable < void ( std : : ostream & ) const > > arg_dumpers_ ;
std : : vector < absl : : AnyInvocable < void ( CustomSink & ) const > > arg_dumpers_ ;
} ;
} // namespace dump_args_detail