pretty print container of arbitrary type
The following code of few lines provides same output as prettyprint.hpp in question,
but the output stream is limited to std::cout
.
How to rewrite those code using boost::hof
to provide print(std::ostream&, ...)
like interface?
#include <iostream>
#include <boost/hof.hpp>
BOOST_HOF_STATIC_LAMBDA_FUNCTION(simple_print) = //boost::hof::proj(
boost::hof::fix(boost::hof::first_of(
[](auto, const auto& x) -> decltype(std::cout << x, void()) {
std::cout << x;
},
[](auto self, const auto& range)
-> decltype(self(*std::begin(range)), void()) {
bool sep = false;
std::cout << '{';
for (const auto& x : range) {
if (sep)
std::cout << ',';
else
sep = true;
self(x);
}
std::cout << '}';
},
[](auto self, const auto& tuple) {
using namespace boost::hof;
std::cout << '(';
bool sep = false;
unpack(proj([&](const auto& i) {
if (sep)
std::cout << ',';
else
sep = true;
self(i);
}))(tuple);
std::cout << ')';
}));//})));
template <typename... Args>
void print(Args&&... args) {
simple_print(std::make_tuple(std::forward<Args>(args)...));
}
//---- user code ---
struct XX {
int n = 0;
friend std::ostream& operator<<(std::ostream& os, const XX& o) {
return os << o.n << "XX";
}
};
int main() {
std::vector v = {1, 2, 3, 4};
std::map<std::string, int> m = {{"a", 30}, {"bb", 31}, {"ccc", 32}};
auto t = std::make_tuple(6, 7, 8, 9);
auto t2 = std::make_tuple(11, std::ref(v), t);
auto t3 = std::make_tuple(t2, std::vector{1234, 23, 2, 3, 3}, "abc",
std::vector{
std::vector{11, 12, 13}, std::vector{15, 16, 17}, std::vector{19}});
print(t3, "xxxx", 55, m, std::vector<std::string>{"x"}, XX{66});
// (((11, [1, 2, 3, 4], (6, 7, 8, 9)), [1234, 23, 2, 3, 3], abc, [[11, 12,
// 13], [15, 16, 17], [19]]), xxxx, 55, [(a, 30), (bb, 31), (ccc, 32)], [x],
// 66XX)
}