Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In D, how do I specify a variadic template constraint on all the whole tuple?

I'm writing 2 overloads of a function, both of them with variadic template compile-time parameters. One should take symbols as the templates, the other strings. I want to constrain the template instantiation to these two cases. The best I came up with was this:

bool func(SYMBOLS...)() if(!is(typeof(SYMBOLS[0]) == string)) {
}

and

bool func(STRINGS...)() if(is(typeof(STRINGS[0]) == string)) {
}

Obviously this only checks the first template parameter, and while it works given the code I've written so far, I wish I could say "only for all strings" and "only for not all strings". Is there a way?

like image 888
Átila Neves Avatar asked Dec 15 '22 08:12

Átila Neves


2 Answers

It took me a while to figure it out, but here is a potential solution to your problem:

module main;

import std.stdio;

int main(string[] argv)
{
    bool test1PASS = func(1,2,3,4,5.5, true);
    //bool test2CTE = func(1,2,3,4,5, true, "CRAP");
    bool test3PASS = func("CRAP", "3", "true");
    //bool test4CTE = func("CRAP", "3", "true", 42, true, 6.5);

    return 0;
}

bool func(NOSTRINGS...)(NOSTRINGS x) 
    if ({foreach(t; NOSTRINGS) if (is(t == string)) return false; return true; }()) {

    // code here ...
    return true;
}

bool func(ONLYSTRINGS...)(ONLYSTRINGS x) 
    if ({foreach(t; ONLYSTRINGS) if (!is(t == string)) return false; return true; }()) {

    // code here ...
    return true;
}
like image 59
komma8.komma1 Avatar answered Jun 02 '23 14:06

komma8.komma1


This works (from http://forum.dlang.org/thread/[email protected] with help from Andrej Mitrovic):

import std.traits;
import std.typetuple;

void runTests(SYMBOLS...)() if(!anySatisfy!(isSomeString, typeof(SYMBOLS))) {
}

void runTests(STRINGS...)() if(allSatisfy!(isSomeString, typeof(STRINGS))) {
}
like image 40
Átila Neves Avatar answered Jun 02 '23 14:06

Átila Neves