BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bslfmt_format.h
Go to the documentation of this file.
1/// @file bslfmt_format.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslfmt_format.h -*-C++-*-
8#ifndef INCLUDED_BSLFMT_FORMAT
9#define INCLUDED_BSLFMT_FORMAT
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bslfmt_format bslfmt_format
15/// @brief Provide a standard compliant `format` implementation.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslfmt
19/// @{
20/// @addtogroup bslfmt_format
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslfmt_format-purpose"> Purpose</a>
25/// * <a href="#bslfmt_format-classes"> Classes </a>
26/// * <a href="#bslfmt_format-canonical-header"> Canonical Header </a>
27/// * <a href="#bslfmt_format-description"> Description </a>
28/// * <a href="#bslfmt_format-user-provided-formatters"> User-provided Formatters </a>
29/// * <a href="#bslfmt_format-usage"> Usage </a>
30/// * <a href="#bslfmt_format-example-1-simple-integer-formatting"> Example 1: Simple Integer Formatting </a>
31/// * <a href="#bslfmt_format-example-2-creating-a-custom-formatter-for-user-defined-type"> Example 2: Creating a Custom Formatter For User Defined Type </a>
32///
33/// # Purpose {#bslfmt_format-purpose}
34/// Provide a standard compliant `format` implementation.
35///
36/// # Classes {#bslfmt_format-classes}
37///
38/// - bsl::basic_format_arg: access to standard-compliant argument
39/// - bsl::basic_format_args: access to formatting arguments
40/// - bsl::basic_format_context: access to formatting state
41/// - bsl::basic_format_parse_context: access to format string parsing state
42/// - bsl::basic_format_string: checked format string
43/// - bsl::formatter: template type for BDE formatters
44/// - bsl::format_args: @ref basic_format_args for `char`
45/// - bsl::format_error: standard-compliant exception type
46/// - bsl::format_parse_context: @ref basic_format_parse_context for `char`
47/// - bsl::format_string: @ref basic_format_string for `char`
48/// - bsl::format_to_n_result: result type for @ref format_to_n
49/// - bsl::wformat_args: @ref basic_format_args for `wchar_t`
50/// - bsl::wformat_parse_context: @ref basic_format_parse_context for `wchar_t`
51/// - bsl::wformat_string: format_string for `wchar_t`
52///
53/// # Canonical Header {#bslfmt_format-canonical-header}
54/// bsl_format.h
55///
56/// @see ISO C++ Standard, <format>
57///
58/// # Description {#bslfmt_format-description}
59/// This component will provide, in the `bsl` namespace, wrappers
60/// around the functions and types exposed by the standard <format> header,
61/// where they are available, otherwise aliases to the `bslfmt` implementation.
62///
63/// This will provide, where a conforming library implementation is available,
64/// wrappers around the `std::format`, `std::format_to`, `std::format_to_n`,
65/// `std::vformat`, and `std::vformat_to` functions of which the `format` and
66/// `vformat` wrappers are allocator-aware. Where a conforming implementation
67/// or when compiling C++17 and earlier, BDE implementation is provided.
68///
69/// Where a BDE implementation is provided, functionality is limited to that
70/// provided by C++20 and excludes the following features:
71///
72/// * Support for locales other than the default ("C") locale
73/// * Support for wide strings
74/// * Alternative date/time representations
75/// * Date/time directives not supported by the standard `strftime` function
76/// * Character escaping
77/// * Compile-time format string checking
78///
79/// This header is not intended to be included directly. Please include
80/// `<bsl_format.h>` to be able to use `bsl::format` functionality.
81///
82/// ## User-provided Formatters {#bslfmt_format-user-provided-formatters}
83///
84///
85/// User-provided formatters are supported by the BSL implementation, just as
86/// they are by the standard library implementation. However, in order for them
87/// to be compatible with both implementations, there are specific requirements,
88/// notably:
89///
90/// - If you will define a formatter for your type `T`, do so in the same
91/// component header that defines `T` itself. This avoids issues due to
92/// users forgetting to include the header for the formatter.
93/// - Define `bsl::formatter<T>`
94/// - *DO NOT* define `std::formatter<T>`
95/// - Use template arguments for the format context and parse context
96/// parameters. This is essential as the parameter type passed in will
97/// depend upon underlying implementation.
98/// - The `parse` function must be `constexpr` in C++20, but this is not
99/// required (and may not be possible) for earlier C++ standards.
100///
101/// An example of a user defined formatter is as follows:
102///
103/// @code
104/// namespace bsl {
105///
106/// template <class t_CHAR>
107/// struct formatter<UserDefinedType, t_CHAR> {
108/// template <class t_PARSE_CONTEXT>
109/// BSLS_KEYWORD_CONSTEXPR_CPP20
110/// t_PARSE_CONTEXT::iterator parse(t_PARSE_CONTEXT& pc)
111/// {
112/// // implementation goes here
113/// }
114///
115/// template <class t_FORMAT_CONTEXT>
116/// t_FORMAT_CONTEXT::iterator format(UserDefinedType s,
117/// t_FORMAT_CONTEXT& ctx) const
118/// {
119/// // implementation goes here
120/// }
121/// };
122///
123/// } // close namespace bsl
124/// @endcode
125///
126/// ## Usage {#bslfmt_format-usage}
127///
128///
129/// This section illustrates the intended use of this component.
130///
131/// ### Example 1: Simple Integer Formatting {#bslfmt_format-example-1-simple-integer-formatting}
132///
133///
134/// Formatters for fundamental types are already defined, so to output such
135/// objects the `bsl::format` function can be used in exactly the same way as
136/// the original one from the `stl` library:
137/// @code
138/// int value = 99;
139/// bsl::string res = bsl::format("{:#06x}", value);
140///
141/// assert(bsl::string("0x0063") == res);
142/// @endcode
143///
144/// ### Example 2: Creating a Custom Formatter For User Defined Type {#bslfmt_format-example-2-creating-a-custom-formatter-for-user-defined-type}
145///
146///
147/// Suppose we have a custom type representing a date and we want to output it
148/// to the stream in different formats depending on the circumstances using
149/// `bsl::format` function. The following example demonstrates how such custom
150/// formatter may be implemented.
151///
152/// First, we define our `Date` class:
153/// @code
154/// /// This class implements a complex-constrained, value-semantic type for
155/// /// representing dates. Each object of this class *always* represents a
156/// /// *valid* date value in the range `[0001JAN01 .. 9999DEC31]` inclusive.
157/// class Date {
158/// private:
159/// // DATA
160/// int d_year; // year
161/// int d_month; // month
162/// int d_day; // day
163///
164/// public:
165/// // CREATORS
166///
167/// /// Create an object having the value represented by the specified
168/// /// `year`, `month`, and `day`.
169/// Date(int year, int month, int day)
170/// : d_year(year)
171/// , d_month(month)
172/// , d_day(day)
173/// {
174/// assert((1 <= year) && (9999 >= year));
175/// assert((1 <= month) && (12 >= month));
176/// assert((1 <= day) && (31 >= day));
177/// }
178///
179/// // ACCESSORS
180///
181/// /// Return the year of this date.
182/// int year() const { return d_year; }
183///
184/// /// Return the month of this date.
185/// int month() const { return d_month; }
186///
187/// /// Return the day of this date.
188/// int day() const { return d_day; }
189/// };
190/// @endcode
191/// Then, we define our custom formatter for this date class. In it, two
192/// methods are necessary: `parse()` and `format()`. The `parse` method parses
193/// the format string itself to determine the formatting to be used by the
194/// `format` method, which writes the formatted date into a string. Both
195/// methods are required to conform to a specific interface.
196/// @code
197/// /// This struct is a base class for `bsl::formatter` specializations for
198/// /// the `Date` class.
199/// template <class t_CHAR>
200/// struct DateFormatter {
201/// private:
202/// @endcode
203/// The convenience of using the `bsl::format` function is that the users can
204/// come up with the description language themselves. In our case, for
205/// simplicity, we will display the date in two formats - numeric (`1999-10-23`)
206/// and verbal (`23 October 1999`). Accordingly, to indicate the desired type,
207/// we will use one of two letters in the format description: 'n' ('N') or 'v'
208/// ('V'). And one field is enough for us to store it.
209/// @code
210/// // PRIVATE TYPES
211/// enum Format {
212/// e_NUMERIC, // 1999-10-23
213/// e_VERBAL // 23 October 1999
214/// };
215///
216/// // DATA
217/// Format d_format; // output format
218///
219/// // PRIVATE ACCESSORS
220///
221/// /// Output the specified `yearValue` to the specified `outIterator`.
222/// /// The specified `paddingRequired` indicates whether additional
223/// /// characters need to be added to fill empty space.
224/// template <class t_FORMAT_CONTEXT>
225/// void outputYear(
226/// typename t_FORMAT_CONTEXT::iterator& outIterator,
227/// int yearValue,
228/// bool paddingRequired) const
229/// {
230/// typedef BloombergLP::bslalg::NumericFormatterUtil NFUtil;
231///
232/// char buffer[4];
233/// char *bufferEnd = NFUtil::toChars(buffer, buffer + 4, yearValue);
234///
235/// if (paddingRequired) {
236/// const char *paddingStr = "000";
237/// size_t numPaddingCharacters = 0;
238///
239/// if (1000 > yearValue) {
240/// ++numPaddingCharacters;
241/// if (100 > yearValue) {
242/// ++numPaddingCharacters;
243/// if (10 > yearValue) {
244/// ++numPaddingCharacters;
245/// }
246/// }
247/// }
248///
249/// if (numPaddingCharacters) {
250/// outIterator = BloombergLP::bslfmt::FormatterCharUtil<
251/// t_CHAR>::outputFromChar(paddingStr,
252/// paddingStr +
253/// numPaddingCharacters,
254/// outIterator);
255/// }
256/// }
257/// outIterator = BloombergLP::bslfmt::FormatterCharUtil<
258/// t_CHAR>::outputFromChar(buffer, bufferEnd, outIterator);
259/// }
260///
261/// /// Output the specified `monthOrDayValue` to the specified
262/// /// `outIterator`. The specified `paddingRequired` indicates whether
263/// /// an additional character needs to be added to fill empty space.
264/// template <class t_FORMAT_CONTEXT>
265/// void outputMonthDay(
266/// typename t_FORMAT_CONTEXT::iterator& outIterator,
267/// int monthOrDayValue,
268/// bool paddingRequired) const
269/// {
270/// typedef BloombergLP::bslalg::NumericFormatterUtil NFUtil;
271///
272/// char buffer[2];
273/// char *bufferEnd = NFUtil::toChars(buffer,
274/// buffer + 2,
275/// monthOrDayValue);
276///
277/// if (paddingRequired) {
278/// if (10 > monthOrDayValue) {
279/// outIterator = BloombergLP::bslfmt::FormatterCharUtil<
280/// t_CHAR>::outputFromChar('0', outIterator);
281/// }
282/// }
283/// outIterator = BloombergLP::bslfmt::FormatterCharUtil<
284/// t_CHAR>::outputFromChar(buffer, bufferEnd, outIterator);
285/// }
286/// @endcode
287/// Notice that if the standard implementation of the format is supported by
288/// your compiler, then the `parse` function as well as the constructor must be
289/// declared as `constexpr`.
290/// @code
291/// public:
292/// // CREATORS
293///
294/// /// Create a formatter that outputs values in the `e_NUMERIC` format.
295/// /// Thus, numeric is the default format for the `Date` object.
296/// BSLS_KEYWORD_CONSTEXPR_CPP20 DateFormatter()
297/// : d_format(e_NUMERIC)
298/// {
299/// }
300///
301/// // MANIPULATORS
302///
303/// /// Parse the specified `context` and return end iterator of parsed
304/// /// range.
305/// template <class t_PARSE_CONTEXT>
306/// BSLS_KEYWORD_CONSTEXPR_CPP20 typename t_PARSE_CONTEXT::iterator parse(
307/// t_PARSE_CONTEXT& context)
308/// {
309/// typedef typename bsl::iterator_traits<
310/// typename t_PARSE_CONTEXT::const_iterator>::value_type
311/// IteratorValueType;
312/// BSLMF_ASSERT((bsl::is_same<IteratorValueType, t_CHAR>::value));
313///
314/// typename t_PARSE_CONTEXT::const_iterator current = context.begin();
315/// typename t_PARSE_CONTEXT::const_iterator end = context.end();
316/// @endcode
317/// `bsl::format` calls `parse()` function first and here we can configure our
318/// formatter so that it then outputs values in the format we need.
319/// `context.begin()` returns an iterator pointing to the end of the parsed
320/// range.
321/// @code
322/// // Handling empty string or empty specification
323/// if (current == end || *current == '}') {
324/// return context.begin(); // RETURN
325/// }
326///
327/// // Reading format specification
328/// switch (*current) {
329/// case 'V':
330/// case 'v': {
331/// d_format = e_VERBAL;
332/// } break;
333/// case 'N':
334/// case 'n': {
335/// // `e_NUMERIC` value is assigned at object construction
336/// } break;
337/// default: {
338/// BSLS_THROW(bsl::format_error(
339/// "Unexpected symbol in format specification")); // THROW
340/// }
341/// }
342///
343/// // Move the iterator to the next position and check that there are
344/// // no extra characters in the description.
345///
346/// ++current;
347///
348/// if (current != end && *current != '}') {
349/// BSLS_THROW(bsl::format_error(
350/// "Too many symbols in format specification")); // THROW
351/// }
352///
353/// context.advance_to(current);
354/// return context.begin();
355/// }
356///
357/// // ACCESSORS
358///
359/// /// Create string representation of the specified `value`, customized
360/// /// in accordance with the requested format and the specified
361/// /// `formatContext`, and copy it to the output that the output iterator
362/// /// of the `formatContext` points to.
363/// template <class t_FORMAT_CONTEXT>
364/// typename t_FORMAT_CONTEXT::iterator format(
365/// Date value,
366/// t_FORMAT_CONTEXT& formatContext) const
367/// {
368/// typename t_FORMAT_CONTEXT::iterator outIterator =
369/// formatContext.out();
370/// @endcode
371/// Next, we outputting the date in accordance with the previously set settings:
372/// @code
373/// if (e_VERBAL == d_format) { // 23 October 1999
374/// static const char *const months[] = {"January",
375/// "February",
376/// "March",
377/// "April",
378/// "May",
379/// "June",
380/// "July",
381/// "August",
382/// "September",
383/// "October",
384/// "November",
385/// "December"};
386///
387/// // Outputting day
388/// outputMonthDay<t_FORMAT_CONTEXT>(outIterator,
389/// value.day(),
390/// false);
391/// outIterator = BloombergLP::bslfmt::FormatterCharUtil<
392/// t_CHAR>::outputFromChar(' ', outIterator);
393///
394/// // Outputting month
395/// const char *month = months[value.month() - 1];
396/// outIterator = BloombergLP::bslfmt::FormatterCharUtil<
397/// t_CHAR>::outputFromChar(month,
398/// month + std::strlen(month),
399/// outIterator);
400/// outIterator = BloombergLP::bslfmt::FormatterCharUtil<
401/// t_CHAR>::outputFromChar(' ', outIterator);
402///
403/// // Outputting year
404/// outputYear<t_FORMAT_CONTEXT>(outIterator, value.year(), false);
405/// }
406/// else if (e_NUMERIC == d_format) { // 1999-10-23
407/// // Outputting year
408/// outputYear<t_FORMAT_CONTEXT>(outIterator, value.year(), true);
409/// outIterator = BloombergLP::bslfmt::FormatterCharUtil<
410/// t_CHAR>::outputFromChar('-', outIterator);
411///
412/// // Outputting month
413/// outputMonthDay<t_FORMAT_CONTEXT>(outIterator,
414/// value.month(),
415/// true);
416/// outIterator = BloombergLP::bslfmt::FormatterCharUtil<
417/// t_CHAR>::outputFromChar('-', outIterator);
418///
419/// // Outputting day
420/// outputMonthDay<t_FORMAT_CONTEXT>(outIterator,
421/// value.day(),
422/// true);
423/// }
424///
425/// return outIterator;
426/// }
427/// };
428/// @endcode
429/// Now, we define the `bsl::formatter` specialization for our `Date` class
430/// simply as a child-class of `DateFormatter`. Alternatively, we could have
431/// placed the implementation directly into the `bsl::formatter` specialization.
432/// Notice that the specialization must be defined in the `bsl` namespace.
433/// @code
434/// namespace bsl {
435///
436/// template <class t_CHAR>
437/// struct formatter<Date, t_CHAR> : DateFormatter<t_CHAR> {
438/// };
439///
440/// } // close namespace bsl
441/// @endcode
442/// Finally, we create a `Date` object, output it to the string and verify the
443/// result:
444/// @code
445/// Date date(1999, 10, 23);
446/// bsl::string result = bsl::format("{:v}", date);
447/// assert(bsl::string("23 October 1999") == result);
448///
449/// result = bsl::format("{:N}", date);
450/// assert(bsl::string("1999-10-23") == result);
451/// @endcode
452/// @}
453/** @} */
454/** @} */
455
456/** @addtogroup bsl
457 * @{
458 */
459/** @addtogroup bslfmt
460 * @{
461 */
462/** @addtogroup bslfmt_format
463 * @{
464 */
465
466#include <bslscm_version.h>
467
468#include <bsls_libraryfeatures.h>
469
470#if !defined(BSLS_LIBRARYFEATURES_HAS_CPP20_FORMAT)
471 #include <bslfmt_format_arg.h>
472 #include <bslfmt_format_args.h>
473 #include <bslfmt_format_context.h>
474 #include <bslfmt_format_imp.h>
475 #include <bslfmt_format_string.h>
476#endif
477
478#include <bslfmt_formaterror.h>
479
480#if !defined(BSLS_LIBRARYFEATURES_HAS_CPP20_FORMAT)
482#endif
483
484#include <bslfmt_formatterbase.h>
485#include <bslfmt_formatterbool.h>
491
492#include <bsls_exceptionutil.h>
493
494#include <bslstl_utility.h>
495
496#if defined(BSLS_LIBRARYFEATURES_HAS_CPP20_FORMAT)
497 #include <format>
498 #include <iterator>
499 #include <locale>
500 #include <string_view>
501 #include <type_traits>
502#endif
503
504#ifndef BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
505# include <stdexcept>
506#endif
507
508#if !defined(BSLS_LIBRARYFEATURES_HAS_CPP20_FORMAT)
509
510namespace bsl {
511using BloombergLP::bslfmt::basic_format_arg;
512using BloombergLP::bslfmt::basic_format_args;
513using BloombergLP::bslfmt::basic_format_context;
514using BloombergLP::bslfmt::basic_format_parse_context;
515using BloombergLP::bslfmt::basic_format_string;
516using BloombergLP::bslfmt::format;
517using BloombergLP::bslfmt::format_args;
518using BloombergLP::bslfmt::format_context;
519using BloombergLP::bslfmt::format_error;
520using BloombergLP::bslfmt::format_parse_context;
521using BloombergLP::bslfmt::format_string;
522using BloombergLP::bslfmt::format_to;
523using BloombergLP::bslfmt::format_to_n;
524using BloombergLP::bslfmt::format_to_n_result;
525using BloombergLP::bslfmt::formatted_size;
526using BloombergLP::bslfmt::make_format_args;
527using BloombergLP::bslfmt::make_wformat_args;
528using BloombergLP::bslfmt::vformat;
529using BloombergLP::bslfmt::vformat_to;
530using BloombergLP::bslfmt::visit_format_arg;
531using BloombergLP::bslfmt::wformat_args;
532using BloombergLP::bslfmt::wformat_context;
533using BloombergLP::bslfmt::wformat_parse_context;
534using BloombergLP::bslfmt::wformat_string;
535} // close namespace bsl
536
537#else // !defined(BSLS_LIBRARYFEATURES_HAS_CPP20_FORMAT)
538
539namespace bsl {
540
541// TYPE ALIASES
542
543using std::basic_format_arg;
544using std::basic_format_args;
545using std::basic_format_context;
546using std::basic_format_parse_context;
547using std::basic_format_string;
548//using std::format;
549using std::format_args;
550using std::format_context;
551using std::format_error;
552using std::format_parse_context;
553using std::format_string;
554using std::format_to;
555using std::format_to_n;
556using std::format_to_n_result;
557using std::formatted_size;
558//using std::make_format_args;
559//using std::make_wformat_args;
560//using std::vformat;
561using std::vformat_to;
562using std::visit_format_arg;
563using std::wformat_args;
564using std::wformat_context;
565using std::wformat_parse_context;
566using std::wformat_string;
567
568// FREE FUNCTIONS
569
570/// Format the specified `args` according to the specification given by the
571/// specified `fmtStr` and return the result as a `bsl::string`. In the event
572/// of an error throw the exception @ref format_error .
573template <class... t_ARGS>
574string format(format_string<t_ARGS...> fmtStr, t_ARGS&&... args);
575
576/// Format the specified `args` according to the specification given by the
577/// specified `fmtStr` and return the result. In the event of an error throw
578/// the exception @ref format_error .
579template <class... t_ARGS>
580wstring format(wformat_string<t_ARGS...> fmtStr, t_ARGS&&... args);
581
582/// Format the specified `args` according to the specification given by the
583/// specified `fmtStr` in the locale of the specified `loc` and return the
584/// result. In the event of an error throw the exception @ref format_error .
585template <class... t_ARGS>
586string format(const std::locale& loc,
587 format_string<t_ARGS...> fmtStr,
588 t_ARGS&&... args);
589
590/// Format the specified `args` according to the specification given by the
591/// specified `fmtStr` in the locale of the specified `loc` and return the
592/// result. In the event of an error throw the exception @ref format_error .
593template <class... t_ARGS>
594wstring format(const std::locale& loc,
595 wformat_string<t_ARGS...> fmtStr,
596 t_ARGS&&... args);
597
598/// Format the specified `args` according to the specification given by the
599/// specified `fmtStr`, using the specified `alloc` to supply memory (if
600/// required), and return the result. In the event of an error throw the
601/// exception @ref format_error .
602template <class... t_ARGS>
603string format(allocator<char> alloc,
604 format_string<t_ARGS...> fmtStr,
605 t_ARGS&&... args);
606
607/// Format the specified `args` according to the specification given by the
608/// specified `fmtStr`, using the specified `alloc` to supply memory (if
609/// required), and return the result. In the event of an error throw the
610/// exception @ref format_error .
611template <class... t_ARGS>
612wstring format(allocator<wchar_t> alloc,
613 wformat_string<t_ARGS...> fmtStr,
614 t_ARGS&&... args);
615
616/// Format the specified `args` according to the specification given by the
617/// specified `fmtStr` in the locale of the specified `loc`, using the
618/// specified `allocator` to supply memory (if required), and return the
619/// result. In the event of an error throw the exception @ref format_error .
620template <class... t_ARGS>
621string format(allocator<char> alloc,
622 const std::locale& loc,
623 format_string<t_ARGS...> fmtStr,
624 t_ARGS&&... args);
625
626/// Format the specified `args` according to the specification given by the
627/// specified `fmtStr` in the locale of the specified `loc`, using the
628/// specified `allocator` to supply memory (if required), and return the
629/// result. In the event of an error throw the exception @ref format_error .
630template <class... t_ARGS>
631wstring format(allocator<wchar_t> alloc,
632 const std::locale& loc,
633 wformat_string<t_ARGS...> fmtStr,
634 t_ARGS&&... args);
635
636/// Return an object, whose type is not specified, holding an array of
637/// `format_arg` types constructed from the specified `args`. The type
638/// returned is implicitly convertible to a @ref format_args holding a reference
639/// to the contained array. This function will statically assert if any of the
640/// specified template parameters `t_ARGS` is of type `long double`.
641template <class t_CONTEXT = std::format_context, class... t_ARGS>
642auto make_format_args(t_ARGS&... args);
643
644/// Return an object, whose type is not specified, holding an array of
645/// `wformat_arg` types constructed from the specified `args`. The type
646/// returned is implicitly convertible to a @ref wformat_args holding a reference
647/// to the contained array. This function will statically assert if any of the
648/// specified template parameters `t_ARGS` is of type `long double`.
649template <class... t_ARGS>
650auto make_wformat_args(t_ARGS&... args);
651
652/// Format the specified `args` according to the specification given by the
653/// specified `fmtStr`, and write the result of this operation into the string
654/// addressed by the specified `out` parameter. In the event of an error throw the exception `format_error`.
655///
656/// \pre The behavior is undefined if `out` does not point to a valid `bsl::string` object.
657///
658/// \note Note that this overload is provided
659/// in addition to the overloads in the standard library, and the `requires`
660/// clause is necessary to avoid ambiguity.
661template <class t_STRING, class... t_ARGS>
662requires(bsl::is_same_v<t_STRING, bsl::string>)
663void format_to(t_STRING *out,
664 format_string<t_ARGS...> fmtStr,
665 t_ARGS&&... args);
666
667/// Format the specified `args` according to the specification given by the
668/// specified `fmtStr`, and write the result of this operation into the string
669/// addressed by the specified `out` parameter. In the event of an error throw the exception `format_error`.
670///
671/// \pre The behavior is undefined if `out` does not point to a valid `bsl::string` object.
672///
673/// \note Note that this overload is provided
674/// in addition to the overloads in the standard library, and the requires
675/// clause is necessary to avoid ambiguity.
676template <class t_STRING, class... t_ARGS>
677requires(bsl::is_same_v<t_STRING, bsl::wstring>)
678void format_to(t_STRING *out,
679 wformat_string<t_ARGS...> fmtStr,
680 t_ARGS&&... args);
681
682/// Format the specified `args` according to the specification given by the
683/// specified `fmtStr` in the locale of the specified `loc`, and write the
684/// result of this operation into the string addressed by the specified `out`
685/// parameter. In the event of an error thrwe the exception @ref format_error .
686///
687/// \pre The behavior is undefined if `out` does not point to a valid `bsl::string` object.
688///
689/// \note Note that this overload is provided in addition to the overloads
690/// in the standard library, and the requires clause is necessary to avoid
691/// ambiguity.
692template <class t_STRING, class... t_ARGS>
693requires(bsl::is_same_v<t_STRING, bsl::string>)
694void format_to(t_STRING *out,
695 const std::locale& loc,
696 format_string<t_ARGS...> fmtStr,
697 t_ARGS&&... args);
698
699/// Format the specified `args` according to the specification given by the
700/// specified `fmtStr` in the locale of the specified `loc`, and write the
701/// result of this operation into the string addressed by the specified `out`
702/// parameter. In the event of an error throw the exception @ref format_error .
703///
704/// \pre The behavior is undefined if `out` does not point to a valid `bsl::string` object.
705///
706/// \note Note that this overload is provided in addition to the overloads
707/// in the standard library, and the requires clause is necessary to avoid
708/// ambiguity.
709template <class t_STRING, class... t_ARGS>
710requires(bsl::is_same_v<t_STRING, bsl::wstring>)
711void format_to(t_STRING *out,
712 const std::locale& loc,
713 wformat_string<t_ARGS...> fmtStr,
714 t_ARGS&&... args);
715
716/// Format the specified `args` according to the specification given by the
717/// specified `fmtStr` and return the result. In the event of an error throw
718/// the exception @ref format_error .
719string vformat(std::string_view fmtStr, format_args args);
720
721/// Format the specified `args` according to the specification given by the
722/// specified `fmtStr` and return the result. In the event of an error throw
723/// the exception @ref format_error .
724wstring vformat(std::wstring_view fmtStr, wformat_args args);
725
726/// Format the specified `args` according to the specification given by the
727/// specified `fmtStr` in the locale of the specified `loc` and return the
728/// result. In the event of an error throw the exception @ref format_error .
729string vformat(const std::locale& loc,
730 std::string_view fmtStr,
731 format_args args);
732
733/// Format the specified `args` according to the specification given by the
734/// specified `fmtStr` in the locale of the specified `loc` and return the
735/// result. In the event of an error throw the exception @ref format_error .
736wstring vformat(const std::locale& loc,
737 std::wstring_view fmtStr,
738 wformat_args args);
739
740/// Format the specified `args` according to the specification given by the
741/// specified `fmtStr`, using the specified `allocator` to supply memory (if
742/// required), and return the result. In the event of an error throw the
743/// exception @ref format_error .
744string vformat(allocator<char> alloc,
745 std::string_view fmtStr,
746 format_args args);
747
748/// Format the specified `args` according to the specification given by the
749/// specified `fmtStr`, using the specified `allocator` to supply memory (if
750/// required), and return the result. In the event of an error throw the
751/// exception @ref format_error .
752wstring vformat(allocator<wchar_t> alloc,
753 std::wstring_view fmtStr,
754 wformat_args args);
755
756/// Format the specified `args` according to the specification given by the
757/// specified `fmtStr` in the locale of the specified `loc`, using the
758/// specified `allocator` to supply memory (if required), and return the
759/// result. In the event of an error throw the exception @ref format_error .
760string vformat(allocator<char> alloc,
761 const std::locale& loc,
762 std::string_view fmtStr,
763 format_args args);
764
765/// Format the specified `args` according to the specification given by the
766/// specified `fmtStr` in the locale of the specified `loc`, using the
767/// specified `allocator` to supply memory (if required), and return the
768/// result. In the event of an error throw the exception @ref format_error .
769wstring vformat(allocator<wchar_t> alloc,
770 const std::locale& loc,
771 std::wstring_view fmtStr,
772 wformat_args args);
773
774/// Format the specified `args` according to the specification given by the
775/// specified `fmtStr`, and write the result of this operation into the string
776/// addressed by the specified `out` parameter. In the event of an error throw the exception `format_error`.
777///
778/// \pre The behavior is undefined if `out` does not point to a valid `bsl::string` object.
779///
780/// \note Note that this overload is provided
781/// in addition to the overloads in the standard library.
782void vformat_to(string *out, std::string_view fmtStr, format_args args);
783
784/// Format the specified `args` according to the specification given by the
785/// specified `fmtStr`, and write the result of this operation into the string
786/// addressed by the specified `out` parameter. In the event of an error throw the exception `format_error`.
787///
788/// \pre The behavior is undefined if `out` does not point to a valid `bsl::wstring` object.
789///
790/// \note Note that this overload is
791/// provided in addition to the overloads in the standard library.
792void vformat_to(wstring *out, std::wstring_view fmtStr, wformat_args args);
793
794/// Format the specified `args` according to the specification given by the
795/// specified `fmtStr` in the locale of the specified `loc`, and write the
796/// result of this operation into the string addressed by the specified `out`
797/// parameter. In the event of an error throw the exception @ref format_error .
798///
799/// \pre The behavior is undefined if `out` does not point to a valid `bsl::string` object.
800///
801/// \note Note that this overload is provided in addition to the overloads
802/// in the standard library.
803void vformat_to(string *out,
804 const std::locale& loc,
805 std::string_view fmtStr,
806 format_args args);
807
808/// Format the specified `args` according to the specification given by the
809/// specified `fmtStr` in the locale of the specified `loc`, and write the
810/// result of this operation into the string addressed by the specified `out`
811/// parameter. In the event of an error throw the exception @ref format_error .
812///
813/// \pre The behavior is undefined if `out` does not point to a valid `bsl::wstring` object.
814///
815/// \note Note that this overload is provided in addition to the overloads
816/// in the standard library.
817void vformat_to(wstring *out,
818 const std::locale& loc,
819 std::wstring_view fmtStr,
820 wformat_args args);
821
822} // close namespace bsl
823
824// ============================================================================
825// INLINE DEFINITIONS
826// ============================================================================
827
828// FREE FUNCTIONS
829template <class t_CONTEXT, class... t_ARGS>
830auto bsl::make_format_args(t_ARGS&... args)
831{
832 static_assert(
833 (... && (!std::is_same_v<std::decay_t<t_ARGS>, long double>)),
834 "long double is not supported in bsl::format");
835 return std::make_format_args<t_CONTEXT>(args...);
836}
837
838template <class... t_ARGS>
839auto bsl::make_wformat_args(t_ARGS&... args)
840{
841 static_assert(
842 (... && (!std::is_same_v<std::decay_t<t_ARGS>, long double>)),
843 "long double is not supported in bsl::format");
844 return std::make_wformat_args(args...);
845}
846
847template <class... t_ARGS>
848bsl::string bsl::format(format_string<t_ARGS...> fmtStr, t_ARGS&&... args)
849{
850 return bsl::vformat(fmtStr.get(),
851 bsl::make_format_args(args...));
852}
853
854template <class... t_ARGS>
855bsl::wstring bsl::format(wformat_string<t_ARGS...> fmtStr, t_ARGS&&... args)
856{
857 return bsl::vformat(fmtStr.get(),
858 bsl::make_wformat_args(args...));
859}
860
861template <class... t_ARGS>
862bsl::string bsl::format(const std::locale& loc,
863 format_string<t_ARGS...> fmtStr,
864 t_ARGS&&... args)
865{
866 return bsl::vformat(loc,
867 fmtStr.get(),
868 bsl::make_format_args(args...));
869}
870
871template <class... t_ARGS>
872bsl::wstring bsl::format(const std::locale& loc,
873 wformat_string<t_ARGS...> fmtStr,
874 t_ARGS&&... args)
875{
876 return bsl::vformat(loc,
877 fmtStr.get(),
878 bsl::make_wformat_args(args...));
879}
880
881template <class... t_ARGS>
882bsl::string bsl::format(allocator<char> alloc,
883 format_string<t_ARGS...> fmtStr,
884 t_ARGS&&... args)
885{
886 return bsl::vformat(alloc,
887 fmtStr.get(),
888 bsl::make_format_args(args...));
889}
890
891template <class... t_ARGS>
892bsl::wstring bsl::format(allocator<wchar_t> alloc,
893 wformat_string<t_ARGS...> fmtStr,
894 t_ARGS&&... args)
895{
896 return bsl::vformat(alloc,
897 fmtStr.get(),
898 bsl::make_wformat_args(args...));
899}
900
901template <class... t_ARGS>
902bsl::string bsl::format(allocator<char> alloc,
903 const std::locale& loc,
904 format_string<t_ARGS...> fmtStr,
905 t_ARGS&&... args)
906{
907 return bsl::vformat(alloc,
908 loc,
909 fmtStr.get(),
910 bsl::make_format_args(args...));
911}
912
913template <class... t_ARGS>
914bsl::wstring bsl::format(allocator<wchar_t> alloc,
915 const std::locale& loc,
916 wformat_string<t_ARGS...> fmtStr,
917 t_ARGS&&... args)
918{
919 return bsl::vformat(alloc,
920 loc,
921 fmtStr.get(),
922 bsl::make_wformat_args(args...));
923}
924
925inline
926bsl::string bsl::vformat(std::string_view fmt, format_args args)
927{
928 string result;
929 bsl::vformat_to(&result, fmt, args);
930 return result;
931}
932
933inline
934bsl::wstring bsl::vformat(std::wstring_view fmt, wformat_args args)
935{
936 wstring result;
937 bsl::vformat_to(&result, fmt, args);
938 return result;
939}
940
941inline
942bsl::string bsl::vformat(const std::locale& loc,
943 std::string_view fmt,
944 format_args args)
945{
946 string result;
947 bsl::vformat_to(&result, loc, fmt, args);
948 return result;
949}
950
951inline
952bsl::wstring bsl::vformat(const std::locale& loc,
953 std::wstring_view fmt,
954 wformat_args args)
955{
956 wstring result;
957 bsl::vformat_to(&result, loc, fmt, args);
958 return result;
959}
960
961inline
962bsl::string bsl::vformat(allocator<char> alloc,
963 std::string_view fmt,
964 format_args args)
965{
966 string result(alloc);
967 bsl::vformat_to(&result, fmt, args);
968 return result;
969}
970
971inline
972bsl::wstring bsl::vformat(allocator<wchar_t> alloc,
973 std::wstring_view fmt,
974 wformat_args args)
975{
976 wstring result(alloc);
977 bsl::vformat_to(&result, fmt, args);
978 return result;
979}
980
981inline
982bsl::string bsl::vformat(allocator<char> alloc,
983 const std::locale& loc,
984 std::string_view fmt,
985 format_args args)
986{
987 string result(alloc);
988 bsl::vformat_to(&result, loc, fmt, args);
989 return result;
990}
991
992inline
993bsl::wstring bsl::vformat(allocator<wchar_t> alloc,
994 const std::locale& loc,
995 std::wstring_view fmt,
996 wformat_args args)
997{
998 wstring result(alloc);
999 bsl::vformat_to(&result, loc, fmt, args);
1000 return result;
1001}
1002
1003template <class t_STRING, class... t_ARGS>
1004requires(bsl::is_same_v<t_STRING, bsl::string>)
1005void bsl::format_to(t_STRING *out,
1006 format_string<t_ARGS...> fmtStr,
1007 t_ARGS&&... args)
1008{
1009 bsl::vformat_to(out,
1010 fmtStr.get(),
1011 bsl::make_format_args(args...));
1012}
1013
1014template <class t_STRING, class... t_ARGS>
1015requires(bsl::is_same_v<t_STRING, bsl::wstring>)
1016void bsl::format_to(t_STRING *out,
1017 wformat_string<t_ARGS...> fmtStr,
1018 t_ARGS&&... args)
1019{
1020 bsl::vformat_to(out,
1021 fmtStr.get(),
1022 bsl::make_wformat_args(args...));
1023}
1024
1025template <class t_STRING, class... t_ARGS>
1026requires(bsl::is_same_v<t_STRING, bsl::string>)
1027void bsl::format_to(t_STRING *out,
1028 const std::locale& loc,
1029 format_string<t_ARGS...> fmtStr,
1030 t_ARGS&&... args)
1031{
1032 bsl::vformat_to(out,
1033 loc,
1034 fmtStr.get(),
1035 bsl::make_format_args(args...));
1036}
1037
1038template <class t_STRING, class... t_ARGS>
1039requires(bsl::is_same_v<t_STRING, bsl::wstring>)
1040void bsl::format_to(t_STRING *out,
1041 const std::locale& loc,
1042 wformat_string<t_ARGS...> fmtStr,
1043 t_ARGS&&... args)
1044{
1045 bsl::vformat_to(out,
1046 loc,
1047 fmtStr.get(),
1048 bsl::make_wformat_args(args...));
1049}
1050
1051
1052inline
1053void bsl::vformat_to(string *out, std::string_view fmt, format_args args)
1054{
1055 out->clear();
1056 std::vformat_to(std::back_inserter(*out), fmt, args);
1057}
1058
1059inline
1060void bsl::vformat_to(wstring *out, std::wstring_view fmt, wformat_args args)
1061{
1062 out->clear();
1063 std::vformat_to(std::back_inserter(*out), fmt, args);
1064}
1065
1066inline
1067void bsl::vformat_to(string *out,
1068 const std::locale& loc,
1069 std::string_view fmt,
1070 format_args args)
1071{
1072 out->clear();
1073 std::vformat_to(std::back_inserter(*out), loc, fmt, args);
1074}
1075
1076inline
1077void bsl::vformat_to(wstring *out,
1078 const std::locale& loc,
1079 std::wstring_view fmt,
1080 wformat_args args)
1081{
1082 out->clear();
1083 std::vformat_to(std::back_inserter(*out), loc, fmt, args);
1084}
1085
1086#endif // defined(BSLS_LIBRARYFEATURES_HAS_CPP20_FORMAT)
1087
1088#endif
1089
1090// ----------------------------------------------------------------------------
1091// Copyright 2023 Bloomberg Finance L.P.
1092//
1093// Licensed under the Apache License, Version 2.0 (the "License");
1094// you may not use this file except in compliance with the License.
1095// You may obtain a copy of the License at
1096//
1097// http://www.apache.org/licenses/LICENSE-2.0
1098//
1099// Unless required by applicable law or agreed to in writing, software
1100// distributed under the License is distributed on an "AS IS" BASIS,
1101// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1102// See the License for the specific language governing permissions and
1103// limitations under the License.
1104// ----------------------------- END-OF-FILE ----------------------------------
1105
1106/** @} */
1107/** @} */
1108/** @} */
Definition bslstl_string.h:1252
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
Definition bdlat_valuetypefunctions.h:939
basic_string< wchar_t > wstring
Definition bslstl_string.h:845
bsl::string vformat(bsl::string_view fmt, format_args args)
Definition bslfmt_format_imp.h:1006
bsl::enable_if<!bsl::is_same< typenamebsl::decay< t_OUT >::type, bsl::string * >::value, t_OUT >::type format_to(t_OUT out, BSLFMT_FORMAT_STRING_PARAMETER fmtStr, const t_ARGS &... args)
Definition bslfmt_format_imp.h:1046
Format_ArgsStore< format_context, t_ARGS... > make_format_args(t_ARGS &... fmt_args)
Definition bslfmt_format_args.h:461
bsl::string format(BSLFMT_FORMAT_STRING_PARAMETER fmtStr, const t_ARGS &... args)
Definition bslfmt_format_imp.h:1085
t_OUT vformat_to(t_OUT out, bsl::string_view fmtStr, format_args args)
Definition bslfmt_format_imp.h:981
Format_ArgsStore< wformat_context, t_ARGS... > make_wformat_args(t_ARGS &... fmt_args)
Definition bslfmt_format_args.h:469