www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Compile time int to string conversion in BetterC

reply Ogi <ogion.art gmail.com> writes:
It’s 2022 already and BetterC still imposes limits at compile 
time and makes things awkward.

I have 3 integer enums that represents my library version. And I 
want to generate a "1.2.3" enum from them. This is a trivial 
thing to do in standard D but I can’t find a way to do it with 
BetterC enabled. I can’t use `to`, `text`, `sformat` or 
`toChars`, as none of them is compatible with BetterC. And I 
can’t use `sprintf` either because ‘stdc’ is not available at 
compile time.

On the other hand, string to integer conversion is simple: just 
‘mixin’ it! So as a workaround, I put numbers into private string 
enums, and the integer enums are generated from them. But this is 
not nice.

Maybe I’m missing something?
Aug 17 2022
parent reply Dennis <dkorpel gmail.com> writes:
On Wednesday, 17 August 2022 at 08:44:30 UTC, Ogi wrote:
 Maybe I’m missing something?
I had the same problem, and came up with the following trick: ```D enum itoa(int i) = i.stringof; enum major = 3; enum minor = 2; enum patch = 1; enum versionString = itoa!major ~ "." ~ itoa!minor ~ "." ~ itoa!patch; static assert(versionString == "3.2.1"); ``` Now I need to warn you that the output of `stringof` is technically implementation defined per the specification, so you shouldn't rely on it. In practice [this doesn't stop people](https://github.com/libmir/mir-algorithm/pull/422), and I don't think integers will ever not be printed as a string of base 10 digits.
Aug 17 2022
next sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 8/17/22 6:38 AM, Dennis wrote:
 On Wednesday, 17 August 2022 at 08:44:30 UTC, Ogi wrote:
 Maybe I’m missing something?
I had the same problem, and came up with the following trick: ```D enum itoa(int i) = i.stringof; ```
I have the same thing in my code: ```d enum intStr(int x) = x.stringof; ``` The reason you do this is to shoehorn things that aren't technically ints (such as enum types) into ints. This avoids weirdness like `cast(foo)bar` or whatnot that might happen if you just use stringof on any expression.
 
 Now I need to warn you that the output of `stringof` is technically 
 implementation defined per the specification, so you shouldn't rely on 
 it. In practice [this doesn't stop 
 people](https://github.com/libmir/mir-algorithm/pull/422), and I don't 
 think integers will ever not be printed as a string of base 10 digits.
Yeah, I wouldn't worry about stringof for ints. -Steve
Aug 17 2022
parent reply Paul Backus <snarwin gmail.com> writes:
On Wednesday, 17 August 2022 at 11:38:31 UTC, Steven 
Schveighoffer wrote:
 On 8/17/22 6:38 AM, Dennis wrote:
 On Wednesday, 17 August 2022 at 08:44:30 UTC, Ogi wrote:
 Maybe I’m missing something?
I had the same problem, and came up with the following trick: ```D enum itoa(int i) = i.stringof; ```
I have the same thing in my code: ```d enum intStr(int x) = x.stringof; ```
I merged a version of this into Phobos (for internal use): https://github.com/dlang/phobos/blob/v2.100.1/std/conv.d#L5986-L5987 It also comes with a unit test, so we don't get surprise breakage if the behavior of `.stringof` ever changes.
Aug 18 2022
parent reply bauss <jacobbauss gmail.com> writes:
On Thursday, 18 August 2022 at 22:00:06 UTC, Paul Backus wrote:
 On Wednesday, 17 August 2022 at 11:38:31 UTC, Steven 
 Schveighoffer wrote:
 On 8/17/22 6:38 AM, Dennis wrote:
 On Wednesday, 17 August 2022 at 08:44:30 UTC, Ogi wrote:
 Maybe I’m missing something?
I had the same problem, and came up with the following trick: ```D enum itoa(int i) = i.stringof; ```
I have the same thing in my code: ```d enum intStr(int x) = x.stringof; ```
I merged a version of this into Phobos (for internal use): https://github.com/dlang/phobos/blob/v2.100.1/std/conv.d#L5986-L5987 It also comes with a unit test, so we don't get surprise breakage if the behavior of `.stringof` ever changes.
Is there a reason why .stringof is implementation defined and not clearly defined in the spec how types and declarations should be treated when being "converted to a string"? I find it really odd that it's implementation defined and you essentially can't rely on it anywhere. It's something that has baffled me a lot. Like are there something I'm missing that means it cannot be specified?
Aug 19 2022
parent reply Paul Backus <snarwin gmail.com> writes:
On Friday, 19 August 2022 at 10:22:25 UTC, bauss wrote:
 Is there a reason why .stringof is implementation defined and 
 not clearly defined in the spec how types and declarations 
 should be treated when being "converted to a string"?

 I find it really odd that it's implementation defined and you 
 essentially can't rely on it anywhere.

 It's something that has baffled me a lot.

 Like are there something I'm missing that means it cannot be 
 specified?
Basically, `.stringof` is what the compiler uses when it needs to display something in an error message. If it were locked down in the spec, then making improvements to error messages would in some cases require a deprecation cycle. That said, it might still be worth specifying the behavior in a few specific cases—e.g., guaranteeing that `.stringof` on an integer value will always produce a valid integer literal.
Aug 19 2022
parent bauss <jacobbauss gmail.com> writes:
On Friday, 19 August 2022 at 13:47:41 UTC, Paul Backus wrote:
 On Friday, 19 August 2022 at 10:22:25 UTC, bauss wrote:
 Is there a reason why .stringof is implementation defined and 
 not clearly defined in the spec how types and declarations 
 should be treated when being "converted to a string"?

 I find it really odd that it's implementation defined and you 
 essentially can't rely on it anywhere.

 It's something that has baffled me a lot.

 Like are there something I'm missing that means it cannot be 
 specified?
Basically, `.stringof` is what the compiler uses when it needs to display something in an error message. If it were locked down in the spec, then making improvements to error messages would in some cases require a deprecation cycle. That said, it might still be worth specifying the behavior in a few specific cases—e.g., guaranteeing that `.stringof` on an integer value will always produce a valid integer literal.
Yeah I mean not all of its behavior has to be implementation defined.
Aug 19 2022
prev sibling parent Ogi <ogion.art gmail.com> writes:
On Wednesday, 17 August 2022 at 10:38:33 UTC, Dennis wrote:
 I had the same problem, and came up with the following trick:

 ```D
 enum itoa(int i) = i.stringof;

 enum major = 3;
 enum minor = 2;
 enum patch = 1;

 enum versionString = itoa!major ~ "." ~ itoa!minor ~ "." ~ 
 itoa!patch;

 static assert(versionString == "3.2.1");
 ```
Nice! Thank you, I’ll use this.
Aug 19 2022