MT Core (C++)
Core library for replacing C++ standard in project usage
Loading...
Searching...
No Matches
mtcore::io::Formatter< T > Struct Template Reference

Formats integer numbers (other than char) such as int, unsigned, long long, etc Format specifier options for output: More...

#include <formats.hpp>

Inheritance diagram for mtcore::io::Formatter< T >:
Collaboration diagram for mtcore::io::Formatter< T >:

Public Types

using ElemType = std::remove_const_t<typename decltype(std::declval<T>().iter())::IterElem>
 
using ElemType = std::remove_reference_t<std::remove_const_t<decltype(*std::begin(std::declval<T &>()))>>
 

Static Public Member Functions

template<WriterImpl WI>
static Result< size_t, typename Writer< WI >::ErrType > fmt (Writer< WI > &writer, const FormatOptions &opts, const T &val)
 
static size_t num_digits (const T &val)
 
template<WriterImpl WI>
static Result< size_t, typename Writer< WI >::ErrType > fmt (Writer< WI > &writer, const FormatOptions &opts, T val)
 
template<WriterImpl WI>
static Result< size_t, typename Writer< WI >::ErrType > fmt (Writer< WI > &writer, FormatOptions opts, const T &iterable)
 
template<WriterImpl WI>
static Result< size_t, typename Writer< WI >::ErrType > fmt (Writer< WI > &writer, FormatOptions opts, const T &iterable)
 
template<WriterImpl WI>
static Result< size_t, typename Writer< WI >::ErrType > fmt (Writer< WI > &writer, const FormatOptions &opts, T ptr)
 
template<WriterImpl WI>
static Result< size_t, typename Writer< WI >::ErrType > fmt (Writer< WI > &writer, const FormatOptions &opts, const T &f)
 

Static Public Attributes

static constexpr auto digitTable
 

Detailed Description

template<std::integral T>
struct mtcore::io::Formatter< T >

Formats integer numbers (other than char) such as int, unsigned, long long, etc Format specifier options for output:

Formatter for pointers Will print "nullptr" if the pointer is null If no formatting options are given, will print the address as "Addr 0x{}" Format options are one of the following:

Formatter for C++ standard iterables (with begin(), end() and C++ iterators) Allows using normal C++ collections for formatting if desired Format specifiers have the slice specifiers left of a colon and the element specifiers on the right of the colon.

Formatter for mtcore iterables (different from C++ standard iterables) Format specifiers have the slice specifiers left of a colon and the element specifiers on the right of the colon.

Formatter for 32-bit floats Format specifiers have the following format: (padding)?(+|())?(f|F)?(e|E)?(+)?(\d+)?(.

  • Format padding options (e.g. 0<2;) - Must come before other options if present (i.e. 0<2;x not x0<2;)
  • x for lowercase hex
  • X for uppercase hex
  • b for binary
  • o for octal
  • d (or none) for decimal (numeric, base 10)
Template Parameters
TInteger number type (other than char)
See also
extract_padding_options

\d+(-\d+)?)? Where padding is the padding options, + indicates always print plus for positive while () indicates to print negatives with parenthesis (these are mutually exclusive), f indicates lowercase scientific notation, F indicates uppercase scientific location, e indicates forced scientific notation, E indicated forced uppercase scientific notation (overrides f), + indicates that a positive exponent should have +, (\d+) indicates the minimum digits of precision (between 0-16), and period indicates decimal place precision (will round). Decimal place precision can be an exact number (e.g. .2 for 2 decimals) or a range (e.g. .2-4 for 2-4 decimals). Note: decimal place will override minimum precision if there is a conflict

E.g. +F+4.2 is "Print always with sign for number end sci notation, have uppercase E, at least 4 digits of precision and exactly 2 decimal places"

