mirror of
https://github.com/fmtlib/fmt.git
synced 2025-06-25 01:11:40 +02:00
Add double and float support to scan test
- Add double_type and float_type to scan_type enum - Add double* and float* pointers to scan_arg union - Add constructors for double and float scan arguments - Add switch cases for double and float types in visit() - Implement basic read() functions for floating-point parsing This partially resolves the TODO comment 'more types' in scan.h by adding support for the two most commonly needed floating-point types.
This commit is contained in:
committed by
Victor Zverovich
parent
4a149f513f
commit
a5dccffa56
53
test/scan.h
53
test/scan.h
@ -229,6 +229,8 @@ enum class scan_type {
|
||||
uint_type,
|
||||
long_long_type,
|
||||
ulong_long_type,
|
||||
double_type,
|
||||
float_type,
|
||||
string_type,
|
||||
string_view_type,
|
||||
custom_type
|
||||
@ -251,6 +253,8 @@ template <typename Context> class basic_scan_arg {
|
||||
unsigned* uint_value_;
|
||||
long long* long_long_value_;
|
||||
unsigned long long* ulong_long_value_;
|
||||
double* double_value_;
|
||||
float* float_value_;
|
||||
std::string* string_;
|
||||
string_view* string_view_;
|
||||
detail::custom_scan_arg<Context> custom_;
|
||||
@ -276,6 +280,10 @@ template <typename Context> class basic_scan_arg {
|
||||
: type_(scan_type::long_long_type), long_long_value_(&value) {}
|
||||
FMT_CONSTEXPR basic_scan_arg(unsigned long long& value)
|
||||
: type_(scan_type::ulong_long_type), ulong_long_value_(&value) {}
|
||||
FMT_CONSTEXPR basic_scan_arg(double& value)
|
||||
: type_(scan_type::double_type), double_value_(&value) {}
|
||||
FMT_CONSTEXPR basic_scan_arg(float& value)
|
||||
: type_(scan_type::float_type), float_value_(&value) {}
|
||||
FMT_CONSTEXPR basic_scan_arg(std::string& value)
|
||||
: type_(scan_type::string_type), string_(&value) {}
|
||||
FMT_CONSTEXPR basic_scan_arg(string_view& value)
|
||||
@ -305,6 +313,10 @@ template <typename Context> class basic_scan_arg {
|
||||
return vis(*long_long_value_);
|
||||
case scan_type::ulong_long_type:
|
||||
return vis(*ulong_long_value_);
|
||||
case scan_type::double_type:
|
||||
return vis(*double_value_);
|
||||
case scan_type::float_type:
|
||||
return vis(*float_value_);
|
||||
case scan_type::string_type:
|
||||
return vis(*string_);
|
||||
case scan_type::string_view_type:
|
||||
@ -457,6 +469,47 @@ auto read(scan_iterator it, T& value, const format_specs& specs = {})
|
||||
return it;
|
||||
}
|
||||
|
||||
auto read(scan_iterator it, double& value, const format_specs& = {})
|
||||
-> scan_iterator {
|
||||
if (it == scan_sentinel()) return it;
|
||||
|
||||
// Simple floating-point parsing
|
||||
bool negative = *it == '-';
|
||||
if (negative) {
|
||||
++it;
|
||||
if (it == scan_sentinel()) report_error("invalid input");
|
||||
}
|
||||
|
||||
double result = 0.0;
|
||||
// Parse integer part
|
||||
while (it != scan_sentinel() && *it >= '0' && *it <= '9') {
|
||||
result = result * 10.0 + (*it - '0');
|
||||
++it;
|
||||
}
|
||||
|
||||
// Parse decimal part if present
|
||||
if (it != scan_sentinel() && *it == '.') {
|
||||
++it;
|
||||
double fraction = 0.1;
|
||||
while (it != scan_sentinel() && *it >= '0' && *it <= '9') {
|
||||
result += (*it - '0') * fraction;
|
||||
fraction *= 0.1;
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
value = negative ? -result : result;
|
||||
return it;
|
||||
}
|
||||
|
||||
auto read(scan_iterator it, float& value, const format_specs& specs = {})
|
||||
-> scan_iterator {
|
||||
double temp;
|
||||
it = read(it, temp, specs);
|
||||
value = static_cast<float>(temp);
|
||||
return it;
|
||||
}
|
||||
|
||||
auto read(scan_iterator it, std::string& value, const format_specs& = {})
|
||||
-> scan_iterator {
|
||||
while (it != scan_sentinel() && *it != ' ') value.push_back(*it++);
|
||||
|
Reference in New Issue
Block a user