24#ifndef LIBXR_PRINT_ENABLE_INTEGER
25#define LIBXR_PRINT_ENABLE_INTEGER 1
28#ifndef LIBXR_PRINT_ENABLE_TEXT
29#define LIBXR_PRINT_ENABLE_TEXT 1
32#ifndef LIBXR_PRINT_ENABLE_POINTER
33#define LIBXR_PRINT_ENABLE_POINTER 0
36#ifndef LIBXR_PRINT_ENABLE_FLOAT
37#define LIBXR_PRINT_ENABLE_FLOAT 1
40#ifndef LIBXR_PRINT_INTEGER_ENABLE_BASE8_16
41#define LIBXR_PRINT_INTEGER_ENABLE_BASE8_16 1
44#ifndef LIBXR_PRINT_INTEGER_ENABLE_64BIT
45#define LIBXR_PRINT_INTEGER_ENABLE_64BIT 0
48#ifndef LIBXR_PRINT_FLOAT_ENABLE_FIXED
49#define LIBXR_PRINT_FLOAT_ENABLE_FIXED 1
52#ifndef LIBXR_PRINT_FLOAT_ENABLE_DOUBLE
53#define LIBXR_PRINT_FLOAT_ENABLE_DOUBLE 0
56#ifndef LIBXR_PRINT_FLOAT_ENABLE_SCIENTIFIC
57#define LIBXR_PRINT_FLOAT_ENABLE_SCIENTIFIC 0
60#ifndef LIBXR_PRINT_FLOAT_ENABLE_GENERAL
61#define LIBXR_PRINT_FLOAT_ENABLE_GENERAL 0
64#ifndef LIBXR_PRINT_FLOAT_ENABLE_LONG_DOUBLE
65#define LIBXR_PRINT_FLOAT_ENABLE_LONG_DOUBLE 0
68#ifndef LIBXR_PRINT_FLOAT_MAX_PRECISION
69#define LIBXR_PRINT_FLOAT_MAX_PRECISION 32
72#ifndef LIBXR_PRINT_FLOAT_MAX_INTEGER_DIGITS
73#define LIBXR_PRINT_FLOAT_MAX_INTEGER_DIGITS 32
76#ifndef LIBXR_PRINT_ENABLE_WIDTH
77#define LIBXR_PRINT_ENABLE_WIDTH 1
80#ifndef LIBXR_PRINT_ENABLE_PRECISION
81#define LIBXR_PRINT_ENABLE_PRECISION 1
84#ifndef LIBXR_PRINT_ENABLE_ALTERNATE
85#define LIBXR_PRINT_ENABLE_ALTERNATE 0
88#ifndef LIBXR_PRINT_ENABLE_EXPLICIT_ARGUMENT_INDEXING
89#define LIBXR_PRINT_ENABLE_EXPLICIT_ARGUMENT_INDEXING 0
92namespace LibXR::Print::Config
98inline constexpr bool enable_integer = LIBXR_PRINT_ENABLE_INTEGER;
102inline constexpr bool enable_text = LIBXR_PRINT_ENABLE_TEXT;
106inline constexpr bool enable_pointer = LIBXR_PRINT_ENABLE_POINTER;
110inline constexpr bool enable_float = LIBXR_PRINT_ENABLE_FLOAT;
116inline constexpr bool enable_integer_base8_16 =
117 enable_integer && LIBXR_PRINT_INTEGER_ENABLE_BASE8_16;
122inline constexpr bool enable_integer_64bit =
123 enable_integer && LIBXR_PRINT_INTEGER_ENABLE_64BIT;
129inline constexpr bool enable_float_fixed = enable_float && LIBXR_PRINT_FLOAT_ENABLE_FIXED;
136inline constexpr bool enable_float_double =
137 enable_float && LIBXR_PRINT_FLOAT_ENABLE_DOUBLE;
142inline constexpr bool enable_float_scientific =
143 enable_float && LIBXR_PRINT_FLOAT_ENABLE_SCIENTIFIC;
148inline constexpr bool enable_float_general =
149 enable_float && LIBXR_PRINT_FLOAT_ENABLE_GENERAL;
154inline constexpr bool enable_float_long_double =
155 enable_float_double && LIBXR_PRINT_FLOAT_ENABLE_LONG_DOUBLE;
156static_assert(LIBXR_PRINT_FLOAT_MAX_PRECISION <=
157 static_cast<int>(std::numeric_limits<uint8_t>::max() - 1),
158 "LibXR::Print: LIBXR_PRINT_FLOAT_MAX_PRECISION must fit in uint8_t "
159 "and stay below the unspecified-precision sentinel");
160static_assert(LIBXR_PRINT_FLOAT_MAX_INTEGER_DIGITS > 0,
161 "LibXR::Print: LIBXR_PRINT_FLOAT_MAX_INTEGER_DIGITS must be positive");
166inline constexpr uint8_t max_float_precision =
167 static_cast<uint8_t
>(LIBXR_PRINT_FLOAT_MAX_PRECISION);
172inline constexpr size_t max_float_integer_digits =
173 static_cast<size_t>(LIBXR_PRINT_FLOAT_MAX_INTEGER_DIGITS);
178inline constexpr bool enable_width = LIBXR_PRINT_ENABLE_WIDTH;
182inline constexpr bool enable_precision = LIBXR_PRINT_ENABLE_PRECISION;
187inline constexpr bool enable_alternate = LIBXR_PRINT_ENABLE_ALTERNATE;
192inline constexpr bool enable_explicit_argument_indexing =
193 LIBXR_PRINT_ENABLE_EXPLICIT_ARGUMENT_INDEXING;
196namespace LibXR::Print
220enum class FormatArgumentRule : uint8_t
255enum class FormatFlag : uint8_t
263 CenterAlign = 1U << 6,
288enum class FormatOp : uint8_t
294 U32ZeroPadWidth = 0x11,
314[[nodiscard]]
constexpr size_t FormatOpPayloadBytes(FormatOp op)
318 case FormatOp::TextInline:
320 case FormatOp::TextRef:
321 return 2 *
sizeof(uint16_t);
322 case FormatOp::U32ZeroPadWidth:
324 case FormatOp::GenericField:
326 case FormatOp::TextSpace:
327 case FormatOp::U32Dec:
328 case FormatOp::I32Dec:
329 case FormatOp::U32Binary:
330 case FormatOp::U32Octal:
331 case FormatOp::U32HexLower:
332 case FormatOp::U32HexUpper:
333 case FormatOp::StringRaw:
334 case FormatOp::CharacterRaw:
348enum class FormatType : uint8_t
385 LongDoubleScientific,
397enum class FormatPackKind : uint8_t
421enum class FormatProfile : uint32_t
426 GenericSigned32 = 1U << 2,
427 GenericSigned64 = 1U << 3,
432 GenericBinary32 = 1U << 6,
433 GenericBinary64 = 1U << 7,
434 GenericOctal32 = 1U << 8,
435 GenericOctal64 = 1U << 9,
444 GenericPointer = 1U << 14,
445 GenericCharacter = 1U << 15,
446 GenericString = 1U << 16,
447 GenericFloatFixed = 1U << 17,
448 GenericFloatScientific =
450 GenericFloatGeneral = 1U << 19,
451 GenericDoubleFixed = 1U << 20,
452 GenericDoubleScientific =
454 GenericDoubleGeneral = 1U << 22,
455 GenericLongDoubleFixed =
457 GenericLongDoubleScientific =
459 GenericLongDoubleGeneral =
461 Generic = 0x03FFFFFCU,
471[[nodiscard]]
constexpr FormatProfile operator|(FormatProfile left, FormatProfile right)
473 return static_cast<FormatProfile
>(
static_cast<uint32_t
>(left) |
474 static_cast<uint32_t
>(right));
483constexpr FormatProfile& operator|=(FormatProfile& left, FormatProfile right)
496[[nodiscard]]
constexpr bool HasProfile(FormatProfile profile, FormatProfile bit)
498 return (
static_cast<uint32_t
>(profile) &
static_cast<uint32_t
>(bit)) != 0;
508[[nodiscard]]
constexpr FormatProfile GenericProfileFor(FormatType type)
510 auto value =
static_cast<uint8_t
>(type);
511 auto first =
static_cast<uint8_t
>(FormatType::Signed32);
512 auto last =
static_cast<uint8_t
>(FormatType::LongDoubleGeneral);
513 if (value < first || value > last)
515 return FormatProfile::None;
517 return static_cast<FormatProfile
>(uint32_t{1} << (2U + value - first));
520static_assert(GenericProfileFor(FormatType::Signed32) == FormatProfile::GenericSigned32);
521static_assert(GenericProfileFor(FormatType::LongDoubleGeneral) ==
522 FormatProfile::GenericLongDoubleGeneral);
523static_assert(GenericProfileFor(FormatType::TextSpace) == FormatProfile::None);
524static_assert(
static_cast<uint32_t
>(FormatProfile::Generic) ==
525 ((uint32_t{1} << 26U) - (uint32_t{1} << 2U)));
557 FormatArgumentRule::None;
560 "LibXR::Print::FormatArgumentInfo must stay tightly packed");
579 FormatType
type = FormatType::End;
582 FormatArgumentRule::None;
599[[nodiscard]]
constexpr size_t FormatArgumentBytes(FormatPackKind pack)
603 case FormatPackKind::I32:
604 return sizeof(int32_t);
605 case FormatPackKind::I64:
606 return sizeof(int64_t);
607 case FormatPackKind::U32:
608 return sizeof(uint32_t);
609 case FormatPackKind::U64:
610 return sizeof(uint64_t);
611 case FormatPackKind::Pointer:
612 return sizeof(uintptr_t);
613 case FormatPackKind::Character:
615 case FormatPackKind::StringView:
616 return sizeof(std::string_view);
617 case FormatPackKind::F32:
618 return sizeof(float);
619 case FormatPackKind::F64:
620 return sizeof(double);
621 case FormatPackKind::LongDouble:
622 return sizeof(
long double);