In the format of: (maxElems)?(iterablePadding)?(separator):(elemFormat)(|(nextElemFormat))* Where maxElems is a number followed by an exclamation pont (!) which limits how meny items to print, slicePadding is overall padding requirements for the whole iterable (this is optional), the separator is any number of characters (including escaped characters) up to the colon. If a colon is present but there is no separator, then the formatter will assume no separation (useful for printing strings). If there is no colon, it will either default to a space (if it's an iterable of anything other than char) or nothing (if it's an iterable of char). After the colon comes element formats. If there's only one format, it will be applied to all elements. Multiple element formats may be specified by putting a pipe between each format. Each format will be used once, with the exception being that the last format will be repeated for all remaining elements. This is useful if you are trying to format a table of results, and you want different paddings for different sections.

Examples:

  • ,: Will separate each element by a comma
  • ^100;, : Will separate each element by a comma and a space, and will print the whole slice centered inside 100 characters
  • :x No separator, will pass the format string "x" to all elements
  • :x|b|x Separates by space, will pass the format string "x" to the first element, "b" to the second, and "x" to remaining elements
  • | : <10;| ^15;| >14; Separates with the string " | ". First element left padded by spaces to 10, second element center padded to 15 by space, remaining elements right padded by space to 14.
Template Parameters
TIterable with mtcore iterable pattern
  • x Hex only (no prefix)
  • s Short prefix (0x{})
  • '' Try to print value at address (if not null). Relies on formatter for underlying type. Will prefix with asterisk "</em>"
    Template Parameters
    TPointer Type

Definition at line 195 of file formats.hpp.

Member Typedef Documentation

◆ ElemType [1/2]

template<std::integral T>
using mtcore::io::Formatter< T >::ElemType = std::remove_const_t<typename decltype(std::declval<T>().iter())::IterElem>

Definition at line 485 of file formats.hpp.

◆ ElemType [2/2]

template<std::integral T>
using mtcore::io::Formatter< T >::ElemType = std::remove_reference_t<std::remove_const_t<decltype(*std::begin(std::declval<T &>()))>>

Definition at line 591 of file formats.hpp.

Member Function Documentation

◆ fmt() [1/6]

template<std::integral T>
template<WriterImpl WI>
static Result< size_t, typename Writer< WI >::ErrType > mtcore::io::Formatter< T >::fmt ( Writer< WI > & writer,
const FormatOptions & opts,
const T & f )
inlinestatic

Definition at line 958 of file formats.hpp.

958 {
959 return f.format(writer, opts);
960 }
Struct to override to specify how a type should be formatted.
Definition format.hpp:45

◆ fmt() [2/6]

template<std::integral T>
template<WriterImpl WI>
static Result< size_t, typename Writer< WI >::ErrType > mtcore::io::Formatter< T >::fmt ( Writer< WI > & writer,
const FormatOptions & opts,
const T & val )
inlinestatic

Definition at line 219 of file formats.hpp.

