mirror of https://gitee.com/bigwinds/arangodb
added optimized StringUtils::uint64_trusted()
This commit is contained in:
parent
d6db132b94
commit
db00e46772
|
@ -192,6 +192,100 @@ BOOST_AUTO_TEST_CASE (test_convertUTF16ToUTF8) {
|
|||
BOOST_CHECK(result.empty());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test_uint64
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
BOOST_AUTO_TEST_CASE (test_uint64) {
|
||||
BOOST_CHECK_EQUAL(0ULL, StringUtils::uint64("abc"));
|
||||
BOOST_CHECK_EQUAL(0ULL, StringUtils::uint64("ABC"));
|
||||
BOOST_CHECK_EQUAL(0ULL, StringUtils::uint64(" foo"));
|
||||
BOOST_CHECK_EQUAL(0ULL, StringUtils::uint64(""));
|
||||
BOOST_CHECK_EQUAL(0ULL, StringUtils::uint64(" "));
|
||||
BOOST_CHECK_EQUAL(12ULL, StringUtils::uint64(" 012"));
|
||||
BOOST_CHECK_EQUAL(1234ULL, StringUtils::uint64("1234a"));
|
||||
BOOST_CHECK_EQUAL(18446744073709551615ULL, StringUtils::uint64("-1"));
|
||||
BOOST_CHECK_EQUAL(18446744073709539271ULL, StringUtils::uint64("-12345"));
|
||||
BOOST_CHECK_EQUAL(1234ULL, StringUtils::uint64("1234.56"));
|
||||
BOOST_CHECK_EQUAL(0ULL, StringUtils::uint64("1234567890123456789012345678901234567890"));
|
||||
BOOST_CHECK_EQUAL(0ULL, StringUtils::uint64("@"));
|
||||
|
||||
BOOST_CHECK_EQUAL(0ULL, StringUtils::uint64("0"));
|
||||
BOOST_CHECK_EQUAL(1ULL, StringUtils::uint64("1"));
|
||||
BOOST_CHECK_EQUAL(12ULL, StringUtils::uint64("12"));
|
||||
BOOST_CHECK_EQUAL(123ULL, StringUtils::uint64("123"));
|
||||
BOOST_CHECK_EQUAL(1234ULL, StringUtils::uint64("1234"));
|
||||
BOOST_CHECK_EQUAL(1234ULL, StringUtils::uint64("01234"));
|
||||
BOOST_CHECK_EQUAL(9ULL, StringUtils::uint64("9"));
|
||||
BOOST_CHECK_EQUAL(9ULL, StringUtils::uint64(" 9"));
|
||||
BOOST_CHECK_EQUAL(9ULL, StringUtils::uint64("0009"));
|
||||
BOOST_CHECK_EQUAL(12345678ULL, StringUtils::uint64("12345678"));
|
||||
BOOST_CHECK_EQUAL(1234567800ULL, StringUtils::uint64("1234567800"));
|
||||
BOOST_CHECK_EQUAL(1234567890123456ULL, StringUtils::uint64("1234567890123456"));
|
||||
BOOST_CHECK_EQUAL(UINT64_MAX, StringUtils::uint64(std::to_string(UINT64_MAX)));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test_uint64_check
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static bool InvalidArgument(std::invalid_argument const& ex) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool OutOfRange(std::out_of_range const& ex) {
|
||||
return true;
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE (test_uint64_check) {
|
||||
BOOST_CHECK_EXCEPTION(StringUtils::uint64_check("abc"), std::invalid_argument, InvalidArgument);
|
||||
BOOST_CHECK_EXCEPTION(StringUtils::uint64_check("ABC"), std::invalid_argument, InvalidArgument);
|
||||
BOOST_CHECK_EXCEPTION(StringUtils::uint64_check(" foo"), std::invalid_argument, InvalidArgument);
|
||||
BOOST_CHECK_EXCEPTION(StringUtils::uint64_check(""), std::invalid_argument, InvalidArgument);
|
||||
BOOST_CHECK_EXCEPTION(StringUtils::uint64_check(" "), std::invalid_argument, InvalidArgument);
|
||||
BOOST_CHECK_EQUAL(12ULL, StringUtils::uint64_check(" 012"));
|
||||
BOOST_CHECK_EXCEPTION(StringUtils::uint64_check("1234a"), std::invalid_argument, InvalidArgument);
|
||||
BOOST_CHECK_EQUAL(18446744073709551615ULL, StringUtils::uint64_check("-1"));
|
||||
BOOST_CHECK_EQUAL(18446744073709539271ULL, StringUtils::uint64_check("-12345"));
|
||||
BOOST_CHECK_EXCEPTION(StringUtils::uint64_check("1234."), std::invalid_argument, InvalidArgument);
|
||||
BOOST_CHECK_EXCEPTION(StringUtils::uint64_check("1234.56"), std::invalid_argument, InvalidArgument);
|
||||
BOOST_CHECK_EXCEPTION(StringUtils::uint64_check("1234567889123456789012345678901234567890"), std::out_of_range, OutOfRange);
|
||||
BOOST_CHECK_EXCEPTION(StringUtils::uint64_check("@"), std::invalid_argument, InvalidArgument);
|
||||
|
||||
BOOST_CHECK_EQUAL(0ULL, StringUtils::uint64_check("0"));
|
||||
BOOST_CHECK_EQUAL(1ULL, StringUtils::uint64_check("1"));
|
||||
BOOST_CHECK_EQUAL(12ULL, StringUtils::uint64_check("12"));
|
||||
BOOST_CHECK_EQUAL(123ULL, StringUtils::uint64_check("123"));
|
||||
BOOST_CHECK_EQUAL(1234ULL, StringUtils::uint64_check("1234"));
|
||||
BOOST_CHECK_EQUAL(1234ULL, StringUtils::uint64_check("01234"));
|
||||
BOOST_CHECK_EQUAL(9ULL, StringUtils::uint64_check("9"));
|
||||
BOOST_CHECK_EQUAL(9ULL, StringUtils::uint64_check(" 9"));
|
||||
BOOST_CHECK_EQUAL(9ULL, StringUtils::uint64_check("0009"));
|
||||
BOOST_CHECK_EQUAL(12345678ULL, StringUtils::uint64_check("12345678"));
|
||||
BOOST_CHECK_EQUAL(1234567800ULL, StringUtils::uint64_check("1234567800"));
|
||||
BOOST_CHECK_EQUAL(1234567890123456ULL, StringUtils::uint64_check("1234567890123456"));
|
||||
BOOST_CHECK_EQUAL(UINT64_MAX, StringUtils::uint64_check(std::to_string(UINT64_MAX)));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test_uint64_trusted
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
BOOST_AUTO_TEST_CASE (test_uint64_trusted) {
|
||||
BOOST_CHECK_EQUAL(0ULL, StringUtils::uint64_trusted("0"));
|
||||
BOOST_CHECK_EQUAL(1ULL, StringUtils::uint64_trusted("1"));
|
||||
BOOST_CHECK_EQUAL(12ULL, StringUtils::uint64_trusted("12"));
|
||||
BOOST_CHECK_EQUAL(123ULL, StringUtils::uint64_trusted("123"));
|
||||
BOOST_CHECK_EQUAL(1234ULL, StringUtils::uint64_trusted("1234"));
|
||||
BOOST_CHECK_EQUAL(1234ULL, StringUtils::uint64_trusted("01234"));
|
||||
BOOST_CHECK_EQUAL(9ULL, StringUtils::uint64_trusted("9"));
|
||||
BOOST_CHECK_EQUAL(9ULL, StringUtils::uint64_trusted("0009"));
|
||||
BOOST_CHECK_EQUAL(12345678ULL, StringUtils::uint64_trusted("12345678"));
|
||||
BOOST_CHECK_EQUAL(1234567800ULL, StringUtils::uint64_trusted("1234567800"));
|
||||
BOOST_CHECK_EQUAL(1234567890123456ULL, StringUtils::uint64_trusted("1234567890123456"));
|
||||
BOOST_CHECK_EQUAL(UINT64_MAX, StringUtils::uint64_trusted(std::to_string(UINT64_MAX)));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief generate tests
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -1586,12 +1586,41 @@ uint64_t uint64_check(std::string const& str) {
|
|||
int64_t value = std::stoull(str, &n, 10);
|
||||
|
||||
if (n < str.size()) {
|
||||
throw std::invalid_argument("cannot convert '" + str + "' to int64");
|
||||
throw std::invalid_argument("cannot convert '" + str + "' to uint64");
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
uint64_t uint64_trusted(char const* value, size_t length) {
|
||||
uint64_t result = 0;
|
||||
|
||||
switch (length) {
|
||||
case 20: result += (value[length - 20] - '0') * 10000000000000000000ULL;
|
||||
case 19: result += (value[length - 19] - '0') * 1000000000000000000ULL;
|
||||
case 18: result += (value[length - 18] - '0') * 100000000000000000ULL;
|
||||
case 17: result += (value[length - 17] - '0') * 10000000000000000ULL;
|
||||
case 16: result += (value[length - 16] - '0') * 1000000000000000ULL;
|
||||
case 15: result += (value[length - 15] - '0') * 100000000000000ULL;
|
||||
case 14: result += (value[length - 14] - '0') * 10000000000000ULL;
|
||||
case 13: result += (value[length - 13] - '0') * 1000000000000ULL;
|
||||
case 12: result += (value[length - 12] - '0') * 100000000000ULL;
|
||||
case 11: result += (value[length - 11] - '0') * 10000000000ULL;
|
||||
case 10: result += (value[length - 10] - '0') * 1000000000ULL;
|
||||
case 9: result += (value[length - 9] - '0') * 100000000ULL;
|
||||
case 8: result += (value[length - 8] - '0') * 10000000ULL;
|
||||
case 7: result += (value[length - 7] - '0') * 1000000ULL;
|
||||
case 6: result += (value[length - 6] - '0') * 100000ULL;
|
||||
case 5: result += (value[length - 5] - '0') * 10000ULL;
|
||||
case 4: result += (value[length - 4] - '0') * 1000ULL;
|
||||
case 3: result += (value[length - 3] - '0') * 100ULL;
|
||||
case 2: result += (value[length - 2] - '0') * 10ULL;
|
||||
case 1: result += (value[length - 1] - '0');
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int32_t int32(std::string const& str) {
|
||||
#ifdef TRI_HAVE_STRTOL_R
|
||||
struct reent buffer;
|
||||
|
|
|
@ -451,6 +451,20 @@ inline uint64_t uint64_check(char const* value, size_t size) {
|
|||
return StringUtils::uint64_check(std::string(value, size));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief parses an unsigned integer
|
||||
/// the caller must make sure that the input buffer only contains valid
|
||||
/// numeric characters - otherwise the uint64_t result will be wrong.
|
||||
/// because the input is restricted to some valid characters, this function
|
||||
/// is highly optimized
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
uint64_t uint64_trusted(char const* value, size_t length);
|
||||
|
||||
inline uint64_t uint64_trusted(std::string const& value) {
|
||||
return uint64_trusted(value.c_str(), value.size());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief parses an integer
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
Loading…
Reference in New Issue