Printer is a template based multifunctor which can print any type. Printer is a stateful functor which support printing to any std::ostream
or std::stringstream
if not specified.
Construction
Printer can be constructed with or without a std::ostream
object:
Printer();
Printer(std::ostream& os);
There are helper functions to get a global printer object that print to stdout or stderr:
extern Printer& getStdoutPrinter();
extern Printer& getStderrPrinter();
Printing Any type
A functor print(...)
of the class Printer can be used to print any type variable/values.
Example:
int a = 1;
int & b = a;
int * c = &a;
print(a, b, c);
return 0;
}
Printer & getStderrPrinter()
Definition print.cpp:12
int main(int argc, const char **argv)
Definition unittest.cpp:884
Output:
1 1 <int* at 0x7ffebc813ed4>
STL container support:
std::vector<int> vec = {1, 5, 2};
auto get_student = [](int id) {
if (id == 0) return std::make_tuple(3.8, 'A' , "Lisa Simpson" );
if (id == 1) return std::make_tuple(2.9, 'C' , "Milhouse Van Houten" );
if (id == 2) return std::make_tuple(1.7, 'D' , "Ralph Wiggum" );
throw std::invalid_argument("id" );
};
print(a, b, c);
print({get_student(0), get_student(1), get_student(2)});
return 0;
}
Output:
[1, 5, 2]
{
(3.8, A, Lisa Simpson)
(2.9, C, Milhouse Van Houten)
(1.7, D, Ralph Wiggum)
}
Shared pointer and unique pointer:
std::shared_ptr<int> p(new int (42));
print(p);
std::unique_ptr<int> up(new int (42));
print(std::move(up));
Output:
<std::shared_ptr<int> at 0x555e1f936140>
<std::unique_ptr<int, std::default_delete<int> > at 0x555e1f931100>
Type Priority
The types are matched in the following priorities:
level types
5 User Customized Rules
4 std::string, std::complex, std::map
3 std::share_ptr, std::unique_ptr, std::weak_ptr, std::tuple, Array
2 container(who has begin, end methods), streamable types(with << operator), bool
1 char, wchar, POD type(need PFR library)
0 Object, C pointer, integer, float
Configuration
The functor can be configured with different mode:
Compact mode - everything in one line, e.g. {"a" : 1, "b" : 2}
Colorful mode - using colorful output
Quoted mode - string will be quoted, "a"
or a
for printing a string a
Indentation - default is 2
.
Liner break - default is \n
. print.line_break = "\r\n" ;
Print inside stream
The printer can be used in a stream once you constructed it without giving a output stream.
Printer print();
std::cerr << print("hello world" ) << std::endl;
Customized Rules
You can extend the printer by creating the PrinterExt
function templates, you need the following function template:
template <typename T> typename std::enable_if< <condition>, void >::type
void PrinterExt(Printer &, T, unsigned, const char *, rank< 0 >)
PrinterExt is an extension of Printer that allows user to write custom rules for printing.
Definition print.h:282
Here is an example for LLVM library, so you can printer pointer of llvm::Value
, llvm::Type
and llvm::Function
:
template <typename T>
typename std::enable_if<
std::is_base_of<llvm::Value, T>::value || std::is_base_of<llvm::Type, T>::value, void >::type
PrinterExt (Printer& P, T* s,
unsigned level,
const char * lb, rank<1>) {
if (s == nullptr ) {
P.os << P.tab(level) << "nullptr" << lb;
} else {
llvm::raw_os_ostream os(P.os);
s->print(os);
}
}
template <typename T>
typename std::enable_if<std::is_base_of<llvm::Function, T>::value,
void >::type
PrinterExt (
Printer& P, T* s, unsigned level, const char * lb, rank<2>) {
if (s == nullptr ) {
P.os << P.tab(level) << "nullptr" << lb;
} else {
llvm::raw_os_ostream os(P.os);
os << P.tab(level) <<
"Function " <<
FgCyan << *s <<
Reset ;
}
}
}
Definition benchmark.cpp:17
const char * FgCyan
Definition color.cpp:48
const char * Reset
Definition color.cpp:34