220 {
221 auto padOpts = extract_padding_options(opts.formatStr);
222 if (padOpts.has_value()) {
223 return Padded<T>::write_padded(writer, padOpts.value(), {opts.formatStr.sub(padOpts->endPos + 1)}, val);
224 }
225
226 size_t written = 0;
227
228 u64 uval;
229 if constexpr (std::is_signed_v<T>) {
230 // We want to copy cast the bits without changing the value
231 // we also want to 0 fill the sign bit when casting up, that way we get the right hex/binary
232 // without a lot of extra padding
233 auto tmp = val;
234 auto tmpPtr = reinterpret_cast<std::make_unsigned_t<T> *>(&tmp);
235 uval = *tmpPtr;
236 }
237 else {
238 uval = val;
239 }
240
241 if (str_equal(opts.formatStr, "X")) {
242 static constexpr auto chars = slice_from("0123456789ABCDEF");
243
245 static_cast<char>(chars[(uval >> 60) & 0xfull]), static_cast<char>(chars[(uval >> 56) & 0xfull]),
246 static_cast<char>(chars[(uval >> 52) & 0xfull]), static_cast<char>(chars[(uval >> 48) & 0xfull]),
247 static_cast<char>(chars[(uval >> 44) & 0xfull]), static_cast<char>(chars[(uval >> 40) & 0xfull]),
248 static_cast<char>(chars[(uval >> 36) & 0xfull]), static_cast<char>(chars[(uval >> 32) & 0xfull]),
249 static_cast<char>(chars[(uval >> 28) & 0xfull]), static_cast<char>(chars[(uval >> 24) & 0xfull]),
250 static_cast<char>(chars[(uval >> 20) & 0xfull]), static_cast<char>(chars[(uval >> 16) & 0xfull]),
251 static_cast<char>(chars[(uval >> 12) & 0xfull]), static_cast<char>(chars[(uval >> 8) & 0xfull]),
252 static_cast<char>(chars[(uval >> 4) & 0xfull]), static_cast<char>(chars[(uval >> 0) & 0xfull]),
253 };
254
255 auto hex = slice_from(hexChars);
256 auto start = slices::first_index_not('0', hex);
257
258 if (start.has_value()) {
259 auto out = hex.sub(start.value());
260 written += out.size();
261 auto res = writer.write_all(out);
262 return res.with_success_val(written);
263 }
264 else {
265 ++written;
266 return writer.write('0').with_success_val(written);
267 }
268 }
269
270 if (str_equal(opts.formatStr, "x")) {
271 static constexpr auto chars = slice_from("0123456789abcdef");
272
274 static_cast<char>(chars[(uval >> 60) & 0xfull]), static_cast<char>(chars[(uval >> 56) & 0xfull]),
275 static_cast<char>(chars[(uval >> 52) & 0xfull]), static_cast<char>(chars[(uval >> 48) & 0xfull]),
276 static_cast<char>(chars[(uval >> 44) & 0xfull]), static_cast<char>(chars[(uval >> 40) & 0xfull]),
277 static_cast<char>(chars[(uval >> 36) & 0xfull]), static_cast<char>(chars[(uval >> 32) & 0xfull]),
278 static_cast<char>(chars[(uval >> 28) & 0xfull]), static_cast<char>(chars[(uval >> 24) & 0xfull]),
279 static_cast<char>(chars[(uval >> 20) & 0xfull]), static_cast<char>(chars[(uval >> 16) & 0xfull]),
280 static_cast<char>(chars[(uval >> 12) & 0xfull]), static_cast<char>(chars[(uval >> 8) & 0xfull]),
281 static_cast<char>(chars[(uval >> 4) & 0xfull]), static_cast<char>(chars[(uval >> 0) & 0xfull]),
282 };
283
284 auto hex = slice_from(hexChars);
285 auto start = slices::first_index_not('0', hex);
286
287 if (start.has_value()) {
288 auto out = hex.sub(start.value());
289 written += out.size();
290 auto res = writer.write_all(out);
291 return res.with_success_val(written);
292 }
293 else {
294 ++written;
295 return writer.write('0').with_success_val(written);
296 }
297 }
298
299 if (str_equal(opts.formatStr, "o")) {
300 static constexpr auto chars = slice_from("01234567");
301
303 static_cast<char>(chars[(uval >> 63) & 0x1ull]), static_cast<char>(chars[(uval >> 60) & 0x7ull]),
304 static_cast<char>(chars[(uval >> 57) & 0x7ull]), static_cast<char>(chars[(uval >> 54) & 0x7ull]),
305 static_cast<char>(chars[(uval >> 51) & 0x7ull]), static_cast<char>(chars[(uval >> 48) & 0x7ull]),
306 static_cast<char>(chars[(uval >> 45) & 0x7ull]), static_cast<char>(chars[(uval >> 42) & 0x7ull]),
307 static_cast<char>(chars[(uval >> 39) & 0x7ull]), static_cast<char>(chars[(uval >> 36) & 0x7ull]),
308 static_cast<char>(chars[(uval >> 33) & 0x7ull]), static_cast<char>(chars[(uval >> 30) & 0x7ull]),
309 static_cast<char>(chars[(uval >> 27) & 0x7ull]), static_cast<char>(chars[(uval >> 24) & 0x7ull]),
310 static_cast<char>(chars[(uval >> 21) & 0x7ull]), static_cast<char>(chars[(uval >> 18) & 0x7ull]),
311 static_cast<char>(chars[(uval >> 15) & 0x7ull]), static_cast<char>(chars[(uval >> 12) & 0x7ull]),
312 static_cast<char>(chars[(uval >> 9) & 0x7ull]), static_cast<char>(chars[(uval >> 6) & 0x7ull]),
313 static_cast<char>(chars[(uval >> 3) & 0x7ull]), static_cast<char>(chars[(uval >> 0) & 0x7ull]),
314 };
315
316 auto hex = slice_from(hexChars);
317 auto start = slices::first_index_not('0', hex);
318
319 if (start.has_value()) {
320 auto out = hex.sub(start.value());
321 written += out.size();
322 auto res = writer.write_all(out);
323 return res.with_success_val(written);
324 }
325 else {
326 ++written;
327 return writer.write('0').with_success_val(written);
328 }
329 }
330
331 if (str_equal(opts.formatStr, "b")) {
333 bits.init(uval);
334
335 // to print properly to make sense to humans, we actually print "backwards"
336 // This is because high bits are traditionally on the left while low bits are traditionally on the right
337 auto firstBit = bits.first_set();
338 auto lastBit = bits.last_set();
339 if (firstBit.has_value()) {
340 ensure(lastBit.has_value());
341 for (size_t j = lastBit.value() + 1; j > 0; --j) {
342 auto i = j - 1;
343 ensure(i < j);
344 auto chRes = writer.write(bits.at(i) ? '1' : '0');
345 if (chRes.is_error()) {
346 return chRes.error();
347 }
348 ++written;
349 }
350 return written;
351 }
352 else {
353 ++written;
354 return writer.write('0').with_success_val(written);
355 }
356 }
357
358 if constexpr (std::is_signed_v<T>) {
359 if (val < 0) {
360 if (auto signRes = writer.write('-'); signRes.is_error()) {
361 return signRes.error();
362 }
363 written += 1;
364 }
365 }
366
367 if (val == 0) {
368 if (auto zRes = writer.write('0'); zRes.is_error()) {
369 return zRes.error();
370 }
371 written += 1;
372 }
373 else {
374 auto v = val;
375 if (val > 0) {
376 for (auto numDigits = num_digits(val); numDigits > 0; --numDigits) {
377 auto digit = (v / digitTable[numDigits - 1]);
378 ensure(digit >= 0 && digit < 10);
379 if (auto chRes = writer.write(digit + '0'); chRes.is_error()) {
380 return chRes.error();
381 }
382 ++written;
383 v -= digit * digitTable[numDigits - 1];
384 }
385 }
386 else {
387 for (auto numDigits = num_digits(val); numDigits > 0; --numDigits) {
388 auto digit = -(v / digitTable[numDigits - 1]);
389 ensure(digit >= 0 && digit < 10);
390 if (auto chRes = writer.write(digit + '0'); chRes.is_error()) {
391 return chRes.error();
392 }
393 ++written;
394 v += digit * digitTable[numDigits - 1];
395 }
396 }
397 }
398
399 return success(written);
400 }
constexpr Slice< const char32_t > slice_from(char32_t *cstr)
Creates a slice from a utf32 string in the form of a c string.
mtcore::Optional< size_t > first_index_not(const std::remove_const_t< T > &needle, const Slice< T > &haystack)
Gets the first index that a needle appears in the haystack, or nullopt if the needle does not appear ...
Optional< PaddingOptions > extract_padding_options(Slice< const char > formatStr)
Extracts padding options from a format string if present Padding options are in the following form: (...
Definition formats.hpp:71
#define ensure(check,...)
Ensures that a check holds true, aborts the program if not true Will print error if the condition is ...
Success< void > success()
Creates a successful void Result object.
Definition result.hpp:398
bool str_equal(const L &left, const R &right)
Compares two string strings for ordering.
static constexpr auto digitTable
Definition formats.hpp:196
static size_t num_digits(const T &val)
Definition formats.hpp:402
static Result< size_t, typename Writer< WI >::ErrType > write_padded(Writer< WI > &writer, const PaddingOptions &padOpts, const FormatOptions &opts, const T &elem)
Definition formats.hpp:791
Here is the call graph for this function:

◆ fmt() [3/6]

template<std::integral T>
template<WriterImpl WI>
static Result< size_t, typename Writer< WI >::ErrType > mtcore::io::Formatter< T >::fmt ( Writer< WI > & writer,
const FormatOptions & opts,
T ptr )
inlinestatic

Definition at line 930 of file formats.hpp.

930 {
931 if (ptr == nullptr) {
932 return writer.write_all(slice_from("nullptr"));
933 }
934
935 if (str_equal(opts.formatStr, "*")) {
937 return print(writer, "*{}", *ptr);
938 }
939 else {
940 return writer.write_all(slice_from("*?"));
941 }
942 }
943
944 auto addr = reinterpret_cast<intptr_t>(ptr);
945 if (str_equal(opts.formatStr, "x")) {
946 return print(writer, "{x}", addr);
947 }
948 if (str_equal(opts.formatStr, "s")) {
949 return print(writer, "0x{x}", addr);
950 }
951 return print(writer, "Addr 0x{x}", addr);
952 }
Result< size_t, typename Writer< WI >::ErrType > print(Writer< WI > &writer, const char *fmt, const Args &...args)
Prints arguments using a format string Element insert points are designated by a pair of curly braces...
Here is the call graph for this function:

