Implements a Formatter according to the formatting standards of the Python language .
In general, the original Python specification is covered quite well. However, there are some differences, some things are not possible (considering python being a scripting language) but then there are also found some very helpful extensions to that standard. Instead of repeating a complete documentation, please refer to the Python Documentation as the foundation and then take note of the following list of differences, extensions and general hints:
"{" [field_name] ["!" conversion] [":" format_spec] "}"
{:11.5,}
where Python allows only {:11,.5}
0
and is incremented each time automatic indexing is used. Occurrences of explict indexing have no influence on the automatic indexing.','
) can also be used with binary, hexadecimal and octal output. The types support different grouping separators for nibbles, bytes, 16-bit and 32-bit words. Changing the separator symbols, is not possible with the format fields of the format strings (if it was, this would become very incompatible to Python standards). Changes have to be made prior to the format operation by modifying field FormatterStdImpl::AlternativeNumberFormat which is provided through parent class FormatterStdImpl.Alternative form ('#'
) adds prefixes as specified in members
For upper case formats, those are taken from field FormatterStdImpl::DefaultNumberFormat , for lower case formats from FormatterStdImpl::AlternativeNumberFormat . However, in alignment with the Python specification, both default to lower case literals "0b"
, "0o"
and "0x"
. All defaults may be changed by the user.
'f'
and 'e'
), the values specified in attributes ExponentSeparator, NANLiteral and INFLiteral of object FormatterStdImpl::AlternativeNumberFormat are used. For upper case types ('F'
and 'E'
) the corresponding attributes in FormatterStdImpl::DefaultNumberFormat apply.'f'
and 'F' types) are not supported to use arbitrary length. See class NumberFormat for the limits. Also, very high values and values close to zero may be converted to scientific format. Finally, if flag ForceScientific field Flags in member DefaultNumberFormat is true
, types 'f'
and 'F' behave like types 'e'
and 'E'.'g'
or 'G'
in the python implementation limits the precision of the fractional part, even if precision is not further specified. This implementation does limit the precision only if type is 'f'
or 'F'
.String Conversion:
If type 's'
(or no type) is given in the format_spec of the replacement field, a string representation of the given argument is used. In Java and C# such representation is received by invoking Object.[t|T]oString()
. Consequently, to support string representations of custom types, in these languages the corresponding [t|T]oString() methods of the type have to be implemented.
In C++ the arguments are "boxed" into objects of type Box. For the string representation, the formatter invokes box-function FAppend . A default implementation exists which for custom types appends the type name and the memory address of the object in hexadecimal format. To support custom string representations (for custom types), this box-function needs to be implemented for the type in question. Information and sample code on how to do this is found in the documentation of ALib Boxing , chapter 10.3 Box-Function FAppend.
Hash-Value Output:
In extension (and deviation) of the Python specification, format specification type 'h'
and its upper case version 'H'
is implemented. The hash-values of the argument object is written in hexadecimal format. Options of the type are identical to those of 'x'
, respectively 'X'
.
In the C++ language implementation of ALib , instead of hash-values of objects, the pointer found in method Box::Data is printed. In case of boxed class-types and default default boxing mechanics are used with such class types, this will show the memory address of the given instance.
Boolean output:
In extension (and deviation) of the Python specification, format specification type 'B'
is implemented. The word "true" is written if the given value represents a boolean true
value, "false" otherwise.
In the C++ language implementation of ALib , the argument is evaluated to boolean by invoking box-function FIsTrue .
Custom Format Specifications:
With Python
formatting syntax, placeholders have the following syntax:
"{" [field_name] ["!" conversion] [":" format_spec] "}"
The part that follows the colon is called format_spec. Python passes this portion of the placeholder to a built-in function format()
. Now, each type may interpret this string in a type specific way. But most built-in Python types do it along what they call the "Format Specification Mini Language" .
With this implementation, the approach is very similar. The only difference is that the "Format Specification Mini Language" is implemented for standard types right within this class. But before processing format_spec, this class will check if the argument type assigned to the placeholder disposes about a custom implementation of box function FFormat . If so, this function is invoked and string format_spec is passed for custom processing.
Information and sample code on how to adopt custom types to support this interface is found in the Programmer's Manual of this module, with chapter 4.3. Formatting Custom Types.
For example, ALib class DateTime supports custom formatting with box-function FFormat_DateTime which uses helper class CalendarDateTime that provides a very common specific mini language for formatting date and time values .
"{" [field_name] ["!" conversion] [":" format_spec] "}"symbol
'!'
if used prior to the colon ':'
defines what is called the conversion. With Python, three options are given: '!s'
which calls str()
on the value, '!r'
which calls repr()
and '!a'
which calls ascii()
. This is of-course not applicable to this formatter. As a replacement, this class extends the original specification of that conversion using '!'
. The following provides a list of conversions supported. The names given can be abbreviated at any point and ignore letter case, e.g. !Upper
can be !UP
or just !u
. In addition, multiple conversions can be given by concatenating them, each repeating character '!'
.!Quote[O[C]]
Puts quote characters around the field. Note that these characters are not respecting any optional given field width but instead are added to such. An alias name for !Quote is given with !Str. As the alias can be abbreviated to !s, this provides compatibility with the Python specification.
In extension to the python syntax specification, one or two optional characters might be given after the (optionally abreviated) terms "Quote" respectively "str". If one character is given, this is used as the open and closing character. If two are given, the first is used as the open character, the second as the closing one. For example {!Q'} uses single quotes, or {!Q[]} uses rectangular brackets. Bracket types '{' and '}' can not be used with this conversion. To surround a placeholder's contents in this bracket type, add {{ and }} around the placeholder - resulting in {{{}}}!.
'<'
is specified, certain characters are converted to escape sequences. If '>'
is given, escape sequences are converted to their (ascii) value. See Format::Escape for details about the conversion that is performed.' '
. It can be changed with optional character 'C' plus the character wanted.' '
. It can be changed with optional character 'C' plus the character wanted. The tab width defaults to 8
. It can be changed by adding an unsigned decimal number.!ATab[[Cc][NNN]|Reset]
Inserts an "automatic tabulator stop". These are tabulator positions that are stored internally and are automatically extended in the moment the actual contents exceeds the currently stored tab-position. An arbitrary amount of auto tab stop and field width (see !AWith below) values is maintained by the formatter.
Which each new invocation of Formatter , the first auto value is chosen and with each use of !ATab
or !AWidth
, the next value is used.
However the stored values are cleared, whenever Format is invoked on a non-acquired formatter! This means, to preserve the auto-positions across multiple format invocations, a formatter has to be acquired explicitly before the format operations and released afterwards.
Alternatively to this, the positions currently stored with the formatter can be reset with providing argument Reset
in the format string.
By default, the fill character is space ' '
. It can be changed with optional character 'C' plus the character wanted. The optional number provided gives the growth value by which the tab will grow if its position is exceeded. This value defaults to 3
.
Both, auto tab and auto width conversions may be used to increase readability of multiple output lines. Of-course, output is not completely tabular, only if those values that result in the biggest sizes are formatted first. If a perfect tabular output is desired, the data to be formatted may be processed twice: Once to temporary buffer which is disposed and then a second time to the desired output AString.
'<'
and '>'
. In the special case that search is empty (<>
), string replace will be inserted if the field argument is an empty string.<b>alib::lang::format::FMTExceptions</b> |
Definition at line 327 of file formatterpythonstyle.hpp.
#include <formatterpythonstyle.hpp>
Inner Type Index: | |
struct | PlaceholderAttributesPS |
Public Field Index: | |
AutoSizes | Sizes |
Public Field Index: inherited from Formatter | |
NumberFormat | AlternativeNumberFormat |
NumberFormat | DefaultNumberFormat |
std::shared_ptr< Formatter > | Next |
Public Field Index: inherited from ThreadLock | |
NCString | DbgOwnerFile =nullptr |
NCString | DbgOwnerFunc =nullptr |
int | DbgOwnerLine |
uint16_t | DbgRecursionWarningThreshold =10 |
integer | DbgWarningAfterWaitTimeInMillis =2000L |
Public Method Index: | |
ALIB_API | FormatterPythonStyle () |
virtual ALIB_API FormatterStdImpl * | Clone () override |
Public Method Index: inherited from FormatterStdImpl | |
FormatterStdImpl (const String &formatterClassName) | |
Public Method Index: inherited from Formatter | |
virtual | ~Formatter () |
ALIB_API Boxes & | Acquire (const NCString &dbgFile, int dbgLine, const NCString &dbgFunc) |
virtual ALIB_API void | CloneSettings (Formatter &reference) |
int | CountAcquirements () const |
template<typename... TArgs> | |
Formatter & | Format (AString &target, TArgs &&... args) |
ALIB_THREADS. | |
ALIB_API Formatter & | FormatArgs (AString &target) |
Formatter & | FormatArgs (AString &target, const Boxes &args) |
ALIB_API void | Release () |
defined(ALIB_DOX) | |
ALIB_API void | ReplaceDefault (Formatter *newFormatter) |
Public Method Index: inherited from ThreadLock | |
ALIB_API | ThreadLock (lang::Safeness safeness=lang::Safeness::Safe) |
ALIB_API | ~ThreadLock () |
ALIB_API void | Acquire (const NCString &dbgFile, int dbgLine, const NCString &dbgFunc) |
int | CountAcquirements () const |
Thread * | GetOwner () const |
lang::Safeness | GetSafeness () const |
bool | IsOwnedByCurrentThread () const |
ALIB_API void | Release () |
defined(ALIB_DOX) | |
ALIB_API void | SetSafeness (lang::Safeness safeness) |
bool | WillRelease () const |
Additional Inherited Members | |
Public Static Method Index: inherited from Formatter | |
static SPFormatter | AcquireDefault (const NCString &dbgFile, int dbgLine, const NCString &dbgFunc) |
static SPFormatter | GetDefault () |
|
protected |
The extended placeholder attributes.
Definition at line 362 of file formatterpythonstyle.hpp.
AutoSizes Sizes |
Storage of sizes for auto-tabulator feature {!ATab} and auto field width feature {!AWidth}
Definition at line 370 of file formatterpythonstyle.hpp.
Constructs this formatter. Inherited field DefaultNumberFormat is initialized to meet the formatting defaults of Python.
Definition at line 40 of file formatterpythonstyle.cpp.
|
overrideprotectedvirtual |
Makes some attribute adjustments and invokes standard implementation
true
if OK, false
if replacement should be aborted. Reimplemented from FormatterStdImpl.
Definition at line 592 of file formatterpythonstyle.cpp.
|
overridevirtual |
Clones and returns a copy of this formatter.
If the formatter attached to field Formatter::Next is of type FormatterStdImpl, then that formatter is copied as well.
Implements Formatter.
Definition at line 49 of file formatterpythonstyle.cpp.
|
overrideprotectedvirtual |
Searches for '{'
which is not '{{'.
Implements FormatterStdImpl.
Definition at line 98 of file formatterpythonstyle.cpp.
|
overrideprotectedvirtual |
Sets the actual auto tab stop index to 0
.
Reimplemented from Formatter.
Definition at line 70 of file formatterpythonstyle.cpp.
|
overrideprotectedvirtual |
Parses placeholder field in python notation. The portion format_spec is not parsed but stored in member FormatSpec .
true
on success, false
on errors. Implements FormatterStdImpl.
Definition at line 111 of file formatterpythonstyle.cpp.
|
overrideprotectedvirtual |
Parses the format specification for standard types as specified in "Format Specification Mini Language" .
true
on success, false
on errors. Implements FormatterStdImpl.
Definition at line 206 of file formatterpythonstyle.cpp.
Processes "conversions" which are specified with '!'
.
startIdx | The index of the start of the field written in targetString. -1 indicates pre-phase. |
target | The target string, only if different from field targetString, which indicates intermediate phase. |
false
, if the placeholder should be skipped (nothing is written for it). true
otherwise. Reimplemented from FormatterStdImpl.
Definition at line 438 of file formatterpythonstyle.cpp.
|
overrideprotectedvirtual |
Resets AutoSizes.
Reimplemented from Formatter.
Definition at line 64 of file formatterpythonstyle.cpp.
|
overrideprotectedvirtual |
Invokes parent implementation and then applies some changes to reflect what is defined as default in the Python string format specification.
Reimplemented from FormatterStdImpl.
Definition at line 77 of file formatterpythonstyle.cpp.
|
overrideprotectedvirtual |
Implementation of abstract method FormatterStdImpl::writeStringPortion .
While writing, replaces "{{"
with "{"
and "}}"
with "}"
as well as standard codes like "\\n"
, "\\r"
or "\\t"
with corresponding ascii codes.
length | The number of characters to write. |
Implements FormatterStdImpl.
Definition at line 381 of file formatterpythonstyle.cpp.