str_format.h (36086B)
1 // 2 // Copyright 2018 The Abseil Authors. 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // https://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 // 16 // ----------------------------------------------------------------------------- 17 // File: str_format.h 18 // ----------------------------------------------------------------------------- 19 // 20 // The `str_format` library is a typesafe replacement for the family of 21 // `printf()` string formatting routines within the `<cstdio>` standard library 22 // header. Like the `printf` family, `str_format` uses a "format string" to 23 // perform argument substitutions based on types. See the `FormatSpec` section 24 // below for format string documentation. 25 // 26 // Example: 27 // 28 // std::string s = absl::StrFormat( 29 // "%s %s You have $%d!", "Hello", name, dollars); 30 // 31 // The library consists of the following basic utilities: 32 // 33 // * `absl::StrFormat()`, a type-safe replacement for `std::sprintf()`, to 34 // write a format string to a `string` value. 35 // * `absl::StrAppendFormat()` to append a format string to a `string` 36 // * `absl::StreamFormat()` to more efficiently write a format string to a 37 // stream, such as`std::cout`. 38 // * `absl::PrintF()`, `absl::FPrintF()` and `absl::SNPrintF()` as 39 // drop-in replacements for `std::printf()`, `std::fprintf()` and 40 // `std::snprintf()`. 41 // 42 // Note: An `absl::SPrintF()` drop-in replacement is not supported as it 43 // is generally unsafe due to buffer overflows. Use `absl::StrFormat` which 44 // returns the string as output instead of expecting a pre-allocated buffer. 45 // 46 // Additionally, you can provide a format string (and its associated arguments) 47 // using one of the following abstractions: 48 // 49 // * A `FormatSpec` class template fully encapsulates a format string and its 50 // type arguments and is usually provided to `str_format` functions as a 51 // variadic argument of type `FormatSpec<Arg...>`. The `FormatSpec<Args...>` 52 // template is evaluated at compile-time, providing type safety. 53 // * A `ParsedFormat` instance, which encapsulates a specific, pre-compiled 54 // format string for a specific set of type(s), and which can be passed 55 // between API boundaries. (The `FormatSpec` type should not be used 56 // directly except as an argument type for wrapper functions.) 57 // 58 // The `str_format` library provides the ability to output its format strings to 59 // arbitrary sink types: 60 // 61 // * A generic `Format()` function to write outputs to arbitrary sink types, 62 // which must implement a `FormatRawSink` interface. 63 // 64 // * A `FormatUntyped()` function that is similar to `Format()` except it is 65 // loosely typed. `FormatUntyped()` is not a template and does not perform 66 // any compile-time checking of the format string; instead, it returns a 67 // boolean from a runtime check. 68 // 69 // In addition, the `str_format` library provides extension points for 70 // augmenting formatting to new types. See "StrFormat Extensions" below. 71 72 #ifndef ABSL_STRINGS_STR_FORMAT_H_ 73 #define ABSL_STRINGS_STR_FORMAT_H_ 74 75 #include <cstdint> 76 #include <cstdio> 77 #include <string> 78 #include <type_traits> 79 80 #include "absl/base/attributes.h" 81 #include "absl/base/config.h" 82 #include "absl/base/nullability.h" 83 #include "absl/strings/internal/str_format/arg.h" // IWYU pragma: export 84 #include "absl/strings/internal/str_format/bind.h" // IWYU pragma: export 85 #include "absl/strings/internal/str_format/checker.h" // IWYU pragma: export 86 #include "absl/strings/internal/str_format/extension.h" // IWYU pragma: export 87 #include "absl/strings/internal/str_format/parser.h" // IWYU pragma: export 88 #include "absl/strings/string_view.h" 89 #include "absl/types/span.h" 90 91 namespace absl { 92 ABSL_NAMESPACE_BEGIN 93 94 // UntypedFormatSpec 95 // 96 // A type-erased class that can be used directly within untyped API entry 97 // points. An `UntypedFormatSpec` is specifically used as an argument to 98 // `FormatUntyped()`. 99 // 100 // Example: 101 // 102 // absl::UntypedFormatSpec format("%d"); 103 // std::string out; 104 // CHECK(absl::FormatUntyped(&out, format, {absl::FormatArg(1)})); 105 class UntypedFormatSpec { 106 public: 107 UntypedFormatSpec() = delete; 108 UntypedFormatSpec(const UntypedFormatSpec&) = delete; 109 UntypedFormatSpec& operator=(const UntypedFormatSpec&) = delete; 110 111 explicit UntypedFormatSpec(string_view s) : spec_(s) {} 112 113 protected: 114 explicit UntypedFormatSpec( 115 absl::Nonnull<const str_format_internal::ParsedFormatBase*> pc) 116 : spec_(pc) {} 117 118 private: 119 friend str_format_internal::UntypedFormatSpecImpl; 120 str_format_internal::UntypedFormatSpecImpl spec_; 121 }; 122 123 // FormatStreamed() 124 // 125 // Takes a streamable argument and returns an object that can print it 126 // with '%s'. Allows printing of types that have an `operator<<` but no 127 // intrinsic type support within `StrFormat()` itself. 128 // 129 // Example: 130 // 131 // absl::StrFormat("%s", absl::FormatStreamed(obj)); 132 template <typename T> 133 str_format_internal::StreamedWrapper<T> FormatStreamed(const T& v) { 134 return str_format_internal::StreamedWrapper<T>(v); 135 } 136 137 // FormatCountCapture 138 // 139 // This class provides a way to safely wrap `StrFormat()` captures of `%n` 140 // conversions, which denote the number of characters written by a formatting 141 // operation to this point, into an integer value. 142 // 143 // This wrapper is designed to allow safe usage of `%n` within `StrFormat(); in 144 // the `printf()` family of functions, `%n` is not safe to use, as the `int *` 145 // buffer can be used to capture arbitrary data. 146 // 147 // Example: 148 // 149 // int n = 0; 150 // std::string s = absl::StrFormat("%s%d%n", "hello", 123, 151 // absl::FormatCountCapture(&n)); 152 // EXPECT_EQ(8, n); 153 class FormatCountCapture { 154 public: 155 explicit FormatCountCapture(absl::Nonnull<int*> p) : p_(p) {} 156 157 private: 158 // FormatCountCaptureHelper is used to define FormatConvertImpl() for this 159 // class. 160 friend struct str_format_internal::FormatCountCaptureHelper; 161 // Unused() is here because of the false positive from -Wunused-private-field 162 // p_ is used in the templated function of the friend FormatCountCaptureHelper 163 // class. 164 absl::Nonnull<int*> Unused() { return p_; } 165 absl::Nonnull<int*> p_; 166 }; 167 168 // FormatSpec 169 // 170 // The `FormatSpec` type defines the makeup of a format string within the 171 // `str_format` library. It is a variadic class template that is evaluated at 172 // compile-time, according to the format string and arguments that are passed to 173 // it. 174 // 175 // You should not need to manipulate this type directly. You should only name it 176 // if you are writing wrapper functions which accept format arguments that will 177 // be provided unmodified to functions in this library. Such a wrapper function 178 // might be a class method that provides format arguments and/or internally uses 179 // the result of formatting. 180 // 181 // For a `FormatSpec` to be valid at compile-time, it must be provided as 182 // either: 183 // 184 // * A `constexpr` literal or `absl::string_view`, which is how it is most often 185 // used. 186 // * A `ParsedFormat` instantiation, which ensures the format string is 187 // valid before use. (See below.) 188 // 189 // Example: 190 // 191 // // Provided as a string literal. 192 // absl::StrFormat("Welcome to %s, Number %d!", "The Village", 6); 193 // 194 // // Provided as a constexpr absl::string_view. 195 // constexpr absl::string_view formatString = "Welcome to %s, Number %d!"; 196 // absl::StrFormat(formatString, "The Village", 6); 197 // 198 // // Provided as a pre-compiled ParsedFormat object. 199 // // Note that this example is useful only for illustration purposes. 200 // absl::ParsedFormat<'s', 'd'> formatString("Welcome to %s, Number %d!"); 201 // absl::StrFormat(formatString, "TheVillage", 6); 202 // 203 // A format string generally follows the POSIX syntax as used within the POSIX 204 // `printf` specification. (Exceptions are noted below.) 205 // 206 // (See http://pubs.opengroup.org/onlinepubs/9699919799/functions/fprintf.html) 207 // 208 // In specific, the `FormatSpec` supports the following type specifiers: 209 // * `c` for characters 210 // * `s` for strings 211 // * `d` or `i` for integers 212 // * `o` for unsigned integer conversions into octal 213 // * `x` or `X` for unsigned integer conversions into hex 214 // * `u` for unsigned integers 215 // * `f` or `F` for floating point values into decimal notation 216 // * `e` or `E` for floating point values into exponential notation 217 // * `a` or `A` for floating point values into hex exponential notation 218 // * `g` or `G` for floating point values into decimal or exponential 219 // notation based on their precision 220 // * `p` for pointer address values 221 // * `n` for the special case of writing out the number of characters 222 // written to this point. The resulting value must be captured within an 223 // `absl::FormatCountCapture` type. 224 // * `v` for values using the default format for a deduced type. These deduced 225 // types include many of the primitive types denoted here as well as 226 // user-defined types containing the proper extensions. (See below for more 227 // information.) 228 // 229 // Implementation-defined behavior: 230 // * A null pointer provided to "%s" or "%p" is output as "(nil)". 231 // * A non-null pointer provided to "%p" is output in hex as if by %#x or 232 // %#lx. 233 // 234 // NOTE: `o`, `x\X` and `u` will convert signed values to their unsigned 235 // counterpart before formatting. 236 // 237 // Examples: 238 // "%c", 'a' -> "a" 239 // "%c", 32 -> " " 240 // "%s", "C" -> "C" 241 // "%s", std::string("C++") -> "C++" 242 // "%d", -10 -> "-10" 243 // "%o", 10 -> "12" 244 // "%x", 16 -> "10" 245 // "%f", 123456789 -> "123456789.000000" 246 // "%e", .01 -> "1.00000e-2" 247 // "%a", -3.0 -> "-0x1.8p+1" 248 // "%g", .01 -> "1e-2" 249 // "%p", (void*)&value -> "0x7ffdeb6ad2a4" 250 // 251 // int n = 0; 252 // std::string s = absl::StrFormat( 253 // "%s%d%n", "hello", 123, absl::FormatCountCapture(&n)); 254 // EXPECT_EQ(8, n); 255 // 256 // NOTE: the `v` specifier (for "value") is a type specifier not present in the 257 // POSIX specification. %v will format values according to their deduced type. 258 // `v` uses `d` for signed integer values, `u` for unsigned integer values, `g` 259 // for floating point values, and formats boolean values as "true"/"false" 260 // (instead of 1 or 0 for booleans formatted using d). `const char*` is not 261 // supported; please use `std::string` and `string_view`. `char` is also not 262 // supported due to ambiguity of the type. This specifier does not support 263 // modifiers. 264 // 265 // The `FormatSpec` intrinsically supports all of these fundamental C++ types: 266 // 267 // * Characters: `char`, `signed char`, `unsigned char`, `wchar_t` 268 // * Integers: `int`, `short`, `unsigned short`, `unsigned`, `long`, 269 // `unsigned long`, `long long`, `unsigned long long` 270 // * Enums: printed as their underlying integral value 271 // * Floating-point: `float`, `double`, `long double` 272 // 273 // However, in the `str_format` library, a format conversion specifies a broader 274 // C++ conceptual category instead of an exact type. For example, `%s` binds to 275 // any string-like argument, so `std::string`, `std::wstring`, 276 // `absl::string_view`, `const char*`, and `const wchar_t*` are all accepted. 277 // Likewise, `%d` accepts any integer-like argument, etc. 278 279 template <typename... Args> 280 using FormatSpec = str_format_internal::FormatSpecTemplate< 281 str_format_internal::ArgumentToConv<Args>()...>; 282 283 // ParsedFormat 284 // 285 // A `ParsedFormat` is a class template representing a preparsed `FormatSpec`, 286 // with template arguments specifying the conversion characters used within the 287 // format string. Such characters must be valid format type specifiers, and 288 // these type specifiers are checked at compile-time. 289 // 290 // Instances of `ParsedFormat` can be created, copied, and reused to speed up 291 // formatting loops. A `ParsedFormat` may either be constructed statically, or 292 // dynamically through its `New()` factory function, which only constructs a 293 // runtime object if the format is valid at that time. 294 // 295 // Example: 296 // 297 // // Verified at compile time. 298 // absl::ParsedFormat<'s', 'd'> format_string("Welcome to %s, Number %d!"); 299 // absl::StrFormat(format_string, "TheVillage", 6); 300 // 301 // // Verified at runtime. 302 // auto format_runtime = absl::ParsedFormat<'d'>::New(format_string); 303 // if (format_runtime) { 304 // value = absl::StrFormat(*format_runtime, i); 305 // } else { 306 // ... error case ... 307 // } 308 309 #if defined(__cpp_nontype_template_parameter_auto) 310 // If C++17 is available, an 'extended' format is also allowed that can specify 311 // multiple conversion characters per format argument, using a combination of 312 // `absl::FormatConversionCharSet` enum values (logically a set union) 313 // via the `|` operator. (Single character-based arguments are still accepted, 314 // but cannot be combined). Some common conversions also have predefined enum 315 // values, such as `absl::FormatConversionCharSet::kIntegral`. 316 // 317 // Example: 318 // // Extended format supports multiple conversion characters per argument, 319 // // specified via a combination of `FormatConversionCharSet` enums. 320 // using MyFormat = absl::ParsedFormat<absl::FormatConversionCharSet::d | 321 // absl::FormatConversionCharSet::x>; 322 // MyFormat GetFormat(bool use_hex) { 323 // if (use_hex) return MyFormat("foo %x bar"); 324 // return MyFormat("foo %d bar"); 325 // } 326 // // `format` can be used with any value that supports 'd' and 'x', 327 // // like `int`. 328 // auto format = GetFormat(use_hex); 329 // value = StringF(format, i); 330 template <auto... Conv> 331 using ParsedFormat = absl::str_format_internal::ExtendedParsedFormat< 332 absl::str_format_internal::ToFormatConversionCharSet(Conv)...>; 333 #else 334 template <char... Conv> 335 using ParsedFormat = str_format_internal::ExtendedParsedFormat< 336 absl::str_format_internal::ToFormatConversionCharSet(Conv)...>; 337 #endif // defined(__cpp_nontype_template_parameter_auto) 338 339 // StrFormat() 340 // 341 // Returns a `string` given a `printf()`-style format string and zero or more 342 // additional arguments. Use it as you would `sprintf()`. `StrFormat()` is the 343 // primary formatting function within the `str_format` library, and should be 344 // used in most cases where you need type-safe conversion of types into 345 // formatted strings. 346 // 347 // The format string generally consists of ordinary character data along with 348 // one or more format conversion specifiers (denoted by the `%` character). 349 // Ordinary character data is returned unchanged into the result string, while 350 // each conversion specification performs a type substitution from 351 // `StrFormat()`'s other arguments. See the comments for `FormatSpec` for full 352 // information on the makeup of this format string. 353 // 354 // Example: 355 // 356 // std::string s = absl::StrFormat( 357 // "Welcome to %s, Number %d!", "The Village", 6); 358 // EXPECT_EQ("Welcome to The Village, Number 6!", s); 359 // 360 // Returns an empty string in case of error. 361 template <typename... Args> 362 [[nodiscard]] std::string StrFormat(const FormatSpec<Args...>& format, 363 const Args&... args) { 364 return str_format_internal::FormatPack( 365 str_format_internal::UntypedFormatSpecImpl::Extract(format), 366 {str_format_internal::FormatArgImpl(args)...}); 367 } 368 369 // StrAppendFormat() 370 // 371 // Appends to a `dst` string given a format string, and zero or more additional 372 // arguments, returning `*dst` as a convenience for chaining purposes. Appends 373 // nothing in case of error (but possibly alters its capacity). 374 // 375 // Example: 376 // 377 // std::string orig("For example PI is approximately "); 378 // std::cout << StrAppendFormat(&orig, "%12.6f", 3.14); 379 template <typename... Args> 380 std::string& StrAppendFormat(absl::Nonnull<std::string*> dst, 381 const FormatSpec<Args...>& format, 382 const Args&... args) { 383 return str_format_internal::AppendPack( 384 dst, str_format_internal::UntypedFormatSpecImpl::Extract(format), 385 {str_format_internal::FormatArgImpl(args)...}); 386 } 387 388 // StreamFormat() 389 // 390 // Writes to an output stream given a format string and zero or more arguments, 391 // generally in a manner that is more efficient than streaming the result of 392 // `absl::StrFormat()`. The returned object must be streamed before the full 393 // expression ends. 394 // 395 // Example: 396 // 397 // std::cout << StreamFormat("%12.6f", 3.14); 398 template <typename... Args> 399 [[nodiscard]] str_format_internal::Streamable StreamFormat( 400 const FormatSpec<Args...>& format, const Args&... args) { 401 return str_format_internal::Streamable( 402 str_format_internal::UntypedFormatSpecImpl::Extract(format), 403 {str_format_internal::FormatArgImpl(args)...}); 404 } 405 406 // PrintF() 407 // 408 // Writes to stdout given a format string and zero or more arguments. This 409 // function is functionally equivalent to `std::printf()` (and type-safe); 410 // prefer `absl::PrintF()` over `std::printf()`. 411 // 412 // Example: 413 // 414 // std::string_view s = "Ulaanbaatar"; 415 // absl::PrintF("The capital of Mongolia is %s", s); 416 // 417 // Outputs: "The capital of Mongolia is Ulaanbaatar" 418 // 419 template <typename... Args> 420 int PrintF(const FormatSpec<Args...>& format, const Args&... args) { 421 return str_format_internal::FprintF( 422 stdout, str_format_internal::UntypedFormatSpecImpl::Extract(format), 423 {str_format_internal::FormatArgImpl(args)...}); 424 } 425 426 // FPrintF() 427 // 428 // Writes to a file given a format string and zero or more arguments. This 429 // function is functionally equivalent to `std::fprintf()` (and type-safe); 430 // prefer `absl::FPrintF()` over `std::fprintf()`. 431 // 432 // Example: 433 // 434 // std::string_view s = "Ulaanbaatar"; 435 // absl::FPrintF(stdout, "The capital of Mongolia is %s", s); 436 // 437 // Outputs: "The capital of Mongolia is Ulaanbaatar" 438 // 439 template <typename... Args> 440 int FPrintF(absl::Nonnull<std::FILE*> output, const FormatSpec<Args...>& format, 441 const Args&... args) { 442 return str_format_internal::FprintF( 443 output, str_format_internal::UntypedFormatSpecImpl::Extract(format), 444 {str_format_internal::FormatArgImpl(args)...}); 445 } 446 447 // SNPrintF() 448 // 449 // Writes to a sized buffer given a format string and zero or more arguments. 450 // This function is functionally equivalent to `std::snprintf()` (and 451 // type-safe); prefer `absl::SNPrintF()` over `std::snprintf()`. 452 // 453 // In particular, a successful call to `absl::SNPrintF()` writes at most `size` 454 // bytes of the formatted output to `output`, including a NUL-terminator, and 455 // returns the number of bytes that would have been written if truncation did 456 // not occur. In the event of an error, a negative value is returned and `errno` 457 // is set. 458 // 459 // Example: 460 // 461 // std::string_view s = "Ulaanbaatar"; 462 // char output[128]; 463 // absl::SNPrintF(output, sizeof(output), 464 // "The capital of Mongolia is %s", s); 465 // 466 // Post-condition: output == "The capital of Mongolia is Ulaanbaatar" 467 // 468 template <typename... Args> 469 int SNPrintF(absl::Nonnull<char*> output, std::size_t size, 470 const FormatSpec<Args...>& format, const Args&... args) { 471 return str_format_internal::SnprintF( 472 output, size, str_format_internal::UntypedFormatSpecImpl::Extract(format), 473 {str_format_internal::FormatArgImpl(args)...}); 474 } 475 476 // ----------------------------------------------------------------------------- 477 // Custom Output Formatting Functions 478 // ----------------------------------------------------------------------------- 479 480 // FormatRawSink 481 // 482 // FormatRawSink is a type erased wrapper around arbitrary sink objects 483 // specifically used as an argument to `Format()`. 484 // 485 // All the object has to do define an overload of `AbslFormatFlush()` for the 486 // sink, usually by adding a ADL-based free function in the same namespace as 487 // the sink: 488 // 489 // void AbslFormatFlush(MySink* dest, absl::string_view part); 490 // 491 // where `dest` is the pointer passed to `absl::Format()`. The function should 492 // append `part` to `dest`. 493 // 494 // FormatRawSink does not own the passed sink object. The passed object must 495 // outlive the FormatRawSink. 496 class FormatRawSink { 497 public: 498 // Implicitly convert from any type that provides the hook function as 499 // described above. 500 template <typename T, 501 typename = typename std::enable_if<std::is_constructible< 502 str_format_internal::FormatRawSinkImpl, T*>::value>::type> 503 FormatRawSink(absl::Nonnull<T*> raw) // NOLINT 504 : sink_(raw) {} 505 506 private: 507 friend str_format_internal::FormatRawSinkImpl; 508 str_format_internal::FormatRawSinkImpl sink_; 509 }; 510 511 // Format() 512 // 513 // Writes a formatted string to an arbitrary sink object (implementing the 514 // `absl::FormatRawSink` interface), using a format string and zero or more 515 // additional arguments. 516 // 517 // By default, `std::string`, `std::ostream`, and `absl::Cord` are supported as 518 // destination objects. If a `std::string` is used the formatted string is 519 // appended to it. 520 // 521 // `absl::Format()` is a generic version of `absl::StrAppendFormat()`, for 522 // custom sinks. The format string, like format strings for `StrFormat()`, is 523 // checked at compile-time. 524 // 525 // On failure, this function returns `false` and the state of the sink is 526 // unspecified. 527 template <typename... Args> 528 bool Format(FormatRawSink raw_sink, const FormatSpec<Args...>& format, 529 const Args&... args) { 530 return str_format_internal::FormatUntyped( 531 str_format_internal::FormatRawSinkImpl::Extract(raw_sink), 532 str_format_internal::UntypedFormatSpecImpl::Extract(format), 533 {str_format_internal::FormatArgImpl(args)...}); 534 } 535 536 // FormatArg 537 // 538 // A type-erased handle to a format argument specifically used as an argument to 539 // `FormatUntyped()`. You may construct `FormatArg` by passing 540 // reference-to-const of any printable type. `FormatArg` is both copyable and 541 // assignable. The source data must outlive the `FormatArg` instance. See 542 // example below. 543 // 544 using FormatArg = str_format_internal::FormatArgImpl; 545 546 // FormatUntyped() 547 // 548 // Writes a formatted string to an arbitrary sink object (implementing the 549 // `absl::FormatRawSink` interface), using an `UntypedFormatSpec` and zero or 550 // more additional arguments. 551 // 552 // This function acts as the most generic formatting function in the 553 // `str_format` library. The caller provides a raw sink, an unchecked format 554 // string, and (usually) a runtime specified list of arguments; no compile-time 555 // checking of formatting is performed within this function. As a result, a 556 // caller should check the return value to verify that no error occurred. 557 // On failure, this function returns `false` and the state of the sink is 558 // unspecified. 559 // 560 // The arguments are provided in an `absl::Span<const absl::FormatArg>`. 561 // Each `absl::FormatArg` object binds to a single argument and keeps a 562 // reference to it. The values used to create the `FormatArg` objects must 563 // outlive this function call. 564 // 565 // Example: 566 // 567 // std::optional<std::string> FormatDynamic( 568 // const std::string& in_format, 569 // const vector<std::string>& in_args) { 570 // std::string out; 571 // std::vector<absl::FormatArg> args; 572 // for (const auto& v : in_args) { 573 // // It is important that 'v' is a reference to the objects in in_args. 574 // // The values we pass to FormatArg must outlive the call to 575 // // FormatUntyped. 576 // args.emplace_back(v); 577 // } 578 // absl::UntypedFormatSpec format(in_format); 579 // if (!absl::FormatUntyped(&out, format, args)) { 580 // return std::nullopt; 581 // } 582 // return std::move(out); 583 // } 584 // 585 [[nodiscard]] inline bool FormatUntyped(FormatRawSink raw_sink, 586 const UntypedFormatSpec& format, 587 absl::Span<const FormatArg> args) { 588 return str_format_internal::FormatUntyped( 589 str_format_internal::FormatRawSinkImpl::Extract(raw_sink), 590 str_format_internal::UntypedFormatSpecImpl::Extract(format), args); 591 } 592 593 //------------------------------------------------------------------------------ 594 // StrFormat Extensions 595 //------------------------------------------------------------------------------ 596 // 597 // AbslStringify() 598 // 599 // A simpler customization API for formatting user-defined types using 600 // absl::StrFormat(). The API relies on detecting an overload in the 601 // user-defined type's namespace of a free (non-member) `AbslStringify()` 602 // function as a friend definition with the following signature: 603 // 604 // template <typename Sink> 605 // void AbslStringify(Sink& sink, const X& value); 606 // 607 // An `AbslStringify()` overload for a type should only be declared in the same 608 // file and namespace as said type. 609 // 610 // Note that unlike with AbslFormatConvert(), AbslStringify() does not allow 611 // customization of allowed conversion characters. AbslStringify() uses `%v` as 612 // the underlying conversion specififer. Additionally, AbslStringify() supports 613 // use with absl::StrCat while AbslFormatConvert() does not. 614 // 615 // Example: 616 // 617 // struct Point { 618 // // To add formatting support to `Point`, we simply need to add a free 619 // // (non-member) function `AbslStringify()`. This method prints in the 620 // // request format using the underlying `%v` specifier. You can add such a 621 // // free function using a friend declaration within the body of the class. 622 // // The sink parameter is a templated type to avoid requiring dependencies. 623 // template <typename Sink> 624 // friend void AbslStringify(Sink& sink, const Point& p) { 625 // absl::Format(&sink, "(%v, %v)", p.x, p.y); 626 // } 627 // 628 // int x; 629 // int y; 630 // }; 631 // 632 // AbslFormatConvert() 633 // 634 // The StrFormat library provides a customization API for formatting 635 // user-defined types using absl::StrFormat(). The API relies on detecting an 636 // overload in the user-defined type's namespace of a free (non-member) 637 // `AbslFormatConvert()` function, usually as a friend definition with the 638 // following signature: 639 // 640 // absl::FormatConvertResult<...> AbslFormatConvert( 641 // const X& value, 642 // const absl::FormatConversionSpec& spec, 643 // absl::FormatSink *sink); 644 // 645 // An `AbslFormatConvert()` overload for a type should only be declared in the 646 // same file and namespace as said type. 647 // 648 // The abstractions within this definition include: 649 // 650 // * An `absl::FormatConversionSpec` to specify the fields to pull from a 651 // user-defined type's format string 652 // * An `absl::FormatSink` to hold the converted string data during the 653 // conversion process. 654 // * An `absl::FormatConvertResult` to hold the status of the returned 655 // formatting operation 656 // 657 // The return type encodes all the conversion characters that your 658 // AbslFormatConvert() routine accepts. The return value should be {true}. 659 // A return value of {false} will result in `StrFormat()` returning 660 // an empty string. This result will be propagated to the result of 661 // `FormatUntyped`. 662 // 663 // Example: 664 // 665 // struct Point { 666 // // To add formatting support to `Point`, we simply need to add a free 667 // // (non-member) function `AbslFormatConvert()`. This method interprets 668 // // `spec` to print in the request format. The allowed conversion characters 669 // // can be restricted via the type of the result, in this example 670 // // string and integral formatting are allowed (but not, for instance 671 // // floating point characters like "%f"). You can add such a free function 672 // // using a friend declaration within the body of the class: 673 // friend absl::FormatConvertResult<absl::FormatConversionCharSet::kString | 674 // absl::FormatConversionCharSet::kIntegral> 675 // AbslFormatConvert(const Point& p, const absl::FormatConversionSpec& spec, 676 // absl::FormatSink* s) { 677 // if (spec.conversion_char() == absl::FormatConversionChar::s) { 678 // absl::Format(s, "x=%vy=%v", p.x, p.y); 679 // } else { 680 // absl::Format(s, "%v,%v", p.x, p.y); 681 // } 682 // return {true}; 683 // } 684 // 685 // int x; 686 // int y; 687 // }; 688 689 // clang-format off 690 691 // FormatConversionChar 692 // 693 // Specifies the formatting character provided in the format string 694 // passed to `StrFormat()`. 695 enum class FormatConversionChar : uint8_t { 696 c, s, // text 697 d, i, o, u, x, X, // int 698 f, F, e, E, g, G, a, A, // float 699 n, p, v // misc 700 }; 701 // clang-format on 702 703 // FormatConversionSpec 704 // 705 // Specifies modifications to the conversion of the format string, through use 706 // of one or more format flags in the source format string. 707 class FormatConversionSpec { 708 public: 709 // FormatConversionSpec::is_basic() 710 // 711 // Indicates that width and precision are not specified, and no additional 712 // flags are set for this conversion character in the format string. 713 bool is_basic() const { return impl_.is_basic(); } 714 715 // FormatConversionSpec::has_left_flag() 716 // 717 // Indicates whether the result should be left justified for this conversion 718 // character in the format string. This flag is set through use of a '-' 719 // character in the format string. E.g. "%-s" 720 bool has_left_flag() const { return impl_.has_left_flag(); } 721 722 // FormatConversionSpec::has_show_pos_flag() 723 // 724 // Indicates whether a sign column is prepended to the result for this 725 // conversion character in the format string, even if the result is positive. 726 // This flag is set through use of a '+' character in the format string. 727 // E.g. "%+d" 728 bool has_show_pos_flag() const { return impl_.has_show_pos_flag(); } 729 730 // FormatConversionSpec::has_sign_col_flag() 731 // 732 // Indicates whether a mandatory sign column is added to the result for this 733 // conversion character. This flag is set through use of a space character 734 // (' ') in the format string. E.g. "% i" 735 bool has_sign_col_flag() const { return impl_.has_sign_col_flag(); } 736 737 // FormatConversionSpec::has_alt_flag() 738 // 739 // Indicates whether an "alternate" format is applied to the result for this 740 // conversion character. Alternative forms depend on the type of conversion 741 // character, and unallowed alternatives are undefined. This flag is set 742 // through use of a '#' character in the format string. E.g. "%#h" 743 bool has_alt_flag() const { return impl_.has_alt_flag(); } 744 745 // FormatConversionSpec::has_zero_flag() 746 // 747 // Indicates whether zeroes should be prepended to the result for this 748 // conversion character instead of spaces. This flag is set through use of the 749 // '0' character in the format string. E.g. "%0f" 750 bool has_zero_flag() const { return impl_.has_zero_flag(); } 751 752 // FormatConversionSpec::conversion_char() 753 // 754 // Returns the underlying conversion character. 755 FormatConversionChar conversion_char() const { 756 return impl_.conversion_char(); 757 } 758 759 // FormatConversionSpec::width() 760 // 761 // Returns the specified width (indicated through use of a non-zero integer 762 // value or '*' character) of the conversion character. If width is 763 // unspecified, it returns a negative value. 764 int width() const { return impl_.width(); } 765 766 // FormatConversionSpec::precision() 767 // 768 // Returns the specified precision (through use of the '.' character followed 769 // by a non-zero integer value or '*' character) of the conversion character. 770 // If precision is unspecified, it returns a negative value. 771 int precision() const { return impl_.precision(); } 772 773 private: 774 explicit FormatConversionSpec( 775 str_format_internal::FormatConversionSpecImpl impl) 776 : impl_(impl) {} 777 778 friend str_format_internal::FormatConversionSpecImpl; 779 780 absl::str_format_internal::FormatConversionSpecImpl impl_; 781 }; 782 783 // Type safe OR operator for FormatConversionCharSet to allow accepting multiple 784 // conversion chars in custom format converters. 785 constexpr FormatConversionCharSet operator|(FormatConversionCharSet a, 786 FormatConversionCharSet b) { 787 return static_cast<FormatConversionCharSet>(static_cast<uint64_t>(a) | 788 static_cast<uint64_t>(b)); 789 } 790 791 // FormatConversionCharSet 792 // 793 // Specifies the _accepted_ conversion types as a template parameter to 794 // FormatConvertResult for custom implementations of `AbslFormatConvert`. 795 // Note the helper predefined alias definitions (kIntegral, etc.) below. 796 enum class FormatConversionCharSet : uint64_t { 797 // text 798 c = str_format_internal::FormatConversionCharToConvInt('c'), 799 s = str_format_internal::FormatConversionCharToConvInt('s'), 800 // integer 801 d = str_format_internal::FormatConversionCharToConvInt('d'), 802 i = str_format_internal::FormatConversionCharToConvInt('i'), 803 o = str_format_internal::FormatConversionCharToConvInt('o'), 804 u = str_format_internal::FormatConversionCharToConvInt('u'), 805 x = str_format_internal::FormatConversionCharToConvInt('x'), 806 X = str_format_internal::FormatConversionCharToConvInt('X'), 807 // Float 808 f = str_format_internal::FormatConversionCharToConvInt('f'), 809 F = str_format_internal::FormatConversionCharToConvInt('F'), 810 e = str_format_internal::FormatConversionCharToConvInt('e'), 811 E = str_format_internal::FormatConversionCharToConvInt('E'), 812 g = str_format_internal::FormatConversionCharToConvInt('g'), 813 G = str_format_internal::FormatConversionCharToConvInt('G'), 814 a = str_format_internal::FormatConversionCharToConvInt('a'), 815 A = str_format_internal::FormatConversionCharToConvInt('A'), 816 // misc 817 n = str_format_internal::FormatConversionCharToConvInt('n'), 818 p = str_format_internal::FormatConversionCharToConvInt('p'), 819 v = str_format_internal::FormatConversionCharToConvInt('v'), 820 821 // Used for width/precision '*' specification. 822 kStar = static_cast<uint64_t>( 823 absl::str_format_internal::FormatConversionCharSetInternal::kStar), 824 // Some predefined values: 825 kIntegral = d | i | u | o | x | X, 826 kFloating = a | e | f | g | A | E | F | G, 827 kNumeric = kIntegral | kFloating, 828 kString = s, 829 kPointer = p, 830 }; 831 832 // FormatSink 833 // 834 // A format sink is a generic abstraction to which conversions may write their 835 // formatted string data. `absl::FormatConvert()` uses this sink to write its 836 // formatted string. 837 // 838 class FormatSink { 839 public: 840 // FormatSink::Append() 841 // 842 // Appends `count` copies of `ch` to the format sink. 843 void Append(size_t count, char ch) { sink_->Append(count, ch); } 844 845 // Overload of FormatSink::Append() for appending the characters of a string 846 // view to a format sink. 847 void Append(string_view v) { sink_->Append(v); } 848 849 // FormatSink::PutPaddedString() 850 // 851 // Appends `precision` number of bytes of `v` to the format sink. If this is 852 // less than `width`, spaces will be appended first (if `left` is false), or 853 // after (if `left` is true) to ensure the total amount appended is 854 // at least `width`. 855 bool PutPaddedString(string_view v, int width, int precision, bool left) { 856 return sink_->PutPaddedString(v, width, precision, left); 857 } 858 859 // Support `absl::Format(&sink, format, args...)`. 860 friend void AbslFormatFlush(absl::Nonnull<FormatSink*> sink, 861 absl::string_view v) { 862 sink->Append(v); 863 } 864 865 private: 866 friend str_format_internal::FormatSinkImpl; 867 explicit FormatSink(absl::Nonnull<str_format_internal::FormatSinkImpl*> s) 868 : sink_(s) {} 869 absl::Nonnull<str_format_internal::FormatSinkImpl*> sink_; 870 }; 871 872 // FormatConvertResult 873 // 874 // Indicates whether a call to AbslFormatConvert() was successful. 875 // This return type informs the StrFormat extension framework (through 876 // ADL but using the return type) of what conversion characters are supported. 877 // It is strongly discouraged to return {false}, as this will result in an 878 // empty string in StrFormat. 879 template <FormatConversionCharSet C> 880 struct FormatConvertResult { 881 bool value; 882 }; 883 884 ABSL_NAMESPACE_END 885 } // namespace absl 886 887 #endif // ABSL_STRINGS_STR_FORMAT_H_