etl icon indicating copy to clipboard operation
etl copied to clipboard

Feature request: Helper functions to convert strings to numeric values

Open oresk opened this issue 2 years ago • 15 comments

We have the to_string() functions that are really ergonomic, especially when paired with format.

Having a utility that would do a conversion the other way round would be really usefull addition to ETL.

oresk avatar Sep 10 '22 15:09 oresk

Do you think that the string passed should only contain the numeric string to convert, or should it search for the start and end of the numeric?

i.e. find non-numeric characters.

"abc# 123.45*sne"
      ^     ^

jwellbelove avatar Sep 11 '22 11:09 jwellbelove

I think that the string passed should be just the value. Even if the incoming string has other characters, then we can just give the conversion functions a string_view of the part to the value, right?

I'd rather have the functions tell me that the string does not match the type of data I told it it would be. Ie. it was supposed to be an int and the string has a dot in it. So it can do a bit of validation.

oresk avatar Sep 12 '22 13:09 oresk

That would definitely be the easiest to implement, and it separates the two steps of 'search' & 'convert', though I would probably let the conversion functions automatically ignore leading and trailing whitespace.

jwellbelove avatar Sep 13 '22 08:09 jwellbelove

That sounds great!

oresk avatar Sep 13 '22 08:09 oresk

Something like stoi in terms of API, perhaps?

jesseli2002 avatar Sep 13 '22 23:09 jesseli2002

Including conversion of strings in binary, octal & hex formats? It may need an explicit base parameter or deduction from the prefix.

etl::to_arithmetic<int>("1234", etl::hex());
etl::to_arithmetic<int>("0x1234");

jwellbelove avatar Sep 14 '22 12:09 jwellbelove

does anyone still use octal?

RallyTronics avatar Sep 14 '22 16:09 RallyTronics

I'm sure someone does somewhere :-)

jwellbelove avatar Sep 16 '22 11:09 jwellbelove

  • The return type of the functions will be an etl::optional<T>, where T is an arithmetic type.
  • A failure to convert will result in a default constructed etl::optional<T>.
  • I'm thinking that I should not bother handling stripping off any 0x, 0X, 0b or 0B prefix from hex and binary strings.
  • I'm also thinking that binary, octal and hex strings that are prefixed with - are not converted (Or - is ignored?).
  • An attempt to convert a negative decimal string to an unsigned type will also be a failure.
  • A + prefix to any numeric string will be ignored.
  • Leading or trailing whitespace will be ignored.
  • Any failure to convert will be submitted to the error handler or thrown as an exception (dependent on configuration)
  • Should binary, octal and hex only be allowed to convert to unsigned?
  • Error on conversion overflow.

jwellbelove avatar Sep 16 '22 12:09 jwellbelove

Examples: " +123 " as signed decimal OK " -123 " as signed decimal OK " -123 " as unsigned decimal FAILURE " +123 " as unsigned hex OK " 123 " as signed hex FAILURE " -123 " as signed hex FAILURE " 0x123 " as unsigned hex FAILURE

jwellbelove avatar Sep 16 '22 12:09 jwellbelove

Should an empty string be an error?

jwellbelove avatar Sep 20 '22 10:09 jwellbelove

At the moment, "" is not an error (and returns a default constructed etl::optional<T>), but "-" or "+" are errors.

jwellbelove avatar Sep 20 '22 10:09 jwellbelove

Hm, what would then be a difference between an error and a default constructed etl::optional<t>? From 4 comments above:

  • A failure to convert will result in a default constructed etl::optional<T>.
  • Any failure to convert will be submitted to the error handler or thrown as an exception (dependent on configuration)

I was under the impression that a default constructed etl::optional<T> indicated an error, and depending on the additional config it can throw an exception.

Which ever one it is I would say an empty string would should have the same consequence as any other string that can not be converted.

oresk avatar Sep 20 '22 14:09 oresk

Sorry for my confusing description. When I said 'errors' I meant a call to ETL_ASSERT. A return of a default constructed etl::optional<T> is of course a 'failure to convert' error, so I agree that an empty string should be treated the same as any other 'failure to convert' error.

jwellbelove avatar Sep 20 '22 22:09 jwellbelove

How important is the ability to have a constexpr conversion? At the moment I am returning etl::optional<T>. Unfortunately, etl::optional cannot be constexpr due to the aligned storage member.

EDIT: I realised that I can probably specialise etl::optional for fundamental types to be constexpr.

jwellbelove avatar Sep 22 '22 11:09 jwellbelove

Floating point in radixes other than decimal?

jwellbelove avatar Sep 24 '22 09:09 jwellbelove

Perfect!

Will be using it over the weekend

oresk avatar Nov 03 '22 10:11 oresk