◆ fmt() [4/6]

template<std::integral T>
template<WriterImpl WI>
static Result< size_t, typename Writer< WI >::ErrType > mtcore::io::Formatter< T >::fmt ( Writer< WI > & writer,
const FormatOptions & opts,
T val )
inlinestatic

Definition at line 445 of file formats.hpp.

445 {
446 auto padOpts = extract_padding_options(opts.formatStr);
447 if (padOpts.has_value()) {
448 return Padded<T>::write_padded(writer, padOpts.value(), {opts.formatStr.sub(padOpts->endPos + 1)}, val);
449 }
450 return floats::dragonbox::format_float(writer, static_cast<f64>(val), opts.formatStr);
451 }
Result< size_t, typename Writer< WI >::ErrType > format_float(Writer< WI > &writer, f64 f, Slice< const char > opts={nullptr, 0})
Definition floats.hpp:159
Here is the call graph for this function:

◆ fmt() [5/6]

template<std::integral T>
template<WriterImpl WI>
static Result< size_t, typename Writer< WI >::ErrType > mtcore::io::Formatter< T >::fmt ( Writer< WI > & writer,
FormatOptions opts,
const T & iterable )
inlinestatic

Definition at line 488 of file formats.hpp.

488 {
490
491 auto endMaxElemPos = slices::first_index_not_proceeded_by('\\', '!', opts.formatStr);
492 if (endMaxElemPos.has_value()) {
493 auto rng = opts.formatStr.sub(0, endMaxElemPos.value());
494 if (!rng.empty() && ascii::is_pos_int_str(rng)) {
496 opts.formatStr = opts.formatStr.sub(endMaxElemPos.value() + 1);
497 }
498 }
499
500 auto padOpts = extract_padding_options(opts.formatStr);
501 if (padOpts.has_value()) {
502 return Padded<T>::write_padded(writer, padOpts.value(), {opts.formatStr.sub(padOpts->endPos + 1)}, iterable);
503 }
504
505 // default separator
506 auto sep = slice_from(" ");
507 if constexpr (std::is_same_v<ElemType, char>) {
508 if (opts.formatStr.empty()) {
509 sep = slice_from("");
510 }
511 }
512
513 auto sepIndex = slices::first_index_not_proceeded_by('\\', ':', opts.formatStr);
514 if (sepIndex.has_value()) {
515 sep = opts.formatStr.sub(0, sepIndex.value());
516 opts.formatStr = opts.formatStr.sub(sepIndex.value() + 1);
517 }
518
519 auto iter = iterable.iter();
521 auto first = true;
522 size_t written = 0;
523 size_t elem = 0;
524 while (elem++ < maxElems && iter.next().move_if_present(cur)) {
525 if (first) {
526 first = false;
527 }
528 else {
530 if (sepRes.is_error()) {
531 auto errCode = sepRes.error().code;
533 return error(std::get<typename Writer<WI>::ErrType>(errCode));
534 }
535 written += sepRes.value();
536 }
537
538 auto fmtSegEnd =
539 opts.formatStr.empty() ? Optional<size_t>{} : slices::first_index_not_proceeded_by('\\', '|', opts.formatStr);
540 auto fullOpts = opts.formatStr;
541 if (fmtSegEnd.has_value()) {
542 opts.formatStr = opts.formatStr.sub(0, fmtSegEnd.value());
543 }
544 mtdefer {
545 if (fmtSegEnd.has_value()) {
546 opts.formatStr = fullOpts.sub(fmtSegEnd.value() + 1);
547 }
548 };
550 if (elemRes.is_error()) {
551 return elemRes.error();
552 }
553 written += elemRes.value();
554 }
555 return success(written);
556 }
Result< Out, AsciiNumericParseError > base10_to_int(const Slice< const char > &parse)
Tries to parse an ASCII numeric string into an integer Will return an error if the parsed string does...
Definition ascii.hpp:244
Result< size_t, std::variant< typename Writer::ErrType, UnescapeError > > write_unescaped(Writer &writer, Slice< const char > str, char escapeChar='\\')
Writes unescaped ASCII characters to a stream Note: This does NOT support writing Unicode escape code...
Definition ascii.hpp:447
mtcore::Optional< size_t > first_index_not_proceeded_by(const std::remove_const_t< T > &prefix, const std::remove_const_t< T > &needle, const Slice< T > &haystack)
Gets the first index that a needle appears in the haystack, or nullopt if the needle does not appear ...
Error< Underlying > error(Underlying err)
Creates an error.
Definition result.hpp:425
std::remove_const_t< typename decltype(std::declval< T >().iter())::IterElem > ElemType
Definition formats.hpp:485
Here is the call graph for this function:

