BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bslfmt_format_context.h
Go to the documentation of this file.
1/// @file bslfmt_format_context.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslfmt_format_context.h -*-C++-*-
8
9#ifndef INCLUDED_BSLFMT_FORMAT_CONTEXT
10#define INCLUDED_BSLFMT_FORMAT_CONTEXT
11
12#include <bsls_ident.h>
13BSLS_IDENT("$Id: $")
14
15/// @defgroup bslfmt_format_context bslfmt_format_context
16/// @brief Provides access to formatting state.
17/// @addtogroup bsl
18/// @{
19/// @addtogroup bslfmt
20/// @{
21/// @addtogroup bslfmt_format_context
22/// @{
23///
24/// <h1> Outline </h1>
25/// * <a href="#bslfmt_format_context-purpose"> Purpose</a>
26/// * <a href="#bslfmt_format_context-classes"> Classes </a>
27/// * <a href="#bslfmt_format_context-canonical-header"> Canonical Header </a>
28/// * <a href="#bslfmt_format_context-description"> Description </a>
29/// * <a href="#bslfmt_format_context-usage"> Usage </a>
30/// * <a href="#bslfmt_format_context-example-1-testing-a-user-defined-formatter-s-format-method"> Example: 1 Testing a user defined formatter's format method. </a>
31///
32/// # Purpose {#bslfmt_format_context-purpose}
33/// Provides access to formatting state.
34///
35/// # Classes {#bslfmt_format_context-classes}
36///
37/// - bslfmt::basic_format_context: standard-compliant output context
38///
39/// # Canonical Header {#bslfmt_format_context-canonical-header}
40/// bsl_format.h
41///
42/// # Description {#bslfmt_format_context-description}
43/// This component provides an implementation of the C++20 Standard
44/// Library's `std::basic_format_context`, which provides access to formatting
45/// state consisting of the formatting arguments and the output iterator.
46///
47/// This type is designed to be constructed from within `bslfmt::format` and
48/// cannot be constructed directly from user code.
49///
50/// As this type contains a @ref basic_format_args type therefore all of the
51/// warnings around lifetime documented in `bslfmt_formatargs.h` also apply
52/// here.
53///
54/// This header is not intended to be included directly. Please include
55/// `<bsl_format.h>` to be able to use `bsl::basic_format_context`.
56///
57/// ## Usage {#bslfmt_format_context-usage}
58///
59///
60/// In this section we show the intended use of this component.
61///
62/// ### Example: 1 Testing a user defined formatter's format method. {#bslfmt_format_context-example-1-testing-a-user-defined-formatter-s-format-method}
63///
64///
65/// We do not expect most users of `bsl::format` to interact with this type
66/// directly and instead use `bsl::format` or `bsl::vformat`. In addition,
67/// there are only a very limited number of public methods so this example is
68/// necessarily unrealistic.
69///
70/// Suppose we have a user-defined formatter and want to test its `format`
71/// method:
72///
73/// @code
74/// struct MyCharFormatter {
75/// template <class t_FORMAT_CONTEXT>
76/// typename t_FORMAT_CONTEXT::iterator format(
77/// char v,
78/// t_FORMAT_CONTEXT& fc) const
79/// {
80/// typename t_FORMAT_CONTEXT::iterator out = fc.out();
81///
82/// *out++ = v;
83///
84/// return out;
85/// }
86/// };
87/// @endcode
88///
89/// We can then write a test function. Note that it is not possible for users
90/// to construct a context directly, so we are forced to abuse the
91/// internal-use-only types `Format_ContextOutputIteratorRef` and
92/// `Format_ContextFactory` in order to write this usage example.
93///
94/// @code
95/// struct MyCharFormatterTestVisitor {
96/// char value;
97///
98/// void operator()(char v) { value = v; }
99///
100/// template <class t_TYPE>
101/// void operator()(const t_TYPE &) const
102/// {
103/// assert(false); // Wrong Type
104/// }
105/// };
106///
107/// void testFormatter(bslfmt::format_args args)
108/// {
109/// MyCharFormatter f;
110/// bsl::string result;
111/// bsl::back_insert_iterator<bsl::string> backiter(result);
112/// bslfmt::Format_ContextOutputIteratorImpl<
113/// char, bsl::back_insert_iterator<bsl::string> >
114/// iter(backiter);
115/// bslfmt::format_context fc =
116/// bslfmt::Format_ContextFactory::construct(
117/// bslfmt::Format_ContextOutputIteratorRef<char>(&iter),
118/// args);
119/// MyCharFormatterTestVisitor visitor;
120/// bslfmt::visit_format_arg(visitor, fc.arg(0));
121/// f.format(visitor.value, fc);
122/// assert(result.size() == 1);
123/// assert(result.front() == `x`);
124/// }
125/// @endcode
126///
127/// Then we perform the test itself:
128///
129/// @code
130/// char value = `x`;
131/// testFormatter(bslfmt::make_format_args(value));
132/// @endcode
133///
134/// @}
135/** @} */
136/** @} */
137
138/** @addtogroup bsl
139 * @{
140 */
141/** @addtogroup bslfmt
142 * @{
143 */
144/** @addtogroup bslfmt_format_context
145 * @{
146 */
147
148#include <bslscm_version.h>
149
150#include <bslfmt_format_args.h>
151#include <bslfmt_formaterror.h>
152#include <bslfmt_formatterbase.h>
153
155
156#include <bslmf_assert.h>
157#include <bslmf_conditional.h>
158#include <bslmf_enableif.h>
160#include <bslmf_isintegral.h>
161#include <bslmf_issame.h>
162#include <bslmf_movableref.h>
163
165#include <bsls_exceptionutil.h>
166#include <bsls_libraryfeatures.h>
167#include <bsls_unspecifiedbool.h>
168#include <bsls_util.h>
169
170#include <bslstl_iterator.h>
171#include <bslstl_string.h>
172#include <bslstl_stringview.h>
173#include <bslstl_array.h>
174#include <bslstl_monostate.h>
175#include <bslstl_utility.h>
176#include <bslstl_variant.h>
177
178
179namespace bslfmt {
180
181// FORWARD DECLARATIONS
182
183template <class t_OUT, class t_CHAR>
184class basic_format_context;
185
186template <class t_VALUE>
187class Format_ContextOutputIteratorRef;
188
189template <class t_CONTEXT>
190class basic_format_arg;
191
192template <class t_CONTEXT>
193class basic_format_args;
194
195// TYPEDEFS
196
197typedef basic_format_context<Format_ContextOutputIteratorRef<char>, char>
199
200typedef basic_format_context<Format_ContextOutputIteratorRef<wchar_t>, wchar_t>
202
203 // ======================================
204 // class Format_ContextOutputIteratorBase
205 // ======================================
206
207/// This component-private type is an abstract base required to type-erase
208/// output iterators as required by the @ref format_context and @ref wformat_context
209/// typedefs.
210///
211/// See @ref bslfmt_format_context
212template <class t_CHAR>
214 public:
215 // MANIPULATORS
216
217 /// Write the specified `character` to the contained iterator and then
218 /// increment this iterator.
219 virtual void put(t_CHAR character) = 0;
220};
221
222 // ======================================
223 // class Format_ContextOutputIteratorImpl
224 // ======================================
225
226/// This type holds a reference to an iterator, and is used to type-erase
227/// output iterators as required by the @ref format_context and @ref wformat_context
228/// typedefs. It is solely for private use by other components of the `bslfmt`
229/// package and should not be used directly.
230template <class t_CHAR, class t_ITER>
232: public Format_ContextOutputIteratorBase<t_CHAR> {
233 private:
234 // DATA
235 t_ITER& d_iter; // The contained iterator
236
237 public:
238 // CREATORS
239
240 /// Create a instance containing a reference to the specified `iter` of
241 /// parameter type `t_ITER`.
243
244 // MANIPULATORS
245
246 /// Write the specified `character` to the contained iterator and then
247 /// increment this iterator.
248 void put(t_CHAR character) BSLS_KEYWORD_OVERRIDE;
249};
250
251 // =====================================
252 // class Format_ContextOutputIteratorRef
253 // =====================================
254
255/// This class provides a type-erased interface to an output iterator that it
256/// holds indirectly via a reference to a `Format_ContextOutputIteratorImpl`
257/// type. It is solely for private use by other components of the `bslfmt`
258/// package and should not be used directly.
259///
260/// See @ref bslfmt_format_context
261template <class t_CHAR>
263 private:
264 // DATA
266 // pointer to `Format_ContextOutputIteratorImpl`
267
268 public:
269 // TYPES
270 typedef bsl::output_iterator_tag iterator_category;
271 typedef void difference_type;
272 typedef t_CHAR value_type;
273 typedef void reference;
274 typedef void pointer;
275
276 // CREATORS
277
278 /// Create an instance of this type. The specified `base` should be a
279 /// pointer to an `Format_ContextOutputIteratorImpl` type whose lifetime
280 /// must outlive that of the constructed instance.
283
284 // MANIPULATORS
285
286 /// Return a reference to `*this`. This method is provided to enable this
287 /// type to satisfy the requirements of [output.iterators].
289
290 /// Call `put(x)` on the referenced `Format_ContextOutputIteratorImpl`
291 /// instance. This will result in the value being written to the
292 /// underlying iterator referenced by the
293 /// `Format_ContextOutputIteratorImpl` instance, and that underlying
294 /// iterator then being incremented.
295 void operator=(t_CHAR x);
296
297 /// Do nothing. This method is provided to enable this type to satisfy the
298 /// requirements of [output.iterators].
300
301 /// Do nothing. This method is provided to enable this type to satisfy the
302 /// requirements of [output.iterators].
304};
305
306 // ==========================
307 // class basic_format_context
308 // ==========================
309
310/// A format context for use by `formatter::format()` partial specialization.
311/// It provides access to the output iterator for writing the formatted value
312/// and access to all formatting arguments.
313///
314/// See @ref bslfmt_format_context
315template <class t_OUT, class t_CHAR>
317 private:
318 // TYPES
320
321 // DATA
322 basic_format_args<basic_format_context> d_args; // format arguments
323 t_OUT d_out; // output iterator
324
325 public:
326 // TYPES
327 typedef t_OUT iterator;
328 typedef t_CHAR char_type;
329
330#if defined(BSLS_COMPILERFEATURES_SUPPORT_ALIAS_TEMPLATES)
331 template <class t_TYPE>
332 using formatter_type = bsl::formatter<t_TYPE, t_CHAR>;
333#endif
334
335 private:
336 // PRIVATE CREATORS
337
338 /// Create a context that contains a copies of the specified output
339 /// iterator `out` and of the specified arguments `args`.
342
343 // FRIENDS
345
346 public:
347
348 // MANIPULATORS
349
350 /// Update the contained iterator to that specified by `it`.
351 void advance_to(iterator it);
352
353 /// Return (by value) the contained output iterator. As this is returned
354 /// by value, any changes will not be reflected in the contained iterator
355 /// unless a subsequent call to `advance_to` is made.
356 iterator out();
357
358 // ACCESSORS
359
360 /// Return a @ref basic_format_arg type for the argument in the position
361 /// specified by `id`, with indexing starting at zero. If `id` is not less
362 /// than the number of contained arguments, a default-constructed
363 /// @ref basic_format_arg object is returned.
364 Arg arg(size_t id) const BSLS_KEYWORD_NOEXCEPT;
365};
366
367 // ===========================
368 // class Format_ContextFactory
369 // ===========================
370
371/// This class provides utility functions to enable manipulation of types
372/// declared by this component. It is solely for private use by other
373/// components of the `bslfmt` package and should not be used directly.
374///
375/// See @ref bslfmt_format_context
377 public:
378 // CLASS METHODS
379
380 /// Create a @ref basic_format_context object holding the specified `out`
381 /// output iterator and a @ref basic_format_args object containing the
382 /// specified @ref fmt_args values.
383 template <class t_OUT, class t_CHAR>
385 t_OUT out,
387};
388
389
390// ============================================================================
391// INLINE DEFINITIONS
392// ============================================================================
393
394 // --------------------------------------
395 // class Format_ContextOutputIteratorImpl
396 // --------------------------------------
397
398// CREATORS
399template <class t_CHAR, class t_ITER>
400inline
403: d_iter(iter)
404{
405 typedef typename bsl::iterator_traits<t_ITER>::value_type ValueType;
406
407 // We allow void because the standard library
408 // @ref back_insert_iterator has a `value_type` of `void`.
411}
412
413// MANIPULATORS
414template <class t_CHAR, class t_ITER>
416{
417 // We cannot use postfix increment in case `d_iter` holds state.
418 *d_iter = character;
419 ++d_iter;
420}
421
422 // -------------------------------------
423 // class Format_ContextOutputIteratorRef
424 // -------------------------------------
425
426// CREATORS
427template <class t_CHAR>
428inline
434
435// MANIPULATORS
436template <class t_CHAR>
437inline
443
444template <class t_CHAR>
445inline
447{
448#if defined(BSLS_PLATFORM_CMP_GNU) && BSLS_PLATFORM_CMP_VERSION < 150000
449# pragma GCC diagnostic push
450# pragma GCC diagnostic ignored "-Warray-bounds"
451
452 // A strange warning is issued by the GNU compiler here sometimes when code
453 // is heavily templated. This was encountered when formatting bdlt
454 // objects. Github Copilot attributes this to a compiler bug.
455#endif
456
457 d_base_p->put(x);
458
459#if defined(BSLS_PLATFORM_CMP_GNU) && BSLS_PLATFORM_CMP_VERSION < 150000
460# pragma GCC diagnostic pop
461#endif
462}
463
464template <class t_CHAR>
465inline
471
472template <class t_CHAR>
473inline
479
480 // --------------------------
481 // class basic_format_context
482 // --------------------------
483
484// PRIVATE CREATORS
485template <class t_OUT, class t_CHAR>
486inline
488 t_OUT out,
490: d_args(args)
491, d_out(out)
492{
493}
494
495// MANIPULATORS
496template <class t_OUT, class t_CHAR>
497inline
500{
501 return BloombergLP::bslmf::MovableRefUtil::move(d_out);
502}
503
504template <class t_OUT, class t_CHAR>
505inline
507{
508 d_out = BloombergLP::bslmf::MovableRefUtil::move(it);
509}
510
511// ACCESSORS
512template <class t_OUT, class t_CHAR>
513inline
514typename basic_format_context<t_OUT, t_CHAR>::Arg
516{
517 return d_args.get(id);
518}
519
520 // ---------------------------
521 // class Format_ContextFactory
522 // ---------------------------
523
524// CLASS METHODS
525template <class t_OUT, class t_CHAR>
526inline
533
534
535} // close package namespace
536
537
538#endif // INCLUDED_BSLFMT_FORMAT_CONTEXT
539
540// ----------------------------------------------------------------------------
541// Copyright 2023 Bloomberg Finance L.P.
542//
543// Licensed under the Apache License, Version 2.0 (the "License");
544// you may not use this file except in compliance with the License.
545// You may obtain a copy of the License at
546//
547// http://www.apache.org/licenses/LICENSE-2.0
548//
549// Unless required by applicable law or agreed to in writing, software
550// distributed under the License is distributed on an "AS IS" BASIS,
551// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
552// See the License for the specific language governing permissions and
553// limitations under the License.
554// ----------------------------- END-OF-FILE ----------------------------------
555
556/** @} */
557/** @} */
558/** @} */
Definition bslfmt_format_context.h:376
static basic_format_context< t_OUT, t_CHAR > construct(t_OUT out, const basic_format_args< basic_format_context< t_OUT, t_CHAR > > &args)
Definition bslfmt_format_context.h:527
Definition bslfmt_format_context.h:213
virtual void put(t_CHAR character)=0
Definition bslfmt_format_context.h:232
Format_ContextOutputIteratorImpl(t_ITER &iter)
Definition bslfmt_format_context.h:402
void put(t_CHAR character) BSLS_KEYWORD_OVERRIDE
Definition bslfmt_format_context.h:415
Definition bslfmt_format_context.h:262
void reference
Definition bslfmt_format_context.h:273
void operator=(t_CHAR x)
Definition bslfmt_format_context.h:446
t_CHAR value_type
Definition bslfmt_format_context.h:272
Format_ContextOutputIteratorRef(Format_ContextOutputIteratorBase< t_CHAR > *base)
Definition bslfmt_format_context.h:429
Format_ContextOutputIteratorRef & operator*()
Definition bslfmt_format_context.h:439
Format_ContextOutputIteratorRef & operator++()
Definition bslfmt_format_context.h:467
void pointer
Definition bslfmt_format_context.h:274
bsl::output_iterator_tag iterator_category
Definition bslfmt_format_context.h:270
void difference_type
Definition bslfmt_format_context.h:271
Definition bslfmt_format_arg.h:162
Definition bslfmt_format_args.h:275
Definition bslfmt_format_context.h:316
void advance_to(iterator it)
Update the contained iterator to that specified by it.
Definition bslfmt_format_context.h:506
iterator out()
Definition bslfmt_format_context.h:499
t_CHAR char_type
Definition bslfmt_format_context.h:328
Arg arg(size_t id) const BSLS_KEYWORD_NOEXCEPT
Definition bslfmt_format_context.h:515
t_OUT iterator
Definition bslfmt_format_context.h:327
#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
#define BSLS_KEYWORD_NOEXCEPT
Definition bsls_keyword.h:674
#define BSLS_KEYWORD_OVERRIDE
Definition bsls_keyword.h:695
Definition bslfmt_enablestreamedformatter.h:130
basic_format_context< Format_ContextOutputIteratorRef< char >, char > format_context
Definition bslfmt_format_arg.h:170
basic_format_context< Format_ContextOutputIteratorRef< wchar_t >, wchar_t > wformat_context
Definition bslfmt_format_arg.h:173
Definition bslfmt_formatterbase.h:426
Definition bslmf_issame.h:146