More API details
This commit is contained in:
parent
7a63e233d2
commit
91b30e5b4e
@ -110,15 +110,25 @@ TEST(scan_test, invalid_format) {
|
|||||||
"invalid format string");
|
"invalid format string");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace std {
|
||||||
|
using fmt::scan;
|
||||||
|
using fmt::scan_error;
|
||||||
|
}
|
||||||
|
|
||||||
TEST(scan_test, example) {
|
TEST(scan_test, example) {
|
||||||
// Example from https://wg21.link/p1729r3.
|
// Example from https://wg21.link/p1729r3.
|
||||||
if (auto result = fmt::scan<std::string, int>("answer = 42", "{} = {}")) {
|
if (auto result = std::scan<std::string, int>("answer = 42", "{} = {}")) {
|
||||||
|
auto range = result->range();
|
||||||
|
EXPECT_EQ(range.begin(), range.end());
|
||||||
|
EXPECT_EQ(result->begin(), result->end());
|
||||||
#ifdef __cpp_structured_bindings
|
#ifdef __cpp_structured_bindings
|
||||||
const auto& [key, value] = result->values();
|
const auto& [key, value] = result->values();
|
||||||
EXPECT_EQ(key, "answer");
|
EXPECT_EQ(key, "answer");
|
||||||
EXPECT_EQ(value, 42);
|
EXPECT_EQ(value, 42);
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
|
std::scan_error error = result.error();
|
||||||
|
(void)error;
|
||||||
FAIL();
|
FAIL();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
19
test/scan.h
19
test/scan.h
@ -570,9 +570,10 @@ void make_args(std::array<scan_arg, sizeof...(T)>& args,
|
|||||||
}
|
}
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
template <typename... T> class scan_data {
|
template <typename Range, typename... T> class scan_data {
|
||||||
private:
|
private:
|
||||||
std::tuple<T...> values_;
|
std::tuple<T...> values_;
|
||||||
|
Range range_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
scan_data() = default;
|
scan_data() = default;
|
||||||
@ -589,6 +590,11 @@ template <typename... T> class scan_data {
|
|||||||
detail::make_args<0>(args, values_);
|
detail::make_args<0>(args, values_);
|
||||||
return args;
|
return args;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto range() const -> Range { return range_; }
|
||||||
|
|
||||||
|
auto begin() const -> decltype(range_.begin()) { return range_.begin(); }
|
||||||
|
auto end() const -> decltype(range_.end()) { return range_.end(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename... T>
|
template <typename... T>
|
||||||
@ -610,10 +616,12 @@ template <typename T, typename E> class expected {
|
|||||||
explicit operator bool() const { return has_value_; }
|
explicit operator bool() const { return has_value_; }
|
||||||
|
|
||||||
auto operator->() const -> const T* { return &value_; }
|
auto operator->() const -> const T* { return &value_; }
|
||||||
|
|
||||||
|
auto error() -> E const { return E(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename... T>
|
template <typename Range, typename... T>
|
||||||
using scan_result = expected<scan_data<T...>, scan_error>;
|
using scan_result = expected<scan_data<Range, T...>, scan_error>;
|
||||||
|
|
||||||
auto vscan(string_view input, string_view fmt, scan_args args)
|
auto vscan(string_view input, string_view fmt, scan_args args)
|
||||||
-> string_view::iterator {
|
-> string_view::iterator {
|
||||||
@ -630,8 +638,9 @@ auto scan_to(string_view input, string_view fmt, T&... args)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename... T>
|
template <typename... T>
|
||||||
auto scan(string_view input, string_view fmt) -> scan_result<T...> {
|
auto scan(string_view input, string_view fmt)
|
||||||
auto data = scan_data<T...>();
|
-> scan_result<string_view, T...> {
|
||||||
|
auto data = scan_data<string_view, T...>();
|
||||||
vscan(input, fmt, data.make_args());
|
vscan(input, fmt, data.make_args());
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user