Advanced usage

Sometimes it is necessary to access the internal workings to create a more complicated printer.

Representing of lines of text

Before we get into printing types, we must understand how outputs are represented. In Hippo, a line of text is represented by hippo::line, which tracks the indentation level of the line separately from the contents.

struct line

Describes a printed line of text.

Public Functions

line(std::uint64_t indent)

Construct an empty line with the given indentation level.

line(std::uint64_t indent, std::string string)

Construct a line with the given indentation level and string.

Public Members

std::uint64_t indent

The indentation level of the line.

std::string string

The contents of the line.

When an object is printed, the generated lines of text are then collected into a hippo::object. Any lines that are shorter than hippo::configuration::width are condensed into a single line if possible. Multiple hippo::object may be condensed as well, but only if all of the objects are a single line.

using hippo::object = std::variant<hippo::line, std::list<hippo::line>>

Describes the printed output of any object, either as a single or multiple lines.

inline hippo::object hippo::condense(const std::list<hippo::line> &lines, const hippo::configuration &config)

Condense a collection of lines into a single object. Multiple lines will be condensed into one if the indented result is less than the configured output width.

inline hippo::object hippo::condense(const std::list<hippo::object> &objects, const hippo::configuration &config)

Condense a collection of objects into a single object. If any of the input objects are multiline, the output is not condensed, otherwise the lines will condensed if the indented result is less than the configured output width.

Defining a printer

Printers are added for a type by specializing the hippo::printer struct. This class is declared as follows:

template<typename T, typename U = T>
struct printer

The core pretty-printer type. T is the type to be printed. U is provided for optionally making SFINAE possible.

Specializations must fulfill the following interface:

template<> hippo::printer<Foo> {
  using format_type = /* any default-constructible and copy-constructible type */
  static ::hippo::object print(const Foo &f,
                               std::uint64_t current_indent,
                               const ::hippo::configuration &config,
                               const format_type &format = format_type());

}

Convenient utilities

The following operations are so common when creating printers that Hippo provides them.

Manipulating lines

struct prepend_visitor

Visitor over objects that prepends a string to the first line.

Public Functions

void operator()(hippo::line &line)

Prepend to a single line.

void operator()(std::list<hippo::line> &lines)

Prepend to the beginning of many lines.

Public Members

std::string prefix

The string to prepend.

struct append_visitor

Visitor over objects that appends a string to the last line.

Public Functions

void operator()(hippo::line &line)

Append to a single line.

void operator()(std::list<hippo::line> &lines)

Append to the end of many lines.

Public Members

std::string suffix

The string to append.

Formatting values

template<typename T>
std::enable_if_t<std::is_floating_point_v<T>, std::string> hippo::apply_format(T value, const float_format &fmt)

Apply format fmt to floating-point value

template<typename T>
std::enable_if_t<std::is_integral_v<T>, std::string> hippo::apply_format(T value, const integer_format &fmt)

Apply format fmt to integer value

template<typename T>
hippo::object hippo::apply_format(const T *value, std::uint64_t current_indent, const hippo::configuration &config, const pointer_format<T> &fmt)

Apply format fmt to pointer value using the current_indent indentation level and configuration config.