os::print_formatted(format, std::uint64_t(val));
}
}
-void os::print_formatted(const char* format, std::uint32_t val) { os::print_formatted(format, std::uint64_t(val)); }
-void os::print_formatted(const char* format, std::uint16_t val) { os::print_formatted(format, std::uint64_t(val)); }
-void os::print_formatted(const char* format, std::uint8_t val) { os::print_formatted(format, std::uint64_t(val)); }
-void os::print_formatted(const char* format, std::int32_t val) { os::print_formatted(format, std::int64_t(val)); }
-void os::print_formatted(const char* format, std::int16_t val) { os::print_formatted(format, std::int64_t(val)); }
-void os::print_formatted(const char* format, std::int8_t val) { os::print_formatted(format, std::int64_t(val)); }
void os::assert(bool cond, const char* diagnostic) {
if (!cond) {
os::print("Error: {}\n", diagnostic);
void print_formatted(const char* format, const char* val);
void print_formatted(const char* format, std::uint64_t val);
void print_formatted(const char* format, std::int64_t val);
-void print_formatted(const char* format, std::uint32_t val);
-void print_formatted(const char* format, std::int32_t val);
-void print_formatted(const char* format, std::uint16_t val);
-void print_formatted(const char* format, std::int16_t val);
-void print_formatted(const char* format, std::uint8_t val);
-void print_formatted(const char* format, std::int8_t val);
+
+template <typename T_> struct get_more_general_type_helper {
+ using T = T_;
+};
+template <typename T> using get_more_general_type_helper_t = get_more_general_type_helper<T>::T;
+template <> struct get_more_general_type_helper<std::uint8_t> { using T = std::uint64_t; };
+template <> struct get_more_general_type_helper<std::uint16_t> { using T = std::uint64_t; };
+template <> struct get_more_general_type_helper<std::uint32_t> { using T = std::uint64_t; };
+template <> struct get_more_general_type_helper<std::int8_t> { using T = std::int64_t; };
+template <> struct get_more_general_type_helper<std::int16_t> { using T = std::int64_t; };
+template <> struct get_more_general_type_helper<std::int32_t> { using T = std::int64_t; };
+template <std::size_t n> struct get_more_general_type_helper<char[n]> { using T = const char*; };
struct print_nth_helper {
std::size_t n;
template<typename... Ts>
void print(const char* format, const Ts&... vs) {
std::size_t arg_n = 0;
+ bool arg_n_is_given = 0;
for (std::size_t i = 0; format[i] != '\0'; i++) {
if (format[i] == '{') {
i++;
}
std::size_t n = arg_n;
if ('0' <= format[i] && format[i] <= '9') {
+ if (arg_n == 0) {
+ arg_n_is_given = true;
+ }
+ os::assert(arg_n_is_given, "Error in format string: either the arg_id is always given, or never.");
std::size_t n_ = 0;
while ('0' <= format[i] && format[i] <= '9') {
n_ = n_ * 10 + (format[i++] - '0');
}
n = n_;
+ } else {
+ if (arg_n == 0) {
+ arg_n_is_given = false;
+ }
+ os::assert(!arg_n_is_given, "Error in format string: either the arg_id is always given, or never.");
}
if (format[i] == ':') {
i++;
os::assert(format[i] == '}', "Error in format string: ':' required before format spec.");
}
os::assert(n < sizeof...(vs), "Error in format string: not enough arguments.");
- (print_nth_helper{n, &format[i]} % ... % vs);
+ (print_nth_helper{n, &format[i]} % ... % get_more_general_type_helper_t<Ts>(vs));
i = format_spec_end;
arg_n++;
}