ZeroErr
Loading...
Searching...
No Matches
Printer MultiFunctor

Printer is a stateful template functor. It captures text in an internal StringBuffer by default and can attach an explicitly supplied output stream. See header dependencies for optional standard stream support.

Capability matching and header dependencies

Printing rules inspect operations rather than specific STL template names:

  • Containers expose const begin()/end() and copyable, incrementable iterators. Indexable containers use brackets.
  • Map elements expose first/second; complex values expose arithmetic real()/imag() results.
  • Text exposes traits_type::char_type = char and data()/size(), or converts to const char*. Ordinary character containers remain containers.
  • Pointer wrappers expose get() convertible to const void*; weak wrappers expose lock() returning such a wrapper.
  • Tuple protocols expose std::tuple_size<T> and ADL-accessible get<I>(const T&). Containers take precedence over tuples.

Include the headers defining your types yourself. <tuple>, <complex>, <memory>, etc. may appear before or after zeroerr/print.h, provided the types are complete before printing. Printing neither copies values nor takes ownership of smart pointers.

The print header retains its std::ostream and std::string interfaces. Stringstream management and type-name demangling live in .cpp implementations: link the zeroerr library, or define ZEROERR_IMPLEMENTATION in one translation unit when using the single header.

Construction

Printer can capture text or attach a stream supplied by the caller:

Printer(); // capture into StringBuffer
template<class Stream> explicit Printer(Stream& os); // attach caller's stream

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 main() {
auto print = zeroerr::getStderrPrinter();
int a = 1;
int& b = a;
int* c = &a;
print(a, b, c);
return 0;
}
Printer & getStderrPrinter()
Definition print.cpp:14
int main(int argc, const char **argv)
Definition unittest.cpp:1263

Output:

1 1 <int* at 0x7ffebc813ed4>

Function pointers print as <function-pointer-type at address>. An empty function pointer prints as nullptr. std::function prints as <wrapper-type holding target-type>, or nullptr when empty. Printing never calls the target. These values are also supported inside containers and tuples.

STL container support:

int main() {
auto print = zeroerr::getStderrPrinter();
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:

  1. Compact mode - everything in one line, e.g. {"a" : 1, "b" : 2}
    print.isCompact = true;
  2. Colorful mode - using colorful output
    print.isColorful = true;
  3. Quoted mode - string will be quoted, "a" or a for printing a string a
    print.isQuoted = true;
  4. Indentation - default is 2.
    print.indent = 4
  5. Liner break - default is \n.
    print.line_break = "\r\n"; // for windows

Print inside stream

The printer can be used in a stream once you constructed it without giving a output stream.

Printer print; // capture into StringBuffer
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
zeroerr::PrinterExt(Printer& P, <type of Input>, unsigned level, const char* lb, rank<N>);
void PrinterExt(Printer &, const T &, unsigned, const char *, rank< 0 >)
PrinterExt is an extension of Printer that allows user to write custom rules for printing.
Definition print.h:388

Here is an example for LLVM library, so you can printer pointer of llvm::Value, llvm::Type and llvm::Function:

namespace zeroerr{
// This will create a special rule for printing pointers from LLVM value
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 {
std::string text; // explicitly include <string> and LLVM raw_ostream headers
llvm::raw_string_ostream os(text);
s->print(os);
os.flush();
P.os << text;
}
}
// Even though llvm::Function is a subclass of `llvm::Value`, but this rule is in rank 2.
// So it will cover the basic rule. All the pointer base of `llvm::Function` will call
// this function to print.
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 {
std::string text; // explicitly include <string> and LLVM raw_ostream headers
llvm::raw_string_ostream os(text);
P.os << P.tab(level) << "Function " << FgCyan;
os << *s;
os.flush();
P.os << text << Reset;
}
}
} // namespace zeroerr
Definition assert_text.cpp:5
const char * FgCyan
Definition color.cpp:48
const char * Reset
Definition color.cpp:34
A functor class Printer for printing a value of any type.
Definition print.h:87
rank is a helper class for Printer to define the priority of overloaded functions.
Definition typetraits.h:43