Formatting¶
Some printable types support formatting.
Formatting is applied with the hippo::formatter
adapter, which itself is a printable type that applies a format to its contents.
Formatting numbers¶
The following example shows how numbers can be formatted for a user-defined type:
struct Foo {
int bar;
float baz;
};
static hippo::integer_format hex() {
hippo::integer_format fmt;
fmt.base = hippo::integer_format::base_type::hex;
return fmt;
}
static hippo::float_format scientific() {
hippo::float_format fmt;
fmt.format = hippo::float_format::notation_type::scientific;
return fmt;
};
HIPPO_CLASS_BEGIN(Foo)
HIPPO_CLASS_MEMBER_EXPR(Foo, hippo::formatter(object.bar, hex()))
HIPPO_CLASS_MEMBER_EXPR(Foo, hippo::formatter(object.baz, scientific()))
HIPPO_CLASS_END()
Using formatting to print polymorphic types¶
Polymorphic types can be printed by use of hippo::derived_type_printer
:
#include "hippo/hippo.h"
#include "hippo/std/memory.h"
#include <iostream>
struct Foo {
virtual ~Foo() = default;
};
struct Bar : Foo {};
struct Baz : Foo {};
HIPPO_CLASS_BEGIN(Foo)
HIPPO_CLASS_END()
HIPPO_CLASS_BEGIN(Bar)
HIPPO_BASE(Foo)
HIPPO_CLASS_END()
HIPPO_CLASS_BEGIN(Baz)
HIPPO_BASE(Foo)
HIPPO_CLASS_END()
int main() {
std::shared_ptr<Foo> foo = std::make_shared<Foo>();
std::shared_ptr<Foo> bar = std::make_shared<Bar>();
std::shared_ptr<Foo> baz = std::make_shared<Baz>();
hippo::dynamic_type_format<Foo> dyn_fmt;
dyn_fmt.printers.push_back(std::make_shared<hippo::derived_type_printer<Foo, Bar>>());
dyn_fmt.printers.push_back(std::make_shared<hippo::derived_type_printer<Foo, Baz>>());
hippo::pointer_format<Foo> fmt = std::move(dyn_fmt);
hippo::print_to(std::cout, hippo::formatter(foo, fmt), hippo::configuration());
hippo::print_to(std::cout, hippo::formatter(bar, fmt), hippo::configuration());
hippo::print_to(std::cout, hippo::formatter(baz, fmt), hippo::configuration());
}
Once Bar
and Baz
are registered with the pointer format, the printer is able to use RTTI to determine which printer to use.
The following is printed:
std::shared_ptr containing [ Foo { } ]
std::shared_ptr containing [ Bar { Base Foo { } } ]
std::shared_ptr containing [ Baz { Base Foo { } } ]
Interface¶
-
template<typename
T
>
structformatter
¶ A printable type that applies formats to other printable types.
Public Types
-
template<>
usingvalue_type
= std::remove_const_t<T>¶ The type to format.
-
template<>
usingprinter_type
= hippo::printer<value_type>¶ The printer for
T
-
template<>
usingformat_type
= typename printer_type::format_type¶ The format configuration for
T
Public Functions
-
formatter
(const value_type &value, const format_type &format)¶ Construct a
formatter
that printsvalue
with the format described byformat
. The constructedformatter
does not ownvalue
orformat
, so both must remain in scope for the lifetime of theformatter
.
-
template<>
-
template<typename
T
>
structformatter
<T *>¶ Specialization of
formatter
for pointer types.Public Types
-
template<>
usingvalue_type
= std::remove_const_t<std::decay_t<T>>¶ The type to format.
-
template<>
usingprinter_type
= hippo::printer<value_type *>¶ The printer for
T
-
template<>
usingformat_type
= typename printer_type::format_type¶ The format configuration for
T
Public Functions
-
formatter
(const value_type *value, const format_type &format)¶ Construct a
formatter
that printsvalue
with the format described byformat
. The constructedformatter
does not ownvalue
orformat
, so both must remain in scope for the lifetime of theformatter
.
-
template<>
-
struct
no_format
¶ Format for non-formattable types.
Number format configurations¶
-
struct
integer_format
¶ Format for integer values.
Public Types
-
struct
float_format
¶ Format for floating-point values.
Public Types
Public Members
-
notation_type
notation
¶ Notation format, defaults to
standard
-
std::optional<std::size_t>
precision
¶ Precision for
std::setprecision
-
notation_type
Pointer configurations¶
-
using
hippo
::
pointer_format
= std::variant<standard_pointer_format<T>, address_format, dynamic_type_format<T>>¶ Format for printing a pointer.
-
template<typename
T
>
structstandard_pointer_format
¶ Format option for non-polymorphic pointers. A non-null pointer is dereferenced and printed.
Public Members
-
format_type
format
¶ The format used for printing.
-
format_type
-
struct
address_format
¶ Format option for printing pointers as addresses (rather than printing the dereferenced pointer)
-
template<typename
T
>
structdynamic_type_format
¶ Format option for printing polymorphic types. A non-null pointer is checked against the registered types, dereferenced, and printed.
Public Types
Public Members
-
std::vector<std::shared_ptr<base_type_printer<T>>>
printers
¶ Printers for derived types, in preference order.
Printers are called one by one and returns the first successful output.
-
base_format_type
base_format
¶ If none of the derived printers are successful, the base class is printed with this format.
-
std::vector<std::shared_ptr<base_type_printer<T>>>
-
template<typename
Base
>
structbase_type_printer
¶ Abstract base for printers of polymorphic pointers.
Subclassed by hippo::derived_type_printer< Base, Derived >
Public Functions
-
virtual std::optional<hippo::object>
print
(const Base *b, std::uint64_t current_indent, const hippo::configuration &config) = 0¶ Prints
b
if possible, otherwise the return value is empty.
-
virtual std::optional<hippo::object>
-
template<typename
Base
, typenameDerived
>
structderived_type_printer
: public hippo::base_type_printer<Base>¶ Printer for a polymorphic type from a base class pointer.
Public Types
-
template<>
usingformat_type
= typename printer_type::format_type¶ Format type of
Derived
Public Functions
-
derived_type_printer
()¶ Construct a printer using the default format.
-
derived_type_printer
(const format_type &format)¶ Construct a printer using the specified format
format
-
std::optional<hippo::object>
print
(const Base *b, std::uint64_t current_indent, const hippo::configuration &config)¶ Prints
b
if it is aDerived
, otherwise returns nothing.
-
template<>