BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bslfmt_formattercharacter.h
Go to the documentation of this file.
1/// @file bslfmt_formattercharacter.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslfmt_formattercharacter.h -*-C++-*-
8
9#ifndef INCLUDED_BSLFMT_FORMATTERCHARACTER
10#define INCLUDED_BSLFMT_FORMATTERCHARACTER
11
12#include <bsls_ident.h>
13BSLS_IDENT("$Id: $")
14
15/// @defgroup bslfmt_formattercharacter bslfmt_formattercharacter
16/// @brief Provide a formatter customization for character types
17/// @addtogroup bsl
18/// @{
19/// @addtogroup bslfmt
20/// @{
21/// @addtogroup bslfmt_formattercharacter
22/// @{
23///
24/// <h1> Outline </h1>
25/// * <a href="#bslfmt_formattercharacter-purpose"> Purpose</a>
26/// * <a href="#bslfmt_formattercharacter-classes"> Classes </a>
27/// * <a href="#bslfmt_formattercharacter-canonical-header"> Canonical Header </a>
28/// * <a href="#bslfmt_formattercharacter-description"> Description </a>
29/// * <a href="#bslfmt_formattercharacter-usage"> Usage </a>
30/// * <a href="#bslfmt_formattercharacter-example-formatting-a-character"> Example: Formatting a character </a>
31///
32/// # Purpose {#bslfmt_formattercharacter-purpose}
33/// Provide a formatter customization for character types
34///
35/// # Classes {#bslfmt_formattercharacter-classes}
36///
37/// - formatter<char, wchar_t> : specialization for `char` and `wchar_t`
38/// - formatter<char, char> : specialization for `char`s
39/// - formatter<wchar_t, wchar_t> : specialization for `wchar_t`s
40///
41/// # Canonical Header {#bslfmt_formattercharacter-canonical-header}
42/// bsl_format.h
43///
44/// # Description {#bslfmt_formattercharacter-description}
45/// This component provides partial specializations of
46/// `bsl::formatter` catering for character types.
47///
48/// This header is not intended to be included directly. Please include
49/// `<bsl_format.h>` to be able to use specializations of the `bsl::formatter`
50/// for character types.
51///
52/// ## Usage {#bslfmt_formattercharacter-usage}
53///
54///
55/// In this section we show the intended use of this component.
56///
57/// ### Example: Formatting a character {#bslfmt_formattercharacter-example-formatting-a-character}
58///
59///
60/// We do not expect most users of `bsl::format` to interact with this type
61/// directly and instead use `bsl::format` or `bsl::vformat`, so this example is
62/// necessarily unrealistic.
63///
64/// Suppose we want to test this formatter's ability to present a character with
65/// defined alignment and padding.
66/// @code
67/// bslfmt::MockParseContext<char> mpc("*<6c", 1);
68///
69/// bsl::formatter<char, char> formatter;
70/// mpc.advance_to(formatter.parse(mpc));
71///
72/// char value = 'a';
73///
74/// bslfmt::MockFormatContext<char> mfc(value, 0, 0);
75///
76/// mfc.advance_to(bsl::as_const(formatter).format(value, mfc));
77///
78/// assert("a*****" == mfc.finalString());
79/// @endcode
80/// @}
81/** @} */
82/** @} */
83
84/** @addtogroup bsl
85 * @{
86 */
87/** @addtogroup bslfmt
88 * @{
89 */
90/** @addtogroup bslfmt_formattercharacter
91 * @{
92 */
93
94#include <bslscm_version.h>
95
99
101
102#include <bslmf_assert.h>
103#include <bslmf_issame.h>
104
105#include <bslstl_iterator.h>
106
107
108namespace bslfmt {
109
110 // ======================================
111 // struct FormatterCharacter_MakeUnsigned
112 // ======================================
113
114/// This `struct` template implements the @ref make_unsigned meta-function defined
115/// in the C++11 standard [meta.trans.sign], providing an alias, `type`, that
116/// returns the result. The `type` is the unsigned analogue of the (template
117/// parameter) `t_TYPE`.
118///
119/// See @ref bslfmt_formattercharacter
120template <class t_TYPE, int t_SIZE>
123
124/// Partial specialization of the `FormatterCharacter_MakeUnsigned` template
125/// for the type `char`.
126template <int t_SIZE>
128 // TYPES
129 typedef unsigned char type; // unsigned analogue for `char`
130};
131
132/// This is a specialization of the `FormatterCharacter_MakeUnsigned` template
133/// for the type `wchar_t` having 1-byte length.
134template <>
136 // TYPES
137 typedef unsigned char type; // unsigned analogue for 1-byte `wchar_t`
138};
139
140/// This is a specialization of the `FormatterCharacter_MakeUnsigned` template
141/// for the type `wchar_t` having 2-byte length.
142template <>
144 // TYPES
145 typedef unsigned short int type; // unsigned analogue for 2-byte `wchar_t`
146};
147
148/// This is a specialization of the `FormatterCharacter_MakeUnsigned` template
149/// for the type `wchar_t` having 4-byte length.
150template <>
152 // TYPES
153 typedef unsigned long int type; // unsigned analogue for 4-byte `wchar_t`
154};
155
156/// This is a specialization of the `FormatterCharacter_MakeUnsigned` template
157/// for the type `wchar_t` having 8-byte length.
158template <>
160 // TYPES
161 typedef unsigned long long int type; // unsigned analogue for 8-byte
162 // `wchar_t`
163};
164
165 // =========================================
166 // struct FormatterCharacter_CharacterOutput
167 // =========================================
168
169/// This struct provides a function that outputs the specified `value` to the
170/// specified `out`.
171///
172/// See @ref bslfmt_formattercharacter
173template <class t_VALUE_TYPE, class t_CHAR>
175 // CLASS METHODS
176
177 /// Output the specified `value` to the specified `out` and return `out`.
178 /// incremented by the number of characters written.
179 template <class t_ITERATOR>
180 static t_ITERATOR output(const t_VALUE_TYPE value, t_ITERATOR out)
181 {
182 typedef
183 typename bsl::iterator_traits<t_ITERATOR>::value_type OutputType;
186
187 *out = value;
188 ++out;
189 return out;
190 }
191};
192
193/// This is a specialization of `FormatterCharacter_CharacterOutput` template
194/// for `char` and `wchar_t`.
195template <>
197 // CLASS METHODS
198
199 /// Output the specified `value` to the specified `out` and return `out`.
200 /// incremented by the number of characters written.
201 template <class t_ITERATOR>
202 static t_ITERATOR output(const char value, t_ITERATOR out)
203 {
204 typedef
205 typename bsl::iterator_traits<t_ITERATOR>::value_type OutputType;
207
208 // Unfortunately, it is not clearly defined in the current version of
209 // the standard (Working draft #4993 from 10/16/2024) what should
210 // happen with non-printable character values (i.e. the negative ones)
211 // during their output to the `wchar_t` sink:
212 //
213 // 28.5.2.2 Standard format specifiers
214 // Table 103 - Meaning of type options for charT [tab:format.type.char]
215 // +---------+-------------------------------------+
216 // | Type | Meaning |
217 // +---------+-------------------------------------+
218 // | none, c | Copies the character to the output. |
219 // +---------+-------------------------------------+
220 //
221 // This implementation adopts behavior consistent with the current
222 // standard library implementations (gcc (14.2), clang (19.1) and msvc
223 // (19.40)).
224
225 *out = static_cast<wchar_t>(static_cast<unsigned char>(value));
226 ++out;
227 return out;
228 }
229};
230
231 // =============================
232 // struct FormatterCharacter_Imp
233 // =============================
234
235/// This type implements the formatter logic specific to the character types
236/// (`char` and `wchar_t`).
237///
238/// See @ref bslfmt_formattercharacter
239template <class t_VALUE, class t_CHAR>
240struct FormatterCharacter_Imp : public FormatterIntegralBase<t_VALUE, t_CHAR> {
241 public:
242 // ACCESSORS
243
244 /// Create string representation of the specified `value`, customized in
245 /// accordance with the requested format and the specified `formatContext`,
246 /// and copy it to the output that the output iterator of the
247 /// `formatContext` points to. Return the output iterator incremented by
248 /// the number of characters written.
249 template <class t_FORMAT_CONTEXT>
250 typename t_FORMAT_CONTEXT::iterator format(
251 t_VALUE value,
252 t_FORMAT_CONTEXT& formatContext) const;
253};
254} // close package namespace
255
256
257namespace bsl {
258
259/// This is a specialization of the `bsl::formatter` template for the types
260/// `char` and `wchar_t`.
261template <>
262struct formatter<char, wchar_t>
263: BloombergLP::bslfmt::FormatterCharacter_Imp<char, wchar_t> {
264};
265
266/// This is a specialization of the `bsl::formatter` template for the type
267/// `char`.
268template <>
269struct formatter<char, char>
270: BloombergLP::bslfmt::FormatterCharacter_Imp<char, char> {
271};
272
273/// This is a specialization of the `bsl::formatter` template for the type
274/// `wchar_t`.
275template <>
276struct formatter<wchar_t, wchar_t>
277: BloombergLP::bslfmt::FormatterCharacter_Imp<wchar_t, wchar_t> {
278};
279
280} // close namespace bsl
281
282// ============================================================================
283// INLINE DEFINITIONS
284// ============================================================================
285
286
287namespace bslfmt {
288
289 // -----------------------------
290 // struct FormatterCharacter_Imp
291 // -----------------------------
292
293template <class t_VALUE, class t_CHAR>
294template <class t_FORMAT_CONTEXT>
295inline
296typename t_FORMAT_CONTEXT::iterator
298 t_VALUE value,
299 t_FORMAT_CONTEXT& formatContext) const
300{
301 typedef StandardFormatSpecification<t_CHAR> Specification;
302 typedef bslalg::NumericFormatterUtil NFUtil;
303
304 const Specification& parsedSpec = this->specification();
305
306 if (Specification::e_CHARACTER_CHARACTER == parsedSpec.formatType()) {
307 char dummyPrefix = 0;
308 t_CHAR valueBuf;
309 t_CHAR *valueBegin = &valueBuf;
310 t_CHAR *valueEnd =
312 value,
313 valueBegin);
314
315 return this->outputValue(&dummyPrefix,
316 &dummyPrefix,
317 valueBegin,
318 valueEnd,
319 formatContext); // RETURN
320 }
321 else {
322 typedef typename FormatterCharacter_MakeUnsigned<t_VALUE,
323 sizeof(wchar_t)>::type
324 UintType;
325
326 const int maxPrefixSize = 4;
327 char prefixBuf[maxPrefixSize];
328 char *prefixBegin = prefixBuf;
329 char *prefixEnd = prefixBuf;
330
331 UintType intValue = static_cast<UintType>(value);
332
333 // We want to make sure that we have enough space to accommodate any
334 // representation of the `value`. Binary representation takes up the
335 // most space.
336
337 const int maxValueSize =
338 NFUtil::ToCharsMaxLength<UintType, 2>::k_VALUE;
339 t_CHAR valueBuf[maxValueSize];
340 t_CHAR *valueBegin = valueBuf;
341 t_CHAR *valueEnd = valueBuf;
342
343 prefixEnd = this->formatPrefix(prefixBuf, maxPrefixSize, intValue);
344 valueEnd = this->formatValue(valueBuf, maxValueSize, intValue);
345 return this->outputValue(prefixBegin,
346 prefixEnd,
347 valueBegin,
348 valueEnd,
349 formatContext);
350 }
351}
352
353} // close package namespace
354
355
356#endif // INCLUDED_BSLFMT_FORMATTERCHARACTER
357
358// ----------------------------------------------------------------------------
359// Copyright 2023 Bloomberg Finance L.P.
360//
361// Licensed under the Apache License, Version 2.0 (the "License");
362// you may not use this file except in compliance with the License.
363// You may obtain a copy of the License at
364//
365// http://www.apache.org/licenses/LICENSE-2.0
366//
367// Unless required by applicable law or agreed to in writing, software
368// distributed under the License is distributed on an "AS IS" BASIS,
369// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
370// See the License for the specific language governing permissions and
371// limitations under the License.
372// ----------------------------- END-OF-FILE ----------------------------------
373
374/** @} */
375/** @} */
376/** @} */
Definition bslfmt_standardformatspecification.h:78
#define BSLMF_ASSERT(expr)
Definition bslmf_assert.h:231
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
Definition bdlat_valuetypefunctions.h:939
Definition bslfmt_enablestreamedformatter.h:130
Definition bslfmt_formatterbase.h:426
Definition bslmf_issame.h:146
Definition bslalg_numericformatterutil.h:400
static t_ITERATOR output(const char value, t_ITERATOR out)
Definition bslfmt_formattercharacter.h:202
Definition bslfmt_formattercharacter.h:174
static t_ITERATOR output(const t_VALUE_TYPE value, t_ITERATOR out)
Definition bslfmt_formattercharacter.h:180
Definition bslfmt_formattercharacter.h:240
t_FORMAT_CONTEXT::iterator format(t_VALUE value, t_FORMAT_CONTEXT &formatContext) const
Definition bslfmt_formattercharacter.h:297
unsigned char type
Definition bslfmt_formattercharacter.h:129
unsigned char type
Definition bslfmt_formattercharacter.h:137
unsigned short int type
Definition bslfmt_formattercharacter.h:145
unsigned long int type
Definition bslfmt_formattercharacter.h:153
unsigned long long int type
Definition bslfmt_formattercharacter.h:161
Definition bslfmt_formattercharacter.h:121
Definition bslfmt_formatterintegralbase.h:171