ALib C++ Library
Library Version: 2510 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
numberformat.inl
Go to the documentation of this file.
1//==================================================================================================
2/// \file
3/// This header-file is part of module \alib_strings of the \aliblong.
4///
5/// \emoji :copyright: 2013-2025 A-Worx GmbH, Germany.
6/// Published under \ref mainpage_license "Boost Software License".
7//==================================================================================================
8ALIB_EXPORT namespace alib { namespace strings {
9
10
11/// Flags used with class \alib{strings;TNumberFormat}.
12/// By default (with construction of an instance of \b TNumberFormat), all flags are unset,
13/// except #ForceDecimalPoint.
14enum class NumberFormatFlags : uint8_t
15{
16 /// If assigned, all flags are unset.
17 NONE = 0,
18
19 /// Denotes if grouping characters are ignored when parsing numbers if they are given
20 /// (not set to \c '\0').
21 /// This applies to all number types.<br>
22 /// Defaults to \c false. If set to \c true, grouping characters are just skipped when
23 /// found while parsing numbers, no matter at which position they occur.
25
26 /// Denotes if grouping characters are written if they are given (not set to \c '\0').
27 /// This applies to all number types.
29
30 /// If \c true, the decimal point of floating point values is written, even if the fractional
31 /// part of the float value is zero. If \c false, in this case the decimal point is omitted.<br>
32 /// Defaults to \c true.
34
35 /// Determines if positive exponent values are prepended with an explicit '+' character when
36 /// written using \alib{strings::detail;WriteFloat}.<br>
37 /// Defaults to \c false, as some systems will not accept a plus sign on the exponent value.
38 /// Note that field \alib{strings;TNumberFormat::PlusSign} is not applicable for exponent numbers.
40
41 /// If this flag ist set, then trailing \c '0' digits in the fractional part of a floating
42 /// point value are not written, even if a \alib{strings;TNumberFormat::FractionalPartWidth}
43 /// is set.
45
46
47 /// If this flag ist set, then leading \c '0' digits and group characters are replaced with
48 /// spaces. This applies to integral values and to the integral part of floating point values,
49 /// in the case that \alib{strings;TNumberFormat::DecMinimumFieldWidth}, respectively
50 /// \alib{strings;TNumberFormat::IntegralPartMinimumWidth}, specifies the output to be wider
51 /// than the number printed.
53
54 /// If \c true, scientific format is always used.<br>
55 /// If \c false (the default), function \alib{strings::detail;WriteFloat} writes scientific
56 /// format only if both fields, \alib{strings;TNumberFormat::IntegralPartMinimumWidth} and
57 /// \alib{strings;TNumberFormat::FractionalPartWidth} are evaluating to \c -1 and only for
58 /// numbers smaller than \c 10E-04 or larger than \c 10E+06.<br>
59 ///
60 /// If one of the fields \alib{strings;TNumberFormat::IntegralPartMinimumWidth} or
61 /// \alib{strings;TNumberFormat::FractionalPartWidth} is set to a positive
62 /// value, these limits get extended. Function \alib{strings::detail;WriteFloat} in this case
63 /// keeps non-scientific notation established if possible.
65
66 /// If \c true, lower case letters \c 'a' - \c 'f' are written.
67 /// Defaults to \c false, which writes upper case letters \c 'A' - \c 'F'.
69}; // enum class NumberFormatFlags
70
71
72//==================================================================================================
73/// This struct defines flags and values that denote the format of conversion of integer and floating
74/// point values to string representations, as well as the reverse operation, thus the
75/// format expected when parsing numbers from strings.
76///
77/// In namespace #alib::strings::detail, corresponding functions that use an instance of this
78/// type are implemented. However, those functions are not intended for common use.
79/// Instead, the interface of classes
80/// \alib{strings;TString;String},
81/// \alib{strings;TSubstring;Substring},
82/// \alib{strings;TAString;AString} or
83/// \alib{format;Formatter}
84/// are preferred to write and parse numbers. Also those accept an object of this type as parameters.
85///
86/// <b>Defined Singletons and User-Defined Instances:</b><br>
87/// Two static singletons of this class, both initialized with function \alib{Bootstrap},
88/// are defined which can be used wherever a number format object is needed as a parameter:
89/// - #Global: Reflects locale-specific settings.
90///
91/// - #Computational:<br>
92/// Intended to be used for writing and parsing numbers which are readable by software (not
93/// humans). Its decimal point character is set to \c '.', the international standard.
94/// Furthermore no group separators are set for decimal and decimal floating point as well as
95/// for binary, hexadecimal and octal conversions.
96///
97/// Any user-defined object defaults to the computational setting after construction.
98///
99/// <b>Output Formats:</b><br>
100/// The following conversion formats are supported:
101///
102/// - \b Decimal<br>
103/// Supports optional minimum output width with field #DecMinimumFieldWidth,
104/// and definable <em>thousands grouping character</em> with field #ThousandsGroupChar, which can
105/// be activated with field #WriteGroupChars.<br>
106/// Furthermore, the plus-sign can be controlled (#PlusSign) to be either omitted or be anything
107/// defined. Of course, values <c>' '</c> and <c>'+'</c> are reasonable options.
108///
109/// - <b>Binary</b><br>
110/// Binary output supports up to 64 digits and different group separators for nibbles, bytes,
111/// 16-bit words and 32 bit words. (See #BinNibbleGroupChar, #BinByteGroupChar,
112/// #BinWordGroupChar and #BinWord32GroupChar ).<br>
113/// When parsing integers, a customizable literal string defined in #BinLiteralPrefix might be used
114/// to auto-detect binary values.
115///
116/// - <b>Hexadecimal</b><br>
117/// Hexadecimal output supports up to 16 digits (64-bit) and different group separators
118/// for bytes, 16-bit words and 32 bit words. (See #HexByteGroupChar, #HexWordGroupChar,
119/// and #HexWord32GroupChar).
120/// When parsing integers, a customizable literal string defined in #HexLiteralPrefix might be used
121/// to auto-detect hexadecimal values.
122///
123/// - <b>Octal</b><br>
124/// Octal output supports up to 22 digits (64-bit) and different a group separator for groups
125/// of three digits defined with #OctGroupChar.
126/// When parsing integers, a customizable literal string defined in #OctLiteralPrefix might be used
127/// to auto-detect hexadecimal values.
128///
129/// - <b>Floating Point</b><br>
130/// The width of the output is provided in two fields, #IntegralPartMinimumWidth and
131/// #FractionalPartWidth. While the integral part is a minimum width (and nothing is ever cut),
132/// the fractional part denotes a fixed width.
133/// Values with higher fractional precision are rounded accordingly.
134/// Note that the parameter of the interface functions that may override the width, in the floating
135/// point case only affects the minimum width of the integral part.<br>
136/// The integral and fractional part of float values are separated by decimalPointChar.
137/// This field of course has to be different from group separator #ThousandsGroupChar, which can
138/// be activated using field #WriteGroupChars.<br>
139/// Other important fields used for writing and parsing floats are: #ExponentSeparator,
140/// #INFLiteral, #NANLiteral, #WriteExponentPlusSign, and #ForceScientific.
141///
142/// <b>Notes on Writing and Parsing Values:</b><br>
143/// For decimal output, the width (#DecMinimumFieldWidth) is a minimum width. This means, that
144/// bigger numbers are written in a higher width.
145///
146/// \attention
147/// This is \c not true for binary, hexadecimal and octal output. In these formats, the width
148/// provided with fields #BinFieldWidth, #HexFieldWidth and #OctFieldWidth, denote an \b absolute
149/// value. Higher digits of numbers are not written! The advantage of this design is that no
150/// masking is needed when just the lower part of an integer number should be written.
151/// However, if a width is set, values might of course change when cut and parsed back later!
152///
153/// All of the integral formats have in common that the output width given includes optional
154/// grouping characters. For example if a width of \b 5 was given for decimal output, the value
155/// \c 12 would be written \c "0,012", hence \b 4 digits plus the grouping character. If grouping
156/// was disabled, the output became \c "00012", which uses one extra digit instead of the group
157/// character.
158/// In contrast to that, sign characters are \c not counted in the width.
159///
160/// When parsing values, grouping characters are ignored at any position within the digits,
161/// except of the start. The same is true for whitespace characters as defined in
162/// #Whitespaces. When this field is \e nulled or empty, then white spaces are \b not ignored.
163/// This might be helpful in some cases where occurrence of white space characters should
164/// indicate an error (or something else) when parsing.
165/// Otherwise, the characters defined in this field are ignored at two places: at the beginning
166/// of a parsing operation and after a sign character was read.
167///
168/// When parsing fails, a value of \c 0 (respectively \c 0.0) is returned by the functions of
169/// namespace #alib::strings::detail which are using this class.
170/// User-friendly classes that use the interface of this type will detect such failure through the
171/// output parameter of the parsing functions, which indicates the index of the end of
172/// the number found.
173///
174/// For each of the four integer formats, decimal, binary, hexadecimal and octal, dedicated
175/// parsing functions exist. Those do not accept literal prefix identifiers as defined in
176/// fields #BinLiteralPrefix, #HexLiteralPrefix and #OctLiteralPrefix. However, the prefixes \b are
177/// identified by function \alib{strings::detail;ParseInt}, which aggregates the other four parsing
178/// functions.<br>
179/// There is no corresponding function defined that writes the literal prefix. When writing
180/// binary, hexadecimal or octal values, such prefixes have to be prepended explicitly by a
181/// user's code.
182///
183/// @tparam TChar The \ref alib_characters_chars "character type" that this class works on.
184/// Alias names for specializations using the different character types are
185/// provided in namespace #alib with type definitions
186/// \alib{NumberFormat},
187/// \alib{NNumberFormat},
188/// \alib{WNumberFormat},
189/// \alib{XNumberFormat},
190/// \alib{ComplementNumberFormat}, and
191/// \alib{StrangeNumberFormat}.
192//==================================================================================================
193template<typename TChar>
195{
196 /// The default static number format object that acts as the default settings of the currently
197 /// running process.<br>
198 /// Function \alib{Bootstrap} invokes #SetFromLocale() on this object and switches grouping
199 /// to \e 'on'.
200 ///
201 /// Classes providing functionality based on this class, might use this as a default
202 /// value for parameters of their interfaces.
204
205 /// A static number format object that may be used to write and parse numbers for 'computational'
206 /// use, which means, that grouping is switched off and decimal point character
207 /// is \c '.'.<br>
208 /// Function \alib{Bootstrap} invokes #SetComputational on this object.
209 ///
210 /// Classes providing functionality based on this class, might use this as a default
211 /// value for parameters of their interfaces.
213
214 // ############################### string members ###################################
215 /// Defines whitespace characters that are ignored when leading the number and after
216 /// the sign-character. Applies to functions
217 /// \alib{strings::detail;ParseInt} and
218 /// \alib{strings::detail;ParseFloat}. In contrast, functions
219 /// \alib{strings::detail;ParseDec},
220 /// \alib{strings::detail;ParseBin},
221 /// \alib{strings::detail;ParseHex}, and
222 /// \alib{strings::detail;ParseOct} do not ignore any whitespace characters.
224
225 /// Defines the decimal exponent symbol of string representations of floating point numbers
226 /// when written or parsed in scientific notation by functions \alib{strings::detail;ParseFloat}
227 /// and \alib{strings::detail;WriteFloat}.<br>
228 /// Function \alib{strings::detail;ParseFloat} accepts characters 'e' and 'E' in addition to
229 /// the character set in this field.<br>
230 /// Defaults to \c 'E'.
232
233 /// Defines what is written and parsed for infinite double values.
235
236 /// Defines what is written and parsed for double values that represent "not a number".
238
239 /// Used by function \alib{strings::detail;ParseInt} to detect binary format of integral values.
240 /// If \e nulled, no binary format is detected.
241 /// Functions provided with \alib are not writing the prefix. If this is desired, it has to
242 /// be performed explicitly by the user code.<br>
243 /// Defaults to \c "0b".
245
246 /// Used by function \alib{strings::detail;ParseInt} to detect hexadecimal format of integer
247 /// values. If \e nulled, no hexadecimal format is detected.
248 /// Functions provided with \alib are not writing the prefix. If this is desired, it has to
249 /// be performed explicitly by the user code.<br>
250 /// Defaults to \c "0x".
252
253 /// Used by function \alib{strings::detail;ParseInt} to detect octal format of integral values.
254 /// If \e nulled, no octal format is detected.
255 /// Functions provided with \alib are not writing the prefix. If this is desired, it has to
256 /// be performed explicitly by the user code.<br>
257 /// Defaults to \c "0o".
259
260 // ############################### character members ###################################
261
262 /// Defines the decimal point character when converting a floating point number to a string
263 /// representation with function \alib{strings::detail;WriteFloat}. Also; function \alib{strings::detail;ParseFloat} uses
264 /// the character provided in this field for parsing the character.<br>
265 /// The field defaults to '.'. By invoking #SetFromLocale(), the current locale's setting is
266 /// determined.
268
269 /// Determines if positive values are prepended with an explicit character (usually '+') when
270 /// written using \alib{strings::detail;WriteFloat} or \alib{strings::detail;WriteDecSigned}.<br>
271 /// Defaults to \c 0 which omits the writing. Usual other values are of course \c '+', but
272 /// also <c>' '</c> (space) which supports better horizontal alignment of numbers when written in
273 /// columns. Note that this is not affecting exponent decimals of floating point values.
274 /// For those, see #WriteExponentPlusSign
275 TChar PlusSign;
276
277 /// Defines the separator character for thousands when converting a number to a string
278 /// representation. In addition, this is used to identify grouping symbols when
279 /// parsing decimal values. If set to \c '\0', no group separator is written and also when
280 /// parsing, a group separator is not accepted.
281 /// If set, still #WriteGroupChars controls if it is written.<br>
282 /// Defaults to \c ','.
283 /// By invoking #SetFromLocale(), the current locale's setting is determined.
285
286 /// This character is written instead of a grouping character in the case that a certain
287 /// output width is requested but a grouping character would be the first character to write.
288 /// Writing this character instead, ensures the field width to be as requested.
289 /// Defaults to space (<c>' '</c>).
291
292
293 /// Defines the separator character for nibbles (4 bits) of binary numbers.
294 /// Defaults to \c '\0' what disables reading and writing of nibble group characters.
296
297 /// Defines the separator character for bytes of binary numbers.
298 /// Defaults to \c '\0' what chooses #BinNibbleGroupChar.
300
301 /// Defines the separator character for 16-bit words of binary numbers.
302 /// Defaults to \c '\0' what chooses #BinByteGroupChar.
304
305 /// Defines the separator character for 32-bit words of binary numbers.
306 /// Defaults to \c '\0' what chooses #BinWordGroupChar.
308
309 /// Defines the separator character for bytes of hexadecimal numbers. Defaults to \c 0,
310 /// Defaults to \c '\0' what disables reading and writing of byte group characters.
312
313 /// Defines the separator character for 16-bit words of hexadecimal numbers.
314 /// Defaults to \c '\0' what chooses #HexByteGroupChar.
316
317 /// Defines the separator character for 32-bit words of hexadecimal numbers.
318 /// Defaults to \c '\0' what chooses #HexWordGroupChar.
320
321 /// Defines the separator character for bytes of hexadecimal numbers.
322 /// Defaults to \c '\0' what disables reading and writing of byte group characters.
324
325 /// The flag field.
327
328 // ############################ width members ###############################
329 /// Defines the minimum digits written for the integral part when converting a floating point
330 /// value into a string.<br>
331 /// If the integral part of the number provided has less digits
332 /// then leading '0' digits are added.<br>
333 /// The maximum value allowed is 15.<br>
334 /// A value of 0 leads to omitting the '0' before the
335 /// decimal separator in the case the value is below 1.0 and higher than -1.0 <br>
336 /// The default value is -1, which writes a minimum of 1 digit.
337 ///
338 /// When either this field or field #FractionalPartWidth is set to a positive value,
339 /// the limits to switch to scientific notation, which otherwise are fixed \c 10E-04 and
340 /// \c 10E+06, get extended. Function \alib{strings::detail;WriteFloat} in this case keeps
341 /// non-scientific notation established if possible.
343
344 /// Defines the number of digits written for the fractional part when converting a floating point
345 /// value into a string. (For integer conversion, see #DecMinimumFieldWidth.)<br>
346 /// If the fractional part of the number provided has less digits then trailing '0'
347 /// digits are added.<br>
348 /// If the fractional part of the number provided has more digits then the fractional part is
349 /// rounded accordingly.<br>
350 /// The maximum value allowed is 15.<br>
351 /// The default value is -1, which writes as many digits as available in the provided float
352 /// variable, with a minimum of 1 digit.
353 ///
354 /// When either this field or field #IntegralPartMinimumWidth is set to a positive value,
355 /// the limits to switch to scientific notation, which otherwise are fixed \c 10E-04 and
356 /// \c 10E+06, get extended. Function \alib{strings::detail;WriteFloat} in this case keeps non-scientific notation
357 /// established if possible.
359
360 /// Defines the minimum digits and grouping symbols written when writing integers in decimal.
361 /// format. If the value to write has less digits (and grouping symbols), then leading '0'
362 /// digits (and eventually grouping symbols) are added.<br> If the value to write has more
363 /// digits, then this field is ignored.
364 /// A sign character is not calculated into the writing width. To have negative and positive
365 /// numbers resulting in the same width, #PlusSign has to be set to a value unequal to \c '\0'
366 /// (usually space character <c>' '</c> or \c '+').
367 ///
368 /// If this field is negative, it is ignored. Defaults to \c -1.
370
371 /// Defines the digits written when writing binary values.
372 /// If the value has less digits, then leading '0' digits are added. If it has more, than
373 /// those digits are \b NOT written (!).<br>
374 /// The default value and minimum value is \c -1, which writes as many bits as necessary.
376
377 /// Defines the digits written when writing hexadecimal values.
378 /// If the value has less digits, then leading '0' digits are added. If it has more, than
379 /// those digits are \b NOT written (!).<br>
380 /// The default value and minimum value is \c -1, which writes as many bits as necessary.
382
383
384 /// Defines the digits written when writing hexadecimal values.
385 /// If the value has less digits, then leading '0' digits are added. If it has more, than
386 /// those digits are \b NOT written (!).<br>
387 /// The default value and minimum value is \c -1, which writes as many bits as necessary.
389
390
391 // #############################################################################################
392 // Interface
393 // #############################################################################################
394
395 //==============================================================================================
396 /// Default constructor. Invokes #SetComputational to reset all fields to their default values.
397 //==============================================================================================
399 {
401 }
402
403 //==============================================================================================
404 /// Copies all fields (settings) from the given object. If no object is provided, values of
405 /// the static singleton found in field #Global are copied
406 ///
407 /// @param other The \b %NumberFormat object to copy the values from.
408 /// Defaults to \c nullptr, which chooses the global singleton.
409 //==============================================================================================
410 void Set( TNumberFormat* other =nullptr );
411
412 //==============================================================================================
413 /// Resets the object to its default values. This method is called in the constructor.
414 ///
415 /// Decimal point character and grouping characters are set as follows:
416 /// <center>Field</center> | <center>Value</center>
417 /// - - - - - - - - - - - - - - - -| - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - -
418 /// #DecimalPointChar | \c .
419 /// #ThousandsGroupChar | \c ,
420 /// #BinNibbleGroupChar | \c '
421 /// #BinByteGroupChar | \c -
422 /// #BinWordGroupChar | <c>' '</c> (space)
423 /// #BinWord32GroupChar | \c #
424 /// #HexWordGroupChar | \c '
425 /// #HexWord32GroupChar | \c '
426 /// #HexByteGroupChar | \c 0 (none)
427 /// #OctGroupChar | \c '
428 ///
429 /// The literal attributes are set as follows:
430 /// <center>Field</center> | <center>Value</center>
431 /// - - - - - - - - - - - - - - - -| - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - -
432 /// #ExponentSeparator | \c "E"
433 /// #INFLiteral | \c "INF"
434 /// #NANLiteral | \c "NAN"
435 /// #BinLiteralPrefix | \c "0b"
436 /// #HexLiteralPrefix | \c "0x"
437 /// #OctLiteralPrefix | \c "0o"
438 ///
439 /// All width-attributes are reset to "automatic mode", \c -1. The attributes are
440 /// #IntegralPartMinimumWidth,
441 /// #FractionalPartWidth,
442 /// #DecMinimumFieldWidth,
443 /// #BinFieldWidth,
444 /// #HexFieldWidth and
445 /// #OctFieldWidth.
446 ///
447 /// Finally, the following further fields are reset to their default values:
448 /// <center>Field</center> | <center>Value</center>
449 /// - - - - - - - - - - - - - - - -| - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - -
450 /// #WriteGroupChars | \c false
451 /// #ForceScientific | \c false
452 /// #ForceDecimalPoint | \c true
453 /// #PlusSign | \c none (0)
454 /// #WriteExponentPlusSign | \c false
455 /// #OmitTrailingFractionalZeros | \c false
456 /// #HexLowerCase | \c false
457 /// #Whitespaces | #alib::DEFAULT_WHITESPACES
458 ///
459 ///
460 /// \note
461 /// With static object
462 /// \ref alib::strings::TNumberFormat::Computational "TNumberFormat::Computational",
463 /// there is a global singleton existing which can be used but must not be changed.
464 //==============================================================================================
466
467 //==============================================================================================
468 /// Sets the field #DecimalPointChar and #ThousandsGroupChar to reflect the current
469 /// system locale setting. No other values are changed.
470 ///
471 /// \note
472 /// Static (global) object \ref alib::strings::TNumberFormat::Global "TNumberFormat::Global",
473 /// implements an instance which has the right locale set (provided that function
474 /// \alib{Bootstrap} was duly invoked by the process).
475 /// Otherwise, this method might be used to initialize a custom object with default values
476 /// to afterwards make some specific changes.
477 //==============================================================================================
479};
480
481//! @cond NO_DOX
482
483extern template ALIB_DLL void TNumberFormat<nchar>::Set ( TNumberFormat* );
484extern template ALIB_DLL void TNumberFormat<nchar>::SetFromLocale ();
485
486
487extern template ALIB_DLL void TNumberFormat<wchar>::Set ( TNumberFormat* );
488extern template ALIB_DLL void TNumberFormat<wchar>::SetFromLocale ();
489
490
491extern template ALIB_DLL void TNumberFormat<xchar>::Set ( TNumberFormat* );
492extern template ALIB_DLL void TNumberFormat<xchar>::SetFromLocale ();
493
494
498
501//! @endcond
502
503} // namespace alib::[strings]
504
505/// Type alias in namespace \b alib.
507
508/// Type alias in namespace \b alib.
510
511/// Type alias in namespace \b alib.
513
514/// Type alias in namespace \b alib.
516
517/// Type alias in namespace \b alib.
519
520/// Type alias in namespace \b alib.
522
523/// Type alias in namespace \b alib.
525
526
527} // namespace [alib]
528
529
#define ALIB_DLL
Definition alib.inl:496
#define ALIB_ENUMS_MAKE_BITWISE(TEnum)
#define ALIB_EXPORT
Definition alib.inl:488
@ NONE
If assigned, all flags are unset.
strings::TNumberFormat< nchar > NNumberFormat
Type alias in namespace alib.
strings::TNumberFormat< xchar > XNumberFormat
Type alias in namespace alib.
strings::NumberFormatFlags NumberFormatFlags
Type alias in namespace alib.
strings::TNumberFormat< complementChar > ComplementNumberFormat
Type alias in namespace alib.
strings::TNumberFormat< character > NumberFormat
Type alias in namespace alib.
strings::TNumberFormat< strangeChar > StrangeNumberFormat
Type alias in namespace alib.
strings::TNumberFormat< wchar > WNumberFormat
Type alias in namespace alib.
void Set(TNumberFormat *other=nullptr)
TNumberFormat()
Default constructor. Invokes SetComputational to reset all fields to their default values.