GCC Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 98.3% 175 / 0 / 178
Functions: 100.0% 45 / 0 / 45
Branches: 72.9% 121 / 0 / 166

src/io/fastin/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 #ifdef __linux__
6 #include <sys/mman.h>
7 #include <sys/stat.h>
8 #endif
9
10 namespace tifa_libs {
11
12 struct fastin_data {
13 CEXP static u32 BUF = 0x200005;
14 FILE* f_ = nullptr;
15 #ifdef __linux__
16 chr *bg, *ed, *p;
17 struct stat Fl;
18
19 32104 void rebind(FILE* f = nullptr) NE {
20 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
21
2/2
✓ Branch 0 taken 16036 times.
✓ Branch 1 taken 16068 times.
32104 if (!f_) munmap(bg, Fl.st_size + 1);
22 #pragma GCC diagnostic warning "-Wmaybe-uninitialized"
23
2/2
✓ Branch 0 taken 16036 times.
✓ Branch 1 taken 16068 times.
32104 if (!f) return;
24 16068 auto fd = fileno(f_ = f);
25 16068 fstat(fd, &Fl);
26 16068 p = (bg = (chr*)mmap(nullptr, Fl.st_size + 4, PROT_READ, MAP_PRIVATE, fd, 0));
27 16068 ed = bg + Fl.st_size;
28 16068 madvise(bg, Fl.st_size + 4, MADV_SEQUENTIAL);
29 }
30
31 20139493677 ND bool iseof() CNE { return p == ed; }
32 16036 ~fastin_data() NE { rebind(); }
33 #else
34 // NOLINTNEXTLINE(modernize-avoid-c-arrays)
35 chr buf[BUF], *ed, *p;
36
37 void rebind(FILE* f) NE { f_ = f, p = ed = buf; }
38 ND bool iseof() NE {
39 if (p == ed) [[unlikely]]
40 ed = (p = buf) + fread(buf, 1, BUF, f_);
41 return p == ed;
42 }
43 #endif
44
45
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16036 times.
16036 fastin_data(FILE* f = stdin) NE { assert(f), rebind(f); }
46 fastin_data(fastin_data CR) = delete;
47 fastin_data& operator=(fastin_data CR) = delete;
48 };
49 // clang-format off
50 enum FIN_SET : u8 { FS_NEWLINE = 1, FS_SPACE = 2, FS_NEG = 4, FS_NUM = 8, FS_ALPHA = 16, FS_OTHERS = 32 };
51 // clang-format on
52 template <u32 charset>
53 class fastin {
54 fastin_data& data;
55
56 static CEXP bool is_cntrl(chr c) NE {
57 if CEXP (charset & FS_OTHERS) return iscntrl(c);
58 else if CEXP (charset & FS_NEWLINE) return c < 32;
59 else return false;
60 }
61 878672468 static CEXP bool is_cntrls(chr c) NE {
62 263738826 if CEXP (charset & FS_OTHERS) return !isgraph(c);
63 614933642 else if CEXP (charset & (FS_NEWLINE | FS_SPACE)) return c <= 32;
64 else return false;
65 }
66 20005062064 static CEXP bool is_digit(chr c) NE {
67 9228493 if CEXP (charset & (FS_ALPHA | FS_OTHERS)) return isdigit(c);
68 else if CEXP (!(charset & FS_NUM)) return false;
69 19958245442 else if CEXP (!(charset & FS_NEG)) return c > 32;
70 37588129 else return c >= 48;
71 }
72 67778592 static CEXP bool is_neg_digit(chr c) NE {
73 if CEXP (!(charset & FS_NEG)) return is_digit(c);
74
3/4
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
8 else if CEXP (charset & (FS_ALPHA | FS_OTHERS)) return c == '-' || isdigit(c);
75 67778584 else return c > 32;
76 }
77 #ifdef __linux__
78 template <bool ignore_space = true>
79 16770785 void read_str(strn& n) NE {
80 chr* l;
81 if CEXP (ignore_space) {
82 16770785 skip_cntrls(), l = data.p;
83
6/6
void tifa_libs::fastin<11u>::read_str<true>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&):
✓ Branch 1 taken 339952855 times.
✓ Branch 2 taken 3748017 times.
void tifa_libs::fastin<15u>::read_str<true>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&):
✓ Branch 1 taken 246325651 times.
✓ Branch 2 taken 8705728 times.
void tifa_libs::fastin<63u>::read_str<true>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&):
✓ Branch 1 taken 245502225 times.
✓ Branch 2 taken 4317040 times.
848551516 while (!is_cntrls(*data.p)) ++data.p;
84 } else {
85 skip_cntrl(), l = data.p;
86 while (!is_cntrl(*data.p)) ++data.p;
87 }
88 16770785 n.assign(l, data.p);
89 16770785 }
90 #else
91 template <bool ignore_space>
92 void read_str(strn& n) NE {
93 if CEXP (n.clear(); ignore_space) {
94 n.push_back(skip_cntrls().get());
95 while (!is_cntrls(peek())) n.push_back(get());
96 } else {
97 n.push_back(skip_cntrl().get());
98 while (!is_cntrl(peek())) n.push_back(get());
99 }
100 }
101 #endif
102 public:
103 48108 fastin(fastin_data& data) NE : data(data) {}
104 fastin(fastin CR) = delete;
105 fastin& operator=(fastin CR) = delete;
106
107 20136850908 chr peek() NE {
108
4/6
tifa_libs::fastin<11u>::peek():
✗ Branch 1 not taken.
✓ Branch 2 taken 19965741105 times.
tifa_libs::fastin<15u>::peek():
✗ Branch 1 not taken.
✓ Branch 2 taken 147961733 times.
tifa_libs::fastin<63u>::peek():
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 23148065 times.
20136850908 if (data.iseof()) [[unlikely]]
109 5 return EOF;
110 20136850903 return *data.p;
111 }
112 12120165701 chr get_unchk() NE { return *data.p++; }
113 2642769 chr get() NE {
114
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2642769 times.
2642769 if (data.iseof()) [[unlikely]]
115 return EOF;
116 2642769 return get_unchk();
117 }
118 #define SKIP(name, pred) \
119 fastin& skip_##name() NE { \
120 while (pred(peek())) get_unchk(); \
121 return *this; \
122 }
123 SKIP(cntrl, is_cntrl)
124
5/6
tifa_libs::fastin<11u>::skip_cntrls():
✓ Branch 3 taken 3747646 times.
✓ Branch 4 taken 3748017 times.
tifa_libs::fastin<15u>::skip_cntrls():
✗ Branch 3 not taken.
✓ Branch 4 taken 8705728 times.
tifa_libs::fastin<63u>::skip_cntrls():
✓ Branch 3 taken 6959752 times.
✓ Branch 4 taken 6959809 times.
30120952 SKIP(cntrls, is_cntrls)
125
4/4
tifa_libs::fastin<11u>::skip_ndigit():
✓ Branch 3 taken 6014223198 times.
✓ Branch 4 taken 6014238713 times.
tifa_libs::fastin<63u>::skip_ndigit():
✓ Branch 3 taken 2642769 times.
✓ Branch 4 taken 2642777 times.
12033747457 SKIP(ndigit, !is_digit)
126
3/4
tifa_libs::fastin<15u>::skip_nnegdigit():
✓ Branch 3 taken 33889292 times.
✓ Branch 4 taken 33889292 times.
tifa_libs::fastin<63u>::skip_nnegdigit():
✗ Branch 3 not taken.
✓ Branch 4 taken 8 times.
67778592 SKIP(nnegdigit, !is_neg_digit)
127 #undef SKIP
128 template <class T>
129 requires(imost64_c<T> && !char_c<T>)
130 6042065058 fastin& operator>>(T& n) NE {
131 if CEXP (std::same_as<T, bool>) n = skip_ndigit().get() != '0';
132 else {
133 6042065058 n = 0;
134 6042065058 bool is_neg = false;
135
9/12
tifa_libs::fastin<63u>& tifa_libs::fastin<63u>::operator>><int>(int&):
✓ Branch 2 taken 1 time.
✓ Branch 3 taken 1 time.
✓ Branch 5 taken 1 time.
✗ Branch 6 not taken.
tifa_libs::fastin<63u>& tifa_libs::fastin<63u>::operator>><long>(long&):
✓ Branch 2 taken 1 time.
✓ Branch 3 taken 1 time.
✓ Branch 5 taken 1 time.
✗ Branch 6 not taken.
tifa_libs::fastin<63u>& tifa_libs::fastin<63u>::operator>><short>(short&):
✓ Branch 2 taken 1 time.
✓ Branch 3 taken 1 time.
✓ Branch 5 taken 1 time.
✗ Branch 6 not taken.
25183570 if CEXP ((charset & FS_NEG) && std::signed_integral<T>) is_neg = (skip_nnegdigit().peek() == '-' && get_unchk());
136 6016881488 else skip_ndigit();
137 6042065058 std::conditional_t<sizeof(T) < sizeof(u32), u32, to_uint_t<T>> n_ = 0;
138 #ifdef __linux__
139 // clang-format off
140 #define _ {while (~STR2U16[*(u16*)data.p]) (n_ *= 100) += STR2U16[*(u16*)data.p], data.p += 2; if (is_digit(peek())) (n_ *= 10) += get_unchk() & 15;}
141
74/108
tifa_libs::fastin<11u>& tifa_libs::fastin<11u>::operator>><int>(int&):
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 18 taken 37 times.
✓ Branch 19 taken 18 times.
✓ Branch 22 taken 11 times.
✓ Branch 23 taken 7 times.
tifa_libs::fastin<11u>& tifa_libs::fastin<11u>::operator>><unsigned int>(unsigned int&):
✓ Branch 0 taken 135976809 times.
✓ Branch 1 taken 129617340 times.
✓ Branch 4 taken 135976809 times.
✗ Branch 5 not taken.
✓ Branch 9 taken 225880473 times.
✓ Branch 10 taken 135976809 times.
✓ Branch 13 taken 44228892 times.
✓ Branch 14 taken 91747917 times.
✓ Branch 18 taken 318210979 times.
✓ Branch 19 taken 129617340 times.
✓ Branch 22 taken 85387396 times.
✓ Branch 23 taken 44229944 times.
tifa_libs::fastin<11u>& tifa_libs::fastin<11u>::operator>><unsigned long>(unsigned long&):
✓ Branch 0 taken 1453247 times.
✓ Branch 1 taken 1653279 times.
✓ Branch 4 taken 1453247 times.
✗ Branch 5 not taken.
✓ Branch 9 taken 2903329 times.
✓ Branch 10 taken 1453247 times.
✓ Branch 13 taken 503069 times.
✓ Branch 14 taken 950178 times.
✓ Branch 18 taken 4046060 times.
✓ Branch 19 taken 1653279 times.
✓ Branch 22 taken 1148978 times.
✓ Branch 23 taken 504301 times.
tifa_libs::fastin<63u>& tifa_libs::fastin<63u>::operator>><int>(int&):
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 1 time.
✓ Branch 4 taken 1 time.
✗ Branch 5 not taken.
✓ Branch 9 taken 4 times.
✓ Branch 10 taken 1 time.
✓ Branch 13 taken 1 time.
✗ Branch 14 not taken.
✓ Branch 18 taken 5 times.
✓ Branch 19 taken 1 time.
✗ Branch 22 not taken.
✓ Branch 23 taken 1 time.
tifa_libs::fastin<63u>& tifa_libs::fastin<63u>::operator>><long>(long&):
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 1 time.
✓ Branch 4 taken 1 time.
✗ Branch 5 not taken.
✓ Branch 9 taken 9 times.
✓ Branch 10 taken 1 time.
✗ Branch 13 not taken.
✓ Branch 14 taken 1 time.
✓ Branch 18 taken 9 times.
✓ Branch 19 taken 1 time.
✓ Branch 22 taken 1 time.
✗ Branch 23 not taken.
tifa_libs::fastin<63u>& tifa_libs::fastin<63u>::operator>><short>(short&):
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 1 time.
✓ Branch 4 taken 1 time.
✗ Branch 5 not taken.
✓ Branch 9 taken 2 times.
✓ Branch 10 taken 1 time.
✗ Branch 13 not taken.
✓ Branch 14 taken 1 time.
✓ Branch 18 taken 2 times.
✓ Branch 19 taken 1 time.
✓ Branch 22 taken 1 time.
✗ Branch 23 not taken.
tifa_libs::fastin<63u>& tifa_libs::fastin<63u>::operator>><unsigned int>(unsigned int&):
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 18 taken 5 times.
✓ Branch 19 taken 2 times.
✓ Branch 22 taken 1 time.
✓ Branch 23 taken 1 time.
tifa_libs::fastin<63u>& tifa_libs::fastin<63u>::operator>><unsigned long>(unsigned long&):
✓ Branch 0 taken 1300163 times.
✓ Branch 1 taken 1342608 times.
✓ Branch 4 taken 1300163 times.
✗ Branch 5 not taken.
✓ Branch 9 taken 71431 times.
✓ Branch 10 taken 1300163 times.
✓ Branch 13 taken 133732 times.
✓ Branch 14 taken 1166431 times.
✓ Branch 18 taken 222668 times.
✓ Branch 19 taken 1342608 times.
✓ Branch 22 taken 1210541 times.
✓ Branch 23 taken 132067 times.
tifa_libs::fastin<63u>& tifa_libs::fastin<63u>::operator>><unsigned short>(unsigned short&):
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 18 taken 2 times.
✓ Branch 19 taken 2 times.
✓ Branch 22 taken 2 times.
✗ Branch 23 not taken.
27113868374 if ((usz)data.p & 1) { if (is_digit(peek())) [[likely]] { (n_ *= 10) += get_unchk() & 15; _ } } else _;
142 #undef _
143 // clang-format on
144 #else
145 while (is_digit(peek())) (n_ *= 10) += get_unchk() & 15;
146 #endif
147 if CEXP (sint_c<T>)
148
7/8
tifa_libs::fastin<11u>& tifa_libs::fastin<11u>::operator>><int>(int&):
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
tifa_libs::fastin<63u>& tifa_libs::fastin<63u>::operator>><int>(int&):
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 1 time.
tifa_libs::fastin<63u>& tifa_libs::fastin<63u>::operator>><long>(long&):
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 1 time.
tifa_libs::fastin<63u>& tifa_libs::fastin<63u>::operator>><short>(short&):
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 1 time.
5488103648 if (is_neg) n_ = -n_;
149 6042065058 n = (T)n_;
150 }
151 6042065058 return *this;
152 }
153 fastin& operator>>(std::floating_point auto& n) NE {
154 static strn s;
155 (*this >> s), std::from_chars(begin(s).base(), end(s).base(), n);
156 return *this;
157 }
158 //! ignore cntrl and space
159 2642769 fastin& operator>>(char_c auto& n) NE {
160 2642769 n = skip_cntrls().get();
161 2642769 return *this;
162 }
163 16770785 fastin& operator>>(strn& n) NE {
164 16770785 read_str<true>(n);
165 16770785 return *this;
166 }
167 fastin& getline(strn& n) NE {
168 read_str<false>(n);
169 return *this;
170 }
171 //! NOT ignore cntrl and space
172 fastin& strict_read(char_c auto& n) NE {
173 n = get();
174 return *this;
175 }
176 fastin& operator>>(fastin& (*func)(fastin&)) NE { return func(*this); }
177 };
178 inline fastin_data fid_stdin;
179 inline fastin<FS_NEWLINE | FS_SPACE | FS_NEG | FS_NUM | FS_ALPHA | FS_OTHERS> fin(fid_stdin);
180 inline fastin<FS_NEWLINE | FS_SPACE | FS_NEG | FS_NUM> fin_int(fid_stdin);
181 inline fastin<FS_NEWLINE | FS_SPACE | FS_NUM> fin_uint(fid_stdin);
182 template <u32 w>
183 inline fastin<w>& ws(fastin<w>& f) NE { return f.skip_cntrls(); }
184
185 } // namespace tifa_libs
186