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