Metaprog can be abstruse

Dom Disc dominikus at scherkl.de
Wed Dec 28 13:57:13 UTC 2022


On Monday, 4 July 2022 at 23:19:27 UTC, kdevel wrote:
>> ```d
>> immutable decimalRanks = iota(10).map!(p => 10.pow(p)).array;
>> ```
>
> This example requires
>
> ```d
> import std.range; // for iota
> import std.algorithm; // for map
> import std.math; // for pow of int
> ```
>
> Then your example is prone to errors:
>
> ```d
> immutable decimalRanks = iota(13).map!(p => 10.pow(p)).array; 
> // silent wrap around
> ```

Sorry for the late reply, but I just stumbled over this old 
thread.
I now have a function

```d
ubyte maxpow(const ulong base) { }
```

That returns the maximum power of the given base that fits in a 
ucent (for smaller target types, shift down the result by one for 
each halfing of the size).

With this you can create the function

     ```d
     ulong[] powersOf(byte n)
     {
        import std.range : iota;
        import std.algorithm : map;
        return iota(maxpow(n)>>1).map!(p => ulong(n)^^p).array;
     }
     ```

If this function is used to create lookup-tables, it will be 
called only during compile-time, so the imports are not in the 
resulting executable (therefore it doesn't matter that I replaced 
pow by the buildin ^^).

```d
static immutable ulong[maxpow(17)>>1] ranksOf17 = powersOf(17);
```

I think this is much more readable as a list of obscure number 
literals, it is safe to use, doesn't increase linker time and 
doesn't blow up the binary.
Hurray to the meta-programming! Hurray! Hurray!


More information about the Digitalmars-d mailing list