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.