◆ fmt() [6/6]

template<std::integral T>
template<WriterImpl WI>
static Result< size_t, typename Writer< WI >::ErrType > mtcore::io::Formatter< T >::fmt ( Writer< WI > & writer,
FormatOptions opts,
const T & iterable )
inlinestatic

Definition at line 594 of file formats.hpp.

594 {
596
597 if (!opts.formatStr.empty()) {
598 auto endMaxElemPos = slices::first_index_not_proceeded_by('\\', '!', opts.formatStr);
599 if (endMaxElemPos.has_value()) {
600 auto rng = opts.formatStr.sub(0, endMaxElemPos.value());
601 if (!rng.empty() && ascii::is_pos_int_str(rng)) {
603 opts.formatStr = opts.formatStr.sub(endMaxElemPos.value() + 1);
604 }
605 }
606 }
607
608 auto padOpts = extract_padding_options(opts.formatStr);
609 if (padOpts.has_value()) {
610 return Padded<T>::write_padded(writer, padOpts.value(), {opts.formatStr.sub(padOpts->endPos + 1)}, iterable);
611 }
612
613 // default separator
614 auto sep = slice_from(" ");
615 if constexpr (std::is_same_v<ElemType, char>) {
616 if (opts.formatStr.empty()) {
617 sep = slice_from("");
618 }
619 }
620
621 auto sepIndex = slices::first_index_not_proceeded_by('\\', ':', opts.formatStr);
622 if (sepIndex.has_value()) {
623 sep = opts.formatStr.sub(0, sepIndex.value());
624 opts.formatStr = opts.formatStr.sub(sepIndex.value() + 1);
625 }
626
627 auto first = true;
628 size_t written = 0;
629 size_t elem = 0;
630 for (const auto &cur: iterable) {
631 if (elem++ >= maxElems) {
632 break;
633 }
634 if (first) {
635 first = false;
636 }
637 else {
639 if (sepRes.is_error()) {
640 auto errCode = sepRes.error().code;
642 return error(std::get<typename Writer<WI>::ErrType>(errCode));
643 }
644 written += sepRes.value();
645 }
646
647 auto fmtSegEnd =
648 opts.formatStr.empty() ? Optional<size_t>{} : slices::first_index_not_proceeded_by('\\', '|', opts.formatStr);
649 auto fullOpts = opts.formatStr;
650 if (fmtSegEnd.has_value()) {
651 opts.formatStr = opts.formatStr.sub(0, fmtSegEnd.value());
652 }
653 mtdefer {
654 if (fmtSegEnd.has_value()) {
655 opts.formatStr = fullOpts.sub(fmtSegEnd.value() + 1);
656 }
657 };
659 if (elemRes.is_error()) {
660 return elemRes.error();
661 }
662 written += elemRes.value();
663 }
664 return success(written);
665 }
Here is the call graph for this function:

