Thread overview
test if the alias of a template is a literal
Oct 27, 2016
Gianni Pisetta
Oct 27, 2016
TheFlyingFiddle
Oct 27, 2016
Gianni Pisetta
Oct 27, 2016
TheFlyingFiddle
Oct 28, 2016
Basile B.
Oct 28, 2016
Basile B.
Oct 28, 2016
Gianni Pisetta
October 27, 2016
Hi all,
I have an AliasSeq composed of literal strings, variables and delegates. I want to build a template Optimize that will return an AliasSeq that have all adjacent literals concatenated into one. So i writed something like this:

template isStringLiteral(alias V) {
    enum bool isStringLiteral = ( is( typeof( V ) == string ) );
}

template Optimize(Os...) {
    static if ( Os.length < 2 )
        alias Optimize = Os;
    else {
        alias Optimized = Optimize!(Os[1..$]);

        static if ( isStringLiteral!(Os[0]) && isStringLiteral!(Optimized[0]) ) {
            enum string First = Os[0] ~ Optimized[0];
            alias Rest = Optimized[1..$];
        }
        else {
            alias First = AliasSeq!(Os[0]);
            alias Rest = Optimized;
        }
        alias Optimize = AliasSeq!(First, Rest);
    }
}

but at the moment isStringLiteral will return true even with variables of type string. So i searched for a metod to check if an alias is a literal value, but found nothing. Anyone have any clue on how can be done?

Thanks,
Gianni Pisetta
October 27, 2016
On Thursday, 27 October 2016 at 14:04:23 UTC, Gianni Pisetta wrote:
> Hi all,
> but at the moment isStringLiteral will return true even with variables of type string. So i searched for a metod to check if an alias is a literal value, but found nothing. Anyone have any clue on how can be done?
>
> Thanks,
> Gianni Pisetta

Not really understanding your problem. Could you include an example use that is problematic?
October 27, 2016
On Thursday, 27 October 2016 at 14:34:38 UTC, TheFlyingFiddle wrote:
> On Thursday, 27 October 2016 at 14:04:23 UTC, Gianni Pisetta wrote:
>> Hi all,
>> but at the moment isStringLiteral will return true even with variables of type string. So i searched for a metod to check if an alias is a literal value, but found nothing. Anyone have any clue on how can be done?
>>
>> Thanks,
>> Gianni Pisetta
>
> Not really understanding your problem. Could you include an example use that is problematic?

Yea, sorry I missed that.
A really stupid example would be

string var;

alias Sequence = Optimize!( "The", " ", "value", " ", "of", " ", "var is ", var );

static assert( is( Sequence == AliasSeq!( "The value of var is ", var ) ) );

writeln( Sequence );

given that you include the code snippet in the first post.

Thanks, Gianni
October 27, 2016
On Thursday, 27 October 2016 at 14:45:22 UTC, Gianni Pisetta wrote:
> On Thursday, 27 October 2016 at 14:34:38 UTC, TheFlyingFiddle wrote:
>> On Thursday, 27 October 2016 at 14:04:23 UTC, Gianni Pisetta wrote:
>>> Hi all,
>>> but at the moment isStringLiteral will return true even with variables of type string. So i searched for a metod to check if an alias is a literal value, but found nothing. Anyone have any clue on how can be done?
>>>
>>> Thanks,
>>> Gianni Pisetta
>>
>> Not really understanding your problem. Could you include an example use that is problematic?
>
> Yea, sorry I missed that.
> A really stupid example would be
>
> string var;
>
> alias Sequence = Optimize!( "The", " ", "value", " ", "of", " ", "var is ", var );
>
> static assert( is( Sequence == AliasSeq!( "The value of var is ", var ) ) );
>
> writeln( Sequence );
>
> given that you include the code snippet in the first post.
>
> Thanks, Gianni

I think this fixes the problem:

template isStringLiteral(T...) if (T.length == 1) {
    static if(is( typeof(T[0]) == string ))
    {
        enum bool isStringLiteral = !__traits(compiles, &T[0]);
    }
    else
    {
        enum bool isStringLiteral = false;
    }
}

