More readable is certainly a matter of opinion, in this case.
if (bpp->b_core == -1) {
snprintf(core, sizeof(core), "%s", "All");
} else {
snprintf(core, sizeof(core), "%2.2d", bpp->b_core);
}
lp->log(" %2.2zu %016llx %3.3s %s\n",
b, bpp->b_address, core, bpp->b_enabled?"Yes":"No");
This is much more readable, and much more important to me, it will perform
much better than the C++ stuff you've written above (two function calls
versus many function calls, smaller cache footprint vs. larger cache footprint).
You should prove that your code will "perform much better". If I have to
bet, I'd say your code actually performs worse. Manipulators can be
easily optimized out by any modern compiler (see later for an example).
Also, clog is buffered, so it is faster than cout and printf() probably.
All the C++ I write is in operating systems, hypervisors and other bare-metal
code for which performance is priority #1, and where we don't have the standard
C++ runtime (such as it is) available. No rtti, no exceptions, no templates
and very few reference objects.
Templates themselves have no impact at run-time. Also, C++ streams were
designed with performance in mind and exceptions are deliberately
disabled by default. Note that I am not saying that printf() is actually
slower than clog.
Anyway, in your case it seems you just want to print out a simple table
to the user (from "%2.2zu" it seems the table is supposed have less than
100 entries), so for these simple cases I suggest you paying attention
to writing readable code rather than trying to optimize where the
benefits will not be noticeable.
To interpret your formatting I had to take a C manual (and a coffee..):
lp->log(" %2.2zu %016llx %3.3s %s\n"...
Not to mention the fact that I had to count the number of white spaces
by moving the cursor from right to left.
With pure C++ style you will not have an headache at least. In the
example below I have used a "custom" manipulator to make the code even
shorter than I wrote in my previous post. As an exercise, you may want
to try to implement a whitespace() manipulator to further improve it;
clog << pad(' ', 3) << ' '
<< pad('0', 2) << b
<< pad(' ', 8) << ' '
<< pad('0', 16)
<< hex << reinterpret_cast<unsigned long> (bpp->b_address)
<< pad(' ', 2) << ' '
<< core.str().substr(0, 3) << ' '
<< pad(' ', 3) << ' '
<< (bpp->b_enabled ? "Yes" : "No")
<< '\n';
The pad manipulator is so simple that can be easily expanded in-line by
any compiler, with no performance loss:
// Place this in a library for re-use
struct smanip {
ostream& (*f)(ostream&, char, int);
char c;
int i;
smanip(ostream& (*ff)(ostream&, char, int), char cc, int ii)
: f(ff), c(cc), i(ii) { }
};
ostream& operator<<(ostream& os, const smanip& m) {
return m.f(os, m.c, m.i);
}
ostream& set_pad(ostream& s, char c, int n) {
s.fill(c);
s.width(n);
return s;
}
inline smanip pad(char c, int n) {
return smanip(set_pad, c, n);
}