Last active
June 13, 2024 11:15
-
-
Save niXman/18922310bd064bdfd7179bd47fbc568d to your computer and use it in GitHub Desktop.
string to integer fast conversion
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <cstdint> | |
#include <cassert> | |
#include <cstring> | |
#if !defined(__fallthrough) && defined(__has_cpp_attribute) | |
#if __has_cpp_attribute(fallthrough) | |
#define __FJ__FALLTHROUGH [[fallthrough]] | |
#elif __has_cpp_attribute(gnu::fallthrough) | |
#define __FJ__FALLTHROUGH [[gnu::fallthrough]] | |
#endif | |
#endif | |
#if !defined(__FJ__FALLTHROUGH) && defined(__has_attribute) | |
#if __has_attribute(__fallthrough__) | |
#define __FJ__FALLTHROUGH __attribute__((__fallthrough__)) | |
#endif | |
#endif | |
#if !defined(__FJ__FALLTHROUGH) /* well, we tried */ | |
#define __FJ__FALLTHROUGH ((void)0) | |
#endif | |
std::uint64_t atou64(const char *ptr, std::size_t len) { | |
# define __FJ__PER_CHAR_EXPR(n) ((res << 1) + (res << 3) + (str[len - n] - '0')) | |
const auto *str = reinterpret_cast<const std::uint8_t *>(ptr); | |
std::uint64_t res = 0; | |
switch ( len ) { | |
case 20: res = __FJ__PER_CHAR_EXPR(20); __FJ__FALLTHROUGH; | |
case 19: res = __FJ__PER_CHAR_EXPR(19); __FJ__FALLTHROUGH; | |
case 18: res = __FJ__PER_CHAR_EXPR(18); __FJ__FALLTHROUGH; | |
case 17: res = __FJ__PER_CHAR_EXPR(17); __FJ__FALLTHROUGH; | |
case 16: res = __FJ__PER_CHAR_EXPR(16); __FJ__FALLTHROUGH; | |
case 15: res = __FJ__PER_CHAR_EXPR(15); __FJ__FALLTHROUGH; | |
case 14: res = __FJ__PER_CHAR_EXPR(14); __FJ__FALLTHROUGH; | |
case 13: res = __FJ__PER_CHAR_EXPR(13); __FJ__FALLTHROUGH; | |
case 12: res = __FJ__PER_CHAR_EXPR(12); __FJ__FALLTHROUGH; | |
case 11: res = __FJ__PER_CHAR_EXPR(11); __FJ__FALLTHROUGH; | |
case 10: res = __FJ__PER_CHAR_EXPR(10); __FJ__FALLTHROUGH; | |
case 9 : res = __FJ__PER_CHAR_EXPR( 9); __FJ__FALLTHROUGH; | |
case 8 : res = __FJ__PER_CHAR_EXPR( 8); __FJ__FALLTHROUGH; | |
case 7 : res = __FJ__PER_CHAR_EXPR( 7); __FJ__FALLTHROUGH; | |
case 6 : res = __FJ__PER_CHAR_EXPR( 6); __FJ__FALLTHROUGH; | |
case 5 : res = __FJ__PER_CHAR_EXPR( 5); __FJ__FALLTHROUGH; | |
case 4 : res = __FJ__PER_CHAR_EXPR( 4); __FJ__FALLTHROUGH; | |
case 3 : res = __FJ__PER_CHAR_EXPR( 3); __FJ__FALLTHROUGH; | |
case 2 : res = __FJ__PER_CHAR_EXPR( 2); __FJ__FALLTHROUGH; | |
case 1 : res = __FJ__PER_CHAR_EXPR( 1); | |
} | |
# undef __FJ__PER_CHAR_EXPR | |
return res; | |
} | |
int main(int, char **argv) { | |
return atou(argv[1], std::strlen(argv[1])); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment