Skip to content

Commit a5dccff

Browse files
Sahil Sinhavitaut
authored andcommitted
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.
1 parent 4a149f5 commit a5dccff

File tree

1 file changed

+53
-0
lines changed

1 file changed

+53
-0
lines changed

test/scan.h

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,8 @@ enum class scan_type {
229229
uint_type,
230230
long_long_type,
231231
ulong_long_type,
232+
double_type,
233+
float_type,
232234
string_type,
233235
string_view_type,
234236
custom_type
@@ -251,6 +253,8 @@ template <typename Context> class basic_scan_arg {
251253
unsigned* uint_value_;
252254
long long* long_long_value_;
253255
unsigned long long* ulong_long_value_;
256+
double* double_value_;
257+
float* float_value_;
254258
std::string* string_;
255259
string_view* string_view_;
256260
detail::custom_scan_arg<Context> custom_;
@@ -276,6 +280,10 @@ template <typename Context> class basic_scan_arg {
276280
: type_(scan_type::long_long_type), long_long_value_(&value) {}
277281
FMT_CONSTEXPR basic_scan_arg(unsigned long long& value)
278282
: type_(scan_type::ulong_long_type), ulong_long_value_(&value) {}
283+
FMT_CONSTEXPR basic_scan_arg(double& value)
284+
: type_(scan_type::double_type), double_value_(&value) {}
285+
FMT_CONSTEXPR basic_scan_arg(float& value)
286+
: type_(scan_type::float_type), float_value_(&value) {}
279287
FMT_CONSTEXPR basic_scan_arg(std::string& value)
280288
: type_(scan_type::string_type), string_(&value) {}
281289
FMT_CONSTEXPR basic_scan_arg(string_view& value)
@@ -305,6 +313,10 @@ template <typename Context> class basic_scan_arg {
305313
return vis(*long_long_value_);
306314
case scan_type::ulong_long_type:
307315
return vis(*ulong_long_value_);
316+
case scan_type::double_type:
317+
return vis(*double_value_);
318+
case scan_type::float_type:
319+
return vis(*float_value_);
308320
case scan_type::string_type:
309321
return vis(*string_);
310322
case scan_type::string_view_type:
@@ -457,6 +469,47 @@ auto read(scan_iterator it, T& value, const format_specs& specs = {})
457469
return it;
458470
}
459471

472+
auto read(scan_iterator it, double& value, const format_specs& = {})
473+
-> scan_iterator {
474+
if (it == scan_sentinel()) return it;
475+
476+
// Simple floating-point parsing
477+
bool negative = *it == '-';
478+
if (negative) {
479+
++it;
480+
if (it == scan_sentinel()) report_error("invalid input");
481+
}
482+
483+
double result = 0.0;
484+
// Parse integer part
485+
while (it != scan_sentinel() && *it >= '0' && *it <= '9') {
486+
result = result * 10.0 + (*it - '0');
487+
++it;
488+
}
489+
490+
// Parse decimal part if present
491+
if (it != scan_sentinel() && *it == '.') {
492+
++it;
493+
double fraction = 0.1;
494+
while (it != scan_sentinel() && *it >= '0' && *it <= '9') {
495+
result += (*it - '0') * fraction;
496+
fraction *= 0.1;
497+
++it;
498+
}
499+
}
500+
501+
value = negative ? -result : result;
502+
return it;
503+
}
504+
505+
auto read(scan_iterator it, float& value, const format_specs& specs = {})
506+
-> scan_iterator {
507+
double temp;
508+
it = read(it, temp, specs);
509+
value = static_cast<float>(temp);
510+
return it;
511+
}
512+
460513
auto read(scan_iterator it, std::string& value, const format_specs& = {})
461514
-> scan_iterator {
462515
while (it != scan_sentinel() && *it != ' ') value.push_back(*it++);

0 commit comments

Comments
 (0)