@@ -52,61 +52,37 @@ fastfloat_really_inline const char *seek_ip_end(const char *p,
5252 return current;
5353}
5454
55- fastfloat_really_inline int parse_u8_fastfloat (const char *&p, const char *pend,
56- uint8_t *out) {
57- if (p == pend)
58- return 0 ;
59- auto r = fast_float::from_chars (p, pend, *out);
60- if (r.ec == std::errc ()) {
61- p = r.ptr ;
62- return 1 ;
63- }
64- return 0 ;
65- }
55+ enum class parse_method { standard, fast_float };
6656
67- fastfloat_really_inline int parse_u8_fromchars (const char *&p, const char *pend,
68- uint8_t *out) {
69- if (p == pend) {
70- return 0 ;
71- }
72- auto r = std::from_chars (p, pend, *out);
73- if (r.ec == std::errc ()) {
74- p = r.ptr ;
75- return 1 ;
76- }
77- return 0 ;
78- }
7957
80- template <typename Parser >
58+ template <parse_method use_standard >
8159fastfloat_really_inline std::pair<bool , uint32_t >
82- simple_parse_ip_line (const char *p, const char *pend, Parser parse_uint8) {
83- uint8_t v1;
84- if (!parse_uint8 (p, pend, &v1)) {
85- return {false , 0 };
86- }
87- if (p == pend || *p++ != ' .' ) {
88- return {false , 0 };
89- }
90- uint8_t v2;
91- if (!parse_uint8 (p, pend, &v2)) {
92- return {false , 0 };
93- }
94- if (p == pend || *p++ != ' .' ) {
95- return {false , 0 };
96- }
97- uint8_t v3;
98- if (!parse_uint8 (p, pend, &v3)) {
99- return {false , 0 };
100- }
101- if (p == pend || *p++ != ' .' ) {
102- return {false , 0 };
103- }
104- uint8_t v4;
105- if (!parse_uint8 (p, pend, &v4)) {
106- return {false , 0 };
60+ simple_parse_ip_line (const char *p, const char *pend) {
61+ const char *current = p;
62+ uint32_t ip = 0 ;
63+ for (int i = 0 ; i < 4 ; ++i) {
64+ uint8_t value;
65+ if constexpr (use_standard == parse_method::standard) {
66+ auto r = std::from_chars (current, pend, value);
67+ if (r.ec != std::errc ()) {
68+ return {false , 0 };
69+ }
70+ current = r.ptr ;
71+ } else if constexpr (use_standard == parse_method::fast_float) {
72+ auto r = fast_float::from_chars (current, pend, value);
73+ if (r.ec != std::errc ()) {
74+ return {false , 0 };
75+ }
76+ current = r.ptr ;
77+ }
78+ ip = (ip << 8 ) | value;
79+ if (i < 3 ) {
80+ if (current == pend || *current++ != ' .' ) {
81+ return {false , 0 };
82+ }
83+ }
10784 }
108- return {true , (uint32_t (v1) << 24 ) | (uint32_t (v2) << 16 ) |
109- (uint32_t (v3) << 8 ) | uint32_t (v4)};
85+ return {true , ip};
11086}
11187
11288static std::string make_ip_line (uint8_t a, uint8_t b, uint8_t c, uint8_t d) {
@@ -176,7 +152,7 @@ int main() {
176152 int ok = 0 ;
177153 for (size_t i = 0 ; i < N; ++i) {
178154 auto [ok, ip] =
179- simple_parse_ip_line (p, pend, parse_u8_fromchars );
155+ simple_parse_ip_line<parse_method::standard> (p, pend);
180156 sum += ip;
181157 if (!ok) {
182158 std::abort ();
@@ -193,7 +169,7 @@ int main() {
193169 int ok = 0 ;
194170 for (size_t i = 0 ; i < N; ++i) {
195171 auto [ok, ip] =
196- simple_parse_ip_line (p, pend, parse_u8_fastfloat );
172+ simple_parse_ip_line<parse_method::fast_float> (p, pend);
197173 sum += ip;
198174 if (!ok) {
199175 std::abort ();
0 commit comments