Make scan variadic

This commit is contained in:
Victor Zverovich 2024-02-04 07:44:11 -08:00
parent 06311ed1ce
commit e17bc67547
2 changed files with 18 additions and 8 deletions

View File

@ -111,11 +111,16 @@ TEST(scan_test, invalid_format) {
}
TEST(scan_test, example) {
std::string key;
int value = 0;
fmt::scan_to("answer = 42", "{} = {}", key, value);
EXPECT_EQ(key, "answer");
EXPECT_EQ(value, 42);
// Example from https://wg21.link/p1729r3.
if (auto result = fmt::scan<std::string, int>("answer = 42", "{} = {}")) {
#ifdef __cpp_structured_bindings
const auto& [key, value] = result->values();
EXPECT_EQ(key, "answer");
EXPECT_EQ(value, 42);
#endif
} else {
FAIL();
}
}
TEST(scan_test, end_of_input) { fmt::scan<int>("", "{}"); }

View File

@ -582,6 +582,8 @@ template <typename... T> class scan_data {
return std::get<0>(values_);
}
auto values() const -> const std::tuple<T...>& { return values_; }
auto make_args() -> std::array<scan_arg, sizeof...(T)> {
auto args = std::array<scan_arg, sizeof...(T)>();
detail::make_args<0>(args, values_);
@ -600,10 +602,13 @@ class scan_error {};
template <typename T, typename E> class expected {
private:
T value_;
bool has_value_ = true;
public:
expected(T value) : value_(std::move(value)) {}
explicit operator bool() const { return has_value_; }
auto operator->() const -> const T* { return &value_; }
};
@ -624,9 +629,9 @@ auto scan_to(string_view input, string_view fmt, T&... args)
return vscan(input, fmt, make_scan_args(args...));
}
template <typename T>
auto scan(string_view input, string_view fmt) -> scan_result<T> {
auto data = scan_data<T>();
template <typename... T>
auto scan(string_view input, string_view fmt) -> scan_result<T...> {
auto data = scan_data<T...>();
vscan(input, fmt, data.make_args());
return data;
}