◆ num_digits()

template<std::integral T>
static size_t mtcore::io::Formatter< T >::num_digits ( const T & val)
inlinestatic

Definition at line 402 of file formats.hpp.

402 {
403 if constexpr (std::is_signed_v<T>) {
404 if (val < 0) {
405 const i64 v = val;
406 for (size_t i = 0; i < digitTable.size(); ++i) {
407 if (v > -digitTable[i]) {
408 return i;
409 }
410 }
411 return digitTable.size();
412 }
413 }
414
415 for (size_t i = 0; i < digitTable.size(); ++i) {
416 if (val < static_cast<T>(digitTable[i])) {
417 return i;
418 }
419 }
420 return digitTable.size();
421 }
Here is the caller graph for this function:

Member Data Documentation

◆ digitTable

template<std::integral T>
auto mtcore::io::Formatter< T >::digitTable
staticconstexpr
Initial value:
= std::array{
static_cast<i64>(1ll),
static_cast<i64>(10ll),
static_cast<i64>(100ll),
static_cast<i64>(1000ll),
static_cast<i64>(10000ll),
static_cast<i64>(100000ll),
static_cast<i64>(1000000ll),
static_cast<i64>(10000000ll),
static_cast<i64>(100000000ll),
static_cast<i64>(1000000000ll),
static_cast<i64>(10000000000ll),
static_cast<i64>(100000000000ll),
static_cast<i64>(1000000000000ll),
static_cast<i64>(10000000000000ll),
static_cast<i64>(100000000000000ll),
static_cast<i64>(1000000000000000ll),
static_cast<i64>(10000000000000000ll),
static_cast<i64>(100000000000000000ll),
static_cast<i64>(1000000000000000000ll),
}
int64_t i64
Alias for 64-bit ints.

Definition at line 196 of file formats.hpp.

196 {
197 static_cast<i64>(1ll),
198 static_cast<i64>(10ll),
199 static_cast<i64>(100ll),
200 static_cast<i64>(1000ll),
201 static_cast<i64>(10000ll),
202 static_cast<i64>(100000ll),
203 static_cast<i64>(1000000ll),
204 static_cast<i64>(10000000ll),
205 static_cast<i64>(100000000ll),
206 static_cast<i64>(1000000000ll),
207 static_cast<i64>(10000000000ll),
208 static_cast<i64>(100000000000ll),
209 static_cast<i64>(1000000000000ll),
210 static_cast<i64>(10000000000000ll),
211 static_cast<i64>(100000000000000ll),
212 static_cast<i64>(1000000000000000ll),
213 static_cast<i64>(10000000000000000ll),
214 static_cast<i64>(100000000000000000ll),
215 static_cast<i64>(1000000000000000000ll),
216 };

The documentation for this struct was generated from the following file: