19constexpr size_t Writer::BoundedTextLength(
const char (&text)[N])
noexcept
22 "LibXR::Print::Writer::BoundedTextLength: char array must be non-empty");
24 while (size < N && text[size] !=
'\0')
32 return size < N ? size : N - 1;
45constexpr std::string_view Writer::ToStringView(
const T& text)
47 using Traits = Detail::FormatArgument::TypeTraits<T>;
49 if constexpr (std::is_same_v<typename Traits::Decayed, std::string_view>)
53 else if constexpr (std::is_same_v<typename Traits::Decayed, std::string>)
55 return std::string_view(text.data(), text.size());
57 else if constexpr (std::is_same_v<typename Traits::Decayed, const char*> ||
58 std::is_same_v<typename Traits::Decayed, char*>)
64 return std::string_view(text, std::strlen(text));
66 else if constexpr (Traits::is_char_array)
68 return std::string_view(text, BoundedTextLength(text));
86template <FormatPackKind pack,
typename T>
87constexpr auto Writer::PackValue(T&& value)
89 using Traits = Detail::FormatArgument::TypeTraits<T>;
90 using Normalized =
typename Traits::Normalized;
92 if constexpr (pack == FormatPackKind::I32)
94 if constexpr (Traits::is_signed_integer)
96 return static_cast<int32_t
>(
static_cast<Normalized
>(value));
99 else if constexpr (pack == FormatPackKind::I64)
101 if constexpr (Traits::is_signed_integer)
103 return static_cast<int64_t
>(
static_cast<Normalized
>(value));
106 else if constexpr (pack == FormatPackKind::U32)
108 if constexpr (std::is_same_v<Normalized, bool>)
110 return static_cast<uint32_t
>(value ? 1U : 0U);
112 else if constexpr (std::is_integral_v<Normalized>)
114 return static_cast<uint32_t
>(
115 static_cast<std::make_unsigned_t<Normalized>
>(
static_cast<Normalized
>(value)));
118 else if constexpr (pack == FormatPackKind::U64)
120 if constexpr (std::is_same_v<Normalized, bool>)
122 return static_cast<uint64_t
>(value ? 1U : 0U);
124 else if constexpr (std::is_integral_v<Normalized>)
126 return static_cast<uint64_t
>(
127 static_cast<std::make_unsigned_t<Normalized>
>(
static_cast<Normalized
>(value)));
130 else if constexpr (pack == FormatPackKind::Pointer)
132 if constexpr (Traits::is_pointer_like)
134 if constexpr (std::is_same_v<typename Traits::Decayed, std::nullptr_t>)
136 return static_cast<uintptr_t
>(0);
140 return (value ==
nullptr) ?
static_cast<uintptr_t
>(0)
141 : reinterpret_cast<uintptr_t>(value);
145 else if constexpr (pack == FormatPackKind::Character)
147 if constexpr (Traits::is_character_like)
149 return static_cast<char>(
static_cast<Normalized
>(value));
152 else if constexpr (pack == FormatPackKind::StringView)
154 if constexpr (Traits::is_string_like)
156 return ToStringView(value);
159 else if constexpr (pack == FormatPackKind::F32)
161 if constexpr (std::is_arithmetic_v<Normalized>)
163 return static_cast<float>(value);
166 else if constexpr (pack == FormatPackKind::F64)
168 if constexpr (std::is_arithmetic_v<Normalized>)
170 return static_cast<double>(value);
173 else if constexpr (pack == FormatPackKind::LongDouble)
175 if constexpr (std::is_arithmetic_v<Normalized>)
177 return static_cast<long double>(value);
182 static_assert(dependent_false_v<pack>,
183 "LibXR::Print::Writer::PackValue: unsupported packed argument kind");
196void Writer::StoreArgument(uint8_t*& out,
const T& value)
198 std::memcpy(out, &value,
sizeof(T));
209template <auto ArgumentInfoList>
210consteval size_t Writer::PackedArgumentBytes()
213 for (
const auto& argument : ArgumentInfoList)
215 bytes += FormatArgumentBytes(argument.pack);
232template <auto ArgumentInfoList, auto ArgumentOrder,
typename Tuple>
233void Writer::StoreArgumentsOrdered(uint8_t*& out, Tuple& tuple)
235 [&]<
size_t... I>(std::index_sequence<I...>)
238 out, PackValue<ArgumentInfoList[I].pack>(std::get<ArgumentOrder[I]>(tuple))),
240 }(std::make_index_sequence<ArgumentInfoList.size()>{});