src/io/fastout/lib.hpp
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include "../../util/alias/others/lib.hpp" | ||
| 4 | #include "../../util/traits/math/lib.hpp" | ||
| 5 | |||
| 6 | namespace tifa_libs { | ||
| 7 | |||
| 8 | class fastout { | ||
| 9 | CEXP static u32 BUF = 0x200005, INTBUF = 63; | ||
| 10 | FILE* f_ = nullptr; | ||
| 11 | // NOLINTNEXTLINE(modernize-avoid-c-arrays) | ||
| 12 | chr int_buf[INTBUF]; | ||
| 13 | // NOLINTNEXTLINE(modernize-avoid-c-arrays) | ||
| 14 | chr buf[BUF], *p; | ||
| 15 | chr CPC ed = buf + BUF; | ||
| 16 | std::chars_format fmt = std::chars_format::general; | ||
| 17 | int precision = 6; | ||
| 18 | |||
| 19 | 15734101 | fastout& write_str(chr CP n, usz len = 0) NE { | |
| 20 |
2/2✓ Branch 0 taken 4746927 times.
✓ Branch 1 taken 10987174 times.
|
15734101 | if (!len) len = strlen(n); |
| 21 | usz l_; | ||
| 22 | 15734101 | chr CP n_ = n; | |
| 23 |
2/2✓ Branch 1 taken 22152 times.
✓ Branch 2 taken 15734101 times.
|
15756253 | while (p + len >= ed) memcpy(p, n_, l_ = usz(ed - p)), p += l_, n_ += l_, len -= l_, flush(); |
| 24 | 15734101 | return memcpy(p, n_, len), p += len, *this; | |
| 25 | } | ||
| 26 | |||
| 27 | public: | ||
| 28 | 16036 | fastout(FILE* f = stdout) NE { rebind(f); } | |
| 29 | fastout(fastout CR) = delete; | ||
| 30 | fastout& operator=(fastout CR) = delete; | ||
| 31 | 16036 | ~fastout() NE { flush(); } | |
| 32 | 16068 | void rebind(FILE* f) NE { f_ = f, p = buf; } | |
| 33 | 38208 | void flush() NE { fwrite(buf, 1, usz(p - buf), f_), p = buf; } | |
| 34 | 7111053942 | fastout& operator<<(char_c auto n) NE { | |
| 35 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 7111053938 times.
|
7111053942 | if (p == ed) [[unlikely]] |
| 36 | 4 | flush(); | |
| 37 | 7111053942 | *(p++) = n; | |
| 38 | 7111053942 | return *this; | |
| 39 | } | ||
| 40 | 4746927 | fastout& operator<<(chr CP n) NE { return write_str(n); } | |
| 41 | 10840845 | fastout& operator<<(strn CR str) NE { return write_str(str.data(), str.size()); } | |
| 42 | fastout& operator<<(strnv str) NE { return write_str(str.data(), str.size()); } | ||
| 43 | template <class T> | ||
| 44 | requires(smost64_c<T> && !char_c<T>) | ||
| 45 | 17659813 | fastout& operator<<(T n) NE { | |
| 46 | 2 | if CEXP (sizeof(T) < sizeof(i32)) return *this << (i32)n; | |
| 47 | else { | ||
| 48 |
4/4tifa_libs::fastout& tifa_libs::fastout::operator<< <int>(int):
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 4835428 times.
tifa_libs::fastout& tifa_libs::fastout::operator<< <long>(long):
✓ Branch 0 taken 2272484 times.
✓ Branch 1 taken 10551897 times.
|
17659811 | if (n < 0) return *this << '-' << -to_uint_t<T>(n); |
| 49 | 15387325 | return *this << to_uint_t<T>(n); | |
| 50 | } | ||
| 51 | } | ||
| 52 | template <class T> | ||
| 53 | requires(umost64_c<T> && !char_c<T>) | ||
| 54 | 7061731881 | fastout& operator<<(T n) NE { | |
| 55 | 30000070 | if CEXP (std::same_as<T, bool>) return *this << (chr(n | '0')); | |
| 56 | 2 | else if CEXP (sizeof(T) < sizeof(u32)) return *this << (u32)n; | |
| 57 |
4/4tifa_libs::fastout& tifa_libs::fastout::operator<< <unsigned int>(unsigned int):
✓ Branch 0 taken 90140 times.
✓ Branch 1 taken 4369298858 times.
tifa_libs::fastout& tifa_libs::fastout::operator<< <unsigned long>(unsigned long):
✓ Branch 0 taken 48141 times.
✓ Branch 1 taken 2266415061 times.
|
7031731809 | else if (usz(p - buf) >= BUF - INTBUF) [[unlikely]] { |
| 58 | 146329 | auto res = std::to_chars(int_buf, int_buf + INTBUF, n); | |
| 59 | 146329 | return write_str(int_buf, usz(res.ptr - int_buf)); | |
| 60 | } else { | ||
| 61 | 7031585480 | auto res = std::to_chars(p, buf + BUF, n); | |
| 62 | 7031585480 | p = res.ptr; | |
| 63 | 7031585480 | return *this; | |
| 64 | } | ||
| 65 | } | ||
| 66 | fastout& operator<<(std::floating_point auto n) NE { | ||
| 67 | if (usz(p - buf) >= BUF - INTBUF) [[unlikely]] { | ||
| 68 | auto res = std::to_chars(int_buf, int_buf + INTBUF, n, fmt, precision); | ||
| 69 | return write_str(int_buf, usz(res.ptr - int_buf)); | ||
| 70 | } else { | ||
| 71 | auto res = std::to_chars(p, buf + BUF, n, fmt, precision); | ||
| 72 | p = res.ptr; | ||
| 73 | return *this; | ||
| 74 | } | ||
| 75 | } | ||
| 76 | fastout& setf(std::chars_format f) NE { | ||
| 77 | fmt = f; | ||
| 78 | return *this; | ||
| 79 | } | ||
| 80 | //! only tested in libstdc++ | ||
| 81 | fastout& operator<<(decltype(std::setprecision(0)) p) NE { | ||
| 82 | precision = *(int*)(&p); | ||
| 83 | return *this; | ||
| 84 | } | ||
| 85 | fastout& operator<<(fastout& (*func)(fastout&)) NE { return func(*this); } | ||
| 86 | }; | ||
| 87 | inline fastout fout; | ||
| 88 | inline fastout& scientific(fastout& f) NE { return f.setf(std::chars_format::scientific); } | ||
| 89 | inline fastout& fixed(fastout& f) NE { return f.setf(std::chars_format::fixed); } | ||
| 90 | inline fastout& hexfloat(fastout& f) NE { return f.setf(std::chars_format::hex); } | ||
| 91 | inline fastout& defaultfloat(fastout& f) NE { return f.setf(std::chars_format::general); } | ||
| 92 | inline fastout& endl(fastout& f) NE { | ||
| 93 | (f << '\n').flush(); | ||
| 94 | return f; | ||
| 95 | } | ||
| 96 | using std::setprecision; | ||
| 97 | |||
| 98 | } // namespace tifa_libs | ||
| 99 |