@@ -52,61 +52,36 @@ 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- }
79-
80- template <typename Parser>
57+ template <parse_method use_standard>
8158fastfloat_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 };
59+ simple_parse_ip_line (const char *p, const char *pend) {
60+ const char *current = p;
61+ uint32_t ip = 0 ;
62+ for (int i = 0 ; i < 4 ; ++i) {
63+ uint8_t value;
64+ if constexpr (use_standard == parse_method::standard) {
65+ auto r = std::from_chars (current, pend, value);
66+ if (r.ec != std::errc ()) {
67+ return {false , 0 };
68+ }
69+ current = r.ptr ;
70+ } else if constexpr (use_standard == parse_method::fast_float) {
71+ auto r = fast_float::from_chars (current, pend, value);
72+ if (r.ec != std::errc ()) {
73+ return {false , 0 };
74+ }
75+ current = r.ptr ;
76+ }
77+ ip = (ip << 8 ) | value;
78+ if (i < 3 ) {
79+ if (current == pend || *current++ != ' .' ) {
80+ return {false , 0 };
81+ }
82+ }
10783 }
108- return {true , (uint32_t (v1) << 24 ) | (uint32_t (v2) << 16 ) |
109- (uint32_t (v3) << 8 ) | uint32_t (v4)};
84+ return {true , ip};
11085}
11186
11287static std::string make_ip_line (uint8_t a, uint8_t b, uint8_t c, uint8_t d) {
@@ -176,7 +151,7 @@ int main() {
176151 int ok = 0 ;
177152 for (size_t i = 0 ; i < N; ++i) {
178153 auto [ok, ip] =
179- simple_parse_ip_line (p, pend, parse_u8_fromchars );
154+ simple_parse_ip_line<parse_method::standard> (p, pend);
180155 sum += ip;
181156 if (!ok) {
182157 std::abort ();
@@ -193,7 +168,7 @@ int main() {
193168 int ok = 0 ;
194169 for (size_t i = 0 ; i < N; ++i) {
195170 auto [ok, ip] =
196- simple_parse_ip_line (p, pend, parse_u8_fastfloat );
171+ simple_parse_ip_line<parse_method::fast_float> (p, pend);
197172 sum += ip;
198173 if (!ok) {
199174 std::abort ();
0 commit comments