BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bslfmt_testspecificationgenerator.h
Go to the documentation of this file.
1/// @file bslfmt_testspecificationgenerator.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslfmt_testspecificationgenerator.h -*-C++-*-
8
9#ifndef INCLUDED_BSLFMT_TESTSPECIFICATIONGENERATOR
10#define INCLUDED_BSLFMT_TESTSPECIFICATIONGENERATOR
11
12#include <bsls_ident.h>
13BSLS_IDENT("$Id: $")
14
15/// @defgroup bslfmt_testspecificationgenerator bslfmt_testspecificationgenerator
16/// @brief Provide a generator for test format specifications
17/// @addtogroup bsl
18/// @{
19/// @addtogroup bslfmt
20/// @{
21/// @addtogroup bslfmt_testspecificationgenerator
22/// @{
23///
24/// <h1> Outline </h1>
25/// * <a href="#bslfmt_testspecificationgenerator-purpose"> Purpose</a>
26/// * <a href="#bslfmt_testspecificationgenerator-classes"> Classes </a>
27/// * <a href="#bslfmt_testspecificationgenerator-description"> Description </a>
28/// * <a href="#bslfmt_testspecificationgenerator-language-specification"> Language Specification </a>
29/// * <a href="#bslfmt_testspecificationgenerator-usage"> Usage </a>
30/// * <a href="#bslfmt_testspecificationgenerator-example-basic-usage-of-generator"> Example: Basic Usage of Generator </a>
31///
32/// # Purpose {#bslfmt_testspecificationgenerator-purpose}
33/// Provide a generator for test format specifications
34///
35/// # Classes {#bslfmt_testspecificationgenerator-classes}
36///
37/// - bslfmt::TestSpecificationGenerator: format specification generator
38///
39/// # Description {#bslfmt_testspecificationgenerator-description}
40/// This component provides a class that generates test
41/// specifications containing all possible combinations of standard options to
42/// format according to the given instructions. The generator is a state
43/// machine, each state of which corresponds to a separate specification.
44///
45/// The set of options can be configured using a special language:
46///
47/// ## Language Specification {#bslfmt_testspecificationgenerator-language-specification}
48///
49///
50/// 'V' - flag indicating if argument id must be present in format
51/// specification. The generator substitutes only the preset zero index
52/// (i.e. `0:`).
53/// 'F' - command indicating if fill characters must be added to the produced
54/// specifications. By default two preset characters are used: '*' and
55/// '=', but the user might add additional characters using
56/// `addFillCharacter` method.
57/// '^' - command indicating if alignment option must be added to the generated
58/// specifications. Three standard options are iterated through in
59/// sequence: '<', '^' and '>'.
60/// '+' - command indicating if sign option must be added to the generated
61/// specifications. Three standard options are iterated through in
62/// sequence: '+', '-' and ' '.
63/// '#' - flag indicating if alternate form option must be present in the
64/// generated specifications.
65/// '0' - flag indicating if zero option must be present in the generated
66/// specifications.
67/// 'W' - command indicating if width option must be added to the produced
68/// specifications. By default the following values are iterated through:
69/// 1, 5, 6 and 10, but the user might add additional values using
70/// `addWidth` method. This command does not add nested width values.
71/// 'P' - command indicating if precision option must be added to the produced
72/// specifications. By default the following values are iterated through:
73/// 0, 5, 6 and 10, but the user might add additional values using
74/// `addPrecision` method. This command does not add nested precision
75/// values.
76/// '{' - command indicating if nested width option must be added to the
77/// produced specifications. By default the following indexes are
78/// iterated through: empty, 1, and 2 (i.e. `{}`, `{1}` and `{2}`. Note
79/// that due to implementation specifics this command automatically adds
80/// non-nested width values (i.e. the default full set looks like ``(no
81/// option), `{}`, `{1}`, `{2}`, `1`, `5`, `6` and `10`.
82/// '}' - command indicating if nested precision option must be added to the
83/// produced specifications. By default the following indexes are
84/// iterated through: empty, 1, and 2 (i.e. `.{}`, `.{1}` and `.{2}`.
85/// Note that due to implementation specifics this command automatically
86/// adds non-nested precision values (i.e. the default full set looks like
87/// ``(no option), `.{}`, `.{1}`, `.{2}`, `.0`, `.5`, `.6` and `.10`.
88/// 'L' - flag indicating if locale option must be present in the generated
89/// specifications.
90/// 's' - command indicating if string presentation type (i.e. `s`) must be
91/// present in the generated specifications.
92/// 'i' - command indicating if integer presentation types must be present in
93/// the generated specifications. The following standard options are
94/// iterated through in sequence: `b`, `B`, `c`, `d`, `o`, `x` and `X`.
95/// 'c' - command indicating if character presentation types must be present in
96/// the generated specifications. The following standard options are
97/// iterated through in sequence: `b`, `B`, `c`, `d`, `o`, `x` and `X`.
98/// 'b' - command indicating if boolean presentation types must be present in
99/// the generated specifications. The following standard options are
100/// iterated through in sequence: `s`, `b`, `B`, `c`, `d`, `o`, `x` and
101/// `X`.
102/// 'f' - command indicating if floating-point presentation types must be
103/// present in the generated specifications. The following standard
104/// options are iterated through in sequence: `a`, `A`, `e`, `E`, `f`,
105/// `F`, `g` and `G`.
106/// 'p' - command indicating if pointer presentation types must be present in
107/// the generated specifications. The following standard options are
108/// iterated through in sequence: `p` and `P`.
109/// 'a' - command indicating if all presentation types must be present in the
110/// generated specifications. The following standard options are iterated
111/// through in sequence: `s`, `b`, `B`, `c`, `d`, `o`, `x`, `X`, `a`, `A`,
112/// `e`, `E`, `f`, `F`, `g`, `G`, `p` and `P`.
113///
114/// The default generator instruction is "F^+#0WP{}L". Note that adding a
115/// particular command to an instruction does not mean that the corresponding
116/// option will be present in every generated specification; a specification
117/// with the missing option will also be generated.
118///
119/// The generator produces both valid and invalid strings from the point of view
120/// of the standard, which also allows thorough testing of the processing of
121/// incorrect input data. But at the same time, it remains possible to iterate
122/// only through valid specifications using 'nextValidForParse` or
123/// 'nextValidForFormat` methods.
124///
125/// ## Usage {#bslfmt_testspecificationgenerator-usage}
126///
127///
128/// This section illustrates intended use of this component.
129///
130/// ### Example: Basic Usage of Generator {#bslfmt_testspecificationgenerator-example-basic-usage-of-generator}
131///
132///
133/// The generator is a state machine, each state of which generates a unique
134/// format specification. Depending on the set of instructions, the number of
135/// possible states also changes. For simplicity, we will take one parameter,
136/// the sign, that takes three possible values: `+`, `-` and ` `. Accordingly,
137/// we expect that the generator will go through four states, because the
138/// default state always comes first, generating an empty specification.
139/// First, let's create the generator and configure it:
140/// @code
141/// typedef bslfmt::TestSpecificationGenerator<char> Generator;
142///
143/// const Generator::Sign POSITIVE = Generator::e_SIGN_POSITIVE;
144/// const Generator::Sign NEGATIVE = Generator::e_SIGN_NEGATIVE;
145/// const Generator::Sign SPACE = Generator::e_SIGN_SPACE;
146///
147/// bslfmt::TestSpecificationGenerator<char> generator;
148/// @endcode
149/// Note that the instructions are given to the generator in a special language,
150/// a description of which can be found in the component documentation:
151/// @code
152/// generator.setup("+");
153/// @endcode
154/// You can get information about the current state of the generator using
155/// multiple accessors. Since we requested only one option, most of these
156/// accessors return false when asked about the presence of a particular option.
157/// Note that a request to get the value of an option, if this option is not
158/// present in the current state, is undefined behavior:
159/// @code
160/// assert(true == generator.isStateValidForParse());
161/// assert(true == generator.isStateValidForFormat());
162///
163/// assert(false == generator.isValueIdOptionPresent());
164/// assert(false == generator.isFillCharacterPresent());
165/// assert(false == generator.isAlignOptionPresent());
166/// assert(false == generator.isSignOptionPresent());
167/// assert(false == generator.isHashOptionPresent());
168/// assert(false == generator.isZeroOptionPresent());
169/// assert(false == generator.isWidthOptionPresent());
170/// assert(false == generator.isNestedWidthPresent());
171/// assert(false == generator.isPrecisionOptionPresent());
172/// assert(false == generator.isNestedPrecisionPresent());
173/// assert(false == generator.isLocaleOptionPresent());
174/// assert(false == generator.isTypeOptionPresent());
175/// @endcode
176/// As we have already said, the initial state of the generator generates an
177/// empty string. Therefore, even though we added the sign to the instruction,
178/// this option is not present in this state. Keep in mind that the absence of
179/// an option is always another variant when iterating through the states of the
180/// generator.
181/// For each state, the generator creates two strings: one that the
182/// `bsl::format` passes to the formatter's `parse` function, and one that can
183/// be passed to the `bsl::format` function itself:
184/// @code
185/// assert("" == generator.spec());
186/// assert("{:}" == generator.formatSpec());
187/// @endcode
188/// Then, let's move on to the next state of the generator. When the generator
189/// has iterated over all possible states, the function `next` will return
190/// `false`, but for now we expect it to return `true`:
191/// @code
192/// assert(true == generator.next());
193/// @endcode
194/// For ease of reading, we will not check all the options each time, but only
195/// those that are significant for our example:
196/// @code
197/// assert(true == generator.isStateValidForParse());
198/// assert(true == generator.isStateValidForFormat());
199/// assert(true == generator.isSignOptionPresent());
200/// assert(POSITIVE == generator.sign());
201/// assert("+" == generator.spec());
202/// assert("{:+}" == generator.formatSpec());
203/// @endcode
204/// The function `next` iterates over all possible states of the generator,
205/// including those that generate strings, the processing of which by the
206/// corresponding functions will lead to an exception being thrown. Such states
207/// can be determined using the functions `isStateValidForParse` and
208/// `isStateValidForFormat`. Another option can be to skip invalid states using
209/// the functions `nextValidForParse` and `nextValidForFormat`, respectively:
210/// @code
211/// assert(true == generator.nextValidForParse());
212/// assert(true == generator.isStateValidForParse());
213/// assert(true == generator.isStateValidForFormat());
214/// assert(true == generator.isSignOptionPresent());
215/// assert(NEGATIVE == generator.sign());
216/// assert("-" == generator.spec());
217/// assert("{:-}" == generator.formatSpec());
218///
219/// assert(true == generator.nextValidForFormat());
220/// assert(true == generator.isStateValidForParse());
221/// assert(true == generator.isStateValidForFormat());
222/// assert(true == generator.isSignOptionPresent());
223/// assert(SPACE == generator.sign());
224/// assert(" " == generator.spec());
225/// assert("{: }" == generator.formatSpec());
226/// @endcode
227/// Now, the generator is in its last state, so the `next` function should
228/// return` false`:
229/// @code
230/// assert(false == generator.next());
231/// @endcode
232/// Finally, let's make sure that the generator is back in its initial state and
233/// ready to go for the second round:
234/// @code
235/// assert("" == generator.spec());
236/// assert("{:}" == generator.formatSpec());
237/// assert(true == generator.next());
238/// @endcode
239/// @}
240/** @} */
241/** @} */
242
243/** @addtogroup bsl
244 * @{
245 */
246/** @addtogroup bslfmt
247 * @{
248 */
249/** @addtogroup bslfmt_testspecificationgenerator
250 * @{
251 */
252
253#include <bslscm_version.h>
254
256
257#include <bslma_managedptr.h>
258
259#include <bsls_assert.h>
260
261#include <bslstl_string.h>
262#include <bslstl_vector.h>
263
264
265namespace bslfmt {
266
267
268 // =======================================
269 // class TestSpecificationGenerator_Option
270 // =======================================
271
272/// This class is a base class for `TestSpecificationGenerator` option nodes,
273/// which, when compiled into a list, represent the state of the generator.
274/// The payload and the process of changing this state are programmed into
275/// specific implementations of this interface. This class contains the basic
276/// functions of adding a new link to the options chain and finding the last
277/// link in the chain.
278///
279/// See @ref bslfmt_testspecificationgenerator
281 // DATA
283 // pointer to the
284 // next option in
285 // the list
286
287 public:
288 // CREATORS
289
290 /// Create an object, having no successor in the list of generator options.
292 : d_nextOption(0)
293 {}
294
295 /// Destroy this object.
298
299 // MANIPULATORS
300
301 /// Switch the state of this object to the next one.
302 virtual bool nextState() = 0;
303
304 /// Set the specified `nextOption` as a successor in the list of generator
305 /// options. Use the specified `allocator` to supply memory.
307 bslma::Allocator *allocator)
308 {
309 if (d_nextOption) {
310 d_nextOption->setNextOption(nextOption, allocator);
311 }
312 else {
313 d_nextOption.load(nextOption, allocator);
314 }
315 }
316
317 /// Return the pointer to the last item in the list of generator options
318 /// (this object can also be one).
320 {
321 if (d_nextOption) {
322 return d_nextOption->lastOption(); // RETURN
323 }
324 else {
325 return this;
326 }
327 }
328
329 // ACCESSORS
330
331 /// Return the pointer to the next item in the list of generator options
332 /// if such an object exists and null otherwise..
334 {
335 return d_nextOption.get();
336 }
337};
338
339 // ===========================================
340 // class TestSpecificationGenerator_BoolOption
341 // ===========================================
342
343/// This class is an implementation of the `TestSpecificationGenerator_Option`
344/// for options that have only two states: they are either present or not.
347 // DATA
348 bool *d_isPresent_p; // current state (held, not owned)
349
350 public:
351 // CREATORS
352
353 /// Create an object that displays its state through the specified `value`.
355 : d_isPresent_p(value)
356 {}
357
358 /// Destroy this object.
361
362 // MANIPULATORS
363
364 /// Switch the state of this object to the next one.
366 {
367 if (!nextOption() || !nextOption()->nextState()) {
368 *d_isPresent_p = !(*d_isPresent_p);
369 return *d_isPresent_p;
370 }
371 return true;
372 }
373};
374
375 // ============================================
376 // class TestSpecificationGenerator_TypedOption
377 // ============================================
378
379/// This class is an implementation of the `TestSpecificationGenerator_Option`
380/// for options that iterate through the states specified by the set of
381/// `t_TYPE` (template parameter) values. The state is determined by the
382/// interaction of two class fields: a flag indicating the presence of the
383/// option and a specific value for the option. If the flag indicates that the
384/// option is not present, the value of the second field is ignored.
385template <class t_TYPE>
388 // DATA
389 bool *d_isPresent_p; // flag indicating if this option is
390 // present in the current state of the
391 // generator (held, not owned)
392
393 t_TYPE *d_value_p; // current state (held, not owned)
394
395 size_t d_index; // index of the current state
396
397 bsl::vector<t_TYPE> d_values; // set of available states
398
399 public:
400 // TRAITS
403
404 // CREATORS
405
406 /// Create an object that iterates through the specified set of possible
407 /// `values` and displays its state through the specified
408 /// `isPresentVariable` and `valueVariable` accordingly. Optionally
409 /// specified `basicAllocator` is used to supply memory.
411 bool *isPresentVariable,
412 t_TYPE *valueVariable,
413 const bsl::vector<t_TYPE>& values,
414 bslma::Allocator *basicAllocator = 0)
415 : d_isPresent_p(isPresentVariable)
416 , d_value_p(valueVariable)
417 , d_index(0)
418 , d_values(values, bslma::Default::allocator(basicAllocator))
419 {
420 BSLS_ASSERT(!d_values.empty());
421 *d_value_p = d_values[d_index];
422 }
423
424 /// Destroy this object.
427
428 // MANIPULATORS
429
430 /// Switch the state of this object to the next one.
432 {
433 if (!nextOption() || !nextOption()->nextState()) {
434 // There is no subsequent node, or all subsequent nodes finished
435 // their cycles. This node needs to change state.
436
437 if (*d_isPresent_p && d_values.size() - 1 == d_index) {
438 // Current state is the latest in the cycle. Resetting to
439 // unrepresented state.
440 *d_isPresent_p = false;
441 d_index = 0;
442 *d_value_p = d_values[d_index];
443 return false; // RETURN
444 }
445 else if (!*d_isPresent_p) {
446 // Node is in unrepresented state. Just switch to the
447 // represented state.
448 *d_isPresent_p = true;
449 }
450 else {
451 // Node is present and there are values to iterate through in
452 // this cycle.
453 ++d_index;
454 *d_value_p = d_values[d_index];
455 }
456 }
457
458 // Some of the subsequent nodes changed its state, so this one doesn't
459 // need to yet. Just notify generator.
460 return true;
461 }
462};
463
464 // ================================
465 // class TestSpecificationGenerator
466 // ================================
467
468/// This class is a generator that provides a set of formatting specifications
469/// obtained by exhaustive search of all combinations of standard options. Its
470/// use allows easy and thorough testing of formatters for standard types. The
471/// generator is a state machine, each state of which corresponds to a separate
472/// specification.
473///
474/// See @ref bslfmt_testspecificationgenerator
475template <class t_CHAR>
477 public:
478 // PUBLIC TYPES
479
486
493
499
522
523 private:
524 // TYPES
526
527 // DATA
528 bslma::ManagedPtr<Option> d_firstOption;
529 // first node in the option list (if any)
530
531 bool d_valueIdOptionIsPresent;
532 // flag indicating that value argument id is
533 // present in the current specification
534
535 bool d_fillCharacterIsPresent;
536 // flag indicating that fill character is
537 // present in the current specification
538
539 char d_fillCharacter;
540 // fill character value
541
542 bool d_alignOptionIsPresent;
543 // flag indicating that align option is
544 // present in the current specification
545
546 Alignment d_alignment;
547 // alignment option value
548
549 bool d_signOptionIsPresent;
550 // flag indicating that sign option is
551 // present in the current specification
552
553 Sign d_sign;
554 // sign option value
555
556 bool d_hashOptionIsPresent;
557 // flag indicating that alternative form
558 // option is present in the current
559 // specification
560
561 bool d_zeroOptionIsPresent;
562 // flag indicating that zero option is
563 // present in the current specification
564
565 bool d_widthOptionIsPresent;
566 // flag indicating that width option is
567 // present in the current specification
568
569 int d_width;
570 // width value
571
572 bool d_nestedWidthIsPresent;
573 // flag indicating that nested width option
574 // is present in the current specification
575
576 NestedVariant d_nestedWidthVariant;
577 // nested width option value
578
579 bool d_precisionOptionIsPresent;
580 // flag indicating that precision option is
581 // present in the current specification
582
583 int d_precision;
584 // precision value
585
586 bool d_nestedPrecisionIsPresent;
587 // flag indicating that nested precision
588 // option is present in the current
589 // specification
590
591 NestedVariant d_nestedPrecisionVariant;
592 // nested precision option value
593
594 bool d_localeOptionIsPresent;
595 // flag indicating that locale option is
596 // present in the current specification
597
598 bool d_typeOptionIsPresent;
599 // flag indicating that presentation type
600 // option is present in the current
601 // specification
602
603 FormatType d_type;
604 // presentation type option value
605
607 // generated specification suitable for
608 // formatters `parse` method
609
610 bsl::basic_string<t_CHAR> d_formatSpec;
611 // generated specification suitable for
612 // formatters `format` method
613
614 bsl::vector<char> d_fillCharacters;
615 // fill characters set
616
617 bsl::vector<int> d_widths;
618 // width values set
619
620 bsl::vector<int> d_precisions;
621 // precision values set
622
623 bslma::Allocator *d_allocator_p;
624 // allocator used to supply memory (held, not
625 // own)
626 public:
627
628 // TRAITS
631
632 private:
633 // PRIVATE MANIPULATORS
634
635 /// Add the specified `newOption` to the option list.
636 void addOption(Option *newOption);
637
638 /// Generate a specification based on the current state of the object.
639 void generateSpecification();
640
641 // PRIVATE ACCESSORS
642
643 /// Return `true` if the current state of the object assumes an automatic
644 /// mode of indexing parameters, and `false` otherwise.
645 bool isAutoIndexingMode() const;
646
647 /// Return `true` if the current state of the object assumes a manual mode
648 /// of indexing parameters, and `false` otherwise.
649 bool isManualIndexingMode() const;
650
651 public:
652 // CREATORS
653
654 /// Create a generator object. Optionally specify the `basicAllocator` to
655 /// supply memory.
656 TestSpecificationGenerator(bslma::Allocator *basicAllocator = 0);
657
658 // MANIPULATORS
659
660 /// Add the specified `character` to the set of fill characters.
661 ///
662 /// \note Note that generated instructions will contain the `character` only if this
663 /// function is called before the `setup` method invocation.
664 void addFillCharacter(char character);
665
666 /// Add the specified `width` to the set of width values.
667 ///
668 /// \note Note that generated instructions will contain the `width` only if this function
669 /// is called before the `setup` method invocation.
670 void addWidth(int width);
671
672 /// Add the specified `precision` to the set of precision values.
673 ///
674 /// \note Note that generated instructions will contain the `precision` only if this
675 /// function is called before the `setup` method invocation.
676 void addPrecision(int precision);
677
678 /// Switch this object to the next state and generate specification based
679 /// on the new state.
680 bool next();
681
682 /// Switch this object to the next state appropriate for generating a
683 /// specification valid for formatters `parse` method and generate
684 /// specification based on the new state.
685 bool nextValidForParse();
686
687 /// Switch this object to the next state appropriate for generating a
688 /// specification valid for formatters `format` method and generate
689 /// specification based on the new state.
690 bool nextValidForFormat();
691
692 /// Setup the sequence of this object's states based on the optionally
693 /// specified `instruction`.
694 void setup(const char *instruction = 0);
695
696 // ACCESSORS
697
698 /// Return the specification for the formatters `parse` method based on the
699 /// current state of this object.
700 const bsl::basic_string<t_CHAR>& spec() const;
701
702 /// Return the specification for the formatters `format` method based on
703 /// the current state of this object.
705
706 /// Return `true` if the generated specification based on the current state
707 /// of this object is valid for the formatters `parse` method, and `false`
708 /// otherwise.
709 bool isStateValidForParse() const;
710
711 /// Return `true` if the generated specification based on the current state
712 /// of this object is valid for the formatters `format` method, and `false`
713 /// otherwise.
714 bool isStateValidForFormat() const;
715
716 /// Return `true` if the value id option is present in the current state of
717 /// this object, and `false` otherwise.
718 bool isValueIdOptionPresent() const;
719
720 /// Return `true` if the value id option is present in the current state of
721 /// this object, and `false` otherwise.
722 bool isFillCharacterPresent() const;
723
724 /// Return the current fill character.
725 char fillCharacter() const;
726
727 /// Return `true` if the align option is present in the current state of
728 /// this object, and `false` otherwise.
729 bool isAlignOptionPresent() const;
730
731 /// Return the current alignment type.
732 Alignment alignment() const;
733
734 /// Return `true` if the sign option is present in the current state of
735 /// this object, and `false` otherwise.
736 bool isSignOptionPresent() const;
737
738 /// Return the current sign option value.
739 Sign sign() const;
740
741 /// Return `true` if the alternative form option is present in the current
742 /// state of this object, and `false` otherwise.
743 bool isHashOptionPresent() const;
744
745 /// Return `true` if the zero option is present in the current state of
746 /// this object, and `false` otherwise.
747 bool isZeroOptionPresent() const;
748
749 /// Return `true` if the width option is present in the current state of
750 /// this object, and `false` otherwise.
751 bool isWidthOptionPresent() const;
752
753 /// Return the current width value.
754 int width() const;
755
756 /// Return `true` if the nested width option is present in the current
757 /// state of this object, and `false` otherwise.
758 bool isNestedWidthPresent() const;
759
760 /// Return the current nested width variant.
762
763 /// Return `true` if the precision option is present in the current state
764 /// of this object, and `false` otherwise.
765 bool isPrecisionOptionPresent() const;
766
767 /// Return the current precision value.
768 int precision() const;
769
770 /// Return `true` if the nested precision option is present in the current
771 /// state of this object, and `false` otherwise.
772 bool isNestedPrecisionPresent() const;
773
774 /// Return the current nested precision variant.
776
777 /// Return `true` if the locale option is present in the current state of
778 /// this object, and `false` otherwise.
779 bool isLocaleOptionPresent() const;
780
781 /// Return `true` if the presentation type option is present in the current
782 /// state of this object, and `false` otherwise.
783 bool isTypeOptionPresent() const;
784
785 /// Return the current presentation type value.
786 FormatType type() const;
787};
788
789// ============================================================================
790// INLINE DEFINITIONS
791// ============================================================================
792
793 // --------------------------------
794 // class TestSpecificationGenerator
795 // --------------------------------
796
797// PRIVATE MANIPULATORS
798template <class t_CHAR>
800{
801 if (d_firstOption) {
802 d_firstOption->setNextOption(newOption, d_allocator_p);
803 }
804 else {
805 d_firstOption.load(newOption, d_allocator_p);
806 }
807}
808
809template <class t_CHAR>
810void TestSpecificationGenerator<t_CHAR>::generateSpecification()
811{
812 typedef bslalg::NumericFormatterUtil NFUtil;
813 const int maxIntValueLength = NFUtil::ToCharsMaxLength<int, 10>::k_VALUE;
814
815 d_spec.clear();
816 d_formatSpec.clear();
817
818 if (d_fillCharacterIsPresent) {
819 d_spec.push_back(d_fillCharacter);
820 }
821
822 if (d_alignOptionIsPresent) {
823 switch (d_alignment) {
824 case e_ALIGN_LEFT: {
825 d_spec.push_back('<');
826 } break;
827 case e_ALIGN_MIDDLE: {
828 d_spec.push_back('^');
829 } break;
830 case e_ALIGN_RIGHT: {
831 d_spec.push_back('>');
832 } break;
833 default: {
834 BSLS_ASSERT_INVOKE("Unexpected alignment option");
835 }
836 }
837 }
838
839 if (d_signOptionIsPresent) {
840 switch (d_sign) {
841 case e_SIGN_POSITIVE: {
842 d_spec.push_back('+');
843 } break;
844 case e_SIGN_NEGATIVE: {
845 d_spec.push_back('-');
846 } break;
847 case e_SIGN_SPACE: {
848 d_spec.push_back(' ');
849 } break;
850 default: {
851 BSLS_ASSERT_INVOKE("Unexpected sign option");
852 }
853 }
854 }
855
856 if (d_hashOptionIsPresent) {
857 d_spec.push_back('#');
858 }
859
860 if (d_zeroOptionIsPresent) {
861 d_spec.push_back('0');
862 }
863
864 if (d_widthOptionIsPresent && !d_nestedWidthIsPresent) {
865 char valueBuf[maxIntValueLength];
866 char *valueEnd = NFUtil::toChars(valueBuf,
867 valueBuf + maxIntValueLength,
868 d_width);
869 d_spec.insert(d_spec.end(), valueBuf, valueEnd);
870 }
871 else if (d_nestedWidthIsPresent) {
872 switch (d_nestedWidthVariant) {
873 case e_NESTED_DEFAULT: {
874 d_spec.push_back('{');
875 d_spec.push_back('}');
876 } break;
877 case e_NESTED_ARG_1: {
878 d_spec.push_back('{');
879 d_spec.push_back('1');
880 d_spec.push_back('}');
881 } break;
882 case e_NESTED_ARG_2: {
883 d_spec.push_back('{');
884 d_spec.push_back('2');
885 d_spec.push_back('}');
886 } break;
887 }
888 }
889
890 if (d_precisionOptionIsPresent && !d_nestedPrecisionIsPresent) {
891 d_spec.push_back('.');
892 char valueBuf[maxIntValueLength];
893 char *valueEnd = NFUtil::toChars(valueBuf,
894 valueBuf + maxIntValueLength,
895 d_precision);
896 d_spec.insert(d_spec.end(), valueBuf, valueEnd);
897 }
898 else if (d_nestedPrecisionIsPresent) {
899 d_spec.push_back('.');
900 switch (d_nestedPrecisionVariant) {
901 case e_NESTED_DEFAULT: {
902 d_spec.push_back('{');
903 d_spec.push_back('}');
904 } break;
905 case e_NESTED_ARG_1: {
906 d_spec.push_back('{');
907 d_spec.push_back('1');
908 d_spec.push_back('}');
909 } break;
910 case e_NESTED_ARG_2: {
911 d_spec.push_back('{');
912 d_spec.push_back('2');
913 d_spec.push_back('}');
914 } break;
915 }
916 }
917
918 if (d_localeOptionIsPresent) {
919 d_spec.push_back('L');
920 }
921 if (d_typeOptionIsPresent) {
922 switch (d_type) {
923 case e_TYPE_STRING: {
924 d_spec.push_back('s');
925 } break;
926 case e_TYPE_ESCAPED: {
927 d_spec.push_back('?');
928 } break;
929 case e_TYPE_BINARY: {
930 d_spec.push_back('b');
931 } break;
932 case e_TYPE_BINARY_UC: {
933 d_spec.push_back('B');
934 } break;
935 case e_TYPE_CHARACTER: {
936 d_spec.push_back('c');
937 } break;
938 case e_TYPE_DECIMAL: {
939 d_spec.push_back('d');
940 } break;
941 case e_TYPE_OCTAL: {
942 d_spec.push_back('o');
943 } break;
944 case e_TYPE_INT_HEX: {
945 d_spec.push_back('x');
946 } break;
947 case e_TYPE_INT_HEX_UC: {
948 d_spec.push_back('X');
949 } break;
950 case e_TYPE_FLOAT_HEX: {
951 d_spec.push_back('a');
952 } break;
953 case e_TYPE_FLOAT_HEX_UC: {
954 d_spec.push_back('A');
955 } break;
956 case e_TYPE_SCIENTIFIC: {
957 d_spec.push_back('e');
958 } break;
959 case e_TYPE_SCIENTIFIC_UC: {
960 d_spec.push_back('E');
961 } break;
962 case e_TYPE_FIXED: {
963 d_spec.push_back('f');
964 } break;
965 case e_TYPE_FIXED_UC: {
966 d_spec.push_back('F');
967 } break;
968 case e_TYPE_GENERAL: {
969 d_spec.push_back('g');
970 } break;
971 case e_TYPE_GENERAL_UC: {
972 d_spec.push_back('G');
973 } break;
974 case e_TYPE_POINTER: {
975 d_spec.push_back('p');
976 } break;
977 case e_TYPE_POINTER_UC: {
978 d_spec.push_back('P');
979 } break;
980 default: {
981 BSLS_ASSERT_INVOKE("Unexpected type option");
982 }
983 }
984 }
985
986 // Assembling format specification
987 if (d_valueIdOptionIsPresent) {
988 d_formatSpec.push_back('{');
989 d_formatSpec.push_back('0');
990 d_formatSpec.push_back(':');
991 }
992 else {
993 d_formatSpec.push_back('{');
994 d_formatSpec.push_back(':');
995 }
996 d_formatSpec.append(d_spec);
997 d_formatSpec.push_back('}');
998}
999
1000// PRIVATE ACCESSORS
1001template <class t_CHAR>
1002bool TestSpecificationGenerator<t_CHAR>::isAutoIndexingMode() const
1003{
1004 bool result = true;
1005 if (d_nestedWidthIsPresent && e_NESTED_DEFAULT != d_nestedWidthVariant) {
1006 result = false;
1007 }
1008 else if (d_nestedPrecisionIsPresent && e_NESTED_DEFAULT !=
1009 d_nestedPrecisionVariant) {
1010 result = false;
1011 }
1012
1013 return result;
1014}
1015
1016template <class t_CHAR>
1017bool TestSpecificationGenerator<t_CHAR>::isManualIndexingMode() const
1018{
1019 bool result = false;
1020 if (d_nestedWidthIsPresent) {
1021 if (e_NESTED_DEFAULT != d_nestedWidthVariant) {
1022 if (d_nestedPrecisionIsPresent) {
1023 if (e_NESTED_DEFAULT != d_nestedPrecisionVariant) {
1024 result = true;
1025 }
1026 }
1027 else {
1028 result = true;
1029 }
1030 }
1031 }
1032 else if (d_nestedPrecisionIsPresent && e_NESTED_DEFAULT !=
1033 d_nestedPrecisionVariant) {
1034 result = true;
1035 }
1036 return result;
1037}
1038
1039// CREATORS
1040template <class t_CHAR>
1042 bslma::Allocator *basicAllocator)
1043: d_valueIdOptionIsPresent(false)
1044, d_fillCharacterIsPresent(false)
1045, d_alignOptionIsPresent(false)
1046, d_signOptionIsPresent(false)
1047, d_hashOptionIsPresent(false)
1048, d_zeroOptionIsPresent(false)
1049, d_widthOptionIsPresent(false)
1050, d_nestedWidthIsPresent(false)
1051, d_precisionOptionIsPresent(false)
1052, d_nestedPrecisionIsPresent(false)
1053, d_localeOptionIsPresent(false)
1054, d_typeOptionIsPresent(false)
1055, d_type(e_TYPE_UNSPECIFIED)
1056, d_spec(basicAllocator)
1057, d_formatSpec(basicAllocator)
1058, d_fillCharacters(basicAllocator)
1059, d_widths(basicAllocator)
1060, d_precisions(basicAllocator)
1061, d_allocator_p(bslma::Default::allocator(basicAllocator))
1062{
1063 // Setup default sets of values.
1064 const char defaultFillCharacters[] = { '*', '=' };
1065 const size_t numFillCharacters = sizeof(defaultFillCharacters);
1066 const int defaultWidths[] = { 1, 5, 6, 10 };
1067 const size_t numWidths =
1068 sizeof(defaultWidths) / sizeof(defaultWidths[0]);
1069 const int defaultPrecisions[] = { 0, 5, 6, 10 };
1070 const size_t numPrecisions =
1071 sizeof(defaultPrecisions) / sizeof(defaultPrecisions[0]);
1072 d_fillCharacters.insert(d_fillCharacters.begin(),
1073 defaultFillCharacters,
1074 defaultFillCharacters + numFillCharacters);
1075 d_widths.insert(d_widths.begin(),
1076 defaultWidths,
1077 defaultWidths + numWidths);
1078 d_precisions.insert(d_precisions.begin(),
1079 defaultPrecisions,
1080 defaultPrecisions + numPrecisions);
1081}
1082
1083// MANIPULATORS
1084template <class t_CHAR>
1086{
1087 d_fillCharacters.push_back(character);
1088}
1089
1090template <class t_CHAR>
1092{
1093 BSLS_ASSERT(0 < width);
1094 d_widths.push_back(width);
1095}
1096
1097template <class t_CHAR>
1099{
1100 BSLS_ASSERT(0 <= precision);
1101 d_precisions.push_back(precision);
1102}
1103
1104template <class t_CHAR>
1106{
1107 if (d_firstOption)
1108 {
1109 if (d_firstOption->nextState()) {
1110 generateSpecification();
1111 return true; // RETURN
1112 }
1113 }
1114 generateSpecification();
1115 return false;
1116}
1117
1118template <class t_CHAR>
1120{
1121 if (d_firstOption)
1122 {
1123 bool rv = d_firstOption->nextState();
1124 while ( rv && !isStateValidForParse()) {
1125 // Skip invalid specifications
1126 rv = d_firstOption->nextState();
1127 }
1128 generateSpecification();
1129 return rv; // RETURN
1130 }
1131
1132 generateSpecification();
1133 return false;
1134}
1135
1136template <class t_CHAR>
1138{
1139 if (d_firstOption)
1140 {
1141 bool rv = d_firstOption->nextState();
1142 while ( rv && !isStateValidForFormat()) {
1143 // Skip invalid specifications
1144 rv = d_firstOption->nextState();
1145 }
1146 generateSpecification();
1147 return rv; // RETURN
1148 }
1149
1150 generateSpecification();
1151 return false;
1152}
1153
1154template <class t_CHAR>
1156{
1157 const char *defaultInstruction = "F^+#0WP{}L";
1158 bsl::string instructionStr = instruction
1159 ? instruction
1160 : defaultInstruction;
1161 bool typeIsSpecified = false;
1162 bool widthIsAdded = false;
1163 bool precisionIsAdded = false;
1164
1165 (void) typeIsSpecified; // suppress compiler warning
1166
1167 for (bsl::string::const_iterator it = instructionStr.begin();
1168 it != instructionStr.end();
1169 ++it) {
1170 switch (*it) {
1171 case 'V': {
1172 addOption(
1173 new (*d_allocator_p) TestSpecificationGenerator_BoolOption(
1174 &d_valueIdOptionIsPresent));
1175 } break;
1176 case 'F': {
1177 addOption(new (*d_allocator_p)
1179 &d_fillCharacterIsPresent,
1180 &d_fillCharacter,
1181 d_fillCharacters));
1182
1183 } break;
1184 case '^': {
1185 bsl::vector<Alignment> alignVector;
1186 alignVector.push_back(e_ALIGN_LEFT);
1187 alignVector.push_back(e_ALIGN_MIDDLE);
1188 alignVector.push_back(e_ALIGN_RIGHT);
1189
1190 addOption(new (*d_allocator_p)
1192 &d_alignOptionIsPresent,
1193 &d_alignment,
1194 alignVector));
1195 } break;
1196 case '+': {
1197 bsl::vector<Sign> signVector;
1198 signVector.push_back(e_SIGN_POSITIVE);
1199 signVector.push_back(e_SIGN_NEGATIVE);
1200 signVector.push_back(e_SIGN_SPACE);
1201
1202 addOption(new (*d_allocator_p)
1204 &d_signOptionIsPresent,
1205 &d_sign,
1206 signVector));
1207 } break;
1208 case '#': {
1209 addOption(
1210 new (*d_allocator_p) TestSpecificationGenerator_BoolOption(
1211 &d_hashOptionIsPresent));
1212 } break;
1213 case '0': {
1214 addOption(
1215 new (*d_allocator_p) TestSpecificationGenerator_BoolOption(
1216 &d_zeroOptionIsPresent));
1217 } break;
1218 case 'W': {
1219 if (!widthIsAdded) {
1220 addOption(new (*d_allocator_p)
1222 &d_widthOptionIsPresent,
1223 &d_width,
1224 d_widths));
1225 widthIsAdded = true;
1226 }
1227 } break;
1228 case 'P': {
1229 if (!precisionIsAdded) {
1230 addOption(new (*d_allocator_p)
1232 &d_precisionOptionIsPresent,
1233 &d_precision,
1234 d_precisions));
1235 precisionIsAdded = true;
1236 }
1237 } break;
1238 case '{': {
1239 if (!widthIsAdded) {
1240 addOption(new (*d_allocator_p)
1242 &d_widthOptionIsPresent,
1243 &d_width,
1244 d_widths));
1245 widthIsAdded = true;
1246 }
1247
1248 bsl::vector<NestedVariant> nestedVector;
1249 nestedVector.push_back(e_NESTED_DEFAULT);
1250 nestedVector.push_back(e_NESTED_ARG_1);
1251 nestedVector.push_back(e_NESTED_ARG_2);
1252
1253 addOption(
1254 new (*d_allocator_p)
1256 &d_nestedWidthIsPresent,
1257 &d_nestedWidthVariant,
1258 nestedVector));
1259 } break;
1260 case '}': {
1261 if (!precisionIsAdded) {
1262 addOption(new (*d_allocator_p)
1264 &d_precisionOptionIsPresent,
1265 &d_precision,
1266 d_precisions));
1267 precisionIsAdded = true;
1268 }
1269
1270 bsl::vector<NestedVariant> nestedVector;
1271 nestedVector.push_back(e_NESTED_DEFAULT);
1272 nestedVector.push_back(e_NESTED_ARG_1);
1273 nestedVector.push_back(e_NESTED_ARG_2);
1274
1275 addOption(
1276 new (*d_allocator_p)
1278 &d_nestedPrecisionIsPresent,
1279 &d_nestedPrecisionVariant,
1280 nestedVector));
1281 } break;
1282 case 'L': {
1283 addOption(
1284 new (*d_allocator_p) TestSpecificationGenerator_BoolOption(
1285 &d_localeOptionIsPresent));
1286 } break;
1287 case 's': {
1288 // string presentation types
1289 BSLS_ASSERT(!typeIsSpecified);
1290 typeIsSpecified = true;
1291
1292 bsl::vector<FormatType> typeVector;
1293 typeVector.push_back(e_TYPE_STRING);
1294
1295 // String escaping is not supported
1296 // typeVector.push_back(e_TYPE_ESCAPED);
1297
1298 addOption(new (*d_allocator_p)
1300 &d_typeOptionIsPresent,
1301 &d_type,
1302 typeVector));
1303 } break;
1304 case 'i':{
1305 // integral and character presentation types
1306 BSLS_ASSERT(!typeIsSpecified);
1307 typeIsSpecified = true;
1308
1309 bsl::vector<FormatType> typeVector;
1310 typeVector.push_back(e_TYPE_BINARY); // b
1311 typeVector.push_back(e_TYPE_BINARY_UC); // B
1312 typeVector.push_back(e_TYPE_CHARACTER); // c
1313 typeVector.push_back(e_TYPE_DECIMAL); // d
1314 typeVector.push_back(e_TYPE_OCTAL); // o
1315 typeVector.push_back(e_TYPE_INT_HEX); // x
1316 typeVector.push_back(e_TYPE_INT_HEX_UC); // X
1317
1318 addOption(new (*d_allocator_p)
1320 &d_typeOptionIsPresent,
1321 &d_type,
1322 typeVector));
1323 } break;
1324 case 'c': {
1325 // integral and character presentation types
1326 BSLS_ASSERT(!typeIsSpecified);
1327 typeIsSpecified = true;
1328
1329 bsl::vector<FormatType> typeVector;
1330 typeVector.push_back(e_TYPE_BINARY); // b
1331 typeVector.push_back(e_TYPE_BINARY_UC); // B
1332 typeVector.push_back(e_TYPE_CHARACTER); // c
1333 typeVector.push_back(e_TYPE_ESCAPED); // ?
1334 typeVector.push_back(e_TYPE_DECIMAL); // d
1335 typeVector.push_back(e_TYPE_OCTAL); // o
1336 typeVector.push_back(e_TYPE_INT_HEX); // x
1337 typeVector.push_back(e_TYPE_INT_HEX_UC); // X
1338
1339 addOption(new (*d_allocator_p)
1341 &d_typeOptionIsPresent,
1342 &d_type,
1343 typeVector));
1344 } break;
1345 case 'b': {
1346 // bool presentation types
1347 BSLS_ASSERT(!typeIsSpecified);
1348 typeIsSpecified = true;
1349
1350 bsl::vector<FormatType> typeVector;
1351 typeVector.push_back(e_TYPE_STRING); // s
1352 typeVector.push_back(e_TYPE_BINARY); // b
1353 typeVector.push_back(e_TYPE_BINARY_UC); // B
1354 typeVector.push_back(e_TYPE_DECIMAL); // d
1355 typeVector.push_back(e_TYPE_OCTAL); // o
1356 typeVector.push_back(e_TYPE_INT_HEX); // x
1357 typeVector.push_back(e_TYPE_INT_HEX_UC); // X
1358
1359 addOption(new (*d_allocator_p)
1361 &d_typeOptionIsPresent,
1362 &d_type,
1363 typeVector));
1364 } break;
1365 case 'f': {
1366 // floating-point presentation types
1367 BSLS_ASSERT(!typeIsSpecified);
1368 typeIsSpecified = true;
1369
1370 bsl::vector<FormatType> typeVector;
1371 typeVector.push_back(e_TYPE_FLOAT_HEX); // a
1372 typeVector.push_back(e_TYPE_FLOAT_HEX_UC); // A
1373 typeVector.push_back(e_TYPE_SCIENTIFIC); // e
1374 typeVector.push_back(e_TYPE_SCIENTIFIC_UC); // E
1375 typeVector.push_back(e_TYPE_FIXED); // f
1376 typeVector.push_back(e_TYPE_FIXED_UC); // F
1377 typeVector.push_back(e_TYPE_GENERAL); // g
1378 typeVector.push_back(e_TYPE_GENERAL_UC); // G
1379
1380 addOption(new (*d_allocator_p)
1382 &d_typeOptionIsPresent,
1383 &d_type,
1384 typeVector));
1385 } break;
1386 case 'p': {
1387 // pointer presentation types
1388 BSLS_ASSERT(!typeIsSpecified);
1389 typeIsSpecified = true;
1390
1391 bsl::vector<FormatType> typeVector;
1392 typeVector.push_back(e_TYPE_POINTER); // 'P'
1393 typeVector.push_back(e_TYPE_POINTER_UC); // 'P'
1394
1395 addOption(new (*d_allocator_p)
1397 &d_typeOptionIsPresent,
1398 &d_type,
1399 typeVector));
1400 } break;
1401 case 'a': {
1402 // all presentation types
1403 BSLS_ASSERT(!typeIsSpecified);
1404 typeIsSpecified = true;
1405
1406 bsl::vector<FormatType> typeVector;
1407 typeVector.push_back(e_TYPE_STRING); // 's'
1408 typeVector.push_back(e_TYPE_BINARY); // `b`
1409 typeVector.push_back(e_TYPE_BINARY_UC); // `B`
1410 typeVector.push_back(e_TYPE_CHARACTER); // `c`
1411 typeVector.push_back(e_TYPE_DECIMAL); // `d`
1412 typeVector.push_back(e_TYPE_OCTAL); // `o`
1413 typeVector.push_back(e_TYPE_INT_HEX); // `x`
1414 typeVector.push_back(e_TYPE_INT_HEX_UC); // `X`
1415 typeVector.push_back(e_TYPE_FLOAT_HEX); // `a`
1416 typeVector.push_back(e_TYPE_FLOAT_HEX_UC); // `A`
1417 typeVector.push_back(e_TYPE_SCIENTIFIC); // `e`
1418 typeVector.push_back(e_TYPE_SCIENTIFIC_UC); // `E`
1419 typeVector.push_back(e_TYPE_FIXED); // `f`
1420 typeVector.push_back(e_TYPE_FIXED_UC); // `F`
1421 typeVector.push_back(e_TYPE_GENERAL); // `g`
1422 typeVector.push_back(e_TYPE_GENERAL_UC); // `G`
1423 typeVector.push_back(e_TYPE_POINTER); // 'p'
1424 typeVector.push_back(e_TYPE_POINTER_UC); // 'p'
1425
1426 addOption(new (*d_allocator_p)
1428 &d_typeOptionIsPresent,
1429 &d_type,
1430 typeVector));
1431 } break;
1432 default: {
1433 BSLS_ASSERT_INVOKE("Unexpected instruction command");
1434 }
1435 }
1436 }
1437
1438 generateSpecification();
1439}
1440
1441// ACCESSORS
1442template <class t_CHAR>
1445{
1446 return d_spec;
1447}
1448
1449template <class t_CHAR>
1452{
1453 return d_formatSpec;
1454}
1455
1456template <class t_CHAR>
1458{
1459 // Rule: The sign, and # options are only valid when an integer or
1460 // floating-point presentation type is used.
1461 bool invalidSignOrHash = d_typeOptionIsPresent &&
1462 (d_signOptionIsPresent || d_hashOptionIsPresent) &&
1463 (e_TYPE_STRING == d_type ||
1464 e_TYPE_ESCAPED == d_type ||
1465 e_TYPE_CHARACTER == d_type ||
1466 e_TYPE_POINTER == d_type ||
1467 e_TYPE_POINTER_UC == d_type);
1468
1469 // Rule: The 0 option is only valid when an integer, floating-point or
1470 // pointer presentation type is used.
1471 bool invalidZero = d_typeOptionIsPresent && d_zeroOptionIsPresent &&
1472 (e_TYPE_STRING == d_type ||
1473 e_TYPE_ESCAPED == d_type ||
1474 e_TYPE_CHARACTER == d_type);
1475
1476 // Rule: Precision can be used with floating-point and string types
1477 // only.
1478 bool invalidTypeForPrecision =
1479 (d_precisionOptionIsPresent || d_nestedPrecisionIsPresent) &&
1480 (e_TYPE_BINARY == d_type ||
1481 e_TYPE_BINARY_UC == d_type ||
1482 e_TYPE_CHARACTER == d_type ||
1483 e_TYPE_DECIMAL == d_type ||
1484 e_TYPE_OCTAL == d_type ||
1485 e_TYPE_INT_HEX == d_type ||
1486 e_TYPE_INT_HEX_UC == d_type ||
1487 e_TYPE_POINTER == d_type ||
1488 e_TYPE_POINTER_UC == d_type);
1489
1490 // Rule: An align option must follow a fill character.
1491 bool missedAlignOption = d_fillCharacterIsPresent &&
1492 !d_alignOptionIsPresent;
1493
1494 // Rule: All parameter indexes in specification must be defined either
1495 // automatically or manually.
1496 bool conflictingIndexingStyle = !isAutoIndexingMode() &&
1497 !isManualIndexingMode();
1498
1499 return !(invalidSignOrHash ||
1500 invalidZero ||
1501 invalidTypeForPrecision ||
1502 missedAlignOption ||
1503 conflictingIndexingStyle);
1504}
1505
1506template <class t_CHAR>
1508{
1509 // Value's index is defined differently than width's or precision's index.
1510 bool conflictingIndexingStyle =
1511 (d_nestedWidthIsPresent || d_nestedPrecisionIsPresent) &&
1512 ((d_valueIdOptionIsPresent && isAutoIndexingMode()) ||
1513 (!d_valueIdOptionIsPresent && isManualIndexingMode()));
1514
1515 return isStateValidForParse() && !conflictingIndexingStyle;
1516}
1517
1518template <class t_CHAR>
1520{
1521 return d_valueIdOptionIsPresent;
1522}
1523
1524template <class t_CHAR>
1526{
1527 return d_fillCharacterIsPresent;
1528}
1529
1530template <class t_CHAR>
1532{
1533 BSLS_ASSERT(isFillCharacterPresent());
1534 return d_fillCharacter;
1535}
1536
1537template <class t_CHAR>
1539{
1540 return d_alignOptionIsPresent;
1541}
1542
1543template <class t_CHAR>
1546{
1547 BSLS_ASSERT(isAlignOptionPresent());
1548 return d_alignment;
1549}
1550
1551template <class t_CHAR>
1553{
1554 return d_signOptionIsPresent;
1555}
1556
1557template <class t_CHAR>
1560{
1561 BSLS_ASSERT(d_signOptionIsPresent);
1562 return d_sign;
1563}
1564
1565template <class t_CHAR>
1567{
1568 return d_hashOptionIsPresent;
1569}
1570
1571template <class t_CHAR>
1573{
1574 return d_zeroOptionIsPresent;
1575}
1576
1577template <class t_CHAR>
1579{
1580 return d_widthOptionIsPresent;
1581}
1582
1583template <class t_CHAR>
1585{
1586 return d_width;
1587}
1588
1589template <class t_CHAR>
1591{
1592 return d_nestedWidthIsPresent;
1593}
1594
1595template <class t_CHAR>
1598{
1599 return d_nestedWidthVariant;
1600}
1601
1602template <class t_CHAR>
1604{
1605 return d_precisionOptionIsPresent;
1606}
1607
1608template <class t_CHAR>
1610{
1611 return d_precision;
1612}
1613
1614template <class t_CHAR>
1616{
1617 return d_nestedPrecisionIsPresent;
1618}
1619
1620template <class t_CHAR>
1623{
1624 return d_nestedPrecisionVariant;
1625}
1626
1627template <class t_CHAR>
1629{
1630 return d_localeOptionIsPresent;
1631}
1632
1633template <class t_CHAR>
1635{
1636 return d_typeOptionIsPresent;
1637}
1638
1639template <class t_CHAR>
1642{
1643 return d_type;
1644}
1645
1646} // close package namespace
1647
1648
1649
1650#endif // INCLUDED_BSLFMT_TESTSPECIFICATIONGENERATOR
1651
1652// ----------------------------------------------------------------------------
1653// Copyright 2025 Bloomberg Finance L.P.
1654//
1655// Licensed under the Apache License, Version 2.0 (the "License");
1656// you may not use this file except in compliance with the License.
1657// You may obtain a copy of the License at
1658//
1659// http://www.apache.org/licenses/LICENSE-2.0
1660//
1661// Unless required by applicable law or agreed to in writing, software
1662// distributed under the License is distributed on an "AS IS" BASIS,
1663// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1664// See the License for the specific language governing permissions and
1665// limitations under the License.
1666// ----------------------------- END-OF-FILE ----------------------------------
1667
1668
1669/** @} */
1670/** @} */
1671/** @} */
Definition bslstl_string.h:1252
iterator end() BSLS_KEYWORD_NOEXCEPT
Return the past-the-end iterator for this modifiable string.
Definition bslstl_string.h:6065
void swap(basic_string &other) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(AllocatorTraits const_iterator begin() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_string.h:2792
const CHAR_TYPE * const_iterator
Definition bslstl_string.h:1282
size_type size() const BSLS_KEYWORD_NOEXCEPT
Return the number of elements in this vector.
Definition bslstl_vector.h:3019
iterator begin() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_vector.h:2866
bool empty() const BSLS_KEYWORD_NOEXCEPT
Return true if this vector has size 0, and false otherwise.
Definition bslstl_vector.h:3034
Definition bslstl_vector.h:1120
iterator insert(const_iterator position, const VALUE_TYPE &value)
Definition bslstl_vector.h:4386
void push_back(const VALUE_TYPE &value)
Definition bslstl_vector.h:4343
Definition bslfmt_testspecificationgenerator.h:346
~TestSpecificationGenerator_BoolOption()
Destroy this object.
Definition bslfmt_testspecificationgenerator.h:359
bool nextState()
Switch the state of this object to the next one.
Definition bslfmt_testspecificationgenerator.h:365
TestSpecificationGenerator_BoolOption(bool *value)
Create an object that displays its state through the specified value.
Definition bslfmt_testspecificationgenerator.h:354
Definition bslfmt_testspecificationgenerator.h:280
void setNextOption(TestSpecificationGenerator_Option *nextOption, bslma::Allocator *allocator)
Definition bslfmt_testspecificationgenerator.h:306
virtual bool nextState()=0
Switch the state of this object to the next one.
TestSpecificationGenerator_Option * nextOption() const
Definition bslfmt_testspecificationgenerator.h:333
TestSpecificationGenerator_Option * lastOption()
Definition bslfmt_testspecificationgenerator.h:319
TestSpecificationGenerator_Option()
Create an object, having no successor in the list of generator options.
Definition bslfmt_testspecificationgenerator.h:291
virtual ~TestSpecificationGenerator_Option()
Destroy this object.
Definition bslfmt_testspecificationgenerator.h:296
Definition bslfmt_testspecificationgenerator.h:387
TestSpecificationGenerator_TypedOption(bool *isPresentVariable, t_TYPE *valueVariable, const bsl::vector< t_TYPE > &values, bslma::Allocator *basicAllocator=0)
Definition bslfmt_testspecificationgenerator.h:410
bool nextState()
Switch the state of this object to the next one.
Definition bslfmt_testspecificationgenerator.h:431
~TestSpecificationGenerator_TypedOption()
Destroy this object.
Definition bslfmt_testspecificationgenerator.h:425
BSLMF_NESTED_TRAIT_DECLARATION(TestSpecificationGenerator_TypedOption, bslma::UsesBslmaAllocator)
Definition bslfmt_testspecificationgenerator.h:476
char fillCharacter() const
Return the current fill character.
Definition bslfmt_testspecificationgenerator.h:1531
Alignment
Definition bslfmt_testspecificationgenerator.h:480
@ e_ALIGN_LEFT
Definition bslfmt_testspecificationgenerator.h:482
@ e_ALIGN_DEFAULT
Definition bslfmt_testspecificationgenerator.h:481
@ e_ALIGN_MIDDLE
Definition bslfmt_testspecificationgenerator.h:483
@ e_ALIGN_RIGHT
Definition bslfmt_testspecificationgenerator.h:484
BSLMF_NESTED_TRAIT_DECLARATION(TestSpecificationGenerator, bslma::UsesBslmaAllocator)
bool isWidthOptionPresent() const
Definition bslfmt_testspecificationgenerator.h:1578
bool isLocaleOptionPresent() const
Definition bslfmt_testspecificationgenerator.h:1628
bool isHashOptionPresent() const
Definition bslfmt_testspecificationgenerator.h:1566
int width() const
Return the current width value.
Definition bslfmt_testspecificationgenerator.h:1584
bool nextValidForParse()
Definition bslfmt_testspecificationgenerator.h:1119
Sign
Definition bslfmt_testspecificationgenerator.h:487
@ e_SIGN_POSITIVE
Definition bslfmt_testspecificationgenerator.h:489
@ e_SIGN_DEFAULT
Definition bslfmt_testspecificationgenerator.h:488
@ e_SIGN_NEGATIVE
Definition bslfmt_testspecificationgenerator.h:490
@ e_SIGN_SPACE
Definition bslfmt_testspecificationgenerator.h:491
bool isNestedWidthPresent() const
Definition bslfmt_testspecificationgenerator.h:1590
const bsl::basic_string< t_CHAR > & formatSpec() const
Definition bslfmt_testspecificationgenerator.h:1451
bool isValueIdOptionPresent() const
Definition bslfmt_testspecificationgenerator.h:1519
bool isPrecisionOptionPresent() const
Definition bslfmt_testspecificationgenerator.h:1603
void addPrecision(int precision)
Definition bslfmt_testspecificationgenerator.h:1098
Alignment alignment() const
Return the current alignment type.
Definition bslfmt_testspecificationgenerator.h:1545
bool isNestedPrecisionPresent() const
Definition bslfmt_testspecificationgenerator.h:1615
void addFillCharacter(char character)
Definition bslfmt_testspecificationgenerator.h:1085
NestedVariant nestedPrecisionVariant() const
Return the current nested precision variant.
Definition bslfmt_testspecificationgenerator.h:1622
NestedVariant
Definition bslfmt_testspecificationgenerator.h:494
@ e_NESTED_DEFAULT
Definition bslfmt_testspecificationgenerator.h:495
@ e_NESTED_ARG_2
Definition bslfmt_testspecificationgenerator.h:497
@ e_NESTED_ARG_1
Definition bslfmt_testspecificationgenerator.h:496
int precision() const
Return the current precision value.
Definition bslfmt_testspecificationgenerator.h:1609
FormatType type() const
Return the current presentation type value.
Definition bslfmt_testspecificationgenerator.h:1641
bool isTypeOptionPresent() const
Definition bslfmt_testspecificationgenerator.h:1634
bool isStateValidForParse() const
Definition bslfmt_testspecificationgenerator.h:1457
Sign sign() const
Return the current sign option value.
Definition bslfmt_testspecificationgenerator.h:1559
const bsl::basic_string< t_CHAR > & spec() const
Definition bslfmt_testspecificationgenerator.h:1444
FormatType
Definition bslfmt_testspecificationgenerator.h:500
@ e_TYPE_POINTER_UC
Definition bslfmt_testspecificationgenerator.h:520
@ e_TYPE_UNSPECIFIED
Definition bslfmt_testspecificationgenerator.h:501
@ e_TYPE_DECIMAL
Definition bslfmt_testspecificationgenerator.h:507
@ e_TYPE_STRING
Definition bslfmt_testspecificationgenerator.h:502
@ e_TYPE_FLOAT_HEX
Definition bslfmt_testspecificationgenerator.h:511
@ e_TYPE_ESCAPED
Definition bslfmt_testspecificationgenerator.h:503
@ e_TYPE_FIXED_UC
Definition bslfmt_testspecificationgenerator.h:516
@ e_TYPE_OCTAL
Definition bslfmt_testspecificationgenerator.h:508
@ e_TYPE_FLOAT_HEX_UC
Definition bslfmt_testspecificationgenerator.h:512
@ e_TYPE_CHARACTER
Definition bslfmt_testspecificationgenerator.h:506
@ e_TYPE_INT_HEX
Definition bslfmt_testspecificationgenerator.h:509
@ e_TYPE_INT_HEX_UC
Definition bslfmt_testspecificationgenerator.h:510
@ e_TYPE_SCIENTIFIC
Definition bslfmt_testspecificationgenerator.h:513
@ e_TYPE_GENERAL
Definition bslfmt_testspecificationgenerator.h:517
@ e_TYPE_BINARY
Definition bslfmt_testspecificationgenerator.h:504
@ e_TYPE_FIXED
Definition bslfmt_testspecificationgenerator.h:515
@ e_TYPE_POINTER
Definition bslfmt_testspecificationgenerator.h:519
@ e_TYPE_BINARY_UC
Definition bslfmt_testspecificationgenerator.h:505
@ e_TYPE_GENERAL_UC
Definition bslfmt_testspecificationgenerator.h:518
@ e_TYPE_SCIENTIFIC_UC
Definition bslfmt_testspecificationgenerator.h:514
bool nextValidForFormat()
Definition bslfmt_testspecificationgenerator.h:1137
void addWidth(int width)
Definition bslfmt_testspecificationgenerator.h:1091
bool isStateValidForFormat() const
Definition bslfmt_testspecificationgenerator.h:1507
bool next()
Definition bslfmt_testspecificationgenerator.h:1105
bool isSignOptionPresent() const
Definition bslfmt_testspecificationgenerator.h:1552
NestedVariant nestedWidthVariant() const
Return the current nested width variant.
Definition bslfmt_testspecificationgenerator.h:1597
bool isAlignOptionPresent() const
Definition bslfmt_testspecificationgenerator.h:1538
bool isZeroOptionPresent() const
Definition bslfmt_testspecificationgenerator.h:1572
TestSpecificationGenerator(bslma::Allocator *basicAllocator=0)
Definition bslfmt_testspecificationgenerator.h:1041
bool isFillCharacterPresent() const
Definition bslfmt_testspecificationgenerator.h:1525
void setup(const char *instruction=0)
Definition bslfmt_testspecificationgenerator.h:1155
Definition bslma_allocator.h:545
Definition bslma_managedptr.h:1173
TARGET_TYPE * get() const
Definition bslma_managedptr.h:2596
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1976
#define BSLS_ASSERT_INVOKE(X)
Definition bsls_assert.h:2084
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
Definition bslfmt_enablestreamedformatter.h:130
Definition baljsn_encoder_testtypes.h:76
Definition bslalg_numericformatterutil.h:400
Definition bslma_usesbslmaallocator.h:344