Commit e9bb35ce by Abseil Team Committed by Copybara-Service

Adding support for int128 and uint128 flag types

PiperOrigin-RevId: 537120102
Change-Id: I7952e53aca10319eb433e4c4d60cf3d7fe74d19a
parent 01e628d2
...@@ -99,6 +99,7 @@ cc_library( ...@@ -99,6 +99,7 @@ cc_library(
"//absl/base:config", "//absl/base:config",
"//absl/base:core_headers", "//absl/base:core_headers",
"//absl/base:log_severity", "//absl/base:log_severity",
"//absl/numeric:int128",
"//absl/strings", "//absl/strings",
"//absl/strings:str_format", "//absl/strings:str_format",
"//absl/types:optional", "//absl/types:optional",
......
...@@ -87,6 +87,7 @@ absl_cc_library( ...@@ -87,6 +87,7 @@ absl_cc_library(
absl::config absl::config
absl::core_headers absl::core_headers
absl::log_severity absl::log_severity
absl::int128
absl::optional absl::optional
absl::strings absl::strings
absl::str_format absl::str_format
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include "absl/base/config.h" #include "absl/base/config.h"
#include "absl/base/log_severity.h" #include "absl/base/log_severity.h"
#include "absl/base/macros.h" #include "absl/base/macros.h"
#include "absl/numeric/int128.h"
#include "absl/strings/ascii.h" #include "absl/strings/ascii.h"
#include "absl/strings/match.h" #include "absl/strings/match.h"
#include "absl/strings/numbers.h" #include "absl/strings/numbers.h"
...@@ -125,6 +126,32 @@ bool AbslParseFlag(absl::string_view text, unsigned long long* dst, ...@@ -125,6 +126,32 @@ bool AbslParseFlag(absl::string_view text, unsigned long long* dst,
return ParseFlagImpl(text, *dst); return ParseFlagImpl(text, *dst);
} }
bool AbslParseFlag(absl::string_view text, absl::int128* dst, std::string*) {
text = absl::StripAsciiWhitespace(text);
// check hex
int base = NumericBase(text);
if (!absl::numbers_internal::safe_strto128_base(text, dst, base)) {
return false;
}
return base == 16 ? absl::SimpleHexAtoi(text, dst)
: absl::SimpleAtoi(text, dst);
}
bool AbslParseFlag(absl::string_view text, absl::uint128* dst, std::string*) {
text = absl::StripAsciiWhitespace(text);
// check hex
int base = NumericBase(text);
if (!absl::numbers_internal::safe_strtou128_base(text, dst, base)) {
return false;
}
return base == 16 ? absl::SimpleHexAtoi(text, dst)
: absl::SimpleAtoi(text, dst);
}
// -------------------------------------------------------------------- // --------------------------------------------------------------------
// AbslParseFlag for floating point types. // AbslParseFlag for floating point types.
......
...@@ -200,6 +200,7 @@ ...@@ -200,6 +200,7 @@
#define ABSL_FLAGS_MARSHALLING_H_ #define ABSL_FLAGS_MARSHALLING_H_
#include "absl/base/config.h" #include "absl/base/config.h"
#include "absl/numeric/int128.h"
#if defined(ABSL_HAVE_STD_OPTIONAL) && !defined(ABSL_USES_STD_OPTIONAL) #if defined(ABSL_HAVE_STD_OPTIONAL) && !defined(ABSL_USES_STD_OPTIONAL)
#include <optional> #include <optional>
...@@ -233,6 +234,8 @@ bool AbslParseFlag(absl::string_view, unsigned long*, std::string*); // NOLINT ...@@ -233,6 +234,8 @@ bool AbslParseFlag(absl::string_view, unsigned long*, std::string*); // NOLINT
bool AbslParseFlag(absl::string_view, long long*, std::string*); // NOLINT bool AbslParseFlag(absl::string_view, long long*, std::string*); // NOLINT
bool AbslParseFlag(absl::string_view, unsigned long long*, // NOLINT bool AbslParseFlag(absl::string_view, unsigned long long*, // NOLINT
std::string*); std::string*);
bool AbslParseFlag(absl::string_view, absl::int128*, std::string*); // NOLINT
bool AbslParseFlag(absl::string_view, absl::uint128*, std::string*); // NOLINT
bool AbslParseFlag(absl::string_view, float*, std::string*); bool AbslParseFlag(absl::string_view, float*, std::string*);
bool AbslParseFlag(absl::string_view, double*, std::string*); bool AbslParseFlag(absl::string_view, double*, std::string*);
bool AbslParseFlag(absl::string_view, std::string*, std::string*); bool AbslParseFlag(absl::string_view, std::string*, std::string*);
......
...@@ -455,6 +455,143 @@ TEST(MarshallingTest, TestUInt64Parsing) { ...@@ -455,6 +455,143 @@ TEST(MarshallingTest, TestUInt64Parsing) {
// -------------------------------------------------------------------- // --------------------------------------------------------------------
TEST(MarshallingTest, TestInt128Parsing) {
std::string err;
absl::int128 value;
absl::int128 zero = 0;
absl::int128 one = 1;
absl::int128 neg_one = -1;
absl::int128 hundred = 100;
absl::int128 hundreds_val = 123;
absl::int128 neg_thousands_val = -98765;
absl::int128 pos_three = 3;
// Decimal values.
EXPECT_TRUE(absl::ParseFlag("0", &value, &err));
EXPECT_EQ(value, zero);
EXPECT_TRUE(absl::ParseFlag("1", &value, &err));
EXPECT_EQ(value, one);
EXPECT_TRUE(absl::ParseFlag("-1", &value, &err));
EXPECT_EQ(value, neg_one);
EXPECT_TRUE(absl::ParseFlag("123", &value, &err));
EXPECT_EQ(value, hundreds_val);
EXPECT_TRUE(absl::ParseFlag("-98765", &value, &err));
EXPECT_EQ(value, neg_thousands_val);
EXPECT_TRUE(absl::ParseFlag("+3", &value, &err));
EXPECT_EQ(value, pos_three);
// Leading zero values.
EXPECT_TRUE(absl::ParseFlag("01", &value, &err));
EXPECT_EQ(value, one);
EXPECT_TRUE(absl::ParseFlag("001", &value, &err));
EXPECT_EQ(value, one);
EXPECT_TRUE(absl::ParseFlag("0000100", &value, &err));
EXPECT_EQ(value, hundred);
absl::int128 sixteen = 16;
absl::int128 quintillion_val = 1152827684197027293;
absl::int128 quintillion_val2 =
absl::MakeInt128(0x000000000000fff, 0xFFFFFFFFFFFFFFF);
// Hex values.
EXPECT_TRUE(absl::ParseFlag("0x10", &value, &err));
EXPECT_EQ(value, sixteen);
EXPECT_TRUE(absl::ParseFlag("0xFFFAAABBBCCCDDD", &value, &err));
EXPECT_EQ(value, quintillion_val);
EXPECT_TRUE(absl::ParseFlag("0xFFF0FFFFFFFFFFFFFFF", &value, &err));
EXPECT_EQ(value, quintillion_val2);
// TODO(b/285183223): Add support for parsing negative hex representation
// Whitespace handling
EXPECT_TRUE(absl::ParseFlag("16 ", &value, &err));
EXPECT_EQ(value, sixteen);
EXPECT_TRUE(absl::ParseFlag(" 16", &value, &err));
EXPECT_EQ(value, sixteen);
EXPECT_TRUE(absl::ParseFlag(" 0100 ", &value, &err));
EXPECT_EQ(value, hundred);
EXPECT_TRUE(absl::ParseFlag(" 0x7B ", &value, &err));
EXPECT_EQ(value, hundreds_val); // =123
// Invalid values.
EXPECT_FALSE(absl::ParseFlag("", &value, &err));
EXPECT_FALSE(absl::ParseFlag(" ", &value, &err));
EXPECT_FALSE(absl::ParseFlag(" ", &value, &err));
EXPECT_FALSE(absl::ParseFlag("--1", &value, &err));
EXPECT_FALSE(absl::ParseFlag("\n", &value, &err));
EXPECT_FALSE(absl::ParseFlag("\t", &value, &err));
EXPECT_FALSE(absl::ParseFlag("2U", &value, &err));
EXPECT_FALSE(absl::ParseFlag("FFF", &value, &err));
}
// --------------------------------------------------------------------
TEST(MarshallingTest, TestUint128Parsing) {
std::string err;
absl::uint128 value;
absl::uint128 zero = 0;
absl::uint128 one = 1;
absl::uint128 hundred = 100;
absl::uint128 hundreds_val = 123;
absl::uint128 pos_three = 3;
// Decimal values.
EXPECT_TRUE(absl::ParseFlag("0", &value, &err));
EXPECT_EQ(value, zero);
EXPECT_TRUE(absl::ParseFlag("1", &value, &err));
EXPECT_EQ(value, one);
EXPECT_TRUE(absl::ParseFlag("123", &value, &err));
EXPECT_EQ(value, hundreds_val);
EXPECT_TRUE(absl::ParseFlag("+3", &value, &err));
EXPECT_EQ(value, pos_three);
// Leading zero values.
EXPECT_TRUE(absl::ParseFlag("01", &value, &err));
EXPECT_EQ(value, one);
EXPECT_TRUE(absl::ParseFlag("001", &value, &err));
EXPECT_EQ(value, one);
EXPECT_TRUE(absl::ParseFlag("0000100", &value, &err));
EXPECT_EQ(value, hundred);
absl::uint128 sixteen = 16;
absl::uint128 quintillion_val = 1152827684197027293;
absl::uint128 quintillion_val2 =
absl::MakeInt128(0x000000000000fff, 0xFFFFFFFFFFFFFFF);
// Hex values.
EXPECT_TRUE(absl::ParseFlag("0x10", &value, &err));
EXPECT_EQ(value, sixteen);
EXPECT_TRUE(absl::ParseFlag("0xFFFAAABBBCCCDDD", &value, &err));
EXPECT_EQ(value, quintillion_val);
EXPECT_TRUE(absl::ParseFlag("0xFFF0FFFFFFFFFFFFFFF", &value, &err));
EXPECT_EQ(value, quintillion_val2);
// Whitespace handling
EXPECT_TRUE(absl::ParseFlag("16 ", &value, &err));
EXPECT_EQ(value, sixteen);
EXPECT_TRUE(absl::ParseFlag(" 16", &value, &err));
EXPECT_EQ(value, sixteen);
EXPECT_TRUE(absl::ParseFlag(" 0100 ", &value, &err));
EXPECT_EQ(value, hundred);
EXPECT_TRUE(absl::ParseFlag(" 0x7B ", &value, &err));
EXPECT_EQ(value, hundreds_val); // =123
// Invalid values.
EXPECT_FALSE(absl::ParseFlag("", &value, &err));
EXPECT_FALSE(absl::ParseFlag(" ", &value, &err));
EXPECT_FALSE(absl::ParseFlag(" ", &value, &err));
EXPECT_FALSE(absl::ParseFlag("-1", &value, &err));
EXPECT_FALSE(absl::ParseFlag("--1", &value, &err));
EXPECT_FALSE(absl::ParseFlag("\n", &value, &err));
EXPECT_FALSE(absl::ParseFlag("\t", &value, &err));
EXPECT_FALSE(absl::ParseFlag("2U", &value, &err));
EXPECT_FALSE(absl::ParseFlag("FFF", &value, &err));
}
// --------------------------------------------------------------------
TEST(MarshallingTest, TestFloatParsing) { TEST(MarshallingTest, TestFloatParsing) {
std::string err; std::string err;
float value; float value;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment