@@ -5151,7 +5151,8 @@ namespace csv {
5151
5151
template <> inline DataType type_num<std::nullptr_t >() { return DataType::CSV_NULL; }
5152
5152
template <> inline DataType type_num<std::string>() { return DataType::CSV_STRING; }
5153
5153
5154
- CONSTEXPR_14 DataType data_type (csv::string_view in, long double * const out = nullptr );
5154
+ CONSTEXPR_14 DataType data_type (csv::string_view in, long double * const out = nullptr ,
5155
+ const char decimalsymbol = ' .' );
5155
5156
#endif
5156
5157
5157
5158
/* * Given a byte size, return the largest number than can be stored in
@@ -5294,9 +5295,11 @@ namespace csv {
5294
5295
* @param[in] in String value to be examined
5295
5296
* @param[out] out Pointer to long double where results of numeric parsing
5296
5297
* get stored
5298
+ * @param[in] decimalsymbol the character separating integral and decimal part,
5299
+ * defaults to '.' if omitted
5297
5300
*/
5298
5301
CONSTEXPR_14
5299
- DataType data_type (csv::string_view in, long double * const out) {
5302
+ DataType data_type (csv::string_view in, long double * const out, const char decimalsymbol ) {
5300
5303
// Empty string --> NULL
5301
5304
if (in.size () == 0 )
5302
5305
return DataType::CSV_NULL;
@@ -5342,14 +5345,8 @@ namespace csv {
5342
5345
5343
5346
is_negative = true ;
5344
5347
break ;
5345
- case ' .' :
5346
- if (!dot_allowed) {
5347
- return DataType::CSV_STRING;
5348
- }
5349
-
5350
- dot_allowed = false ;
5351
- prob_float = true ;
5352
- break ;
5348
+ // case decimalsymbol: not allowed because decimalsymbol is not a literal,
5349
+ // it is handled in the default block
5353
5350
case ' e' :
5354
5351
case ' E' :
5355
5352
// Process scientific notation
@@ -5388,6 +5385,11 @@ namespace csv {
5388
5385
else
5389
5386
integral_part = (integral_part * 10 ) + digit;
5390
5387
}
5388
+ // case decimalymbol: not allowed because decimalsymbol is not a literal.
5389
+ else if (dot_allowed && current == decimalsymbol) {
5390
+ dot_allowed = false ;
5391
+ prob_float = true ;
5392
+ }
5391
5393
else {
5392
5394
return DataType::CSV_STRING;
5393
5395
}
@@ -5610,6 +5612,12 @@ namespace csv {
5610
5612
/* * Parse a hexadecimal value, returning false if the value is not hex. */
5611
5613
bool try_parse_hex (int & parsedValue);
5612
5614
5615
+ /* * Parse a value, returning false if the value is not decimal.
5616
+ * If true it also sets the private members _type and value.
5617
+ * Decimal symbol may be given explicitly, default is '.'.
5618
+ */
5619
+ bool try_parse_decimal (long double & dVal, const char decimalsymbol = ' .' );
5620
+
5613
5621
/* * Compares the contents of this field to a numeric value. If this
5614
5622
* field does not contain a numeric value, then all comparisons return
5615
5623
* false.
@@ -7847,6 +7855,29 @@ namespace csv {
7847
7855
return true ;
7848
7856
}
7849
7857
7858
+ // try_parse_decimal uses the specified decimal symbol and
7859
+ // also sets the private members _type and value
7860
+ CSV_INLINE bool CSVField::try_parse_decimal (long double & dVal, const char decimalsymbol) {
7861
+ // If field has already been parsed to empty, no need to do it aagin:
7862
+ if (this ->_type == DataType::CSV_NULL)
7863
+ return false ;
7864
+
7865
+ // Not yet parsed or possibly parsed with other decimalsymbol
7866
+ if (this ->_type == DataType::UNKNOWN || this ->_type == DataType::CSV_STRING || this ->_type == DataType::CSV_DOUBLE)
7867
+ this ->_type = internals::data_type (this ->sv , &this ->value , decimalsymbol); // parse again
7868
+
7869
+ // Integral types are not affected by decimalsymbol and need not be parsed again
7870
+
7871
+ // Either we already had an integral type before, or we we just got any numeric type now.
7872
+ if (this ->_type >= DataType::CSV_INT8 && this ->_type <= DataType::CSV_DOUBLE) {
7873
+ dVal = this ->value ;
7874
+ return true ;
7875
+ }
7876
+
7877
+ // CSV_NULL or CSV_STRING, not numeric
7878
+ return false ;
7879
+ }
7880
+
7850
7881
#ifdef _MSC_VER
7851
7882
#pragma region CSVRow Iterator
7852
7883
#endif
0 commit comments