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!