Component of the Week #4: bslalg_numericformatterutil
- Summary:
Provides utilities for efficiently converting integral and floating-point values to strings in various formats.
Have you ever needed to obtain a string representation of an int? Perhaps,
in hex or binary format? When to_string is not configurable enough, and
ostringstream and sprintf are too general purpose, verbose, and
inefficient? How about formatting a float with similar requirements?
There is a BDE component for that! And that component is
bslalg_numericformatterutil, which parallels bsl::to_chars but
supports legacy platforms and provides a facility to help correctly size output
buffers.
bslalg_numericformatterutil contains a collection functions (or rather a large overload set) that make such scenarios easy to handle.
bslalg::NumericFormatterUtil::toChars is lean. All it does is convert a
numeric value to text. It does not allocate - you need to provide it with an
output buffer, it does not support locales, it just does what it says on the
tin, efficiently and with enough flexibility.
Suppose we want to print an integer in hex format. We need a character buffer
for it. Instead of guessing how large the buffer should be, we can use
bslalg::NumericFormatterUtil::ToCharsMaxLength to determine the size:
typedef bslalg::NumericFormatterUtil NFUtil;
int value = -10555592;
const int k_BASE = 16;
char buffer[NFUtil::ToCharsMaxLength<int, k_BASE>::k_VALUE];
char *end =
NFUtil::toChars(bsl::begin(buffer), bsl::end(buffer), value, k_BASE);
bsl::cout << bsl::string_view(buffer, end) << '\n';
The code for double is not that much different, though instead of the base
we can specify the format we want to use for formatting a floating-point value
- fixed, scientific, hex, or general. The latter of the four is perhaps the
most interesting one. For the general format, when precision is not specified,
the output will be the shortest text representation that guarantees that
parsing that text back into the original floating-point type will result in the
binary-identical value!
double value = 1618e033 * 314.1592 / 0.27182;
const NFUtil::Format k_FORMAT = NFUtil::e_GENERAL;
char buffer[NFUtil::ToCharsMaxLength<double, k_FORMAT>::k_VALUE];
char *end =
NFUtil::toChars(bsl::begin(buffer), bsl::end(buffer), value, k_FORMAT);
bsl::cout << bsl::string_view(buffer, end) << '\n';
Check out the documentation for bslalg_numericformatterutil for many more details.
Keep an eye out for next week’s component of the week
bdlb_numericparseutil - the component that does the inverse operation to
formatting: parsing!