BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bslfmt.h
Go to the documentation of this file.
1/// @file bslfmt.h
2///
3///
4/// @defgroup bslfmt Package bslfmt
5/// @brief Basic Standard Library Format Implementation (bslfmt)
6/// @addtogroup bsl
7/// @{
8/// @addtogroup bslfmt
9/// @{
10/// * <a href="#bslfmt-purpose"> Purpose</a>
11/// * <a href="#bslfmt-mnemonic"> Mnemonic </a>
12/// * <a href="#bslfmt-description"> Description </a>
13/// * <a href="#bslfmt-hierarchical-synopsis"> Hierarchical Synopsis </a>
14/// * <a href="#bslfmt-component-synopsis"> Component Synopsis </a>
15/// * <a href="#bslfmt-streaming-based-formatting"> Streaming-based Formatting </a>
16/// * <a href="#bslfmt-design-choices"> Design Choices </a>
17/// * <a href="#bslfmt-wrapper"> Wrapper </a>
18/// * <a href="#bslfmt-trait-enabled-formatter"> Trait-enabled Formatter </a>
19/// * <a href="#bslfmt-format-specification-strings-for-streamed-types"> Format Specification Strings for Streamed Types </a>
20///
21/// # Purpose {#bslfmt-purpose}
22/// Provide implementation mechanisms for bsl::format.
23///
24/// # Mnemonic {#bslfmt-mnemonic}
25/// Basic Standard Library Format Implementation (bslfmt)
26///
27/// # Description {#bslfmt-description}
28/// The 'bslfmt' package provides implementation mechanisms for
29/// bsl::format and associated types.
30///
31/// ## Hierarchical Synopsis {#bslfmt-hierarchical-synopsis}
32///
33/// The 'bslfmt' package currently has 40 components having 14 levels of physical
34/// dependency. The list below shows the hierarchical ordering of the components.
35/// The order of components within each level is not architecturally significant,
36/// just alphabetical.
37/// @code
38/// 14. bslfmt_enablestreamedformatter
39/// bslfmt_print
40/// bslfmt_print_ostream !PRIVATE!
41/// bslfmt_streamed
42///
43/// 13. bslfmt_formattable
44/// bslfmt_print_imp !PRIVATE!
45/// bslfmt_print_ostream_imp !PRIVATE!
46/// bslfmt_streamedformatter
47///
48/// 12. bslfmt_format
49///
50/// 11. bslfmt_format_imp !PRIVATE!
51///
52/// 10. bslfmt_formatterbool
53/// bslfmt_formattercharacter
54/// bslfmt_formatterintegral
55/// bslfmt_formatterpointer
56///
57/// 9. bslfmt_formatterfloating
58/// bslfmt_formatterintegralbase
59/// bslfmt_formatterstring
60///
61/// 8. bslfmt_padutil
62/// bslfmt_standardformatspecification
63///
64/// 7. bslfmt_formatspecificationparser
65/// bslfmt_formattertestutil
66///
67/// 6. bslfmt_mockformatcontext
68/// bslfmt_mockparsecontext
69///
70/// 5. bslfmt_format_context !PRIVATE!
71/// bslfmt_formatterspecificationnumericvalue
72///
73/// 4. bslfmt_format_args !PRIVATE!
74///
75/// 3. bslfmt_format_arg !PRIVATE!
76/// bslfmt_formatparsecontext
77/// bslfmt_unicodecodepoint
78///
79/// 2. bslfmt_format_string !PRIVATE!
80/// bslfmt_formaterror
81/// bslfmt_formatterbase
82/// bslfmt_formattercharutil
83/// bslfmt_formatterunicodedata
84/// bslfmt_testspecificationgenerator
85///
86/// 1. bslfmt_format_arg_cpp03 !PRIVATE!
87/// bslfmt_format_args_cpp03 !PRIVATE!
88/// bslfmt_format_imp_cpp03 !PRIVATE!
89/// bslfmt_print_imp_cpp03 !PRIVATE!
90/// bslfmt_print_ostream_imp_cpp03 !PRIVATE!
91/// @endcode
92///
93/// ## Component Synopsis {#bslfmt-component-synopsis}
94///
95/// @ref bslfmt_enablestreamedformatter :
96/// Provide a trait to enable stream based formatting of a type.
97///
98/// @ref bslfmt_format :
99/// Provide a standard compliant `format` implementation.
100///
101/// @ref bslfmt_format_arg : !PRIVATE!
102/// Provide a proxy for an argument for use by bsl::format
103///
104/// @ref bslfmt_format_arg_cpp03 : !PRIVATE!
105/// Provide C++03 implementation for bslfmt_format_arg.h
106///
107/// @ref bslfmt_format_args : !PRIVATE!
108/// Provide a container of arguments for use by bsl::format
109///
110/// @ref bslfmt_format_args_cpp03 : !PRIVATE!
111/// Provide C++03 implementation for bslfmt_format_args.h
112///
113/// @ref bslfmt_format_context : !PRIVATE!
114/// Provides access to formatting state.
115///
116/// @ref bslfmt_format_imp : !PRIVATE!
117/// Provide a standard compliant `format` implementation
118///
119/// @ref bslfmt_format_imp_cpp03 : !PRIVATE!
120/// Provide C++03 implementation for bslfmt_format_imp.h
121///
122/// @ref bslfmt_format_string : !PRIVATE!
123/// Provide a string_view wrapper for formatting library usage
124///
125/// @ref bslfmt_formaterror :
126/// Provide an exception type for format library errors.
127///
128/// @ref bslfmt_formatparsecontext :
129/// Provides access to formatting parsing string and parsing state.
130///
131/// @ref bslfmt_formatspecificationparser :
132/// Tokenization utility for use within BSL `format` spec parsers
133///
134/// @ref bslfmt_formattable :
135/// Provide a concept to check for the presence of a `bsl::formatter`.
136///
137/// @ref bslfmt_formatterbase :
138/// Provide a base template for formatter specializations.
139///
140/// @ref bslfmt_formatterbool :
141/// Provide a formatter customization for bool type
142///
143/// @ref bslfmt_formattercharacter :
144/// Provide a formatter customization for character types
145///
146/// @ref bslfmt_formattercharutil :
147/// Character conversion utilities for `bsl::format`.
148///
149/// @ref bslfmt_formatterfloating :
150/// Provide a formatter customization for floating point types
151///
152/// @ref bslfmt_formatterintegral :
153/// Provide a formatter customization for integer types
154///
155/// @ref bslfmt_formatterintegralbase :
156/// Provide a formatter customization for integer types
157///
158/// @ref bslfmt_formatterpointer :
159/// Provide a formatter customization for pointer types
160///
161/// @ref bslfmt_formatterspecificationnumericvalue :
162/// Integer value for use within `bsl::format` specification parsers
163///
164/// @ref bslfmt_formatterstring :
165/// Provide a string formatter for use by bsl::format
166///
167/// @ref bslfmt_formattertestutil :
168/// Provide utilities for testing custom formatters
169///
170/// @ref bslfmt_formatterunicodedata :
171/// Private unicode data tables for use by `bsl::format`.
172///
173/// @ref bslfmt_mockformatcontext :
174/// Provide mock context to test formatter specializations
175///
176/// @ref bslfmt_mockparsecontext :
177/// Provide mock context to test formatter specializations
178///
179/// @ref bslfmt_padutil :
180/// Provide padding utilities for the `bslfmt` package and clients.
181///
182/// @ref bslfmt_print :
183/// Provide a standard compliant `print(FILE)` implementation.
184///
185/// @ref bslfmt_print_imp : !PRIVATE!
186/// Provide a standard compliant `print(FILE)` implementation.
187///
188/// @ref bslfmt_print_imp_cpp03 : !PRIVATE!
189/// Provide C++03 implementation for bslfmt_print_imp.h
190///
191/// @ref bslfmt_print_ostream : !PRIVATE!
192/// Provide a standard compliant `print(ostream)` implementation.
193///
194/// @ref bslfmt_print_ostream_imp : !PRIVATE!
195/// Provide a standard compliant `print(ostream)` implementation.
196///
197/// @ref bslfmt_print_ostream_imp_cpp03 : !PRIVATE!
198/// Provide C++03 implementation for bslfmt_print_ostream_imp.h
199///
200/// @ref bslfmt_standardformatspecification :
201/// Private utility for use within BSL `format` standard spec parsers
202///
203/// @ref bslfmt_streamed :
204/// Provide a wrapper to format using an `ostream` `operator<<`
205///
206/// @ref bslfmt_streamedformatter :
207/// Provide a formatter that uses the `ostream` insert `operator<<`.
208///
209/// @ref bslfmt_testspecificationgenerator :
210/// Provide a generator for test format specifications
211///
212/// @ref bslfmt_unicodecodepoint :
213/// Provide a Unicode code point representation
214///
215/// ## Streaming-based Formatting {#bslfmt-streaming-based-formatting}
216///
217/// This package contains two components that facilitate adoption of `bsl::format`
218/// for user-defined types that provide an `ostream` insert `operator<<`.
219///
220/// ### Design Choices {#bslfmt-design-choices}
221///
222/// This package has two different ways to support formatting types that have an
223/// `ostream` insert `operator<<` defined but don't have `bsl::format`ing enabled.
224/// Choosing between the two solutions is a design decision and here we present
225/// the circumstances and consequences of using either solution.
226///
227/// The choices are wrapping or enabling stream-based formatting using a trait.
228/// Either option provides the same (limited) functionality: the type is converted
229/// to a string using `ostream` insert `operator<<` and that string is then
230/// formatted as if the string had been passed directly to `bsl::format` (see the
231/// table below).
232///
233/// ### Wrapper {#bslfmt-wrapper}
234///
235/// The wrapper should be the first design choice as it does not lock in a design
236/// decision (unlike creating a formatter).
237///
238/// The wrapper has a simple, (as) short (as possible) syntax:
239///```
240/// bsl::string bsl::format("{:-^12}", bslfmt::streamed(streamableType));
241///```
242///
243/// The above code uses the `ostream` insert `operator<<` of `StreamableType` to
244/// "convert" the object to string and formats the string according to the format
245/// specification.
246///
247/// **Consequences**:
248/// * The wrapper has to be used at every place where such an object is
249/// formatted.
250///
251/// * The formatting support is simplistic.
252///
253/// May be Useful in the Following Circumstances:
254/// * You do not own the type so you cannot create a `formatter` for it without
255/// creating a possible collision with a formatter introduced by the owner.
256///
257/// * Your type really needs its own `formatter` but you need time to design and
258/// implement that. You do not want to lock yourself into forever supporting
259/// the string-based simplistic formatting abilities in your future formatter
260/// so you rather wrap the type where you need to `format` (e.g., log) it.
261///
262/// There may be many reasons why a type should have its own formatter. One is
263/// that it is not string-like but number-like. Or it is complex where you may
264/// want to show only parts of it, or in different format etc. The type may also
265/// be an identifier so that truncating it (which the string format supports) is a
266/// mistake.
267///
268/// As the previous (non-exhaustive) list shows you probably want to use the
269/// wrapper in **most** cases, because using the trait-enabled formatter may lock
270/// you into supporting the string-based format string syntax.
271///
272/// ### Trait-enabled Formatter {#bslfmt-trait-enabled-formatter}
273///
274/// If the stream-capable type you are formatting is **your** type (so you can
275/// safely define a formatter) you may opt for enabling string-like formatting.
276///
277/// Note that the **consequence** is that may be locked into supporting
278/// string-like formatting for that type. That means when you design your own
279/// format-specification syntax has to be able tell the difference between the
280/// string-like formatting specification and your new formatting specification.
281///
282/// Enabling the formatting is as simple as:
283///```
284/// public:
285/// // TRAITS
286/// BSLMF_NESTED_TRAIT_DECLARATION(NowFormattableType,
287/// bslfmt::EnableStreamedFormatter);
288///```
289///
290/// **Consequences**
291/// * You may be locked into supporting the string-like format specification and
292/// whatever the resulting streamed output looks like.
293///
294/// * You get the simplistic, string-based formatting.
295///
296///
297/// May be Useful in the Following Circumstances:
298/// * You do not care to implement a formatter for the type, and it is unlikely
299/// to ever require a different or more complicated format specification.
300///
301/// * You own the type.
302///
303/// In other words, if you declare the trait for your type, users of your type
304/// will start formatting your type with string options, and those users will
305/// become broken later if you write your own formatter that either does not
306/// support all string-formatting options, or repurposes any subset of the string
307/// format specification with a different meaning.
308///
309/// ### Format Specification Strings for Streamed Types {#bslfmt-format-specification-strings-for-streamed-types}
310///
311/// The format specification string for a `bsl::streamed` wrapped object matches
312/// that for a string. Specifically, it supports:
313/// * alignment
314/// * width
315/// * precision (which is used to truncate)
316///
317/// For details see
318/// [Standard format specification]
319/// (http://www.en.cppreference.com/w/cpp/utility/format/spec.html)
320///
321/// Imagine we have a simple type that outputs "12345" when output to a stream:
322///```
323/// class Streamable {};
324///
325/// std::ostream& operator<<(std::ostream& os, const Streamable&)
326/// {
327/// return os << "012345";
328/// }
329///```
330/// The following table describes the effect of different format specifications:
331///
332/// | Width | Alignment | Pad Char | Precision | Format Spec | Output Text |
333/// |-------|-----------|----------|-----------|-------------|--------------|
334/// | N/A | N/A | N/A | N/A | "{}" | "012345" |
335/// | N/A | N/A | N/A | 3 | "{:.3}" | "012" |
336/// | 8 | N/A | N/A | N/A | "{:8}" | "012345 " |
337/// | 8 | left | N/A | N/A | "{:<8}" | "012345 " |
338/// | 8 | center | N/A | N/A | "{:^8}" | " 012345 " |
339/// | 8 | right | N/A | N/A | "{:>8}" | " 012345" |
340/// | 8 | center | = | N/A | "{:=^8}" | "=012345=" |
341/// | 6 | center | * | 2 | "{:*^6.2}" | "**01**" |
342///
343///
344/// @}
345/** @} */