Implicit enum conversions are a stupid PITA

Adam D. Ruppe destructionator at gmail.com
Thu Mar 25 14:32:07 PDT 2010


On Thu, Mar 25, 2010 at 05:12:07PM -0400, bearophile wrote:
> It needs many more unittests, to tests all the bounds, corner cases, etc. They also have to test that the code actually asserts when the inputs are wrong in various ways. This is how I test my D code.

Yeah, you're right on a few counts. The template there actually fails on
any string with length > 2. I rewrote it just now to do CTFE too to get
around it. I also let underscores into the string in my new version, and
switched the uints to ulongs so we can get bigger literals before needing
strings.

It seems to work well. Here's my new code:

===
ulong octal(string num)() {
    static assert(num.length > 0);

    ulong pow = 1;
    ulong value = 0;

    for(int pos = num.length - 1; pos >= 0; pos--) {
        char s = num[pos];
	if(s == '_')
		continue;
        assert(s >= '0' && s < '8',
            "Incorrect character in octal constant: `" ~ s ~ "'");
	
	value += pow * (s - '0');
	pow *= 8;
  }

  return value;
}

import std.metastrings;

template octal(ulong s) {
	enum uint octal = octal!(toStringNow!(s));
}

unittest
{
    static assert(octal!"45" == 37);
    static assert(octal!"0" == 0);
    static assert(octal!"7" == 7);
    static assert(octal!"10" == 8);
    static assert(octal!"666" == 438);

    static assert(octal!45 == 37);
    static assert(octal!0 == 0);
    static assert(octal!7 == 7);
    static assert(octal!10 == 8);
    static assert(octal!666 == 438);

    static assert(octal!"66_6" == 438);

    static assert(octal!2520046213 == 356535435);
    static assert(octal!"2520046213" == 356535435);

}

import std.stdio;
void main() {
	int a = octal!254; // just checking implicit conversion of ulong to int; it would suck if this failed
	writefln("%d", a);
}
====
-- 
Adam D. Ruppe
http://arsdnet.net



More information about the Digitalmars-d mailing list