Skip to content

Commit 0c7e4d5

Browse files
committed
try using SFINAE instead of macro
1 parent 65e70b7 commit 0c7e4d5

1 file changed

Lines changed: 28 additions & 17 deletions

File tree

src/iceberg/util/string_util.h

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -70,23 +70,26 @@ class ICEBERG_EXPORT StringUtils {
7070
}
7171

7272
template <typename T>
73-
requires std::is_arithmetic_v<T> && (!std::same_as<T, bool>)
73+
requires std::is_integral_v<T> && (!std::same_as<T, bool>)
7474
static Result<T> ParseNumber(std::string_view str) {
75-
T value = 0;
76-
if constexpr (std::is_integral_v<T>) {
77-
auto [ptr, ec] = std::from_chars(str.data(), str.data() + str.size(), value);
78-
if (ec == std::errc() && ptr == str.data() + str.size()) [[likely]] {
79-
return value;
80-
}
81-
if (ec == std::errc::result_out_of_range) {
82-
return InvalidArgument("Failed to parse {} from string '{}': value out of range",
83-
typeid(T).name(), str);
84-
}
85-
return InvalidArgument("Failed to parse {} from string '{}': invalid argument",
75+
T value{};
76+
auto [ptr, ec] = std::from_chars(str.data(), str.data() + str.size(), value);
77+
if (ec == std::errc() && ptr == str.data() + str.size()) [[likely]] {
78+
return value;
79+
}
80+
if (ec == std::errc::result_out_of_range) {
81+
return InvalidArgument("Failed to parse {} from string '{}': value out of range",
8682
typeid(T).name(), str);
87-
} else {
88-
// libc++ 20+ provides floating-point std::from_chars. Use fallback for older libc++
89-
#if defined(_LIBCPP_VERSION) && _LIBCPP_VERSION >= 200000
83+
}
84+
return InvalidArgument("Failed to parse {} from string '{}': invalid argument",
85+
typeid(T).name(), str);
86+
}
87+
88+
template <typename T>
89+
requires std::is_floating_point_v<T>
90+
static Result<T> ParseNumber(std::string_view str) {
91+
T value{};
92+
if constexpr (kHasFloatFromChars) {
9093
auto [ptr, ec] = std::from_chars(str.data(), str.data() + str.size(), value);
9194
if (ec == std::errc() && ptr == str.data() + str.size()) [[likely]] {
9295
return value;
@@ -97,7 +100,7 @@ class ICEBERG_EXPORT StringUtils {
97100
}
98101
return InvalidArgument("Failed to parse {} from string '{}': invalid argument",
99102
typeid(T).name(), str);
100-
#else
103+
} else {
101104
// strto* require null-terminated input; string_view does not guarantee it.
102105
std::string owned(str);
103106
const char* start = owned.c_str();
@@ -121,9 +124,17 @@ class ICEBERG_EXPORT StringUtils {
121124
typeid(T).name(), str);
122125
}
123126
return value;
124-
#endif
125127
}
126128
}
129+
130+
private:
131+
// libc++ 20+ provides floating-point std::from_chars; use strto* fallback for older
132+
// versions.
133+
#if defined(_LIBCPP_VERSION) && _LIBCPP_VERSION < 200000
134+
static constexpr bool kHasFloatFromChars = false;
135+
#else
136+
static constexpr bool kHasFloatFromChars = true;
137+
#endif
127138
};
128139

129140
/// \brief Transparent hash function that supports std::string_view as lookup key

0 commit comments

Comments
 (0)