Literals do not have an address but variables do.

However note that:
string var;
static assert(!is(AliasSeq!(var) == AliasSeq!(var)));

It still works at run-time though:
string var = " hello ";
alias Seq = Optimize!("This", " is", " a", " variable! ", var);
//pragma(msg, Seq) //Fails to compile at var
//static assert(is(Seq == AliasSeq!("This is a variable!", var))); //Also fails
writeln(Seq); //Still works

October 28, 2016
On Thursday, 27 October 2016 at 14:04:23 UTC, Gianni Pisetta wrote:
> Hi all,
> I have an AliasSeq composed of literal strings, variables and delegates. I want to build a template Optimize that will return an AliasSeq that have all adjacent literals concatenated into one. So i writed something like this:
>
> template isStringLiteral(alias V) {
>     enum bool isStringLiteral = ( is( typeof( V ) == string ) );
> }
>
> template Optimize(Os...) {
>     static if ( Os.length < 2 )
>         alias Optimize = Os;
>     else {
>         alias Optimized = Optimize!(Os[1..$]);
>
>         static if ( isStringLiteral!(Os[0]) && isStringLiteral!(Optimized[0]) ) {
>             enum string First = Os[0] ~ Optimized[0];
>             alias Rest = Optimized[1..$];
>         }
>         else {
>             alias First = AliasSeq!(Os[0]);
>             alias Rest = Optimized;
>         }
>         alias Optimize = AliasSeq!(First, Rest);
>     }
> }
>
> but at the moment isStringLiteral will return true even with variables of type string. So i searched for a metod to check if an alias is a literal value, but found nothing. Anyone have any clue on how can be done?
>
> Thanks,
> Gianni Pisetta

Hello, I think the correct isStringLiteral would be:

import
    std.meta;

template isStringLiteral(alias V)
{
    enum isCompileTime = is(typeof((){enum a = V;}));
    enum isString = is(typeof(V) == string);
    enum isStringLiteral = isCompileTime && isString;
}

unittest
{
    string a;
    enum b = "0";
    enum c = 0;
    static assert(!isStringLiteral!a);
    static assert(isStringLiteral!b);
    static assert(!isStringLiteral!c);
}

It's decomposed to show the logic:

1. If the delegate that assigns the parameter to a compile-time enum is valid we know that the parameter value is defined at compile-time.
2. check that the parameter is a string.
October 28, 2016
On Friday, 28 October 2016 at 03:33:33 UTC, Basile B. wrote:
> On Thursday, 27 October 2016 at 14:04:23 UTC, Gianni Pisetta wrote:
>> So i searched for a metod to check if an alias is a literal value, but found nothing. Anyone have any clue on how can be done?
>>
>> Thanks,
>> Gianni Pisetta
>
> Hello, I think the correct isStringLiteral would be:
>
> import
>     std.meta;
>
> template isStringLiteral(alias V)
> {
>     enum isCompileTime = is(typeof((){enum a = V;}));
>     enum isString = is(typeof(V) == string);
>     enum isStringLiteral = isCompileTime && isString;
> }
>
> [...]

In addition a fallback for the types must be added:

template isStringLiteral(V){enum isStringLiteral = false;}
October 28, 2016
On Friday, 28 October 2016 at 03:33:33 UTC, Basile B. wrote:
> Hello, I think the correct isStringLiteral would be:
>
> import
>     std.meta;
>
> template isStringLiteral(alias V)
> {
>     enum isCompileTime = is(typeof((){enum a = V;}));
>     enum isString = is(typeof(V) == string);
>     enum isStringLiteral = isCompileTime && isString;
> }
>

It works, Thanks. Also, i don't think in my case there is the need for a variant for types( aka isStringLiteral(V) without alias) because it's an error to pass a type to Optimize in first place. But for a general purpouse library, maybe a template isLiteral(alias V) that only checks if it is a literal without the type checking, would have more sense to have also isLiteral(V) for types that returns always false.

Gianni Pisetta