more OO way to do hex string to bytes conversion

Ali Çehreli acehreli at yahoo.com
Tue Feb 6 21:56:05 UTC 2018


On 02/06/2018 11:55 AM, Ralph Doncaster wrote:

 > I'll have to do some more reading about
 > maps.  My initial though is they don't seem as readable as loops.

Surprisingly, they may be very easy to read in some situations.

 > The chunks() is useful, so for now what I'm going with is:
 >      ubyte[] arr;
 >      foreach (b; "deadbeef".chunks(2))
 >      {
 >          arr ~= b.to!ubyte(16);
 >      }

That is great but it has two issues that may be important in some programs:

1) It makes multiple allocations as the array grows

2) You need another loop to to do the actual work later on

If you needed to go through the elements just once, the memory 
allocations would be wasted. Instead, you can solve both issues with a 
chained expression like the ones that has been shown by others.

The cool thing is, you can always hide the ugly bits in a function. 
Starting with ag0aep6g's code, I went overboard to pick a better 
destination type (other than ubyte) to support different chunk sizes:

void main()
{
     import std.stdio;
     foreach (b; "deadbeef".hexValues)
     {
         writefln("%2X", b);
     }

     // Works for different sized chunks as well:
     writeln("12345678".hexValues!4);
}

auto hexValues(size_t digits = 2, ToType = 
DefaultTypeForSize!digits)(string s) {
     import std.algorithm: map;
     import std.conv: to;
     import std.range: chunks;

     return s.chunks(digits).map!(chars => chars.to!ToType(16));
}

template DefaultTypeForSize(size_t s) {
     static if (s == 1) {
         alias DefaultTypeForSize = ubyte;
     } else static if (s == 2) {
         alias DefaultTypeForSize = ushort;
     } else static if (s == 4) {
         alias DefaultTypeForSize = uint;
     } else static if (s == 8) {
         alias DefaultTypeForSize = ulong;
     } else {
         import std.string : format;

         static assert(false, format("There is no default %s-byte type", 
s));
     }
}

Ali



More information about the Digitalmars-d-learn mailing list