Defining a static array with values in a range

Meta via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Thu Jan 22 11:33:28 PST 2015


On Thursday, 22 January 2015 at 19:13:46 UTC, Meta wrote:
> On Thursday, 22 January 2015 at 19:12:32 UTC, zeljkog wrote:
>> On 22.01.15 20:05, Meta wrote:
>>> On Thursday, 22 January 2015 at 19:00:47 UTC, zeljkog wrote:
>>>> On 22.01.15 19:26, Meta wrote:
>>>>> On Thursday, 22 January 2015 at 18:23:00 UTC, Meta wrote:
>>>>> Whoops, I forgot to make it a template to force CTFE.
>>>>>
>>>>
>>>> You can force CTFE assigning to manifest constant.
>>>>
>>>> enum t = charRange!...
>>>
>>> By wrapping it in a template the array will always be 
>>> generated at
>>> compile time, even if you assign it to a runtime variable.
>>
>> Yes, but then you can not use runtime spec.
>
> OP wanted it to be done at compile time.

A small improvement to ensure the input consists of all ASCII 
characters, and support for backward intervals.

import std.stdio;

template charRange(string spec)
{
     static processSpec(string spec)
     {
         import std.algorithm;
         import std.ascii;
         import std.conv;
         import std.range;
         import std.string;

         return spec.split(',').map!((s)
         {
             s = s.strip;
             assert(s.all!(c => cast(ulong)c < 256),
                    "Expected all characters in 'spec' to be 
ASCII");

             auto start = cast(ubyte)s[1..$].front;
             auto end = cast(ubyte)s[0..$-1].back;

             return start <= end
                 ? iota(start, end + 1)
                     .map!(c => cast(char)c).array
                 : iota(end, start + 1)
                     .retro
                     .map!(c => cast(char)c).array;
         }).join;
     }

     enum charRange = processSpec(spec);
}

unittest
{
     assert(charRange!q{ 'a'..'z', 'A'..'Z', '0'..'9' } == 
charRange!q{ '9'..'0', 'Z'..'A', 'z'..'a' }.reverse);
}

void main(string[] argv)
{
     auto t1 = charRange!q{ 'a'..'z', 'A'..'Z', '0'..'9' };
     writeln(t1);

     auto t2 = charRange!q{ '9'..'0', 'Z'..'A', 'z'..'a' };
     writeln(t2);
}


More information about the Digitalmars-d-learn mailing list