example usage:
using namespace explore;
// ... some container c defined here print(c);
print( c, std::cerr, html_table_format());
full argument list of print (informal, declaration follows later):
print( item, stream = std::cout, format = default_format(), element_policy = default_policy())
The print function will either:
An element policy tells the print function if an object is printable, a container or none. It does this by wrapping two unary metafunctions: is_printable<T> and is_container<T>. The implementations of these metafunctions in the default policy delegate their decision to the "global" metafunctions explore::is_printable and explore::is_container respectively:
struct default_policy { template< typename T> struct is_printable : explore::is_printable<T> {};
template< typename T> struct is_container : explore::is_container<T> {}; };
The definitions of the "global" metafunctions are such that a type is by default printable if there is a stream output operator for the type and it is a container if it fits the range concept. By default tuples (and std::pair) will be treated as ranges.
Note that the previous paragraph implies that std::string will be streamed directly and not as a container of characters. If I want the characters of a string to be printed separately (and be subject to formatting), I could define the following policy:
struct string_as_container : explore::default_policy { template<> struct is_printable<std::string> : mpl::false_ { };
// default is fine for is_container };
print( std::string("hello")); // outputs: hello
print( std::string("hello"), std::cout, /*default_format(), */string_as_container()); // outputs something like: [ h, e, l, l, o ]
Formatting is specified in terms of karma generators.
In general terms: a format given to print is in fact a karma generator generator (referred to as 'instant karma' in the rest of this text). print will recursively call print_container, which may in turn call print. At every level, a slightly modified version of the instant karma is handed to the next version. This way, at compile time a karma generator is created that can handle an object of the dimension that was given to the print function.
See Hartmut's and Joao's implementation...