D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 5127 - Template instantiation arguments with CTFE on expressions
Summary: Template instantiation arguments with CTFE on expressions
Status: NEW
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: All All
: P4 enhancement
Assignee: No Owner
URL:
Keywords: rejects-valid
Depends on:
Blocks:
 
Reported: 2010-10-28 14:42 UTC by bearophile_hugs
Modified: 2024-12-13 17:54 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description bearophile_hugs 2010-10-28 14:42:11 UTC
This is a correct D2 program. Given an array, doubleit() returns an array with two copies of each item, in this example doubleit() outputs [1, 1, 2, 2, 3, 3, 4, 4], the return type is a twice long array of ints:


T[n+n] doubleit(T, int n)(T[n] data) {
    typeof(return) result;
    foreach (i, x; data) {
        result[i * 2] = x;
        result[i * 2 + 1] = x;
    }
    return result;
}
void main() {
    int[4] v = [1, 2, 3, 4];
    int[8] r = doubleit(v);
}




This is a similar program, but it currently doesn't compile:


void doubleit(T, int n)(T[n] data, out T[n+n] result) {
    foreach (i, x; data) {
        result[i * 2] = x;
        result[i * 2 + 1] = x;
    }
}
void main() {
    int[4] v = [1, 2, 3, 4];
    int[8] r;
    doubleit(v, r);
}


DMD 2.050beta shows the errors:

test.d(1): Error: Integer constant expression expected instead of n + n
test.d(10): Error: template test2.doubleit(T,int n) does not match any function template declaration
test.d(10): Error: template test2.doubleit(T,int n) cannot deduce template function from argument types !()(int[4u],int[8u])


The type inferencing of the template instantiation is able to perform and test n+n for return value length, but it's not currently able to do it for that out argument.

This missing capability is generally useful for data structures that are defined on one or more compile-time integer values (as fixed-sized arrays here) (For more info search for "number parameterized types" with Google).
Comment 1 bearophile_hugs 2010-10-28 16:34:23 UTC
Currently the best workaround for that limitation is to use a template constraint:


void doubleit(T, int n, int m)(T[n] data, out T[m] result) if (m == n+n) {
    foreach (i, x; data) {
        result[i * 2] = x;
        result[i * 2 + 1] = x;
    }
}
void main() {
    int[4] v = [1, 2, 3, 4];
    int[8] r;
    doubleit(v, r);
}
Comment 2 dlangBugzillaToGithub 2024-12-13 17:54:01 UTC
THIS ISSUE HAS BEEN MOVED TO GITHUB

https://github.com/dlang/dmd/issues/17519

DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB