www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Voldemort toHexString Compile Error

reply Salih Dincer <salihdb hotmail.com> writes:
```d
void main()
{
   import std.stdio;

   "Hello D".toHexString.writeln;
}

struct HexString
{
   int i;

   auto nibbleSplit()
   {
     auto MSB = i >> 4;
     auto LSB = i & 15;
     return [MSB, LSB];
   }
}

auto toHexString(string str)
{
   struct Hex { int i;
     auto nibbleSplit() {
       auto MSB = i >> 4;
       auto LSB = i & 15;
       return [MSB, LSB];
     }
   }

   import std.algorithm : map;
   import std.conv, std.range : join;

   return str.map!Hex//String
             .map!(e => e.nibbleSplit).join
             .map!(n => n += n > 9 ? '7' : '0')
             .map!(c => c.to!char);
}
```

Why doesn't the function compile?  But the code is compiled with 
the HexString structure.  The error given by the compiler is as 
follows:

 /dlang/dmd/linux/bin64/../../src/phobos/std/algorithm/iteration.d(582): Error:
cannot access frame pointer of `onlineapp.toHexString.Hex`
/dlang/dmd/linux/bin64/../../src/phobos/std/algorithm/iteration.d(479): Error: template instance `std.algorithm.iteration.MapResult!(Hex, string)` error instantiating onlineapp.d(33): instantiated from here: `map!string` onlineapp.d(34): Error: template `onlineapp.toHexString.map!((e) => e.nibbleSplit).map` is not callable using argument types `!()(MapResult!(Hex, string))` /dlang/dmd/linux/bin64/../../src/phobos/std/algorithm/iteration.d(446): Candidate is: `map(Range)(Range r)` with `Range = MapResult!(Hex, string)` must satisfy the following constraint: ` isInputRange!(Unqual!Range)
Mar 17
parent reply "Richard (Rikki) Andrew Cattermole" <richard cattermole.co.nz> writes:
It is because Hex is nested, it has an outer pointer to the call frame 
of toHexString.

Make Hex static, and it works.
Mar 17
next sibling parent reply kdevel <kdevel vogtner.de> writes:
On Sunday, 17 March 2024 at 13:08:14 UTC, Richard (Rikki) Andrew 
Cattermole wrote:
 It is because Hex is nested, it has an outer pointer to the 
 call frame of toHexString.

 Make Hex static, and it works.
Not really. Have you ever tried? "abc äöü߀ D".toHexString.writeln;
Mar 17
parent reply "Richard (Rikki) Andrew Cattermole" <richard cattermole.co.nz> writes:
On 18/03/2024 5:45 AM, kdevel wrote:
 On Sunday, 17 March 2024 at 13:08:14 UTC, Richard (Rikki) Andrew 
 Cattermole wrote:
 It is because Hex is nested, it has an outer pointer to the call frame 
 of toHexString.

 Make Hex static, and it works.
Not really. Have you ever tried?    "abc äöü߀ D".toHexString.writeln;
I did run it, both with and without static on Hex. Without did not work on run.dlang.io which was consistent with the error that Salih had provided. The error is clear on the first line: "cannot access frame pointer of onlineapp.toHexString.Hex"
Mar 17
parent kdevel <kdevel vogtner.de> writes:
On Sunday, 17 March 2024 at 16:48:23 UTC, Richard (Rikki) Andrew 
Cattermole wrote:
 [...]
 Make Hex static, and it works.
Not really. Have you ever tried?    "abc äöü߀ D".toHexString.writeln;
I did run it, both with and without static on Hex. Without did not work on run.dlang.io which was consistent with the error that Salih had provided. The error is clear on the first line: "cannot access frame pointer of onlineapp.toHexString.Hex"
I meant the compiled executable, not the compilation. The code has an autodecoding issue which goes unnoticed due to using int (instead of ubyte?) for i. When I run the executable I get a three screens stack trace. std.conv.ConvOverflowException [...]linux/bin64/../../src/phob s/std/conv.d(1556): Conversion positive overflow BTW: What is the purpose of not writing a free function like this?: auto nibbleSplit(ubyte b) { auto MSB = b >> 4; auto LSB = b & 15; return [MSB, LSB]; } auto toHexString(string str) { import std.algorithm : map; import std.conv, std.range : join; import std.utf; return str // .byCodeUnit // <-- solves the auto-decoding issue .map!(e => e.nibbleSplit).join .map!(n => n += n > 9 ? '7' : '0') .map!(c => c.to!char); }
Mar 17
prev sibling parent Salih Dincer <salihdb hotmail.com> writes:
On Sunday, 17 March 2024 at 13:08:14 UTC, Richard (Rikki) Andrew 
Cattermole wrote:
 It is because Hex is nested, it has an outer pointer to the 
 call frame of toHexString.

 Make Hex static, and it works.
Thank you for your contributions. It's great to develop something with you. So is having such a forum. Thanks everyone, here is the new version: ```d auto toHexRange(T)(const char[] str) { static struct HexRange { int i; auto nibbleSplit() { auto MSB = i >> 4; auto LSB = i & 15; return [MSB, LSB]; } } import std.utf : byCodeUnit; import std.algorithm : map; import std.range : join; return str.byCodeUnit.map!HexRange .map!(e => e.nibbleSplit).join .map!(n => n += n > 9 ? '7' : '0') .map!(c => c.to!T); } auto toHex(T)(const char[] str) { static if(is(T : string)) { import std.algorithm : copy; auto result = new char[str.length * 2]; str.toHexRange!char.copy(result); return cast(string)result; } else { import std.array; return str.toHexRange!T.array; } } unittest { enum Expected = "61626320C3A4C3B6C3BC50C39FE282AC207B447D"; enum str = "abc äöüP߀ {D}"; assert(str.toHex!string == Expected); import std.conv : hexString; static assert(hexString!Expected == str); enum NATO { Alpha = '0', Bravo, Charlie, Delta, Echo, Foxtrot, Golf, Hotel, India, Juliett, Kilo = 'A', Lima, Mike, November, Oscar, Papa } auto test = str.toHex!NATO; assert(is(typeof(test) : NATO[])); } ``` SDB 79
Mar 17