libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
writer_argument.hpp
1#pragma once
2
16template <size_t N>
17constexpr size_t Writer::BoundedTextLength(const char (&text)[N]) noexcept
18{
19 size_t size = 0;
20 while (size < N && text[size] != '\0')
21 {
22 ++size;
23 }
24 ASSERT(size < N);
25 return size;
26}
27
36template <typename T>
37constexpr std::string_view Writer::ToStringView(const T& text)
38{
39 using Traits = Detail::FormatArgument::TypeTraits<T>;
40
41 if constexpr (std::is_same_v<typename Traits::Decayed, std::string_view>)
42 {
43 return text;
44 }
45 else if constexpr (std::is_same_v<typename Traits::Decayed, std::string>)
46 {
47 return std::string_view(text.data(), text.size());
48 }
49 else if constexpr (std::is_same_v<typename Traits::Decayed, const char*> ||
50 std::is_same_v<typename Traits::Decayed, char*>)
51 {
52 if (text == nullptr)
53 {
54 return "(null)";
55 }
56 return std::string_view(text, std::strlen(text));
57 }
58 else if constexpr (Traits::is_char_array)
59 {
60 return std::string_view(text, BoundedTextLength(text));
61 }
62 else
63 {
64 return {};
65 }
66}
67
75template <FormatPackKind pack, typename T>
76constexpr auto Writer::PackValue(T&& value)
77{
78 using Traits = Detail::FormatArgument::TypeTraits<T>;
79 using Normalized = typename Traits::Normalized;
80
81 if constexpr (pack == FormatPackKind::I32)
82 {
83 if constexpr (Traits::is_signed_integer)
84 {
85 return static_cast<int32_t>(static_cast<Normalized>(value));
86 }
87 }
88 else if constexpr (pack == FormatPackKind::I64)
89 {
90 if constexpr (Traits::is_signed_integer)
91 {
92 return static_cast<int64_t>(static_cast<Normalized>(value));
93 }
94 }
95 else if constexpr (pack == FormatPackKind::U32)
96 {
97 if constexpr (std::is_same_v<Normalized, bool>)
98 {
99 return static_cast<uint32_t>(value ? 1U : 0U);
100 }
101 else if constexpr (std::is_integral_v<Normalized>)
102 {
103 return static_cast<uint32_t>(static_cast<std::make_unsigned_t<Normalized>>(
104 static_cast<Normalized>(value)));
105 }
106 }
107 else if constexpr (pack == FormatPackKind::U64)
108 {
109 if constexpr (std::is_same_v<Normalized, bool>)
110 {
111 return static_cast<uint64_t>(value ? 1U : 0U);
112 }
113 else if constexpr (std::is_integral_v<Normalized>)
114 {
115 return static_cast<uint64_t>(static_cast<std::make_unsigned_t<Normalized>>(
116 static_cast<Normalized>(value)));
117 }
118 }
119 else if constexpr (pack == FormatPackKind::Pointer)
120 {
121 if constexpr (Traits::is_pointer_like)
122 {
123 if constexpr (std::is_same_v<typename Traits::Decayed, std::nullptr_t>)
124 {
125 return static_cast<uintptr_t>(0);
126 }
127 else
128 {
129 return (value == nullptr) ? static_cast<uintptr_t>(0)
130 : reinterpret_cast<uintptr_t>(value);
131 }
132 }
133 }
134 else if constexpr (pack == FormatPackKind::Character)
135 {
136 if constexpr (Traits::is_character_like)
137 {
138 return static_cast<char>(static_cast<Normalized>(value));
139 }
140 }
141 else if constexpr (pack == FormatPackKind::StringView)
142 {
143 if constexpr (Traits::is_string_like)
144 {
145 return ToStringView(value);
146 }
147 }
148 else if constexpr (pack == FormatPackKind::F32)
149 {
150 if constexpr (std::is_arithmetic_v<Normalized>)
151 {
152 return static_cast<float>(value);
153 }
154 }
155 else if constexpr (pack == FormatPackKind::F64)
156 {
157 if constexpr (std::is_arithmetic_v<Normalized>)
158 {
159 return static_cast<double>(value);
160 }
161 }
162 else if constexpr (pack == FormatPackKind::LongDouble)
163 {
164 if constexpr (std::is_arithmetic_v<Normalized>)
165 {
166 return static_cast<long double>(value);
167 }
168 }
169 else
170 {
171 static_assert(
172 dependent_false_v<pack>,
173 "LibXR::Print::Writer::PackValue: unsupported packed argument kind");
174 }
175}
176
183template <typename T>
184void Writer::StoreArgument(uint8_t*& out, const T& value)
185{
186 std::memcpy(out, &value, sizeof(T));
187 out += sizeof(T);
188}
189
195template <auto ArgumentInfoList>
196consteval size_t Writer::PackedArgumentBytes()
197{
198 size_t bytes = 0;
199 for (const auto& argument : ArgumentInfoList)
200 {
201 bytes += FormatArgumentBytes(argument.pack);
202 }
203 return bytes;
204}
205
214template <auto ArgumentInfoList, auto ArgumentOrder, typename Tuple>
215void Writer::StoreArgumentsOrdered(uint8_t*& out, Tuple& tuple)
216{
217 [&]<size_t... I>(std::index_sequence<I...>) {
218 (StoreArgument(out, PackValue<ArgumentInfoList[I].pack>(
219 std::get<ArgumentOrder[I]>(tuple))),
220 ...);
221 }(std::make_index_sequence<ArgumentInfoList.size()>{});
222}