-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathprintf.cppm
More file actions
executable file
·109 lines (97 loc) · 3.47 KB
/
printf.cppm
File metadata and controls
executable file
·109 lines (97 loc) · 3.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
export module cpuf.printf;
import std;
import cpuf.op;
namespace cpuf {
// Base case: no arguments left
inline void print_nth(std::ostream& out, int index) {
out << "<none>";
}
// Recursive variadic print_nth, perfect forwarding args
template <typename T, typename... Args>
void print_nth(std::ostream& out, int index, T&& first, Args&&... args) {
if (index == 0) {
out << std::forward<T>(first);
} else {
print_nth(out, index - 1, std::forward<Args>(args)...);
}
}
// Internal helper: processes the format string and outputs to the given ostream
template <typename... Args>
int vprintf_impl(std::ostream& out, const char* format, Args&&... args) {
int id = 0;
const char* start = format;
while (*format) {
if (*format == '{' && *(format + 1) == '}') {
print_nth(out, id++, std::forward<Args>(args)...);
format += 2;
} else {
out << *format++;
}
}
return static_cast<int>(format - start);
}
// Overload for std::string format: just forward to the const char* version
template <typename... Args>
int vprintf_impl(std::ostream& out, const std::string& format, Args&&... args) {
return vprintf_impl(out, format.c_str(), std::forward<Args>(args)...);
}
export template <typename... Args>
int printf(const char* format, Args&&... args) {
auto r = vprintf_impl(std::cout, format, std::forward<Args>(args)...);
#ifndef DEBUG
std::cout << std::endl;
#else
std::cout << '\n';
#endif
return r;
}
export template <typename... Args>
int printf(const std::string& format, Args&&... args) {
auto r = vprintf_impl(std::cout, format, std::forward<Args>(args)...);
#ifndef DEBUG
std::cout << std::endl;
#else
std::cout << '\n';
#endif
return r;
}
// Public printf writes to std::cout
export template <typename... Args>
int dprintf(const char* format, Args&&... args) {
return vprintf_impl(std::cout, format, std::forward<Args>(args)...);
}
export template <typename... Args>
int dprintf(const std::string& format, Args&&... args) {
return vprintf_impl(std::cout, format, std::forward<Args>(args)...);
}
// Public perror writes to std::cerr
export template <typename... Args>
int perror(const char* format, Args&&... args) {
return vprintf_impl(std::cerr, format, std::forward<Args>(args)...);
}
export template <typename... Args>
int perror(const std::string& format, Args&&... args) {
return vprintf_impl(std::cerr, format, std::forward<Args>(args)...);
}
// sprintf returns std::string instead of int (makes sense)
export template <typename... Args>
std::string sprintf(const char* format, Args&&... args) {
std::ostringstream os;
vprintf_impl(os, format, std::forward<Args>(args)...);
return os.str();
}
export template <typename... Args>
std::string sprintf(const std::string& format, Args&&... args) {
std::ostringstream os;
vprintf_impl(os, format, std::forward<Args>(args)...);
return os.str();
}
// convert_to_num unchanged
inline long long convert_to_num(const char* start, char*& end) {
long long id = std::strtoll(start, &end, 10);
#ifdef CPUF_NON_ZERO_COUNT
id++;
#endif
return id;
}
} // namespace cpuf