I am formatting some log output. I want the end result to look like this:
Foo.................................12.1 Bar....................................4 Foo Bar............................42.01 The total width is constant but both parameters (name and value) have various sizes. Is there a clean way to get the width of a given parameter, once included in a std::ostream?
#include <iostream> struct Entry { std::string name_; double value_; }; constexpr int line_width = 30; std::ostream& operator<<(std::ostream& log, const Entry& e) { log << e.name_ << std::string(line_width - e.name_.size(), '.') \\ should subtract the width of e.value_ << e.value_; return log; } int main() { Entry foo = { "Foo", 12.1 }; Entry bar = { "Bar", 4}; Entry foobar = { "Foo Bar", 42.01}; std::cout << foo << '\n' << bar << '\n' << foobar << '\n'; } The code above won't work because I did not subtract the width of the value. I was thinking about writing a function that would do something like this:
template <typename T> int get_width(std::ostream& log, T value) { // 1. use tellp to get initial stream size // 2. insert the value in the stream // 3. use tellp to get final stream size // 4. remove the value from the stream (is that even possible?) // 5. return the size = final - initial } Is there a clean way to reach my goal?
name_andvalue_known ahead of time? Or does each maximum of those two widths need to be calculated from the data, and then use that to determine the layout?