BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bslfmt_mockformatcontext.h
Go to the documentation of this file.
1/// @file bslfmt_mockformatcontext.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslfmt_mockformatcontext.h -*-C++-*-
8
9#ifndef INCLUDED_BSLFMT_MOCKFORMATCONTEXT
10#define INCLUDED_BSLFMT_MOCKFORMATCONTEXT
11
12#include <bsls_ident.h>
13BSLS_IDENT("$Id: $")
14
15/// @defgroup bslfmt_mockformatcontext bslfmt_mockformatcontext
16/// @brief Provide mock context to test formatter specializations
17/// @addtogroup bsl
18/// @{
19/// @addtogroup bslfmt
20/// @{
21/// @addtogroup bslfmt_mockformatcontext
22/// @{
23///
24/// <h1> Outline </h1>
25/// * <a href="#bslfmt_mockformatcontext-purpose"> Purpose</a>
26/// * <a href="#bslfmt_mockformatcontext-classes"> Classes </a>
27/// * <a href="#bslfmt_mockformatcontext-description"> Description </a>
28/// * <a href="#bslfmt_mockformatcontext-usage"> Usage </a>
29/// * <a href="#bslfmt_mockformatcontext-example-testing-a-formatter"> Example: Testing a formatter </a>
30///
31/// # Purpose {#bslfmt_mockformatcontext-purpose}
32/// Provide mock context to test formatter specializations
33///
34/// # Classes {#bslfmt_mockformatcontext-classes}
35///
36/// - MockFormatContext: format context for use in formatter tests
37///
38/// # Description {#bslfmt_mockformatcontext-description}
39/// This component provides a class that holds the state of the
40/// format operation and is used for formatter testing.
41///
42/// ## Usage {#bslfmt_mockformatcontext-usage}
43///
44///
45/// This section illustrates intended usage of this component.
46///
47/// ### Example: Testing a formatter {#bslfmt_mockformatcontext-example-testing-a-formatter}
48///
49///
50/// Suppose we want to test `format` function of some formatter that meets
51/// `BasicFormatter` requirements. For example a formatter that formats integer
52/// values:
53/// @code
54/// template <class t_VALUE>
55/// class IntegerFormatter {
56/// public:
57/// // CREATORS
58///
59/// /// Create a formatter object.
60/// IntegerFormatter();
61///
62/// // MANIPULATORS
63///
64/// /// Parse the specified `parseContext` and return an iterator, pointing
65/// /// to the end of the format string.
66/// template <class t_PARSE_CONTEXT>
67/// typename t_PARSE_CONTEXT::iterator parse(
68/// t_PARSE_CONTEXT& parseContext);
69///
70/// // ACCESSORS
71///
72/// /// Create string representation of the specified `value`, customized
73/// /// in accordance with the requested format and the specified
74/// /// `formatContext`, and copy it to the output that the output iterator
75/// /// of the `formatContext` points to.
76/// template <class t_FORMAT_CONTEXT>
77/// typename t_FORMAT_CONTEXT::iterator format(
78/// t_VALUE value,
79/// t_FORMAT_CONTEXT& formatContext) const;
80/// };
81/// @endcode
82/// First, we create an object of our formatter:
83/// @code
84/// IntegerFormatter<int> formatter;
85/// @endcode
86/// Next, we specify a value to format and define expected result of formatting.
87/// In this example we will skip the spec parsing step, but let's say we want to
88/// format the number `42` with the following spec: "*<5x".
89/// @code
90/// const int value = 42;
91/// const char *expectedResult = "2a***";
92/// const size_t expectedResultLength = std::strlen(expectedResult);
93/// @endcode
94/// Now create a `MockFormatContext` and format the value using our formatter:
95/// @code
96/// typedef bslfmt::MockFormatContext<char> FormatContext;
97///
98/// FormatContext mfc(value);
99/// FormatContext::iterator begin = mfc.out();
100///
101/// mfc.advance_to(bsl::as_const(formatter).format(value, mfc));
102/// FormatContext::iterator end = mfc.out();
103/// @endcode
104/// Finally, verify that `format` function returns the correct past-the-end
105/// iterator and produces the expected result string:
106/// @code
107/// const size_t actualResultLength = static_cast<size_t>(end.rawPointer() -
108/// begin.rawPointer());
109/// ASSERT(expectedResultLength == actualResultLength);
110/// assert(expectedResult == mfc.finalString());
111/// @endcode
112/// @}
113/** @} */
114/** @} */
115
116/** @addtogroup bsl
117 * @{
118 */
119/** @addtogroup bslfmt
120 * @{
121 */
122/** @addtogroup bslfmt_mockformatcontext
123 * @{
124 */
125
126#include <bslscm_version.h>
127
128#include <bslfmt_format_arg.h>
130#include <bslfmt_formatterbase.h>
131
132#include <bsls_assert.h>
134#include <bsls_exceptionutil.h>
135#include <bsls_keyword.h>
136
137#include <bslstl_array.h>
138#include <bslstl_stringview.h>
139
140
141namespace bslfmt {
142
143
144 // ================================
145 // class MockFormatContext_Iterator
146 // ================================
147
148/// This class template provides an output iterator to the `MockFormatContext`
149/// output buffer allowing appending formatted data.
150///
151/// See @ref bslfmt_mockformatcontext
152template <class t_CHAR>
154 private:
155 // DATA
156 t_CHAR *d_ptr; // pointer to the beginning of output buffer
157 t_CHAR *d_max; // pointer to the end of output buffer
158
159 public:
160 // TYPES
161 typedef std::ptrdiff_t difference_type;
162 typedef t_CHAR value_type;
163 typedef t_CHAR * pointer;
164 typedef t_CHAR& reference;
165 typedef std::output_iterator_tag iterator_category;
166
167 // CREATORS
168
169 /// Create an iterator, pointing to the specified `ptr` and having the
170 /// specified `max` as the end of the buffer available for output.
171 ///
172 /// \pre The behavior is undefined unless `max >=ptr`.
173 MockFormatContext_Iterator(t_CHAR *ptr, t_CHAR *max);
174
175 // MANIPULATORS
176
177 /// Increment this object to refer to the next character in the output
178 /// buffer. Throw `bslfmt::format_error` if the iterator goes beyond the
179 /// allowed buffer bounds.
181
182 /// Copy this iterator, increment it, and return by value the copy that was
183 /// made prior the increment.
185
186 // ACCESSORS
187
188 /// Return a reference to the character referred to by this iterator.
189 t_CHAR& operator*() const;
190
191 /// Return a pointer pointing to the character referred to by this
192 /// iterator.
193 t_CHAR *rawPointer() const;
194};
195
196 // =======================
197 // class MockFormatContext
198 // =======================
199
200/// This unconstrained (value-semantic) class provides an access to the current
201/// state of the format operation and is used for testing `bsl::formatter`
202/// specializations.
203///
204/// See @ref bslfmt_mockformatcontext
205template <class t_CHAR>
207 public:
208 // TYPES
211
212 private:
213 // PRIVATE TYPES
214 enum {
215 k_BUFFER_SIZE = 512 // maximum output buffer size
216 };
217
218 // DATA
219 Arg d_arg_0; // first argument
220 Arg d_arg_1; // second argument
221 Arg d_arg_2; // third argument
222 Arg d_arg_3; // forth argument
223
224 t_CHAR d_buffer[k_BUFFER_SIZE]; // output buffer
225 iterator d_iterator; // output iterator
226
227 private:
228 // NOT IMPLEMENTED
229 MockFormatContext(const MockFormatContext& original);
230 MockFormatContext& operator=(const MockFormatContext& original);
231
232 public:
233 // TYPES
234 typedef t_CHAR char_type;
235
236#ifdef BSLS_COMPILERFEATURES_SUPPORT_ALIAS_TEMPLATES
237 template <class t_TYPE>
238 using formatter_type = bsl::formatter<t_TYPE, t_CHAR>;
239#endif
240
241 // CREATORS
242
243 /// Create an object having the specified `arg_0` as an argument.
244 template <class t_ARG0>
245 MockFormatContext(const t_ARG0& arg_0);
246
247 /// Create an object having the specified `arg_0` and `arg_1` as arguments.
248 template <class t_ARG0, class t_ARG1>
249 MockFormatContext(const t_ARG0& arg_0, const t_ARG1& arg_1);
250
251 /// Create an object having the specified `arg_0`, `arg_1` and `arg_2` as
252 /// arguments.
253 template <class t_ARG0, class t_ARG1, class t_ARG2>
254 MockFormatContext(const t_ARG0& arg_0,
255 const t_ARG1& arg_1,
256 const t_ARG2& arg_2);
257
258 /// Create an object having the specified `arg_0`, `arg_1`, `arg_2` and
259 /// `arg_3` as arguments.
260 template <class t_ARG0, class t_ARG1, class t_ARG2, class t_ARG3>
261 MockFormatContext(const t_ARG0& arg_0,
262 const t_ARG1& arg_1,
263 const t_ARG2& arg_2,
264 const t_ARG3& arg_3);
265
266 // MANIPULATORS
267
268 /// Advance the output iterator to the position referred by the specified
269 /// `it`.
270 void advance_to(iterator it);
271
272 // ACCESSORS
273
274 /// Return the argument with the specified `id` or the default constructed
275 /// object if there is no argument with such `id`.
276 Arg arg(size_t id) const BSLS_KEYWORD_NOEXCEPT;
277
278 /// Return this object's output iterator.
279 iterator out() const;
280
281 /// Return output string.
283};
284
285// ============================================================================
286// INLINE DEFINITIONS
287// ============================================================================
288
289 // --------------------------------
290 // class MockFormatContext_Iterator
291 // --------------------------------
292
293// CREATORS
294template <class t_CHAR>
296 t_CHAR *max)
297: d_ptr(ptr)
298, d_max(max)
299{
300 BSLS_ASSERT(max >=ptr);
301}
302
303// MANIPULATORS
304template <class t_CHAR>
307{
308 d_ptr++;
309 if (d_ptr >= d_max)
310 BSLS_THROW(format_error("MockFormatContext buffer overrun"));
311 return *this;
312}
313
314template <class t_CHAR>
317{
318 MockFormatContext_Iterator copy = *this;
319 ++*this;
320 return copy;
321}
322
323// ACCESSORS
324template <class t_CHAR>
326{
327 return *d_ptr;
328}
329
330template <class t_CHAR>
332{
333 return d_ptr;
334}
335
336 // -----------------------
337 // class MockFormatContext
338 // -----------------------
339
340template <class t_CHAR>
341template <class t_ARG0>
343: d_buffer()
344, d_iterator(d_buffer, d_buffer + k_BUFFER_SIZE - 1)
345{
348 d_arg_0 = Arg(arr[0]);
349}
350
351template <class t_CHAR>
352template <class t_ARG0, class t_ARG1>
354 const t_ARG1& arg_1)
355: d_buffer()
356, d_iterator(d_buffer, d_buffer + k_BUFFER_SIZE - 1)
357{
359 Format_ArgUtil::makeFormatArgArray(&arr, arg_0, arg_1);
360 d_arg_0 = Arg(arr[0]);
361 d_arg_1 = Arg(arr[1]);
362}
363
364template <class t_CHAR>
365template <class t_ARG0, class t_ARG1, class t_ARG2>
367 const t_ARG1& arg_1,
368 const t_ARG2& arg_2)
369: d_buffer()
370, d_iterator(d_buffer, d_buffer + k_BUFFER_SIZE - 1)
371{
373 Format_ArgUtil::makeFormatArgArray(&arr, arg_0, arg_1, arg_2);
374 d_arg_0 = Arg(arr[0]);
375 d_arg_1 = Arg(arr[1]);
376 d_arg_2 = Arg(arr[2]);
377}
378
379template <class t_CHAR>
380template <class t_ARG0, class t_ARG1, class t_ARG2, class t_ARG3>
382 const t_ARG1& arg_1,
383 const t_ARG2& arg_2,
384 const t_ARG3& arg_3)
385: d_buffer()
386, d_iterator(d_buffer, d_buffer + k_BUFFER_SIZE - 1)
387{
389 Format_ArgUtil::makeFormatArgArray(&arr, arg_0, arg_1, arg_2, arg_3);
390 d_arg_0 = Arg(arr[0]);
391 d_arg_1 = Arg(arr[1]);
392 d_arg_2 = Arg(arr[2]);
393 d_arg_3 = Arg(arr[3]);
394}
395
396// MANIPULATORS
397template <class t_CHAR>
399{
400 d_iterator = it;
401}
402
403// ACCESSORS
404template <class t_CHAR>
406 size_t id) const BSLS_KEYWORD_NOEXCEPT
407{
408 if (id == 0)
409 return d_arg_0;
410 if (id == 1)
411 return d_arg_1;
412 if (id == 2)
413 return d_arg_2;
414 if (id == 3)
415 return d_arg_3;
416
417 return Arg();
418}
419
420template <class t_CHAR>
423{
424 return d_iterator;
425}
426
427template <class t_CHAR>
429{
430 return bsl::basic_string_view<t_CHAR>(d_buffer, d_iterator.rawPointer());
431}
432
433} // close package namespace
434
435
436
437#endif // INCLUDED_BSLFMT_MOCKFORMATCONTEXT
438
439// ----------------------------------------------------------------------------
440// Copyright 2024 Bloomberg Finance L.P.
441//
442// Licensed under the Apache License, Version 2.0 (the "License");
443// you may not use this file except in compliance with the License.
444// You may obtain a copy of the License at
445//
446// http://www.apache.org/licenses/LICENSE-2.0
447//
448// Unless required by applicable law or agreed to in writing, software
449// distributed under the License is distributed on an "AS IS" BASIS,
450// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
451// See the License for the specific language governing permissions and
452// limitations under the License.
453// ----------------------------- END-OF-FILE ----------------------------------
454
455
456/** @} */
457/** @} */
458/** @} */
Definition bslstl_stringview.h:471
static void makeFormatArgArray(bsl::array< basic_format_arg< t_CONTEXT >, sizeof...(t_FMTARGS)> *out, t_FMTARGS &... fmt_args)
Definition bslfmt_format_arg.h:875
Definition bslfmt_mockformatcontext.h:153
t_CHAR & reference
Definition bslfmt_mockformatcontext.h:164
t_CHAR value_type
Definition bslfmt_mockformatcontext.h:162
t_CHAR * rawPointer() const
Definition bslfmt_mockformatcontext.h:331
t_CHAR * pointer
Definition bslfmt_mockformatcontext.h:163
MockFormatContext_Iterator(t_CHAR *ptr, t_CHAR *max)
Definition bslfmt_mockformatcontext.h:295
t_CHAR & operator*() const
Return a reference to the character referred to by this iterator.
Definition bslfmt_mockformatcontext.h:325
MockFormatContext_Iterator & operator++()
Definition bslfmt_mockformatcontext.h:306
std::ptrdiff_t difference_type
Definition bslfmt_mockformatcontext.h:161
std::output_iterator_tag iterator_category
Definition bslfmt_mockformatcontext.h:165
Definition bslfmt_mockformatcontext.h:206
basic_format_arg< basic_format_context< t_CHAR *, t_CHAR > > Arg
Definition bslfmt_mockformatcontext.h:209
bsl::basic_string_view< t_CHAR > finalString() const
Return output string.
Definition bslfmt_mockformatcontext.h:428
Arg arg(size_t id) const BSLS_KEYWORD_NOEXCEPT
Definition bslfmt_mockformatcontext.h:405
void advance_to(iterator it)
Definition bslfmt_mockformatcontext.h:398
t_CHAR char_type
Definition bslfmt_mockformatcontext.h:234
MockFormatContext_Iterator< t_CHAR > iterator
Definition bslfmt_mockformatcontext.h:210
iterator out() const
Return this object's output iterator.
Definition bslfmt_mockformatcontext.h:422
Definition bslfmt_format_arg.h:162
Definition bslfmt_formaterror.h:118
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1976
#define BSLS_THROW(X)
Definition bsls_exceptionutil.h:374
#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
Definition bslfmt_enablestreamedformatter.h:130
Definition bslstl_array.h:293
Definition bslfmt_formatterbase.h:426