43concept FromChars =
requires(
const char* p, T& v) { std::from_chars(p, p, v); };
62 static std::string
ToLower(std::string_view str);
72 static std::string
ToUpper(std::string_view str) {
73 return str | std::ranges::views::transform(ToUpperAscii) |
74 std::ranges::to<std::string>();
83 const std::optional<bool> fast = AsciiEqualsIgnoreCase(lhs, rhs);
84 return fast.has_value() ? *fast : (ToLower(lhs) == ToLower(rhs));
94 if (prefix.size() <= str.size()) {
95 const std::optional<bool> fast =
96 AsciiEqualsIgnoreCase(str.substr(0, prefix.size()), prefix);
97 if (fast.has_value()) {
101 return ToLower(str).starts_with(ToLower(prefix));
108 if ((i & 0xC0) != 0x80) {
115 template <
typename T>
116 requires std::is_arithmetic_v<T> &&
FromChars<T> && (!std::same_as<T, bool>)
117 static Result<T> ParseNumber(std::string_view str) {
119 auto [ptr, ec] = std::from_chars(str.data(), str.data() + str.size(), value);
120 if (ec == std::errc()) [[likely]] {
121 if (ptr != str.data() + str.size()) {
122 return InvalidArgument(
"Failed to parse {} from string '{}': trailing characters",
123 typeid(T).name(), str);
127 if (ec == std::errc::invalid_argument) {
128 return InvalidArgument(
"Failed to parse {} from string '{}': invalid argument",
129 typeid(T).name(), str);
131 if (ec == std::errc::result_out_of_range) {
132 return InvalidArgument(
"Failed to parse {} from string '{}': value out of range",
133 typeid(T).name(), str);
142 template <
typename T>
144 static Result<T> ParseNumber(std::string_view str) {
147 std::string owned(str);
148 const char* start = owned.c_str();
152 if constexpr (std::same_as<T, float>) {
153 value = std::strtof(start, &end);
154 }
else if constexpr (std::same_as<T, double>) {
155 value = std::strtod(start, &end);
157 value = std::strtold(start, &end);
160 if (end == start || end != start +
static_cast<std::ptrdiff_t
>(owned.size())) {
161 return InvalidArgument(
"Failed to parse {} from string '{}': invalid argument",
162 typeid(T).name(), str);
164 if (errno == ERANGE) {
165 return InvalidArgument(
"Failed to parse {} from string '{}': value out of range",
166 typeid(T).name(), str);
174 static constexpr char ToUpperAscii(
char c)
noexcept {
175 return (c >=
'a' && c <=
'z') ?
static_cast<char>(c -
'a' +
'A') : c;
177 static constexpr char ToLowerAscii(
char c)
noexcept {
178 return (c >=
'A' && c <=
'Z') ?
static_cast<char>(c -
'A' +
'a') : c;
183 static constexpr bool IsAsciiByte(
char c)
noexcept {
184 return (
static_cast<unsigned char>(c) & 0x80) == 0;
191 static std::optional<bool> AsciiEqualsIgnoreCase(std::string_view a,
192 std::string_view b) {
193 const size_t n = std::min(a.size(), b.size());
194 for (
size_t i = 0; i < n; ++i) {
195 if (!IsAsciiByte(a[i]) || !IsAsciiByte(b[i])) {
198 if (ToLowerAscii(a[i]) != ToLowerAscii(b[i])) {
202 return a.size() == b.size();
211 using hash_type = std::hash<std::string_view>;
212 using is_transparent = void;
214 std::size_t operator()(std::string_view str)
const {
return hash_type{}(str); }
215 std::size_t operator()(
const char* str)
const {
return hash_type{}(str); }
216 std::size_t operator()(
const std::string& str)
const {
return hash_type{}(str); }
221 using is_transparent = void;
223 bool operator()(std::string_view lhs, std::string_view rhs)
const {
return lhs == rhs; }
224 bool operator()(
const std::string& lhs,
const std::string& rhs)
const {
231 using is_transparent = void;
233 bool operator()(std::string_view lhs, std::string_view rhs)
const {
return lhs < rhs; }
Definition string_util.h:45
static bool StartsWithIgnoreCase(std::string_view str, std::string_view prefix)
Case-insensitive prefix test using Unicode simple (1:1) case mapping.
Definition string_util.h:93
static size_t CodePointCount(std::string_view str)
Count the number of code points in a UTF-8 string.
Definition string_util.h:105
static std::string ToUpper(std::string_view str)
Upper-case the ASCII letters (a-z) in a string; all other bytes, including multi-byte UTF-8 sequences...
Definition string_util.h:72
static std::string ToLower(std::string_view str)
Lower-case a UTF-8 string using Unicode simple (1:1) case mapping.
static Result< std::vector< uint8_t > > HexStringToBytes(std::string_view hex)
Decode a hex string (upper or lower case) into bytes. Returns an error if the string has odd length o...
static bool EqualsIgnoreCase(std::string_view lhs, std::string_view rhs)
Case-insensitive equality using Unicode simple (1:1) case mapping.
Definition string_util.h:82
Definition string_util.h:43
Define symbol visibility macros for core Iceberg APIs.
Core Apache Iceberg C++ APIs.
Definition arrow_io_util.h:33
std::expected< T, E > Result
Result alias.
Definition result.h:88
Define Result, Status, and error helpers.
Transparent equality function that supports std::string_view as lookup key.
Definition string_util.h:220
Transparent hash function that supports std::string_view as lookup key.
Definition string_util.h:210
Transparent less function that supports std::string_view as lookup key.
Definition string_util.h:230