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