Add scan_data::make_args
This commit is contained in:
parent
e1832bcf00
commit
6f260455aa
37
test/scan.h
37
test/scan.h
@ -10,7 +10,7 @@
|
|||||||
#include <climits>
|
#include <climits>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
|
||||||
#include "fmt/format.h"
|
#include "fmt/format-inl.h"
|
||||||
|
|
||||||
FMT_BEGIN_NAMESPACE
|
FMT_BEGIN_NAMESPACE
|
||||||
namespace detail {
|
namespace detail {
|
||||||
@ -555,25 +555,45 @@ void vscan(detail::scan_buffer& buf, string_view fmt, scan_args args) {
|
|||||||
auto h = detail::scan_handler(fmt, buf, args);
|
auto h = detail::scan_handler(fmt, buf, args);
|
||||||
detail::parse_format_string<false>(fmt, h);
|
detail::parse_format_string<false>(fmt, h);
|
||||||
}
|
}
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
template <typename... T>
|
template <size_t I, typename... T, FMT_ENABLE_IF(I == sizeof...(T))>
|
||||||
auto make_scan_args(T&... args) -> std::array<scan_arg, sizeof...(T)> {
|
void make_args(std::array<scan_arg, sizeof...(T)>&, std::tuple<T...>&) {}
|
||||||
return {{args...}};
|
|
||||||
|
template <size_t I, typename... T, FMT_ENABLE_IF(I < sizeof...(T))>
|
||||||
|
void make_args(std::array<scan_arg, sizeof...(T)>& args,
|
||||||
|
std::tuple<T...>& values) {
|
||||||
|
using element_type = typename std::tuple_element<I, std::tuple<T...>>::type;
|
||||||
|
static_assert(std::is_same<remove_cvref_t<element_type>, element_type>::value,
|
||||||
|
"");
|
||||||
|
args[I] = std::get<I>(values);
|
||||||
|
make_args<I + 1>(args, values);
|
||||||
}
|
}
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
template <typename... T> class scan_data {
|
template <typename... T> class scan_data {
|
||||||
private:
|
private:
|
||||||
std::tuple<T...> values_;
|
std::tuple<T...> values_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
scan_data() = default;
|
||||||
scan_data(T... values) : values_(std::move(values)...) {}
|
scan_data(T... values) : values_(std::move(values)...) {}
|
||||||
|
|
||||||
auto value() const -> decltype(std::get<0>(values_)) {
|
auto value() const -> decltype(std::get<0>(values_)) {
|
||||||
return std::get<0>(values_);
|
return std::get<0>(values_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto make_args() -> std::array<scan_arg, sizeof...(T)> {
|
||||||
|
auto args = std::array<scan_arg, sizeof...(T)>();
|
||||||
|
detail::make_args<0>(args, values_);
|
||||||
|
return args;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename... T>
|
||||||
|
auto make_scan_args(T&... args) -> std::array<scan_arg, sizeof...(T)> {
|
||||||
|
return {{args...}};
|
||||||
|
}
|
||||||
|
|
||||||
class scan_error {};
|
class scan_error {};
|
||||||
|
|
||||||
// A rudimentary version of std::expected for testing the API shape.
|
// A rudimentary version of std::expected for testing the API shape.
|
||||||
@ -606,10 +626,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) -> scan_result<T> {
|
||||||
static_assert(std::is_same<remove_cvref_t<T>, T>::value, "");
|
auto data = scan_data<T>();
|
||||||
auto value = T();
|
vscan(input, fmt, data.make_args());
|
||||||
scan_to(input, fmt, value);
|
return data;
|
||||||
return scan_data<T>(std::move(value));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Range, typename... T,
|
template <typename Range, typename... T,
|
||||||
|
Loading…
Reference in New Issue
Block a user