ALib C++ Library
Library Version: 2412 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
formatterpythonstyle.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_PYTHONSTYLE
10#define HPP_ALIB_LANG_FORMAT_FORMATTER_PYTHONSTYLE 1
11#pragma once
14
15
16namespace alib::lang::format {
17 //==============================================================================================
18 /// Implements a \alib{lang::format;Formatter} according to the
19 /// \https{formatting standards of the Python language,docs.python.org/3.5/library/string.html#format-string-syntax}.
20 ///
21 /// \note
22 /// Inherited, public fields of parent class \b FormatterStdImpl provide important possibilities
23 /// for changing the formatting behavior of instances of this class. Therefore, do not forget
24 /// to consult the \ref alib::lang::format::FormatterStdImpl "parent classes documentation".
25 ///
26 /// In general, the original \b Python specification is covered quite well. However, there are
27 /// some differences, some things are not possible (considering python being a scripting language)
28 /// but then there are also found some very helpful extensions to that standard. Instead of repeating
29 /// a complete documentation, please refer to the
30 /// \https{Python Documentation,docs.python.org/3.5/library/string.html#format-string-syntax}
31 /// as the foundation and then take note of the following list of differences, extensions and
32 /// general hints:
33 ///
34 /// - <b>General Notes:</b>
35 /// \b Python defines a placeholder field as follows
36 ///
37 /// "{" [field_name] ["!" conversion] [":" format_spec] "}"
38 ///
39 ///
40 /// - This formatter is <b>less strict</b> in respect to the order of the format symbols. E.g.
41 /// it allows <c>{:11.5,}</c> where Python allows only <c>{:11,.5}</c>
42 ///
43 /// - With this class being derived from
44 /// \ref alib::lang::format::FormatterStdImpl "FormatterStdImpl", features of the parent are
45 /// available to this formatter as well. This is especially true and sometimes useful in respect to
46 /// setting default values number formatting. For example, this allows modifying all number output
47 /// without explicitly repeating the settings in each placeholder of format strings. Other options
48 /// for example the grouping characters used with hexadecimal numbers, cannot be even changed
49 /// with the <b>Python Style</b> formatting options. The only way of doing so is modifying the
50 /// properties of the formatter object before the format operation.
51 ///
52 /// - Nested replacements in format specification fields are (by nature of this implementation
53 /// language) \b not supported.
54 ///
55 /// <p>
56 /// - <b>Positional arguments and field name:</b>
57 /// - By the nature of the implementation language (<em>C++, no introspection</em>) of this class,
58 /// \b field_name can \b not be the name of an identifier, an attribute name or an array element
59 /// index. It can only be a positional argument index, hence a number that chooses a different
60 /// index in the provided argument list.<br>
61 /// However, the use of field names is often a requirement in use cases that offer configurable
62 /// format string setup to the "end user". Therefore, there are two alternatives to cope
63 /// with the limitation:
64 /// - In simple cases, it is possible to just add all optionally needed data in the argument list,
65 /// document their index position and let the user use positional argument notation to choose
66 /// the right value from the list.
67 /// - More elegant however, is the use of class
68 /// \ref alib::lang::format::PropertyFormatter "PropertyFormatter"
69 /// which extends the format specification by custom identifiers which control the placement
70 /// of corresponding data in the format argument list. This class uses a translator table from
71 /// identifier strings to custom callback functions. This way, much more than just simple
72 /// field names are allowed.
73 ///
74 /// - When using positional arguments in a format string placeholders, the Python formatter
75 /// implementation does not allow to switch from <b>automatic field indexing</b> to explicit
76 /// indexing. This \b %Aib implementation does allow it. The automatic index (aka no positional
77 /// argument is given for a next placeholder) always starts with index \c 0 and is incremented
78 /// each time automatic indexing is used. Occurrences of explict indexing have no influence
79 /// on the automatic indexing.
80 ///
81 ///
82 /// <p>
83 /// - <b>Binary, Hexadecimal and Octal Numbers:</b>
84 /// - Binary, hexadecimal and octal output is <b>cut in size</b> (!) when a field width is given that
85 /// is smaller than the resulting amount of digits of the number arguments provided.
86 /// \note This implies that a value written might not be equal to the value given.
87 /// This is not a bug but a design decision. The rationale behind this is that with this
88 /// behavior, there is no need to mask lower digits when passing the arguments to the
89 /// format invocation. In other words, the formatter "assumes" that the given field width
90 /// indicates that only a corresponding number of lower digits are of interest.
91 ///
92 /// - If no width is given and the argument contains a boxed pointer, then the platform-dependent
93 /// full output width of pointer types is used.
94 ///
95 /// - The number <b>grouping option</b> (<c>','</c>) can also be used with binary, hexadecimal and octal
96 /// output.
97 /// The types support different grouping separators for nibbles, bytes, 16-bit and 32-bit words.
98 /// Changing the separator symbols, is not possible with the format fields of the format strings
99 /// (if it was, this would become very incompatible to Python standards). Changes have to be made
100 /// before the format operation by modifying field
101 /// \alib{lang::format;FormatterStdImpl::AlternativeNumberFormat;FormatterStdImpl::AlternativeNumberFormat}
102 /// which is provided through parent class \b %FormatterStdImpl.
103 ///
104 /// - Alternative form (\c '#') adds prefixes as specified in members
105 /// - \alib{strings;TNumberFormat::BinLiteralPrefix;BinLiteralPrefix},
106 /// - \alib{strings;TNumberFormat::HexLiteralPrefix;HexLiteralPrefix}, and
107 /// - \alib{strings;TNumberFormat::OctLiteralPrefix;OctLiteralPrefix}.
108 ///
109 /// For upper case formats, those are taken from field
110 /// \alib{lang::format;FormatterStdImpl::DefaultNumberFormat;FormatterStdImpl::DefaultNumberFormat},
111 /// for lower case formats from
112 /// \alib{lang::format;FormatterStdImpl::AlternativeNumberFormat;FormatterStdImpl::AlternativeNumberFormat}.
113 /// However, in alignment with the \b Python specification, \b both default to lower case
114 /// literals \c "0b", \c "0o" and \c "0x". All defaults may be changed by the user.
115 ///
116 ///
117 /// <p>
118 /// - <b>Floating point values:</b>
119 /// - If floating point values are provided without a type specification in the format string, then
120 /// all values of
121 /// \alib{lang::format;FormatterStdImpl::DefaultNumberFormat;FormatterStdImpl::DefaultNumberFormat}
122 /// are used to format the number
123 /// - For lower case floating point format types (\c 'f' and \c 'e'), the values specified in
124 /// attributes \b %ExponentSeparator, \b %NANLiteral and \b %INFLiteral of object
125 /// \alib{lang::format;FormatterStdImpl::AlternativeNumberFormat;FormatterStdImpl::AlternativeNumberFormat}
126 /// are used. For upper case types (\c 'F' and \c 'E') the corresponding attributes in
127 /// \alib{lang::format;FormatterStdImpl::DefaultNumberFormat;FormatterStdImpl::DefaultNumberFormat} apply.
128 /// - Fixed point formats (\c 'f' and 'F' types) are not supported to use an arbitrary length.
129 /// See class \alib{strings;TNumberFormat;NumberFormat} for the limits.
130 /// Also, very high values and values close to zero may be converted to scientific format.
131 /// Finally, if flag \alib{strings;NumberFormatFlags;ForceScientific} field
132 /// \alib{strings::NumberFormat;Flags} in member #DefaultNumberFormat is \c true, types
133 /// \c 'f' and 'F' behave like types \c 'e' and 'E'.
134 /// - When both, a \p{width} and a \p{precision} is given, then the \p{precision} determines the
135 /// fractional part, even if the type is \b 'g' or \b 'G'. This is different than specified with
136 /// Python formatter, which uses \p{precision} as the overall width in case of types
137 /// \b 'g' or \b 'G'.
138 /// - The 'general format' type for floats, specified with \c 'g' or \c 'G' in the python
139 /// implementation limits the precision of the fractional part, even if \p{precision} is not
140 /// further specified. This implementation does limit the precision only if type is \c 'f'
141 /// or \c 'F'.
142 ///
143 /// <p>
144 /// - <b>%String Conversion:</b><br>
145 /// If \e type \c 's' (or no \e type) is given in the \b format_spec of the replacement field,
146 /// a string representation of the given argument is used.
147 /// In \b Java and \b C# such representation is received by invoking <c>Object.[t|T]oString()</c>.
148 /// Consequently, to support string representations of custom types, in these languages
149 /// the corresponding <b>[t|T]oString()</b> methods of the type have to be implemented.
150 ///
151 /// In C++ the arguments are "boxed" into objects of type
152 /// \ref alib::boxing::Box "Box". For the string representation, the formatter invokes
153 /// box-function \alib{boxing;FAppend}. A default implementation exists which
154 /// for custom types appends the type name and the memory address of the object in hexadecimal
155 /// format. To support custom string representations (for custom types), this box-function
156 /// needs to be implemented for the type in question. Information and sample code on how to do this
157 /// is found in the documentation of \alib_boxing , chapter
158 /// \ref alib_boxing_strings_fappend "10.3 Box-Function FAppend".
159 ///
160 /// - <b>Hash-Value Output:</b><br>
161 /// In extension (and deviation) of the Python specification, format specification type \c 'h' and
162 /// its upper case version \c 'H' is implemented. The hash-values of the argument object is
163 /// written in hexadecimal format. Options of the type are identical to those of \c 'x',
164 /// respectively \c 'X'.
165 ///
166 /// In the C++ language implementation of \alib, instead of hash-values of objects, the pointer
167 /// found in method \alib{boxing;Box::Data} is printed. In case of boxed class-types and default
168 /// default boxing mechanics are used with such class types, this will show the memory address of
169 /// the given instance.
170 ///
171 /// - <b>Boolean output:</b><br>
172 /// In extension (and deviation) of the Python specification, format specification type \c 'B'
173 /// is implemented. The word \b "true" is written if the given value represents a boolean \c true
174 /// value, \b "false" otherwise.
175 ///
176 /// In the C++ language implementation of \alib, the argument is evaluated to boolean by invoking
177 /// box-function \alib{boxing;FIsTrue}.
178 ///
179 /// <p>
180 /// - <b>%Custom %Format Specifications:</b><br>
181 /// With \c Python formatting syntax, placeholders have the following syntax:
182 ///
183 /// "{" [field_name] ["!" conversion] [":" format_spec] "}"
184 ///
185 /// The part that follows the colon is called \b format_spec. \b Python passes this portion of the
186 /// placeholder to a built-in function \c format(). Now, each type may interpret this string in a
187 /// type specific way. But most built-in \b Python types do it along what they call the
188 /// \https{"Format Specification Mini Language",docs.python.org/3.5/library/string.html#format-specification-mini-language}.
189 ///
190 /// With this implementation, the approach is very similar. The only difference is that the
191 /// "Format Specification Mini Language" is implemented for standard types right within this class.
192 /// But before processing \b format_spec, this class will check if the argument type assigned to
193 /// the placeholder disposes about a custom implementation of box function \alib{lang::format;FFormat}.
194 /// If so, this function is invoked and string \b format_spec is passed for custom processing.
195 ///
196 /// Information and sample code on how to adopt custom types to support this interface is
197 /// found in the Programmer's Manual of this module, with chapter
198 /// \ref alib_basecamp_format_custom_types_fformat "4.3. Formatting Custom Types".
199 ///
200 /// For example, \alib class \alib{time;DateTime} supports custom formatting with box-function
201 /// \alib{lang::system;FFormat_DateTime} which uses helper-class \alib{lang::system;CalendarDateTime} that
202 /// provides a very common specific mini language for
203 /// \alib{lang::system::CalendarDateTime;Format;formatting date and time values}.
204 ///
205 /// <p>
206 /// - <b>Conversions:</b><br>
207 /// In the \b Python placeholder syntax specification:
208 ///
209 /// "{" [field_name] ["!" conversion] [":" format_spec] "}"
210 ///
211 /// symbol \c '!' if used before the colon <c>':'</c> defines
212 /// what is called the <b>conversion</b>. With \b Python, three options are given:
213 /// \c '!s' which calls \c str() on the value, \c '!r' which calls \c repr() and \c '!a' which
214 /// calls \c ascii(). This is of course not applicable to this formatter. As a replacement,
215 /// this class extends the original specification of that conversion using \c '!'.
216 /// The following provides a list of conversions supported. The names given can be abbreviated
217 /// at any point and ignore letter case, e.g., \c !Upper can be \c !UP or just \c !u.
218 /// In addition, multiple conversions can be given by concatenating them, each repeating
219 /// character \c '!'.<br>
220 /// The conversions supported are:
221 ///
222 /// - <b>!Upper</b><br>
223 /// Converts the contents of the field to upper case.
224 ///
225 /// - <b>!Lower</b><br>
226 /// Converts the contents of the field to lower case.
227 ///
228 /// - <b>!Quote[O[C]]</b><br>
229 /// Puts quote characters around the field.
230 /// Note that these characters are not respecting any optional given field width but instead
231 /// are added to such.
232 /// An alias name for \!Quote is given with \b !Str. As the alias can be abbreviated to \b !s,
233 /// this provides compatibility with the \b Python specification.
234 ///
235 /// In extension to the python syntax specification, one or two optional characters might be
236 /// given after the (optionally abreviated) terms "Quote" respectively "str".
237 /// If one character is given, this is used as the open and closing character. If two are given,
238 /// the first is used as the open character, the second as the closing one.
239 /// For example <b>{!Q'}</b> uses single quotes, or <b>{!Q[]}</b> uses rectangular brackets.
240 /// Bracket types <b>'{'</b> and <b>'}'</b> cannot be used with this conversion.
241 /// To surround a placeholder's contents in this bracket type, add <b>{{</b> and <b>}}</b>
242 /// around the placeholder - resulting in <b>{{{}}}</b>!.
243 ///
244 /// - <b>!ESC[<|>]</b><br>
245 /// In its default behavior or if \c '<' is specified, certain characters are converted to escape
246 /// sequences.
247 /// If \c '>' is given, escape sequences are converted to their (ascii) value.
248 /// See \alib{strings;TFormat::Escape;Format::Escape} for details about the conversion
249 /// that is performed.<br>
250 /// An alias name for \b !ESC< is given with \b !a which provides compatibility
251 /// with the \b Python specification.
252 /// \note If \b !ESC< is used in combination with \b !Quote, then \b !ESC< should be the first
253 /// conversion specifier. Otherwise, the quotes inserted might be escaped as well.
254 ///
255 /// - <b>!Fill[Cc]</b><br>
256 /// Inserts as many characters as denoted by the integer type argument.
257 /// By default the fill character is space <c>' '</c>. It can be changed with optional character
258 /// 'C' plus the character wanted.
259 ///
260 /// - <b>!Tab[Cc][NNN]</b><br>
261 /// Inserts fill characters to extend the length of the string to be a multiple of a tab width.
262 /// By default the fill character is space <c>' '</c>. It can be changed with optional character
263 /// 'C' plus the character wanted. The tab width defaults to \c 8. It can be changed by adding
264 /// an unsigned decimal number.
265 ///
266 /// - <b>!ATab[[Cc][NNN]|Reset]</b><br>
267 /// Inserts an "automatic tabulator stop". These are tabulator positions that are stored
268 /// internally and are automatically extended at the moment the actual contents exceeds the
269 /// currently stored tab-position. An arbitrary number of auto tab stop and field width
270 /// (see <b>!AWith</b> below) values is maintained by the formatter.
271 ///
272 /// Which each new invocation of \alib{lang::format;Formatter},
273 /// the first auto value is chosen and with each use of \c !ATab or \c !AWidth, the next value is
274 /// used.<br>
275 /// However the stored values are cleared, whenever \b %Format is invoked on a non-acquired
276 /// formatter! This means, to preserve the auto-positions across multiple format invocations,
277 /// a formatter has to be acquired explicitly before the format operations and released
278 /// afterwards.
279 ///
280 /// Alternatively to this, the positions currently stored with the formatter can be reset with
281 /// providing argument \c Reset in the format string.
282 ///
283 /// By default, the fill character is space <c>' '</c>. It can be changed with optional character
284 /// 'C' plus the character wanted. The optional number provided gives the growth value by which
285 /// the tab will grow if its position is exceeded. This value defaults to \c 3.
286 ///
287 /// Both, auto tab and auto width conversions may be used to increase readability of multiple
288 /// output lines. Of course, output is not completely tabular, only if those values that result
289 /// in the biggest sizes are formatted first. If a perfect tabular output is desired, the data
290 /// to be formatted may be processed twice: Once to temporary buffer which is disposed and then
291 /// a second time to the desired output \b %AString.
292 ///
293 /// - <b>!AWidth[NNN|Reset]</b><br>
294 /// Increases field width with repetitive invocations of format whenever a field value did not
295 /// fit to the actually stored width. Optional decimal number \b NNN is added as a padding value.
296 /// for more information, see <b>!ATab</b> above.
297 ///
298 /// - <b>!Xtinguish</b><br>
299 /// Does not print anything. This is useful if format strings are externalized, e.g defined
300 /// in \alib{lang::Camp;GetResourcePool;library resources}. Modifications of such resources
301 /// might use this conversion to suppress the display of arguments (which usually are
302 /// hard-coded).
303 ///
304 /// - <b>!Replace<search><replace></b><br>
305 /// Searches string \p{search} and replaces with \p{replace}. Both values have to be given
306 /// enclosed by characters \c '<' and \c '>'. In the special case that \p{search} is empty
307 /// (<c><></c>), string \p{replace} will be inserted if the field argument is an empty
308 /// string.
309 ///
310 ///\I{##########################################################################################}
311 /// # Reference Documentation #
312 /// @throws <b>alib::lang::format::FMTExceptions</b>
313 /// - \alib{lang::format::FMTExceptions;ArgumentIndexOutOfBounds}
314 /// - \alib{lang::format::FMTExceptions;IncompatibleTypeCode}
315 /// - \alib{lang::format::FMTExceptions;MissingClosingBracket}
316 /// - \alib{lang::format::FMTExceptions;MissingPrecisionValuePS}
317 /// - \alib{lang::format::FMTExceptions;DuplicateTypeCode}
318 /// - \alib{lang::format::FMTExceptions;UnknownTypeCode}
319 /// - \alib{lang::format::FMTExceptions;ExclamationMarkExpected}
320 /// - \alib{lang::format::FMTExceptions;UnknownConversionPS}
321 /// - \alib{lang::format::FMTExceptions;PrecisionSpecificationWithInteger}
322 //==============================================================================================
324 {
325 // #############################################################################################
326 // Protected fields
327 // #############################################################################################
328 protected:
329 /// Set of extended placeholder attributes, needed for this type of formatter in
330 /// addition to parent's \alib{lang::format::FormatterStdImpl;PlaceholderAttributes}.
332 {
333 /// The portion of the replacement field that represents the conversion specification.
334 /// This specification is given at the beginning of the replacement field, starting with
335 /// \c '!'.
337
338 /// The position where the conversion was read. This is set to \c -1 in #resetPlaceholder.
340
341
342 /// The value read from the precision field. This is set to \c -1 in #resetPlaceholder.
344
345 /// The position where the precision was read. This is set to \c -1 in #resetPlaceholder.
347
348 /// The default precision if not given.
349 /// This is set to \c 6 in #resetPlaceholder, but is changed when specific.
351 };
352
353 /// The extended placeholder attributes.
355
356 // #############################################################################################
357 // Public fields
358 // #############################################################################################
359 public:
360 /// Storage of sizes for auto-tabulator feature <b>{!ATab}</b> and auto field width feature
361 /// <b>{!AWidth}</b>
363
364 /// The default instance of field #Sizes. This might be replaced with an external object.
366
367 // #############################################################################################
368 // Constructor/Destructor
369 // #############################################################################################
370 public:
371 //==========================================================================================
372 /// Constructs this formatter.
373 /// Inherited field #DefaultNumberFormat is initialized to meet the formatting defaults of
374 /// Python.
375 //==========================================================================================
378
379 //==========================================================================================
380 /// Clones and returns a copy of this formatter.
381 ///
382 /// If the formatter attached to field
383 /// \alib{lang::format;Formatter::Next} is of type \b %FormatterStdImpl, then that
384 /// formatter is copied as well.
385 ///
386 /// @returns An object of type \b %FormatterPythonStyle and with the same custom settings
387 /// than this.
388 //==========================================================================================
389 ALIB_API virtual
390 SPFormatter Clone() override;
391
392 //==========================================================================================
393 /// Resets #AutoSizes.
394 /// @return An internally allocated container of boxes that may be used to collect
395 /// formatter arguments.
396 //==========================================================================================
397 virtual BoxesMA& Reset() override
398 {
399 Sizes->Reset();
400 return Formatter::Reset();
401 }
402
403
404 // #############################################################################################
405 // Implementation of FormatterStdImpl interface
406 // #############################################################################################
407 protected:
408 //==========================================================================================
409 /// Sets the actual auto tab stop index to \c 0.
410 //==========================================================================================
411 virtual void initializeFormat() override
412 {
413 Sizes->Restart();
414 }
415
416
417
418 //==========================================================================================
419 /// Invokes parent implementation and then applies some changes to reflect what is defined as
420 /// default in the Python string format specification.
421 //==========================================================================================
423 virtual void resetPlaceholder() override;
424
425 //==========================================================================================
426 /// Searches for \c '{' which is not '{{'.
427 ///
428 /// @return The index found, -1 if not found.
429 //==========================================================================================
431 virtual integer findPlaceholder() override;
432
433 //==========================================================================================
434 /// Parses placeholder field in python notation. The portion \p{format_spec} is not
435 /// parsed but stored in member
436 /// \alib{lang::format::FormatterStdImpl::PlaceholderAttributes;FormatSpec}.
437 ///
438 /// @return \c true on success, \c false on errors.
439 //==========================================================================================
441 virtual bool parsePlaceholder() override;
442
443 //==========================================================================================
444 /// Parses the format specification for standard types as specified in
445 /// \https{"Format Specification Mini Language",docs.python.org/3.5/library/string.html#format-specification-mini-language}.
446 ///
447 /// @return \c true on success, \c false on errors.
448 //==========================================================================================
450 virtual bool parseStdFormatSpec() override;
451
452 //==========================================================================================
453 /// Implementation of abstract method
454 /// \alib{lang::format;FormatterStdImpl::writeStringPortion}.<br>
455 /// While writing, replaces \c "{{" with \c "{" and \c "}}" with \c "}" as well as
456 /// standard codes like \c "\\n", \c "\\r" or \c "\\t" with corresponding ascii codes.
457 ///
458 /// @param length The number of characters to write.
459 //==========================================================================================
461 virtual void writeStringPortion( integer length ) override;
462
463 //==========================================================================================
464 /// Processes "conversions" which are specified with \c '!'.
465 ///
466 /// @param startIdx The index of the start of the field written in #targetString.
467 /// \c -1 indicates pre-phase.
468 /// @param target The target string, only if different from field #targetString, which
469 /// indicates intermediate phase.
470 /// @return \c false, if the placeholder should be skipped (nothing is written for it).
471 /// \c true otherwise.
472 //==========================================================================================
474 virtual bool preAndPostProcess( integer startIdx,
475 AString* target ) override;
476
477
478 //==========================================================================================
479 /// Makes some attribute adjustments and invokes standard implementation
480 /// @return \c true if OK, \c false if replacement should be aborted.
481 //==========================================================================================
483 virtual bool checkStdFieldAgainstArgument() override;
484 };
485} // namespace [alib::lang::format]
486
487#endif // HPP_ALIB_LANG_FORMAT_FORMATTER_PYTHONSTYLE
488
virtual ALIB_API integer findPlaceholder() override
virtual ALIB_API bool preAndPostProcess(integer startIdx, AString *target) override
virtual ALIB_API bool checkStdFieldAgainstArgument() override
virtual ALIB_API SPFormatter Clone() override
virtual ALIB_API bool parsePlaceholder() override
AutoSizes SizesDefaultInstance
The default instance of field Sizes. This might be replaced with an external object.
virtual ALIB_API void writeStringPortion(integer length) override
virtual void initializeFormat() override
Sets the actual auto tab stop index to 0.
virtual ALIB_API bool parseStdFormatSpec() override
PlaceholderAttributesPS placeholderPS
The extended placeholder attributes.
virtual ALIB_API void resetPlaceholder() override
virtual BoxesMA & Reset()
void Restart(unsigned int startIdx=0)
#define ALIB_API
Definition alib.hpp:639
platform_specific integer
Definition integers.hpp:43
int PrecisionPos
The position where the precision was read. This is set to -1 in resetPlaceholder.
int Precision
The value read from the precision field. This is set to -1 in resetPlaceholder.
int ConversionPos
The position where the conversion was read. This is set to -1 in resetPlaceholder.