str_format.h 35 KB

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