17constexpr size_t Writer::BoundedTextLength(
const char (&text)[N])
noexcept
20 while (size < N && text[size] !=
'\0')
37constexpr std::string_view Writer::ToStringView(
const T& text)
39 using Traits = Detail::FormatArgument::TypeTraits<T>;
41 if constexpr (std::is_same_v<typename Traits::Decayed, std::string_view>)
45 else if constexpr (std::is_same_v<typename Traits::Decayed, std::string>)
47 return std::string_view(text.data(), text.size());
49 else if constexpr (std::is_same_v<typename Traits::Decayed, const char*> ||
50 std::is_same_v<typename Traits::Decayed, char*>)
56 return std::string_view(text, std::strlen(text));
58 else if constexpr (Traits::is_char_array)
60 return std::string_view(text, BoundedTextLength(text));
75template <FormatPackKind pack,
typename T>
76constexpr auto Writer::PackValue(T&& value)
78 using Traits = Detail::FormatArgument::TypeTraits<T>;
79 using Normalized =
typename Traits::Normalized;
81 if constexpr (pack == FormatPackKind::I32)
83 if constexpr (Traits::is_signed_integer)
85 return static_cast<int32_t
>(
static_cast<Normalized
>(value));
88 else if constexpr (pack == FormatPackKind::I64)
90 if constexpr (Traits::is_signed_integer)
92 return static_cast<int64_t
>(
static_cast<Normalized
>(value));
95 else if constexpr (pack == FormatPackKind::U32)
97 if constexpr (std::is_same_v<Normalized, bool>)
99 return static_cast<uint32_t
>(value ? 1U : 0U);
101 else if constexpr (std::is_integral_v<Normalized>)
103 return static_cast<uint32_t
>(
static_cast<std::make_unsigned_t<Normalized>
>(
104 static_cast<Normalized
>(value)));
107 else if constexpr (pack == FormatPackKind::U64)
109 if constexpr (std::is_same_v<Normalized, bool>)
111 return static_cast<uint64_t
>(value ? 1U : 0U);
113 else if constexpr (std::is_integral_v<Normalized>)
115 return static_cast<uint64_t
>(
static_cast<std::make_unsigned_t<Normalized>
>(
116 static_cast<Normalized
>(value)));
119 else if constexpr (pack == FormatPackKind::Pointer)
121 if constexpr (Traits::is_pointer_like)
123 if constexpr (std::is_same_v<typename Traits::Decayed, std::nullptr_t>)
125 return static_cast<uintptr_t
>(0);
129 return (value ==
nullptr) ?
static_cast<uintptr_t
>(0)
130 : reinterpret_cast<uintptr_t>(value);
134 else if constexpr (pack == FormatPackKind::Character)
136 if constexpr (Traits::is_character_like)
138 return static_cast<char>(
static_cast<Normalized
>(value));
141 else if constexpr (pack == FormatPackKind::StringView)
143 if constexpr (Traits::is_string_like)
145 return ToStringView(value);
148 else if constexpr (pack == FormatPackKind::F32)
150 if constexpr (std::is_arithmetic_v<Normalized>)
152 return static_cast<float>(value);
155 else if constexpr (pack == FormatPackKind::F64)
157 if constexpr (std::is_arithmetic_v<Normalized>)
159 return static_cast<double>(value);
162 else if constexpr (pack == FormatPackKind::LongDouble)
164 if constexpr (std::is_arithmetic_v<Normalized>)
166 return static_cast<long double>(value);
172 dependent_false_v<pack>,
173 "LibXR::Print::Writer::PackValue: unsupported packed argument kind");
184void Writer::StoreArgument(uint8_t*& out,
const T& value)
186 std::memcpy(out, &value,
sizeof(T));
195template <auto ArgumentInfoList>
196consteval size_t Writer::PackedArgumentBytes()
199 for (
const auto& argument : ArgumentInfoList)
201 bytes += FormatArgumentBytes(argument.pack);
214template <auto ArgumentInfoList, auto ArgumentOrder,
typename Tuple>
215void Writer::StoreArgumentsOrdered(uint8_t*& out, Tuple& tuple)
217 [&]<
size_t... I>(std::index_sequence<I...>) {
218 (StoreArgument(out, PackValue<ArgumentInfoList[I].pack>(
219 std::get<ArgumentOrder[I]>(tuple))),
221 }(std::make_index_sequence<ArgumentInfoList.size()>{});