Thread overview
Templates with strings
Jul 03, 2010
Mike Linford
Jul 04, 2010
BCS
Jul 04, 2010
Mike Linford
Jul 04, 2010
Simen kjaeraas
Jul 04, 2010
Ali Çehreli
Jul 04, 2010
Philippe Sigaud
July 03, 2010
I'm trying to compile the following file. Can somebody explain to me how I can rewrite it so that I don't get "Error: non-constant expression"? All I'm trying to do is create, using templates, a string of all characters between two given characters:

  1 module ua;
  2
  3 template dcharInterval(immutable(dchar) start, immutable(dchar) stop)
  4 {
  5    static assert(stop >= start);
  6    static if(start == stop)
  7       dstring dcharInterval = [start];
  8    else
  9       dstring dcharInterval = [start] ~ dcharInterval!(start + 1,
stop);
 10 }
 11
 12 dstring LATIN = "\u00AA"d ~ "\u00BA"d ~ dcharInterval!(0x00C0,
0x00D6);
 13

Thanks.

-- 
Mike Linford
July 04, 2010
Hello Mike,

> I'm trying to compile the following file. Can somebody explain to me
> how I can rewrite it so that I don't get "Error: non-constant
> expression"? All I'm trying to do is create, using templates, a string
> of all characters between two given characters:
> 

1) where did you get that error? (I'm lazy, sorry)
2) is there a reason you don't use CTFE?

dchar[] Between(dchar start, dchar stop)
{
 if(start > stop) { auto t = start; start = stop; stop = t; }

 dchar[] ret;
 for(dchar d = start; d<=stop; d++) ret ~= d;
 return ret;
}

import std.stdio;
void Go(dchar[] s)(){writef("%s\n", s); }
void main(){Go!(Between('a','g'))();}

> 1 module ua;
> 2
> 3 template dcharInterval(immutable(dchar) start, immutable(dchar)
> stop)
> 4 {
> 5    static assert(stop >= start);
> 6    static if(start == stop)
> 7       dstring dcharInterval = [start];
> 8    else
> 9       dstring dcharInterval = [start] ~ dcharInterval!(start + 1,
> stop);
> 10 }
> 11
> 12 dstring LATIN = "\u00AA"d ~ "\u00BA"d ~ dcharInterval!(0x00C0,
> 0x00D6);
> 13
> Thanks.
> 
-- 
... <IXOYE><



July 04, 2010
On Sun, 04 Jul 2010 00:43:50 +0000, BCS wrote:

> Hello Mike,
> 
>> I'm trying to compile the following file. Can somebody explain to me how I can rewrite it so that I don't get "Error: non-constant expression"? All I'm trying to do is create, using templates, a string of all characters between two given characters:
>> 
>> 
> 1) where did you get that error? (I'm lazy, sorry) 2) is there a reason
> you don't use CTFE?
> 
> dchar[] Between(dchar start, dchar stop) {
>   if(start > stop) { auto t = start; start = stop; stop = t; }
> 
>   dchar[] ret;
>   for(dchar d = start; d<=stop; d++) ret ~= d; return ret;
> }
> 
> import std.stdio;
> void Go(dchar[] s)(){writef("%s\n", s); } void
> main(){Go!(Between('a','g'))();}
> 
>> 1 module ua;
>> 2
>> 3 template dcharInterval(immutable(dchar) start, immutable(dchar) stop)
>> 4 {
>> 5    static assert(stop >= start);
>> 6    static if(start == stop)
>> 7       dstring dcharInterval = [start]; 8    else
>> 9       dstring dcharInterval = [start] ~ dcharInterval!(start + 1,
>> stop);
>> 10 }
>> 11
>> 12 dstring LATIN = "\u00AA"d ~ "\u00BA"d ~ dcharInterval!(0x00C0,
>> 0x00D6);
>> 13
>> Thanks.
>>

Hi BCS,

1. I was getting that error on lines 9 and 12. I got it a couple dozen times (I assume once for each template instance).

2. The reason I don't use CTFE is because I don't know how to be certain its been called at compile time. Apparently using a result in a template like you did will accomplish that, but is there a way I can be sure without making up bogus empty templates?

Thanks.

-- 
Mike Linford
July 04, 2010
Mike Linford <mike.linford.reg@gmail.com> wrote:

> 2. The reason I don't use CTFE is because I don't know how to be certain
> its been called at compile time. Apparently using a result in a template
> like you did will accomplish that, but is there a way I can be sure
> without making up bogus empty templates?

Anything that is static, that is, static member variables, globals with
initializers, and enums, will be CTFE'd. An enum is probably the best
match for you.

-- 
Simen
July 04, 2010
Mike Linford wrote:

> 2. The reason I don't use CTFE is because I don't know how to be certain
> its been called at compile time. Apparently using a result in a template
> like you did will accomplish that, but is there a way I can be sure
> without making up bogus empty templates?

There is relatively detailed information on what types of functions can be called at compile time:

  http://www.digitalmars.com/d/2.0/function.html#interpretation

<quote>
In order to be executed at compile time, the function must appear in a context where it must be so executed, for example:

    * initialization of a static variable
    * dimension of a static array
    * argument for a template value parameter
</quote>

Ali
July 04, 2010
On Sun, Jul 4, 2010 at 09:34, Ali Çehreli <acehreli@yahoo.com> wrote:

> Mike Linford wrote:
>
> > 2. The reason I don't use CTFE is because I don't know how to be certain its been called at compile time. Apparently using a result in a template like you did will accomplish that, but is there a way I can be sure without making up bogus empty templates?
>
> There is relatively detailed information on what types of functions can be called at compile time:
>
>  http://www.digitalmars.com/d/2.0/function.html#interpretation
>
> <quote>
> In order to be executed at compile time, the function must appear in a
> context where it must be so executed, for example:
>
>    * initialization of a static variable
>    * dimension of a static array
>    * argument for a template value parameter
> </quote>
>


And, traditionally, being defined as an enum (a C/C++ inheritance?)

enum thingy = funToBeTested();

If it compiles, then funToBeTested works at compile-time.

Is there not a __ctfe trait or somesuch?

Philippe