BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bslfmt_formattertestutil.h
Go to the documentation of this file.
1/// @file bslfmt_formattertestutil.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslfmt_formattertestutil.h -*-C++-*-
8
9#ifndef INCLUDED_BSLFMT_FORMATTERTESTUTIL
10#define INCLUDED_BSLFMT_FORMATTERTESTUTIL
11
12#include <bsls_ident.h>
13BSLS_IDENT("$Id: $")
14
15/// @defgroup bslfmt_formattertestutil bslfmt_formattertestutil
16/// @brief Provide utilities for testing custom formatters
17/// @addtogroup bsl
18/// @{
19/// @addtogroup bslfmt
20/// @{
21/// @addtogroup bslfmt_formattertestutil
22/// @{
23///
24/// <h1> Outline </h1>
25/// * <a href="#bslfmt_formattertestutil-purpose"> Purpose</a>
26/// * <a href="#bslfmt_formattertestutil-classes"> Classes </a>
27/// * <a href="#bslfmt_formattertestutil-description"> Description </a>
28/// * <a href="#bslfmt_formattertestutil-usage"> Usage </a>
29/// * <a href="#bslfmt_formattertestutil-example-testing-an-integer-formatter"> Example: Testing an integer formatter </a>
30///
31/// # Purpose {#bslfmt_formattertestutil-purpose}
32/// Provide utilities for testing custom formatters
33///
34/// # Classes {#bslfmt_formattertestutil-classes}
35///
36/// - FormatterTestUtil: formatter test utilities
37///
38/// # Description {#bslfmt_formattertestutil-description}
39/// This component provides a utility to facilitate testing of
40/// `bsl::formatter` partial specializations where, due to hierarchical reasons,
41/// the testing cannot be performed using `bslfmt::format`.
42///
43/// This component is for use within `bslfmt` only.
44///
45/// ## Usage {#bslfmt_formattertestutil-usage}
46///
47///
48/// This section illustrates intended usage of this component.
49/// ### Example: Testing an integer formatter {#bslfmt_formattertestutil-example-testing-an-integer-formatter}
50///
51///
52/// Suppose we want to test `bsl::formatter` specialization for `int`.
53///
54/// First, to test `parse` function, we can use `testParseVFormat` function,
55/// that accepts pointer to `bsl::string` in which to store an error message if
56/// any, a flag indicating our desire to see the result of the standard
57/// implementation and accordingly the format string itself:
58/// @code
59/// typedef bslfmt::FormatterTestUtil<char> TestUtilChar;
60///
61/// bsl::string message;
62/// bool rv = TestUtilChar::testParseVFormat<int>(&message, true, "{0:}");
63/// @endcode
64/// Since the input data is correct, we get a positive result and the error
65/// message is empty:
66/// @code
67/// assert(true == rv);
68/// assert(message.empty());
69/// @endcode
70/// Then, we try to parse invalid format string and get the expected error
71/// message at the output:
72/// @code
73/// rv = TestUtilChar::testParseVFormat<int>(&message, true, "{0");
74///
75/// assert(false == rv);
76/// assert(bsl::string("Format string too short") == message);
77/// message.clear();
78/// @endcode
79/// Now we check `format` formatter's method using `testEvaluateVFormat`
80/// function, that in addition to the parameters already mentioned, accepts a
81/// string with the expected formatting result and a value for formatting:
82/// @code
83/// rv = TestUtilChar::testEvaluateVFormat<int>(&message, // message
84/// "5", // expected result
85/// true, // oracle required
86/// "{0:}", // format string
87/// 5); // value
88/// assert(true == rv);
89/// assert(message.empty());
90/// @endcode
91/// Finally verify that this function returns a false value if the expected and
92/// actual results do not match:
93/// @code
94/// rv = TestUtilChar::testEvaluateVFormat<int>(&message, // message
95/// "7", // incorrect result
96/// true, // oracle required
97/// "{0:}", // format string
98/// 5); // value
99/// assert(false == rv);
100/// assert(message.starts_with("bslfmt result does not match"));
101/// @endcode
102/// @}
103/** @} */
104/** @} */
105
106/** @addtogroup bsl
107 * @{
108 */
109/** @addtogroup bslfmt
110 * @{
111 */
112/** @addtogroup bslfmt_formattertestutil
113 * @{
114 */
115
116#include <bslscm_version.h>
117
118#include <bslfmt_format_arg.h>
119#include <bslfmt_format_args.h>
121#include <bslfmt_format_string.h>
122#include <bslfmt_formaterror.h>
124#include <bslfmt_formatterbase.h>
127
129
130#include <bslmf_assert.h>
132#include <bslmf_isarithmetic.h>
133#include <bslmf_issame.h>
134#include <bslmf_util.h> // 'forward(V)' for C++03
135
137#include <bsls_keyword.h>
138#include <bsls_libraryfeatures.h>
139#include <bsls_platform.h>
140#include <bsls_util.h> // 'forward<T>(V)' for C++11
141
142#include <bslstl_iterator.h>
143#include <bslstl_string.h>
144#include <bslstl_stringview.h>
145
146#include <locale> // for 'std::ctype', 'locale'
147#include <utility> // for `std::forward'
148
149#if defined(BSLS_COMPILERFEATURES_FULL_CPP11)
150# include <type_traits> // for 'is_constant_evaluated'
151#endif
152
153using namespace BloombergLP;
154
155#ifdef BSLS_COMPILERFEATURES_SUPPORT_CONSTEXPR_CPP20
156# define BSLFMT_FORMATTER_TEST_CONSTEVAL consteval
157#else
158# define BSLFMT_FORMATTER_TEST_CONSTEVAL
159#endif
160
161#if defined(BSLS_LIBRARYFEATURES_HAS_CPP20_FORMAT)
162#define BSLFMT_FORMATTER_TEST_UTIL_FORMAT_STRING \
163 std::format_string<t_TYPE>
164#define BSLFMT_FORMATTER_TEST_UTIL_FORMAT_STRING_ONE_ARG \
165 std::format_string<t_TYPE, t_ARG>
166#define BSLFMT_FORMATTER_TEST_UTIL_FORMAT_STRING_TWO_ARGS \
167 std::format_string<t_TYPE, t_ARG_1, t_ARG_2>
168#define BSLFMT_FORMATTER_TEST_UTIL_WFORMAT_STRING \
169 std::wformat_string<t_TYPE>
170#define BSLFMT_FORMATTER_TEST_UTIL_WFORMAT_STRING_ONE_ARG \
171 std::wformat_string<t_TYPE, t_ARG>
172#define BSLFMT_FORMATTER_TEST_UTIL_WFORMAT_STRING_TWO_ARGS \
173 std::wformat_string<t_TYPE, t_ARG_1, t_ARG_2>
174#define BSLFMT_FORMATTER_TEST_UTIL_BASIC_FORMAT_STRING \
175 std::basic_format_string<t_CHAR, t_TYPE>
176#define BSLFMT_FORMATTER_TEST_UTIL_BASIC_FORMAT_STRING_ONE_ARG \
177 std::basic_format_string<t_CHAR, t_TYPE, t_ARG>
178#define BSLFMT_FORMATTER_TEST_UTIL_BASIC_FORMAT_STRING_TWO_ARGS \
179 std::basic_format_string<t_CHAR, t_TYPE, t_ARG_1, t_ARG_2>
180#define BSLFMT_FORMATTER_TEST_UTIL_FORMAT_STRING_P \
181 std::format_string<t_TYPE, int, int>
182#define BSLFMT_FORMATTER_TEST_UTIL_WFORMAT_STRING_P \
183 std::wformat_string<t_TYPE, int, int>
184#define BSLFMT_FORMATTER_TEST_UTIL_BASIC_FORMAT_STRING_P \
185 std::basic_format_string<t_CHAR, t_TYPE, int, int>
186#define BSLFMT_FORMATTER_TEST_UTIL_BASIC_FORMAT_STRING_GETTER(ARG) \
187 ARG.get()
188#else
189#define BSLFMT_FORMATTER_TEST_UTIL_FORMAT_STRING \
190 bslfmt::basic_format_string<char>
191#define BSLFMT_FORMATTER_TEST_UTIL_FORMAT_STRING_ONE_ARG \
192 bslfmt::basic_format_string<char>
193#define BSLFMT_FORMATTER_TEST_UTIL_FORMAT_STRING_TWO_ARGS \
194 bslfmt::basic_format_string<char>
195#define BSLFMT_FORMATTER_TEST_UTIL_WFORMAT_STRING \
196 bslfmt::basic_format_string<wchar_t>
197#define BSLFMT_FORMATTER_TEST_UTIL_WFORMAT_STRING_ONE_ARG \
198 bslfmt::basic_format_string<wchar_t>
199#define BSLFMT_FORMATTER_TEST_UTIL_WFORMAT_STRING_TWO_ARGS \
200 bslfmt::basic_format_string<wchar_t>
201#define BSLFMT_FORMATTER_TEST_UTIL_BASIC_FORMAT_STRING \
202 bslfmt::basic_format_string<t_CHAR>
203#define BSLFMT_FORMATTER_TEST_UTIL_BASIC_FORMAT_STRING_ONE_ARG \
204 bslfmt::basic_format_string<t_CHAR>
205#define BSLFMT_FORMATTER_TEST_UTIL_BASIC_FORMAT_STRING_TWO_ARGS \
206 bslfmt::basic_format_string<t_CHAR>
207#define BSLFMT_FORMATTER_TEST_UTIL_FORMAT_STRING_P \
208 bslfmt::basic_format_string<char>
209#define BSLFMT_FORMATTER_TEST_UTIL_WFORMAT_STRING_P \
210 bslfmt::basic_format_string<wchar_t>
211#define BSLFMT_FORMATTER_TEST_UTIL_BASIC_FORMAT_STRING_P \
212 bslfmt::basic_format_string<t_CHAR>
213#define BSLFMT_FORMATTER_TEST_UTIL_BASIC_FORMAT_STRING_GETTER(ARG) \
214 ARG.get()
215#endif
216
217
218namespace bslfmt {
219
220#if defined(BSLS_LIBRARYFEATURES_HAS_CPP20_FORMAT)
221
222 // ==============================
223 // class FormatterTestUtil_Oracle
224 // ==============================
225
226/// This template struct provides a namespace for a utility function that
227/// creates a string containing the result of formatting done by standard
228/// implementations. This struct is meant for test purposes only.
229///
230/// See @ref bslfmt_formattertestutil
231template <class t_CHAR>
232struct FormatterTestUtil_Oracle {
233};
234
235/// This is a specialization of `FormatterTestUtil_Oracle` template for `char`.
236template <>
237struct FormatterTestUtil_Oracle<char> {
238 public:
239 // CLASS METHODS
240
241 /// Store to the specified `result` the string containing the result of
242 /// formatting the specified `value` using a standard implementation
243 /// with the specified `fmtStr` as a format specification and the
244 /// specified `args` as value(s).
245 template <class t_TYPE, class... t_ARGS>
246 static void evaluateOracle(bsl::basic_string<char> *result,
248 t_TYPE&& value,
249 t_ARGS&&... args);
250};
251
252/// This is a specialization of `FormatterTestUtil_Oracle` template for
253// `wchar_t`.
254template <>
255struct FormatterTestUtil_Oracle<wchar_t> {
256 public:
257 // CLASS METHODS
258
259 /// Store to the specified `result` the string containing the result of
260 /// formatting the specified `value` using a standard implementation
261 /// with the specified `fmtStr` as a format specification and the
262 /// specified `args` as value(s).
263 template <class t_TYPE, class... t_ARGS>
264 static void evaluateOracle(bsl::basic_string<wchar_t> *result,
266 t_TYPE&& value,
267 t_ARGS&&... args);
268};
269#endif
270
271 // ============================
272 // class FormatterTestUtil_Impl
273 // ============================
274
275/// This struct provides a namespace for implementations of test functions that
276/// verify the correctness of formatting performed by `bslfmt` tools, where
277/// those implementations are common for all character types. Those
278/// implementations were moved to a separate struct to avoid code duplication.
279/// Due to the limitations of template argument deduction, it is necessary to
280/// explicitly specialize the `FormatterTestUtil` template for `char` and
281/// `wchar_t`. This struct contains that part of the implementation.
282///
283/// See @ref bslfmt_formattertestutil
284template <class t_CHAR>
286 private:
287 // PRIVATE CLASS METHODS
288
289 /// Parse the specified `fmtStr` and format the specified `value` using a
290 /// `bslfmt::formatter` specialization for the (template parameter)
291 /// `t_TYPE`, passing the specified `mockContext`. In case of success
292 /// store the obtained string to the specified `result` and return `true`,
293 /// otherwise store a description of the error in the specified output
294 /// `message` and return `false`.
295 template <class t_TYPE>
296 static bool evaluateBslfmtResult(
297 bsl::string *message,
300 const t_TYPE& value,
302
303 /// Compare the specified `expectedResult` with the result of formatting
304 /// the specified `value` with the specified `fmtStr` obtained using a
305 /// `bslfmt::formatter` specialization for the (template parameter)
306 /// `t_TYPE` and the specified `mockContext`. Return `true` if these
307 /// strings are equal, otherwise store a description of the error in the
308 /// specified output `message` and return `false`.
309 template <class t_TYPE>
310 static bool testEvaluateVFormatBslfmtImpl(
311 bsl::string *message,
312 bsl::basic_string_view<t_CHAR> expectedResult,
316
317#if defined(BSLS_LIBRARYFEATURES_HAS_CPP20_FORMAT)
318 /// Compare the specified `expectedResult` with the result of formatting
319 /// the specified `value` using a standard implementation, passing the
320 // specified `fmtStr` as a format specification and the specified `args` as
321 // value(s). Return `true` if these strings are equal, otherwise store
322 /// error description to the specified `message` and return `false`.
323 template <class t_TYPE, class... t_ARGS>
324 static bool testEvaluateVFormatStdImpl(
325 bsl::string *message,
326 bsl::basic_string_view<t_CHAR> expectedResult,
328 t_TYPE&& value,
329 t_ARGS&&... args);
330#endif
331
332 /// Verify that the specified `fmtStr` has a valid structure and, if so,
333 /// parse it using a `bslfmt::formatter` specialization for the (template
334 /// parameter) `t_TYPE`. If the specified `alsoTestOracle` is `true`,
335 /// also parse the `fmtStr` using a standard library implementation. If
336 /// the specified `expectedToFail` is true then an exception is excepted
337 /// to be thrown during parsing. Return `true` if the `fmtStr` is valid
338 /// and the behavior related to `expectedToFail` meets expectations, and
339 /// return `false` otherwise.
340 template <class t_TYPE>
341 static BSLS_KEYWORD_CONSTEXPR_CPP20 bool testParseFormatImpl(
342 bsl::string *message,
343 bool alsoTestOracle,
345 bool expectedToFail);
346
347 /// Convert the specified `string` into its narrow format, if necessary,
348 /// using the default `locale()`, using the question mark (`'?'`) character
349 /// for characters that cannot be represented as narrow, and return the
350 /// resulting narrow string.
351 static bsl::string toNarrow(const bsl::string_view& string);
352 static bsl::string toNarrow(const bsl::wstring_view& string);
353
354 public:
355 // CLASS METHODS
356
357 /// Compare the specified `expectedResult` with the result of formatting
358 /// the specified `value` with the specified `fmtStr` obtained using a
359 /// `bslfmt::formatter` specialization for the (template parameter)
360 /// `t_TYPE`. If the specified `alsoTestOracle` is `true`, also compare
361 /// the `expectedResult` with the result of formatting obtained using a
362 /// standard library implementation. Optionally specify `arg`, `arg1` and
363 /// `arg2` to be passed to the formatter as additional arguments. Return
364 /// `true` if these strings are equal, otherwise store a description of the
365 /// error in the specified output `message` and return `false`.
366 ///
367 /// \note Note that `fmtStr` is required to be a compile time constant expression.
368 template <class t_TYPE>
369 static bool testEvaluateFormat(
370 bsl::string *message,
371 bsl::basic_string_view<t_CHAR> expectedResult,
372 bool alsoTestOracle,
375 template <class t_TYPE, class t_ARG>
376 static bool testEvaluateFormat(
377 bsl::string *message,
378 bsl::basic_string_view<t_CHAR> expectedResult,
379 bool alsoTestOracle,
383 template <class t_TYPE, class t_ARG_1, class t_ARG_2>
384 static bool testEvaluateFormat(
385 bsl::string *message,
386 bsl::basic_string_view<t_CHAR> expectedResult,
387 bool alsoTestOracle,
392
393 /// Compare the specified `expectedResult` with the result of formatting
394 /// the specified `value` with the specified `fmtStr` obtained using a
395 /// `bslfmt::formatter` specialization for the (template parameter)
396 /// `t_TYPE`. If the specified `alsoTestOracle` is `true`, also compare
397 /// the `expectedResult` with the result of formatting obtained using a
398 /// standard library implementation. Optionally specify `arg`, `arg1` and
399 /// `arg2` to be passed to the formatter as additional arguments. Return
400 /// `true` if these strings are equal, otherwise store a description of the
401 /// error in the specified output `message` and return `false`.
402 ///
403 /// \note Note that `fmtStr` is **NOT** required to be a compile time constant expression.
404 template <class t_TYPE>
405 static bool testEvaluateVFormat(
406 bsl::string *message,
407 bsl::basic_string_view<t_CHAR> expectedResult,
408 bool alsoTestOracle,
411 template <class t_TYPE, class t_ARG>
412 static bool testEvaluateVFormat(
413 bsl::string *message,
414 bsl::basic_string_view<t_CHAR> expectedResult,
415 bool alsoTestOracle,
419 template <class t_TYPE, class t_ARG_1, class t_ARG_2>
420 static bool testEvaluateVFormat(
421 bsl::string *message,
422 bsl::basic_string_view<t_CHAR> expectedResult,
423 bool alsoTestOracle,
428
429 /// Verify that the specified `fmtStr` has a valid structure and, if so,
430 /// parse it using a `bslfmt::formatter` specialization for the (template
431 /// parameter) `t_TYPE`. If the specified `alsoTestOracle` is `true`, also
432 /// parse `fmtStr` using a standard library implementation. Return `true`
433 /// if `fmtStr` is valid and the exception **IS** thrown during the
434 /// parsing, and return `false` otherwise.
435 template <class t_TYPE>
436 static bool testParseFailure(
437 bsl::string *message,
438 bool alsoTestOracle,
440
441 /// Verify that the specified `fmtStr` has a valid structure and, if so,
442 /// parse it using a `bslfmt::formatter` specialization for the (template
443 /// parameter) `t_TYPE`. If the specified `alsoTestOracle` is `true`, also
444 /// parse `fmtStr` using a standard library implementation. Return `true`
445 /// if `fmtStr` is valid and **NO** exception is thrown during the parsing, and return `false` otherwise.
446 ///
447 /// \note Note that `fmtStr` is required to be a
448 /// compile time constant expression.
449 template <class t_TYPE>
451 bsl::string *message,
452 bool alsoTestOracle,
454
455 /// Verify that the specified `fmtStr` has a valid structure and, if so,
456 /// parse it using a `bslfmt::formatter` specialization for the (template
457 /// parameter) `t_TYPE`. If the specified `alsoTestOracle` is `true`, also
458 /// parse `fmtStr` using a standard library implementation. Return `true`
459 /// if `fmtStr` is valid and **NO** exception is thrown during the parsing, and return `false` otherwise.
460 ///
461 /// \note Note that `fmtStr` is not required to be
462 /// a compile time constant expression.
463 template <class t_TYPE>
464 static bool testParseVFormat(
465 bsl::string *message,
466 bool alsoTestOracle,
468};
469
470 // =======================
471 // class FormatterTestUtil
472 // =======================
473
474/// This struct provides a namespace for test functions that verify the
475/// correctness of formatting performed by `bslfmt` tools. Due to the
476/// limitations of template argument deduction, it is necessary to explicitly
477/// specialize the `FormatterTestUtil` template for `char` and `wchar_t`.
478///
479/// See @ref bslfmt_formattertestutil
480template <class t_CHAR>
482};
483
484/// This is a specialization of `FormatterTestUtil` template for `char`.
485template <>
486struct FormatterTestUtil<char> {
487 public:
488 // CLASS METHODS
489
490 /// Compare the specified `expectedResult` with the result of formatting
491 /// the specified `value` with the specified `fmt` obtained using a
492 /// `bslfmt::formatter` specialization for the (template parameter)
493 /// `t_TYPE`. If the specified `alsoTestOracle` is `true`, also compare
494 /// the `expectedResult` with the result of formatting obtained using
495 /// standard library implementation. Optionally specify `arg`, `arg1` and
496 /// `arg2` to be passed to the formatter as additional arguments. Return
497 /// `true` if these strings are equal, otherwise store a description of the
498 /// error in the specified output `message` and return `false`.
499 ///
500 /// \note Note that `fmt` is required to be a compile time constant expression.
501 template <class t_TYPE>
502 static bool testEvaluateFormat(
503 bsl::string *message,
504 bsl::basic_string_view<char> expectedResult,
505 bool alsoTestOracle,
508 template <class t_TYPE, class t_ARG>
509 static bool testEvaluateFormat(
510 bsl::string *message,
511 bsl::basic_string_view<char> expectedResult,
512 bool alsoTestOracle,
516 template <class t_TYPE, class t_ARG_1, class t_ARG_2>
517 static bool testEvaluateFormat(
518 bsl::string *message,
519 bsl::basic_string_view<char> expectedResult,
520 bool alsoTestOracle,
525
526 /// Compare the specified `expectedResult` with the result of formatting
527 /// the specified `value` with the specified `fmt` obtained using a
528 /// `bslfmt::formatter` specialization for the (template parameter)
529 /// `t_TYPE`. If the specified `alsoTestOracle` is `true`, also compare
530 /// the `expectedResult` with the result of formatting obtained using
531 /// standard library implementation. Optionally specify `arg`, `arg1` and
532 /// `arg2` to be passed to the formatter as additional arguments. Return
533 /// `true` if these strings are equal, otherwise store a description of the
534 /// error in the specified output `message` and return `false`.
535 ///
536 /// \note Note that `fmt` is **NOT** required to be a compile time constant expression.
537 template <class t_TYPE>
538 static bool testEvaluateVFormat(
539 bsl::string *message,
540 bsl::basic_string_view<char> expectedResult,
541 bool alsoTestOracle,
544
545 template <class t_TYPE, class t_ARG>
546 static bool testEvaluateVFormat(
547 bsl::string *message,
548 bsl::basic_string_view<char> expectedResult,
549 bool alsoTestOracle,
553
554 template <class t_TYPE, class t_ARG_1, class t_ARG_2>
555 static bool testEvaluateVFormat(
556 bsl::string *message,
557 bsl::basic_string_view<char> expectedResult,
558 bool alsoTestOracle,
563
564 /// Verify that the specified `fmt` has a valid structure and, if so, parse
565 /// it using a `bslfmt::formatter` specialization for the (template
566 /// parameter) `t_TYPE`. If the specified `alsoTestOracle` is `true`, also
567 /// parse `fmt` using a standard library implementation. Return `true` if
568 /// `fmt` is valid and the exception *IS* thrown during the parsing, and
569 /// return `false` otherwise.
570 template <class t_TYPE>
571 static bool testParseFailure(bsl::string *message,
572 bool alsoTestOracle,
574
575 /// Verify that the specified `fmt` has a valid structure and, if so, parse
576 /// it using a `bslfmt::formatter` specialization for the (template
577 /// parameter) `t_TYPE`. If the specified `alsoTestOracle` is `true`, also
578 /// parse the `fmt` using a standard library implementation. Return `true`
579 /// if the `fmt` is valid and the exception is *NOT* thrown during the parsing, and return `false` otherwise.
580 ///
581 /// \note Note that `fmt` is required to
582 /// be a compile time constant expression.
583 template <class t_TYPE>
584 static BSLFMT_FORMATTER_TEST_CONSTEVAL bool testParseFormat(
585 bsl::string *message,
586 bool alsoTestOracle,
588
589 /// Verify that the specified `fmt` has a valid structure and, if so, parse
590 /// it using a `bslfmt::formatter` specialization for the (template
591 /// parameter) `t_TYPE`. If the specified `alsoTestOracle` is `true`, also
592 /// parse the `fmt` using a standard library implementation. Return `true`
593 /// if the `fmt` is valid and the exception is *NOT* thrown during the parsing, and return `false` otherwise.
594 ///
595 /// \note Note that `fmt` can be
596 /// determined at runtime.
597 template <class t_TYPE>
598 static bool testParseVFormat(bsl::string *message,
599 bool alsoTestOracle,
601};
602
603/// This is a specialization of `FormatterTestUtil` template for `wchar_t`.
604template <>
605struct FormatterTestUtil<wchar_t> {
606 public:
607 // CLASS METHODS
608
609 /// Compare the specified `expectedResult` with the result of formatting
610 /// the specified `value` with the specified `fmt` obtained using a
611 /// `bslfmt::formatter` specialization for the (template parameter)
612 /// `t_TYPE`. If the specified `alsoTestOracle` is `true`, also compare
613 /// the `expectedResult` with the result of formatting obtained using a
614 /// standard library implementation. Optionally specify `arg`, `arg1` and
615 /// `arg2` to be passed to the formatter as additional arguments. Return
616 /// `true` if these strings are equal, otherwise store a description of the
617 /// error in the specified output `message` and return `false`.
618 ///
619 /// \note Note that `fmt` is required to be a constant expression, known at compile time.
620 template <class t_TYPE>
621 static bool testEvaluateFormat(
622 bsl::string *message,
623 bsl::basic_string_view<wchar_t> expectedResult,
624 bool alsoTestOracle,
627
628 template <class t_TYPE, class t_ARG>
629 static bool testEvaluateFormat(
630 bsl::string *message,
631 bsl::basic_string_view<wchar_t> expectedResult,
632 bool alsoTestOracle,
636
637 template <class t_TYPE, class t_ARG_1, class t_ARG_2>
638 static bool testEvaluateFormat(
639 bsl::string *message,
640 bsl::basic_string_view<wchar_t> expectedResult,
641 bool alsoTestOracle,
646
647 /// Compare the specified `expectedResult` with the result of formatting
648 /// the specified `value` with the specified `fmt` obtained using a
649 /// `bslfmt::formatter` specialization for the (template parameter)
650 /// `t_TYPE`. If the specified `alsoTestOracle` is `true`, also compare
651 /// the `expectedResult` with the result of formatting obtained using a
652 /// standard library implementation. Optionally specify `arg`, `arg1` and
653 /// `arg2` to be passed to the formatter as additional arguments. Return
654 /// `true` if these strings are equal, otherwise store a description of the
655 /// error in the specified output `message` and return `false`.
656 ///
657 /// \note Note that `fmt` can be determined at runtime.
658 template <class t_TYPE>
659 static bool testEvaluateVFormat(
660 bsl::string *message,
661 bsl::basic_string_view<wchar_t> expectedResult,
662 bool alsoTestOracle,
665
666 template <class t_TYPE, class t_ARG>
667 static bool testEvaluateVFormat(
668 bsl::string *message,
669 bsl::basic_string_view<wchar_t> expectedResult,
670 bool alsoTestOracle,
674
675 template <class t_TYPE, class t_ARG_1, class t_ARG_2>
676 static bool testEvaluateVFormat(
677 bsl::string *message,
678 bsl::basic_string_view<wchar_t> expectedResult,
679 bool alsoTestOracle,
684
685 /// Verify that the specified `fmt` has a valid structure and, if so, parse
686 /// it using a `bslfmt::formatter` specialization for the (template
687 /// parameter) `t_TYPE`. If the specified `alsoTestOracle` is `true`, also
688 /// parse `fmt` using a standard library implementation. Return `true` if
689 /// `fmt` is valid and the exception *IS* thrown during the parsing, and
690 /// return `false` otherwise.
691 template <class t_TYPE>
692 static bool testParseFailure(
693 bsl::string *message,
694 bool alsoTestOracle,
696
697 /// Verify that the specified `fmt` has a valid structure and, if so, parse
698 /// it using a `bslfmt::formatter` specialization for the (template
699 /// parameter) `t_TYPE`. If the specified `alsoTestOracle` is `true`, also
700 /// parse the `fmt` using a standard library implementation. Return `true`
701 /// if the `fmt` is valid and the exception is *NOT* thrown during the parsing, and return `false` otherwise.
702 ///
703 /// \note Note that the `fmt` is required
704 /// to be a compile time constant expression.
705 template <class t_TYPE>
706 static BSLFMT_FORMATTER_TEST_CONSTEVAL bool testParseFormat(
707 bsl::string *message,
708 bool alsoTestOracle,
710
711 /// Verify that the specified `fmt` has a valid structure and, if so, parse
712 /// it using a `bslfmt::formatter` specialization for the (template
713 /// parameter) `t_TYPE`. If the specified `alsoTestOracle` is `true`, also
714 /// parse `fmt` using a standard library implementation. Return `true` if
715 /// `fmt` is valid and the exception is *NOT* thrown during the parsing, and return `false` otherwise.
716 ///
717 /// \note Note that `fmt` is **NOT** required to
718 /// be a compile time constant expression.
719 template <class t_TYPE>
720 static bool testParseVFormat(
721 bsl::string *message,
722 bool alsoTestOracle,
724};
725
726// ============================================================================
727// INLINE DEFINITIONS
728// ============================================================================
729
730#if defined(BSLS_LIBRARYFEATURES_HAS_CPP20_FORMAT)
731
732 // ------------------------------
733 // class FormatterTestUtil_Oracle
734 // ------------------------------
735
736template <class t_TYPE, class... t_ARGS>
737void FormatterTestUtil_Oracle<char>::evaluateOracle(
740 t_TYPE&& value,
741 t_ARGS&&... args)
742{
743 *result = std::vformat(fmtStr, std::make_format_args(value, args...));
744}
745
746template <class t_TYPE, class... t_ARGS>
747void FormatterTestUtil_Oracle<wchar_t>::evaluateOracle(
750 t_TYPE&& value,
751 t_ARGS&&... args)
752{
753 *result = std::vformat(fmtStr, std::make_wformat_args(value, args...));
754}
755
756#endif
757
758 // ----------------------------
759 // class FormatterTestUtil_Impl
760 // ----------------------------
761
762// PRIVATE CLASS METHODS
763template <class t_CHAR>
764template <class t_TYPE>
765bool FormatterTestUtil_Impl<t_CHAR>::evaluateBslfmtResult(
766 bsl::string *message,
769 const t_TYPE& value,
770 bslmf::MovableRef<MockFormatContext<t_CHAR> > mockContext)
771{
772 MockParseContext<t_CHAR> mpc(fmtStr, 3);
773
774 if (fmtStr.size() == 0) {
775 if (message)
776 *message = "Empty format string";
777 return false; // RETURN
778 }
779
780 if (fmtStr.front() != '{') {
781 if (message)
782 *message = "Opening brace missing";
783 return false; // RETURN
784 }
785 fmtStr.remove_prefix(1);
786 mpc.advance_to(mpc.begin() + 1);
787
788 if (fmtStr.size() == 0) {
789 if (message)
790 *message = "Format string too short";
791 return false; // RETURN
792 }
793
794 if (fmtStr.front() != '0' && fmtStr.front() != ':' &&
795 fmtStr.front() != '}') {
796 if (message)
797 *message = "For testing, value must be arg 0 if specified";
798 return false; // RETURN
799 }
800
801 if (fmtStr.front() == '0') {
802 mpc.check_arg_id(0);
803 fmtStr.remove_prefix(1);
804 mpc.advance_to(mpc.begin() + 1);
805 if (fmtStr.size() == 0) {
806 if (message)
807 *message = "Format string too short";
808 return false; // RETURN
809 }
810 if (fmtStr.front() != ':' && fmtStr.front() != '}') {
811 if (message)
812 *message = "Missing ':' separator";
813 return false; // RETURN
814 }
815 }
816 else {
817 (void) mpc.next_arg_id();
818 }
819
820 if (fmtStr.front() == ':') {
821 fmtStr.remove_prefix(1);
822 mpc.advance_to(mpc.begin() + 1);
823 }
824
825 if (fmtStr.size() == 0) {
826 if (message)
827 *message = "Format string too short";
828 return false; // RETURN
829 }
830
831 try {
833
834 mpc.advance_to(formatter.parse(mpc));
835
836 if (mpc.begin() != mpc.end() &&
837 (*mpc.begin() != '}' || mpc.begin() + 1 != mpc.end())) {
838 if (message)
839 *message = "Spec string has extra characters";
840 return false; // RETURN
841 }
842
843 MockFormatContext<t_CHAR>& mockFormatContext = mockContext;
844 mockFormatContext.advance_to(
845 bsl::as_const(formatter).format(value, mockFormatContext));
846
847 *result = bsl::basic_string<t_CHAR>(mockFormatContext.finalString());
848 }
849 catch (const bsl::format_error& e) {
850 if (message) {
851 *message = "Exception bsl::format_error: ";
852 *message += e.what();
853 }
854 return false; // RETURN
855 }
856
857 return true;
858}
859
860template <class t_CHAR>
861template <class t_TYPE>
862bool FormatterTestUtil_Impl<t_CHAR>::testEvaluateVFormatBslfmtImpl(
863 bsl::string *message,
864 bsl::basic_string_view<t_CHAR> expectedResult,
867 bslmf::MovableRef<MockFormatContext<t_CHAR> > mockFormatContext)
868{
869 bsl::basic_string<t_CHAR> bslfmtResult;
870
871 bool rv = evaluateBslfmtResult(
872 message,
873 &bslfmtResult,
874 fmtStr,
875 value,
877 bslmf::MovableRefUtil::access(mockFormatContext)));
878
879 if (!rv)
880 return false; // RETURN
881
882 if (expectedResult != bslfmtResult) {
883 if (message) {
884 *message = "bslfmt result does not match: Format: \"";
885 *message += toNarrow(fmtStr);
886 *message += "\", result: \"";
887 *message += toNarrow(bslfmtResult);
888 *message += "\" != EXPECTED: \"";
889 *message += toNarrow(expectedResult);
890 *message += "\"";
891 }
892 return false; // RETURN
893 }
894
895 return true;
896}
897
898#if defined(BSLS_LIBRARYFEATURES_HAS_CPP20_FORMAT)
899template <class t_CHAR>
900template <class t_TYPE, class... t_ARGS>
901bool FormatterTestUtil_Impl<t_CHAR>::testEvaluateVFormatStdImpl(
902 bsl::string *message,
903 bsl::basic_string_view<t_CHAR> expectedResult,
905 t_TYPE&& value,
906 t_ARGS&&... args)
907{
909 try {
910 FormatterTestUtil_Oracle<t_CHAR>::evaluateOracle(
911 &stdResult,
912 fmtStr,
913 std::forward<t_TYPE>(value),
914 std::forward<t_ARGS>(args)...);
915 }
916 catch (const std::format_error& e) {
917 if (message) {
918 *message = "Exception std::format_error: ";
919 *message += e.what();
920 }
921 return false; // RETURN
922 }
923
924 if (expectedResult != stdResult) {
925 if (message) {
926 *message = "oracle result does not match: Format: \"";
927 *message += toNarrow(fmtStr);
928 *message += "\", Oracle: \"";
929 *message += toNarrow(stdResult);
930 *message += "\" != EXPECTED: \"";
931 *message += toNarrow(expectedResult);
932 *message += "\"";
933 }
934 return false; // RETURN
935 }
936
937 return true;
938}
939#endif
940
941template <class t_CHAR>
942template <class t_TYPE>
944FormatterTestUtil_Impl<t_CHAR>::testParseFormatImpl(
945 bsl::string *message,
946 bool alsoTestOracle,
948 bool expectedToFail)
949{
950 MockParseContext<t_CHAR> mpc(fmtStr, 3);
951
952 if (fmtStr.size() == 0) {
953 if (message)
954 *message = "Empty format string";
955 return false; // RETURN
956 }
957
958 if (fmtStr.front() != '{') {
959 if (message)
960 *message = "Opening brace missing";
961 return false; // RETURN
962 }
963 fmtStr.remove_prefix(1);
964 mpc.advance_to(mpc.begin() + 1);
965
966 if (fmtStr.size() == 0) {
967 if (message)
968 *message = "Format string too short";
969 return false; // RETURN
970 }
971
972 if (fmtStr.front() != '0' && fmtStr.front() != ':' &&
973 fmtStr.front() != '}') {
974 if (message)
975 *message = "For testing, value must be arg 0 if specified";
976 return false; // RETURN
977 }
978
979 bool haveArgIds;
980
981 if (fmtStr.front() == '0') {
982 mpc.check_arg_id(0);
983 fmtStr.remove_prefix(1);
984 mpc.advance_to(mpc.begin() + 1);
985 if (fmtStr.size() == 0) {
986 if (message)
987 *message = "Format string too short";
988 return false; // RETURN
989 }
990 if (fmtStr.front() != ':' && fmtStr.front() != '}') {
991 if (message)
992 *message = "Missing ':' separator";
993 return false; // RETURN
994 }
995 haveArgIds = true;
996 }
997 else {
998 (void)mpc.next_arg_id();
999 haveArgIds = false;
1000 }
1001
1002 if (fmtStr.front() == ':') {
1003 fmtStr.remove_prefix(1);
1004 mpc.advance_to(mpc.begin() + 1);
1005 }
1006
1007 if (fmtStr.size() == 0) {
1008 if (message)
1009 *message = "Format string too short";
1010 return false; // RETURN
1011 }
1012
1014
1015 if (expectedToFail) {
1016 try {
1017 mpc.advance_to(bslFormatter.parse(mpc));
1018
1019 if (message)
1020 *message = "bslfmt parsing failed to fail";
1021 return false; // RETURN
1022 }
1023 catch (const bsl::format_error&) {
1024 }
1025 }
1026 else {
1027 try {
1028 mpc.advance_to(bslFormatter.parse(mpc));
1029 }
1030 catch (const bsl::format_error&) {
1031 if (message)
1032 *message = "bslfmt parsing failed";
1033 return false; // RETURN
1034 }
1035 }
1036
1037#if defined(BSLS_LIBRARYFEATURES_HAS_CPP20_FORMAT)
1038
1039 // We cannot do a consteval parse test on the MSVC standard library due to
1040 // the way the MSVC library implements nested parameters.
1041# if defined(BSLS_PLATFORM_CMP_MSVC)
1042 if (std::is_constant_evaluated()) {
1043 alsoTestOracle = false;
1044 }
1045# endif
1046
1047 if (alsoTestOracle) {
1048 // TODO: this interface changes in C++26 so we will need to modify this
1049 // code accordingly then.
1050 std::basic_format_parse_context<t_CHAR> spc(fmtStr, 3);
1051
1052 if (haveArgIds) {
1053 spc.check_arg_id(0);
1054 }
1055 else {
1056 (void)spc.next_arg_id();
1057 }
1058 std::formatter<typename bsl::decay<t_TYPE>::type, t_CHAR> stdFormatter;
1059
1060 if (expectedToFail) {
1061 try {
1062 spc.advance_to(stdFormatter.parse(spc));
1063
1064 if (message)
1065 *message = "std parsing failed to fail";
1066 return false; // RETURN
1067 }
1068 catch (const bsl::format_error&) {
1069 }
1070 }
1071 else {
1072 try {
1073 spc.advance_to(stdFormatter.parse(spc));
1074 }
1075 catch (const bsl::format_error&) {
1076 if (message)
1077 *message = "std parsing failed";
1078 return false; // RETURN
1079 }
1080 }
1081 }
1082#else
1083 (void)alsoTestOracle;
1084 (void)haveArgIds;
1085#endif
1086
1087 return true;
1088}
1089
1090template <class t_CHAR>
1092FormatterTestUtil_Impl<t_CHAR>::toNarrow(const bsl::string_view& string)
1093{
1094 return bsl::string(string.data(), string.size());
1095}
1096
1097template <class t_CHAR>
1099FormatterTestUtil_Impl<t_CHAR>::toNarrow(const bsl::wstring_view& string)
1100{
1101 bsl::string rv;
1102 const std::locale loc;
1103
1105 for (Cit i = string.begin(); i != string.end(); ++i) {
1106 rv += std::use_facet<std::ctype<wchar_t> >(loc).narrow(*i, '?');
1107 }
1108 return rv;
1109}
1110
1111// CLASS METHODS
1112template <class t_CHAR>
1113template <class t_TYPE>
1115 bsl::string *message,
1116 bsl::basic_string_view<t_CHAR> expectedResult,
1117 bool alsoTestOracle,
1120{
1121 bsl::basic_string_view<t_CHAR> formatStringView =
1123
1124 return testEvaluateVFormat(message,
1125 expectedResult,
1126 alsoTestOracle,
1127 formatStringView,
1128 BSLS_COMPILERFEATURES_FORWARD(t_TYPE, value));
1129}
1130
1131template <class t_CHAR>
1132template <class t_TYPE, class t_ARG>
1134 bsl::string *message,
1135 bsl::basic_string_view<t_CHAR> expectedResult,
1136 bool alsoTestOracle,
1140{
1141 bsl::basic_string_view<t_CHAR> formatStringView =
1143
1144 return testEvaluateVFormat(message,
1145 expectedResult,
1146 alsoTestOracle,
1147 formatStringView,
1148 BSLS_COMPILERFEATURES_FORWARD(t_TYPE, value),
1149 BSLS_COMPILERFEATURES_FORWARD(t_ARG, arg));
1150}
1151
1152template <class t_CHAR>
1153template <class t_TYPE, class t_ARG_1, class t_ARG_2>
1155 bsl::string *message,
1156 bsl::basic_string_view<t_CHAR> expectedResult,
1157 bool alsoTestOracle,
1162{
1163 bsl::basic_string_view<t_CHAR> formatStringView =
1165
1166 return testEvaluateVFormat(message,
1167 expectedResult,
1168 alsoTestOracle,
1169 formatStringView,
1170 BSLS_COMPILERFEATURES_FORWARD(t_TYPE, value),
1171 BSLS_COMPILERFEATURES_FORWARD(t_ARG_1, arg1),
1172 BSLS_COMPILERFEATURES_FORWARD(t_ARG_2, arg2));
1173}
1174
1175template <class t_CHAR>
1176template <class t_TYPE>
1178 bsl::string *message,
1179 bsl::basic_string_view<t_CHAR> expectedResult,
1180 bool alsoTestOracle,
1183{
1184 MockFormatContext<t_CHAR> mockFormatContext(value);
1185 bool rv = testEvaluateVFormatBslfmtImpl(
1186 message,
1187 expectedResult,
1188 fmtStr,
1189 BSLS_COMPILERFEATURES_FORWARD(t_TYPE, value),
1190 bslmf::MovableRefUtil::move(mockFormatContext));
1191
1192 if (!rv) {
1193 return false; // RETURN
1194 }
1195
1196#if defined(BSLS_LIBRARYFEATURES_HAS_CPP20_FORMAT)
1197 if (alsoTestOracle) {
1198 rv = testEvaluateVFormatStdImpl(message,
1199 expectedResult,
1200 fmtStr,
1201 std::forward<t_TYPE>(value));
1202 }
1203#else
1204 (void) alsoTestOracle;
1205#endif
1206
1207 return rv;
1208}
1209
1210template <class t_CHAR>
1211template <class t_TYPE, class t_ARG>
1213 bsl::string *message,
1214 bsl::basic_string_view<t_CHAR> expectedResult,
1215 bool alsoTestOracle,
1219{
1220 MockFormatContext<t_CHAR> mockFormatContext(value, arg);
1221 bool rv = testEvaluateVFormatBslfmtImpl(
1222 message,
1223 expectedResult,
1224 fmtStr,
1225 BSLS_COMPILERFEATURES_FORWARD(t_TYPE, value),
1226 bslmf::MovableRefUtil::move(mockFormatContext));
1227
1228 if (!rv) {
1229 return false; // RETURN
1230 }
1231
1232#if defined(BSLS_LIBRARYFEATURES_HAS_CPP20_FORMAT)
1233 if (alsoTestOracle) {
1234 rv = testEvaluateVFormatStdImpl(message,
1235 expectedResult,
1236 fmtStr,
1237 std::forward<t_TYPE>(value),
1238 std::forward<t_ARG>(arg));
1239 }
1240#else
1241 (void) alsoTestOracle;
1242#endif
1243
1244 return rv;
1245}
1246
1247template <class t_CHAR>
1248template <class t_TYPE, class t_ARG_1, class t_ARG_2>
1250 bsl::string *message,
1251 bsl::basic_string_view<t_CHAR> expectedResult,
1252 bool alsoTestOracle,
1257{
1258 MockFormatContext<t_CHAR> mockFormatContext(value, arg1, arg2);
1259 bool rv = testEvaluateVFormatBslfmtImpl(
1260 message,
1261 expectedResult,
1262 fmtStr,
1263 BSLS_COMPILERFEATURES_FORWARD(t_TYPE, value),
1264 bslmf::MovableRefUtil::move(mockFormatContext));
1265
1266 if (!rv) {
1267 return false; // RETURN
1268 }
1269
1270#if defined(BSLS_LIBRARYFEATURES_HAS_CPP20_FORMAT)
1271 if (alsoTestOracle) {
1272 rv = testEvaluateVFormatStdImpl(message,
1273 expectedResult,
1274 fmtStr,
1275 std::forward<t_TYPE>(value),
1276 std::forward<t_ARG_1>(arg1),
1277 std::forward<t_ARG_2>(arg2));
1278 }
1279#else
1280 (void) alsoTestOracle;
1281#endif
1282
1283 return rv;
1284}
1285
1286template <class t_CHAR>
1287template <class t_TYPE>
1289 bsl::string *message,
1290 bool alsoTestOracle,
1292{
1293 return testParseFormatImpl<t_TYPE>(message, alsoTestOracle, fmtStr, true);
1294}
1295
1296template <class t_CHAR>
1297template <class t_TYPE>
1300 bsl::string *message,
1301 bool alsoTestOracle,
1303{
1304 bsl::basic_string_view<t_CHAR> formatStringView =
1306
1307 return testParseFormatImpl<t_TYPE>(message,
1308 alsoTestOracle,
1309 formatStringView,
1310 false);
1311}
1312
1313template <class t_CHAR>
1314template <class t_TYPE>
1316 bsl::string *message,
1317 bool alsoTestOracle,
1319{
1320 return testParseFormatImpl<t_TYPE>(message, alsoTestOracle, fmtStr, false);
1321}
1322
1323 // -----------------------
1324 // class FormatterTestUtil
1325 // -----------------------
1326
1327// CLASS METHODS
1328template <class t_TYPE>
1330 bsl::string *message,
1331 bsl::basic_string_view<char> expectedResult,
1332 bool alsoTestOracle,
1335{
1337 message,
1338 expectedResult,
1339 alsoTestOracle,
1340 fmt,
1341 BSLS_COMPILERFEATURES_FORWARD(t_TYPE, value));
1342}
1343
1344template <class t_TYPE, class t_ARG>
1346 bsl::string *message,
1347 bsl::basic_string_view<char> expectedResult,
1348 bool alsoTestOracle,
1352{
1354 message,
1355 expectedResult,
1356 alsoTestOracle,
1357 fmt,
1358 BSLS_COMPILERFEATURES_FORWARD(t_TYPE, value),
1359 BSLS_COMPILERFEATURES_FORWARD(t_ARG, arg));
1360}
1361
1362template <class t_TYPE, class t_ARG_1, class t_ARG_2>
1364 bsl::string *message,
1365 bsl::basic_string_view<char> expectedResult,
1366 bool alsoTestOracle,
1371{
1373 message,
1374 expectedResult,
1375 alsoTestOracle,
1376 fmt,
1377 BSLS_COMPILERFEATURES_FORWARD(t_TYPE, value),
1378 BSLS_COMPILERFEATURES_FORWARD(t_ARG_1, arg1),
1379 BSLS_COMPILERFEATURES_FORWARD(t_ARG_2, arg2));
1380}
1381
1382template <class t_TYPE>
1384 bsl::string *message,
1385 bsl::basic_string_view<char> expectedResult,
1386 bool alsoTestOracle,
1389{
1391 message,
1392 expectedResult,
1393 alsoTestOracle,
1394 fmt,
1395 BSLS_COMPILERFEATURES_FORWARD(t_TYPE, value));
1396}
1397
1398template <class t_TYPE, class t_ARG>
1400 bsl::string *message,
1401 bsl::basic_string_view<char> expectedResult,
1402 bool alsoTestOracle,
1406{
1408 message,
1409 expectedResult,
1410 alsoTestOracle,
1411 fmt,
1412 BSLS_COMPILERFEATURES_FORWARD(t_TYPE, value),
1413 BSLS_COMPILERFEATURES_FORWARD(t_ARG, arg));
1414}
1415
1416template <class t_TYPE, class t_ARG_1, class t_ARG_2>
1418 bsl::string *message,
1419 bsl::basic_string_view<char> expectedResult,
1420 bool alsoTestOracle,
1425{
1427 message,
1428 expectedResult,
1429 alsoTestOracle,
1430 fmt,
1431 BSLS_COMPILERFEATURES_FORWARD(t_TYPE, value),
1432 BSLS_COMPILERFEATURES_FORWARD(t_ARG_1, arg1),
1433 BSLS_COMPILERFEATURES_FORWARD(t_ARG_2, arg2));
1434}
1435
1436template <class t_TYPE>
1438 bsl::string *message,
1439 bool alsoTestOracle,
1441{
1443 message,
1444 alsoTestOracle,
1445 fmt);
1446}
1447
1448template <class t_TYPE>
1451 bsl::string *message,
1452 bool alsoTestOracle,
1454{
1456 message,
1457 alsoTestOracle,
1458 fmt);
1459}
1460
1461template <class t_TYPE>
1463 bsl::string *message,
1464 bool alsoTestOracle,
1466{
1468 message,
1469 alsoTestOracle,
1470 fmt);
1471}
1472
1473template <class t_TYPE>
1475 bsl::string *message,
1476 bsl::basic_string_view<wchar_t> expectedResult,
1477 bool alsoTestOracle,
1479 BSLS_COMPILERFEATURES_FORWARD_REF(t_TYPE) dummyValue)
1480{
1482 message,
1483 expectedResult,
1484 alsoTestOracle,
1485 fmt,
1486 BSLS_COMPILERFEATURES_FORWARD(t_TYPE, dummyValue));
1487}
1488
1489template <class t_TYPE, class t_ARG>
1491 bsl::string *message,
1492 bsl::basic_string_view<wchar_t> expectedResult,
1493 bool alsoTestOracle,
1495 BSLS_COMPILERFEATURES_FORWARD_REF(t_TYPE) dummyValue,
1497{
1499 message,
1500 expectedResult,
1501 alsoTestOracle,
1502 fmt,
1503 BSLS_COMPILERFEATURES_FORWARD(t_TYPE, dummyValue),
1504 BSLS_COMPILERFEATURES_FORWARD(t_ARG, arg));
1505}
1506
1507template <class t_TYPE, class t_ARG_1, class t_ARG_2>
1509 bsl::string *message,
1510 bsl::basic_string_view<wchar_t> expectedResult,
1511 bool alsoTestOracle,
1513 BSLS_COMPILERFEATURES_FORWARD_REF(t_TYPE) dummyValue,
1516{
1518 message,
1519 expectedResult,
1520 alsoTestOracle,
1521 fmt,
1522 BSLS_COMPILERFEATURES_FORWARD(t_TYPE, dummyValue),
1523 BSLS_COMPILERFEATURES_FORWARD(t_ARG_1, arg1),
1524 BSLS_COMPILERFEATURES_FORWARD(t_ARG_2, arg2));
1525}
1526
1527template <class t_TYPE>
1529 bsl::string *message,
1530 bsl::basic_string_view<wchar_t> expectedResult,
1531 bool alsoTestOracle,
1533 BSLS_COMPILERFEATURES_FORWARD_REF(t_TYPE) dummyValue)
1534{
1536 message,
1537 expectedResult,
1538 alsoTestOracle,
1539 fmt,
1540 BSLS_COMPILERFEATURES_FORWARD(t_TYPE, dummyValue));
1541}
1542
1543template <class t_TYPE, class t_ARG>
1545 bsl::string *message,
1546 bsl::basic_string_view<wchar_t> expectedResult,
1547 bool alsoTestOracle,
1549 BSLS_COMPILERFEATURES_FORWARD_REF(t_TYPE) dummyValue,
1551{
1553 message,
1554 expectedResult,
1555 alsoTestOracle,
1556 fmt,
1557 BSLS_COMPILERFEATURES_FORWARD(t_TYPE, dummyValue),
1558 BSLS_COMPILERFEATURES_FORWARD(t_ARG, arg));
1559}
1560
1561template <class t_TYPE, class t_ARG_1, class t_ARG_2>
1563 bsl::string *message,
1564 bsl::basic_string_view<wchar_t> expectedResult,
1565 bool alsoTestOracle,
1567 BSLS_COMPILERFEATURES_FORWARD_REF(t_TYPE) dummyValue,
1570{
1572 message,
1573 expectedResult,
1574 alsoTestOracle,
1575 fmt,
1576 BSLS_COMPILERFEATURES_FORWARD(t_TYPE, dummyValue),
1577 BSLS_COMPILERFEATURES_FORWARD(t_ARG_1, arg1),
1578 BSLS_COMPILERFEATURES_FORWARD(t_ARG_2, arg2));
1579}
1580
1581template <class t_TYPE>
1583 bsl::string *message,
1584 bool alsoTestOracle,
1586{
1588 message,
1589 alsoTestOracle,
1590 fmt);
1591}
1592
1593template <class t_TYPE>
1596 bsl::string *message,
1597 bool alsoTestOracle,
1599{
1601 message,
1602 alsoTestOracle,
1603 fmt);
1604}
1605
1606template <class t_TYPE>
1608 bsl::string *message,
1609 bool alsoTestOracle,
1611{
1613 message,
1614 alsoTestOracle,
1615 fmt);
1616}
1617
1618} // close package namespace
1619
1620
1621#undef BSLFMT_FORMATTER_TEST_UTIL_FORMAT_STRING
1622#undef BSLFMT_FORMATTER_TEST_UTIL_FORMAT_STRING_ONE_ARG
1623#undef BSLFMT_FORMATTER_TEST_UTIL_FORMAT_STRING_TWO_ARGS
1624#undef BSLFMT_FORMATTER_TEST_UTIL_WFORMAT_STRING
1625#undef BSLFMT_FORMATTER_TEST_UTIL_WFORMAT_STRING_ONE_ARG
1626#undef BSLFMT_FORMATTER_TEST_UTIL_WFORMAT_STRING_TWO_ARGS
1627#undef BSLFMT_FORMATTER_TEST_UTIL_BASIC_FORMAT_STRING
1628#undef BSLFMT_FORMATTER_TEST_UTIL_BASIC_FORMAT_STRING_ONE_ARG
1629#undef BSLFMT_FORMATTER_TEST_UTIL_BASIC_FORMAT_STRING_TWO_ARGS
1630#undef BSLFMT_FORMATTER_TEST_UTIL_FORMAT_STRING_P
1631#undef BSLFMT_FORMATTER_TEST_UTIL_WFORMAT_STRING_P
1632#undef BSLFMT_FORMATTER_TEST_UTIL_BASIC_FORMAT_STRING_P
1633#undef BSLFMT_FORMATTER_TEST_UTIL_BASIC_FORMAT_STRING_GETTER
1634#undef BSLFMT_FORMATTER_TEST_CONSTEVAL
1635
1636#endif // INCLUDED_BSLFMT_FORMATTERTESTUTIL
1637
1638// ----------------------------------------------------------------------------
1639// Copyright 2023 Bloomberg Finance L.P.
1640//
1641// Licensed under the Apache License, Version 2.0 (the "License");
1642// you may not use this file except in compliance with the License.
1643// You may obtain a copy of the License at
1644//
1645// http://www.apache.org/licenses/LICENSE-2.0
1646//
1647// Unless required by applicable law or agreed to in writing, software
1648// distributed under the License is distributed on an "AS IS" BASIS,
1649// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1650// See the License for the specific language governing permissions and
1651// limitations under the License.
1652// ----------------------------- END-OF-FILE ----------------------------------
1653
1654/** @} */
1655/** @} */
1656/** @} */
Definition bslstl_stringview.h:471
BSLS_KEYWORD_CONSTEXPR size_type size() const BSLS_KEYWORD_NOEXCEPT
Return the length of this view.
Definition bslstl_stringview.h:1904
BSLS_KEYWORD_CONSTEXPR_CPP14 const_reference front() const
Definition bslstl_stringview.h:1966
const value_type * const_iterator
Definition bslstl_stringview.h:481
BSLS_KEYWORD_CONSTEXPR_CPP14 void remove_prefix(size_type numChars)
Definition bslstl_stringview.h:1800
Definition bslstl_string.h:1252
Definition bslfmt_mockformatcontext.h:206
Definition bslmf_movableref.h:752
#define BSLFMT_FORMATTER_TEST_UTIL_FORMAT_STRING_P
Definition bslfmt_formattertestutil.h:207
#define BSLFMT_FORMATTER_TEST_UTIL_WFORMAT_STRING_TWO_ARGS
Definition bslfmt_formattertestutil.h:199
#define BSLFMT_FORMATTER_TEST_UTIL_WFORMAT_STRING_ONE_ARG
Definition bslfmt_formattertestutil.h:197
#define BSLFMT_FORMATTER_TEST_UTIL_WFORMAT_STRING
Definition bslfmt_formattertestutil.h:195
#define BSLFMT_FORMATTER_TEST_UTIL_BASIC_FORMAT_STRING_ONE_ARG
Definition bslfmt_formattertestutil.h:203
#define BSLFMT_FORMATTER_TEST_UTIL_FORMAT_STRING_ONE_ARG
Definition bslfmt_formattertestutil.h:191
#define BSLFMT_FORMATTER_TEST_CONSTEVAL
Definition bslfmt_formattertestutil.h:158
#define BSLFMT_FORMATTER_TEST_UTIL_BASIC_FORMAT_STRING_TWO_ARGS
Definition bslfmt_formattertestutil.h:205
#define BSLFMT_FORMATTER_TEST_UTIL_WFORMAT_STRING_P
Definition bslfmt_formattertestutil.h:209
#define BSLFMT_FORMATTER_TEST_UTIL_FORMAT_STRING_TWO_ARGS
Definition bslfmt_formattertestutil.h:193
#define BSLFMT_FORMATTER_TEST_UTIL_BASIC_FORMAT_STRING
Definition bslfmt_formattertestutil.h:201
#define BSLFMT_FORMATTER_TEST_UTIL_FORMAT_STRING
Definition bslfmt_formattertestutil.h:189
#define BSLFMT_FORMATTER_TEST_UTIL_BASIC_FORMAT_STRING_P
Definition bslfmt_formattertestutil.h:211
#define BSLFMT_FORMATTER_TEST_UTIL_BASIC_FORMAT_STRING_GETTER(ARG)
Definition bslfmt_formattertestutil.h:213
#define BSLS_COMPILERFEATURES_FORWARD_REF(T)
Definition bsls_compilerfeatures.h:2343
#define BSLS_COMPILERFEATURES_FORWARD(T, V)
Definition bsls_compilerfeatures.h:2349
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
#define BSLS_KEYWORD_CONSTEXPR_CPP20
Definition bsls_keyword.h:645
bsl::size_t size(const TYPE &array)
Return the number of elements in the specified array.
T::iterator begin(T &container)
Definition bslstl_iterator.h:1593
basic_string< char > string
Definition bslstl_string.h:844
BSLS_KEYWORD_CONSTEXPR CONTAINER::value_type * data(CONTAINER &container)
Definition bslstl_iterator.h:1325
BSLS_KEYWORD_CONSTEXPR bsl::add_const< TYPE >::type & as_const(TYPE &t) BSLS_KEYWORD_NOEXCEPT
Return a reference offering non-modifiable access to the specified t.
Definition bslstl_utility.h:129
Definition bslfmt_enablestreamedformatter.h:130
Definition bslfmt_formatterbase.h:426
Definition bslfmt_formattertestutil.h:285
static bool testEvaluateFormat(bsl::string *message, bsl::basic_string_view< t_CHAR > expectedResult, bool alsoTestOracle, BSLFMT_FORMATTER_TEST_UTIL_BASIC_FORMAT_STRING fmtStr, BSLS_COMPILERFEATURES_FORWARD_REF(t_TYPE) value)
Definition bslfmt_formattertestutil.h:1114
static bool testParseVFormat(bsl::string *message, bool alsoTestOracle, bsl::basic_string_view< t_CHAR > fmtStr)
Definition bslfmt_formattertestutil.h:1315
static BSLS_KEYWORD_CONSTEXPR_CPP20 bool testParseFormat(bsl::string *message, bool alsoTestOracle, BSLFMT_FORMATTER_TEST_UTIL_BASIC_FORMAT_STRING_P fmtStr)
Definition bslfmt_formattertestutil.h:1299
static bool testEvaluateVFormat(bsl::string *message, bsl::basic_string_view< t_CHAR > expectedResult, bool alsoTestOracle, bsl::basic_string_view< t_CHAR > fmtStr, BSLS_COMPILERFEATURES_FORWARD_REF(t_TYPE) value)
Definition bslfmt_formattertestutil.h:1177
static bool testParseFailure(bsl::string *message, bool alsoTestOracle, bsl::basic_string_view< t_CHAR > fmtStr)
Definition bslfmt_formattertestutil.h:1288
Definition bslfmt_formattertestutil.h:481
static MovableRef< t_TYPE > move(t_TYPE &reference) BSLS_KEYWORD_NOEXCEPT
Definition bslmf_movableref.h:1067
static t_TYPE & access(t_TYPE &ref) BSLS_KEYWORD_NOEXCEPT
Definition bslmf_movableref.h:1039