Skip to content

Commit 88699d3

Browse files
committed
feat: enhance fast-io to support std::string and specialized unsigned int reading
1 parent 2421474 commit 88699d3

1 file changed

Lines changed: 50 additions & 8 deletions

File tree

src/alfred/config/fast-io.hpp

Lines changed: 50 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
#define ALFRED_IO
33

44
#include "../math/mod-int.hpp"
5-
#include <iostream>
5+
#include <cstdlib> // for malloc, free
6+
#include <cstring> // for memcpy
7+
#include <iostream> // for fwrite, fread, std::string
68

79
class FastIO {
810
private:
@@ -13,6 +15,10 @@ class FastIO {
1315
fwrite(obuf, 1, len, stdout), op = obuf;
1416
}
1517

18+
inline size_t min(const size_t &a, const size_t &b) { // avoid including <algorithm>
19+
return a < b ? a : b;
20+
}
21+
1622
public:
1723
inline char nc(void) {
1824
if (p1 == p2) {
@@ -25,6 +31,14 @@ class FastIO {
2531
if (op == oe) flush_output();
2632
*op++ = c;
2733
}
34+
inline void ps(char *s, size_t len) {
35+
// do memcpy magic here
36+
while (len > 0) {
37+
size_t cp = min(len, oe - op);
38+
memcpy(op, s, cp), s += cp, len -= cp;
39+
if ((op += cp) == oe) flush_output();
40+
}
41+
}
2842
FastIO(void) {
2943
p1 = p2 = ibuf = (char *)(malloc(chunk));
3044
op = obuf = (char *)(malloc(chunk)), oe = obuf + chunk;
@@ -41,11 +55,22 @@ class FastIO {
4155
#define getchar() __buf.nc()
4256
#define putchar(x) __buf.pc(x)
4357

44-
template <class T>
58+
// specialized for unsigned int: no negative sign handling
59+
template <class T, is_unsigned_int_t<T> *_ = nullptr>
4560
inline void fast_read(T &x) {
4661
x = 0;
47-
static bool neg = false;
4862
static char c = __buf.nc();
63+
while (c < '0' || c > '9') c = __buf.nc();
64+
while (c >= '0' && c <= '9') {
65+
x = (x << 1) + (x << 3) + (c ^ 48), c = __buf.nc();
66+
}
67+
}
68+
69+
template <class T, is_signed_int_t<T> *_ = nullptr>
70+
inline void fast_read(T &x) {
71+
x = 0;
72+
static bool neg = false;
73+
static char c = __buf.nc(); // it runs ok though initialized only once
4974
while (c < '0' || c > '9') {
5075
neg = (c == '-'), c = __buf.nc();
5176
}
@@ -54,17 +79,34 @@ inline void fast_read(T &x) {
5479
}
5580
if (neg) x = -x;
5681
}
82+
83+
inline void fast_read(std::string &s) {
84+
s.clear();
85+
static char c = __buf.nc();
86+
while (c == ' ' || c == '\n') {
87+
c = __buf.nc();
88+
}
89+
while (c != ' ' && c != '\n') {
90+
s.push_back(c), c = __buf.nc();
91+
}
92+
}
93+
5794
template <class T>
5895
inline void write(T x) {
96+
int cnt = 0;
97+
static char buf[40];
5998
if (x < 0) {
60-
__buf.pc('-'), x = -x;
99+
buf[cnt++] = '-', x = -x;
61100
}
62-
if (x > 9) write(x / 10);
63-
__buf.pc((x % 10) ^ 48);
101+
do {
102+
buf[cnt++] = (x % 10) ^ 48, x /= 10;
103+
} while (x);
104+
while (cnt--) __buf.pc(buf[cnt]);
64105
}
65106
template <int mod>
66-
inline void write(ModInt<mod> x) {
67-
write(x.x);
107+
inline void write(ModInt<mod> x) { write(x.x); }
108+
inline void write(const std::string &s) {
109+
__buf.ps(s.c_str(), s.size());
68110
}
69111
template <typename T, typename... V>
70112
inline void write(T x, V... v) {

0 commit comments

Comments
 (0)