Strings and Formatting - CPULL/Dflat GitHub Wiki
Dflat handles strings natively as UTF-8 data, heavily optimized for both short and long text, and includes a comprehensive formatting engine for data conversion.
Strings in Dflat are UTF-8 encoded. The .len property returns the number of characters, while .sizeof returns the size in bytes.
-
Literals: Declared with double quotes (e.g.,
"text"). -
Concatenation: The
+operator concatenates string and other types."The" + ' ' + "book " + 32is"The book 32". It evaluates left to right, so :1 + 2 + "a"is equivalent to(1 + 2) + "a"and results in"3a". -
Comparing strings and chars:
==between a string and a char is true only if the string is exactly that one character ("\n" == '\n'is true,"\n\n" == '\n'is false).!=is its opposite, so any string longer than one character is always!=a char.<,>,<=and>=compare the char as a one-character string. -
Comparing chars and integers: a char can be compared with an integer, using its code point (
c == 13); the compiler emits a level 2 warning. In+a char is always treated as text:'a' + 1is"a1". -
Nulls and Empty Strings: In Dflat,
""andnullare identical. Becausestringis already nullable by default, declaringstring?is a compile error, and strings cannot be unwrapped usingenforce. - Memory Optimization: "Small strings" (up to 62 bytes) are stored compactly in a 64-byte block with a 1-byte length prefix. Large strings use a 32-byte header and can allocate 4 KB blocks. A compact string is inherently a valid C string.
-
Escapes: Standard escapes are supported (
\n,\r,\t,\\,\',\",\0). Unicode code points can be written in hex (\u{1F600}) or decimal (\#{123}). Invalid code points in literals trigger a compile error, while casting to a char an illegal code point generates an Exception. -
Interpolation: Prefix a string with
$to inject expressions directly. Expressions must be wrapped in braces:$"Hello {name}". Use\{and\}if you need literal braces.string greeting = $"Hello {name}, total is {x:D,02}"
Formatting is applied either via interpolated strings ($"{expr:spec}") or by calling the toStr("spec") method, which is available on all native types and classes. Formatting options can be combined in any order.
Options are case-insensitive (except for upper/lower hex h/H):
-
Bases:
bd(decimal, default),bh/bH(hex lowercase and uppercase),bb(binary),bo(octal),b64(base-64). -
Decimals (
D): Specifies separators, fixed size, and rounding modes (e.g.,ufor half-up,bfor banker's,cfor ceil). -
Signs (
S): Control sign display.S-(negatives only, default),S+(always),S()(parentheses for negatives). -
Layout: Width (
w<n>), fill character (f<char>), and alignment (a<left,a>right,a^center,a.on decimal). -
Scientific (
e): Mantissa with one non-zero digit before the decimal. Format:e[<lit>]<min>(e.g.,e[E+]02D2outputs1.23E+03).
-
Layout: Width in characters (
w<n>), fill (f<char>), and alignment (a<,a^,a>). -
Case adjustments: Upper (
cU), lower (cL), sentence case, first letter up all others lower (cS), and title case, all first letters up (cT). -
Trimming & Truncation: Trim both/left/right sides (
s,sl,sr), or truncate keeping the start (t<'…') or the end (t>'…'), with a marker counted in the width.
Dflat supports standard C# custom pattern letters (d, f, F, g, h, H, k, m, M, s, t, y, z) plus several additions:
-
w(week),q(quarter),i(ISO week),r(ISO year),e(day of year),j(day of week). -
Spacing: Doubling any of the formatting letters pads the output with a space.
-
Alignment: Dates can be aligned using
a<(left),a^(center), ora>(right) followed by the width (e.g.,a<20), with no truncation applied. -
y: Year.yyoutputs the last two digits, andyyyyoutputs the full four digits. -
M: Month (1–12).MMzero-pads,MMMgives the abbreviated name, andMMMMgives the full name. -
d: Day of the month (1–31).ddzero-pads to two digits. -
g: Era or period (e.g., A.D.). -
k: Time zone information (e.g., +01:00). -
z: Time zone offset from UTC in whole hours. -
h: Hour using a 12-hour clock (1–12).hhzero-pads. -
H: Hour using a 24-hour clock (0–23).HHzero-pads. -
m: Minute (0–59).mmzero-pads. -
s: Second (0–59).sszero-pads. -
t: AM/PM designator (e.g.,tfor A/P,ttfor AM/PM). -
f: Fractions of a second (e.g.,fffor hundredths,ffffor milliseconds). -
F: Fractions of a second, but trailing zeros are omitted. -
w: Week. -
q: Quarter. -
i: ISO week. -
r: ISO year. -
e: Day of the year (fixed to 3 characters wide). -
j: Day of the week.
Formatting works in the same way in interpolated strings:
date now = Root.Now()
string today = $"{now:yyyyMMdd}"
and with toStr():
string today = Root.Now().toStr("yyyyMMdd")