ALib C++ Library
Library Version: 2511 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
formatterjavastyle.inl
Go to the documentation of this file.
1//==================================================================================================
2/// \file
3/// This header-file is part of module \alib_format of the \aliblong.
4///
5/// \emoji :copyright: 2013-2025 A-Worx GmbH, Germany.
6/// Published under \ref mainpage_license "Boost Software License".
7//==================================================================================================
8namespace alib::format {
9
10//==================================================================================================
11/// Implements a \alib{format;Formatter} according to the
12/// \https{formatting standards of the Java language,docs.oracle.com/javase/8/docs/api/java/util/Formatter.html}.
13///
14/// \note
15/// Inherited, public fields of parent class \b FormatterStdImpl provide important possibilities
16/// for changing the formatting behavior of instances of this class. Therefore, do not forget
17/// to consult the \ref alib::format::FormatterStdImpl "parent classes documentation".
18///
19/// In general, the original specification is covered quite well. The differences and specialties
20/// are:
21/// - In deviation of the Java specification, after creation, a formatter in this implementation
22/// does not produce locale-aware output. Instead, number formatting is set to "computational",
23/// hence the decimal point separator is <c>'.'</c> and the grouping character <c>','</c>.
24/// As the syntax specification does not provide a feature to switch between standard and locale
25/// settings, the corresponding fields of #AlternativeNumberFormat are not used with this
26/// formatter. Instead, to enable localized output, method
27/// \alib{strings;TNumberFormat::SetFromLocale;NumberFormat::SetFromLocale}
28/// has to be invoked on field
29/// \alib{format;FormatterStdImpl::DefaultNumberFormat;FormatterStdImpl::DefaultNumberFormat}.
30/// Alternatively, attributes of this object may be changed manually or by other means to reflect
31/// a desired locale.
32/// - Hexadecimal floating point output (conversion type \c 'a' and \c 'A') is not supported.
33/// - Flag <c>'('</c>, used to write negative numbers in round brackets, is not supported.
34/// - Addressing the previous argument index using \c '%<' is already allowed with the first
35/// placeholder.
36/// This Chooses the first argument. (In Java a \b MissingFormatArgumentException would be thrown.)
37/// - Flag \c '^' is an extension to the standard and denotes
38/// center-alignment - just like \c '-' in the standard denotes left-alignment.
39/// Right-alignment is the default.
40///
41///<p>
42/// - <b>Floating point values:</b>
43/// - If standard field type \c 's' is given together with a precision, the field is cut, even if
44/// it cuts the number somewhere. (This is just a warning and same behavior as in original
45/// specification.)
46/// - For lower case floating point format types (\c 'f', \c 'g' and \c 'e'), the values specified
47/// in attributes \b %ExponentSeparator, \b %NANLiteral and \b %INFLiteral of object
48/// \alib{format;FormatterStdImpl::AlternativeNumberFormat;FormatterStdImpl::AlternativeNumberFormat}
49/// are used. For upper case types (\c 'G' and \c 'E'), the corresponding attributes in
50/// \alib{format;FormatterStdImpl::DefaultNumberFormat;FormatterStdImpl::DefaultNumberFormat} apply.
51/// - Fixed point format (\c 'f' ) is not supported to use arbitrary length.
52/// See class \alib{strings;TNumberFormat;NumberFormat} for the limits.
53/// Due to this limitation, the default number of fractional digits is not set with type \c 'f',
54/// while in Java it is set to \c 6. This is to allow higher numbers up to \c 1.e13 to be printed
55/// in non-scientific format
56/// - When both, \p{width} and \p{precision} are given, then the \p{precision} determines the
57/// fractional part, even if the type is \b 'g' or \b 'G'. This is different from the
58/// corresponding specification of Java formatter, which uses \p{precision} as the overall
59/// width in the case of types \b 'g' or \b 'G'.
60///
61///<p>
62/// - <b>Hexadecimal and Octal Numbers:</b>
63/// - Hexadecimal and octal output is <b>cut in size</b> (!) when a field width is given that
64/// is smaller than the resulting number of digits of the number arguments provided.
65/// \note This implies that a value written might not be equal to the value given.
66/// This is not a bug but a design decision. The rationale behind this is that with
67/// this behavior, there is no need to mask lower digits when passing the arguments
68/// to the format invocation. In other words, the formatter "assumes" that the given
69/// field width indicates that only a corresponding number of lower digits are of
70/// interest.
71///
72/// - If no width is given and the argument contains a boxed pointer, then the platform-dependent
73/// full output width of pointer types is used.
74/// - The number <b>grouping option</b> (<c>','</c>) can also be used with binary, hexadecimal
75/// and octal output.
76/// The types support different grouping separators for nibbles, bytes, 16-bit and 32-bit words.
77/// Changing the separator symbols, is not possible with the format fields of the format strings
78/// (if it was, this would become very incompatible to Java standards). Changes have to be made
79/// before the format operation by modifying field
80/// \alib{format;FormatterStdImpl::AlternativeNumberFormat;FormatterStdImpl::AlternativeNumberFormat}
81/// which is provided through parent class \b %FormatterStdImpl.
82///
83/// - Alternative form (\c '#') adds prefixes as specified in members
84/// - \alib{strings;TNumberFormat::HexLiteralPrefix;HexLiteralPrefix} and
85/// - \alib{strings;TNumberFormat::OctLiteralPrefix;OctLiteralPrefix}.
86///
87/// For upper case formats, those are taken from field
88/// \alib{format;FormatterStdImpl::DefaultNumberFormat;FormatterStdImpl::DefaultNumberFormat},
89/// for lower case formats from
90/// \alib{format;FormatterStdImpl::AlternativeNumberFormat;FormatterStdImpl::AlternativeNumberFormat}.
91/// The user may change all defaults.
92///
93///<p>
94/// - <b>Time and Date:</b>
95/// - In this C++ version of the class, boxed values of type \alib{time;DateTime} are applicable
96/// to conversion type \c 't'.
97/// - The following time conversion suffix characters are supported:
98/// \c 'H', \c 'k', \c 'I', \c 'l', \c 'M', \c 'S', \c 'B', \c 'b', \c 'h', \c 'A', \c 'a',
99/// \c 'Y', \c 'y', \c 'm', \c 'd', \c 'e', \c 'R', \c 'T', \c 'D' and \c 'F'
100/// - The following time conversion suffix characters are \b not supported:
101/// \c 'L', \c 'N', \c 'p', \c 'z', \c 'Z', \c 's', \c 'Q', \c 'C', \c 'j', \c 'r' and \c 'c'.
102///
103///\I{##############################################################################################}
104/// # Reference Documentation #
105/// @throws <b>alib::format::FMTExceptions</b>
106/// - \alib{format::FMTExceptions;ArgumentIndexIs0}
107/// - \alib{format::FMTExceptions;ArgumentIndexOutOfBounds}
108/// - \alib{format::FMTExceptions;IncompatibleTypeCode}
109/// - \alib{format::FMTExceptions;NegativeValuesInBracketsNotSupported}
110/// - \alib{format::FMTExceptions;MissingPrecisionValueJS}
111/// - \alib{format::FMTExceptions;HexadecimalFloatFormatNotSupported}
112/// - \alib{format::FMTExceptions;NoAlternateFormOfConversion}
113/// - \alib{format::FMTExceptions;NoPrecisionWithConversion}
114/// - \alib{format::FMTExceptions;UnknownDateTimeConversionSuffix}
115/// - \alib{format::FMTExceptions;UnknownConversionJS}
116///
117//==================================================================================================
119{
120 //################################################################################################
121 // Protected fields
122 //################################################################################################
123 protected:
124 /// Set of extended placeholder attributes, needed for this type of formatter in
125 /// addition to parent's \alib{format::FormatterStdImpl;PlaceholderAttributes}.
127 {
128 /// The character after conversion type 't'/'T'.
130
131 /// The value read from the precision field.
132 /// This is set to \c -1 in #resetPlaceholder.
133 int8_t Precision;
134
135 /// The default precision if not given.
136 /// This is set to \c 6 in #resetPlaceholder, but is changed when specified.
138
139 /// Convert to upper case.
141
142 /// Alternate form given ('#').
144 };
145
146 /// The extended placeholder attributes.
148
149
150 //################################################################################################
151 // Constructor/Destructor
152 //################################################################################################
153 public:
154 /// Constructs this formatter.
155 /// Inherited field #DefaultNumberFormat is initialized to meet the formatting defaults of
156 /// Java.
159
160 /// Clones and returns a copy of this formatter.
161 ///
162 /// If the formatter attached to field
163 /// \alib{format;Formatter::Next} is of type \b %FormatterStdImpl, then that
164 /// formatter is copied as well.
165 ///
166 /// @returns An object of type \b %FormatterPythonStyle and with the same custom settings
167 /// than this.
168 ALIB_DLL virtual
169 SPFormatter Clone() override;
170
171 //################################################################################################
172 // Implementation of FormatterStdImpl interface
173 //################################################################################################
174 protected:
175
176 /// Invokes parent implementation and then applies some changes to reflect what is defined as
177 /// default in the Java string format specification.
179 virtual void resetPlaceholder() override;
180
181 /// Searches for \c '\%' which is not '%%' or '%n'.
182 ///
183 /// @return The index found, -1 if not found.
185 virtual integer findPlaceholder() override;
186
187 /// Parses placeholder field in Java syntax. The portion \p{format_spec} is not set as this
188 /// is not supported by the syntax.
189 ///
190 /// @return \c true on success, \c false on errors.
192 virtual bool parsePlaceholder() override;
193
194 /// Does nothing. Java does not support custom format specifications.
195 ///
196 /// @return \c true to indicate success.
197 virtual bool parseStdFormatSpec() override { return true; }
198
199 /// Implementation of abstract method \alib{format;FormatterStdImpl::writeStringPortion}.<br>
200 /// Replaces \c "%%" with \c '\%' and \c "%n" with ascii \c 0x0a. In addition applies
201 /// \alib{strings;TEscape;Escape} on \p{target} which replaces
202 /// standard codes like \c "\\n", \c "\\r" or \c "\\t" with corresponding ascii codes.
203 /// (The latter is an extension to the standard behavior of Java formatter.)
204 ///
205 /// @param length The number of characters to write.
207 virtual void writeStringPortion( integer length ) override;
208
209 /// All that this formatter does with this overridden method is to convert strings to
210 /// upper case.
211 ///
212 /// @param startIdx The index of the start of the field written in #targetString.
213 /// \c -1 indicates pre-phase.
214 /// @param target The target string, only if different from field #targetString, which
215 /// indicates intermediate phase.
216 /// @return \c false, if the placeholder should be skipped (nothing is written for it).
217 /// \c true otherwise.
219 virtual bool preAndPostProcess( integer startIdx,
220 AString* target ) override;
221
222 /// Makes some attribute adjustments and invokes standard implementation
223 /// @return \c true if OK, \c false if replacement should be aborted.
225 virtual bool checkStdFieldAgainstArgument() override;
226};
227
228} // namespace [alib::format]
229
230ALIB_EXPORT namespace alib {
231/// Type alias in namespace \b alib.
233}
virtual ALIB_DLL void writeStringPortion(integer length) override
virtual ALIB_DLL void resetPlaceholder() override
virtual bool parseStdFormatSpec() override
virtual ALIB_DLL SPFormatter Clone() override
PlaceholderAttributesJS placeholderJS
The extended placeholder attributes.
virtual ALIB_DLL bool checkStdFieldAgainstArgument() override
virtual ALIB_DLL integer findPlaceholder() override
virtual ALIB_DLL bool parsePlaceholder() override
virtual ALIB_DLL bool preAndPostProcess(integer startIdx, AString *target) override
FormatterStdImpl(const String &formatterClassName)
#define ALIB_DLL
Definition alib.inl:503
#define ALIB_EXPORT
Definition alib.inl:497
format::FormatterJavaStyle FormatterJavaStyle
Type alias in namespace alib.
strings::TAString< character, lang::HeapAllocator > AString
Type alias in namespace alib.
lang::integer integer
Type alias in namespace alib.
Definition integers.inl:149
containers::SharedPtr< format::Formatter > SPFormatter
Definition formatter.inl:42
characters::character character
Type alias in namespace alib.
character DateTime
The character after conversion type 't'/'T'.