digitalmars.D - Enum arguments?
- bearophile (11/11) Mar 30 2010 This is a function that convolves a 2D rectangular matrix with another g...
- Max Samukha (7/8) Mar 31 2010 Actually, they are allowed via an additional alias:
- bearophile (31/32) Mar 31 2010 This doesn't compile:
- bearophile (9/11) Mar 31 2010 Or better a template constraint:
- Fawzi Mohamed (4/39) Mar 31 2010 well you can always use Varargs...
- bearophile (25/26) Apr 04 2010 A possible variant of "enum" arguments is "auto enum" arguments. If the ...
This is a function that convolves a 2D rectangular matrix with another given rectangular matrix, and puts the result into an output matrix. Among other things, the precondition makes sure that outmat is already the same size of mat: void convolve(float[][] mat, float[][] mask, float[][] outmat); In the program mask is a compile-time constant (an enum), so to use a static foreach with Range I'd like to be able to mark an argument as enum: void convolve(const float[][] mat, enum float[][] mask, float[][] outmat); (After the call to convolve outmat will keep its outer length/ptr, but in the postcondition I'd like to assert that outmat has not changed all its length and ptr fields.) Now in D2 I can use: void convolve(alias mask)(const float[][] mat, float[][] outmat); followed by a static assert that makes sure mask is a static array of static arrays. D templates allow as compile-time arguments both floating point values and strings of 8,16,32 bit chars, but I don't know why arrays are not allowed. Bye, bearophile
Mar 30 2010
On 31.03.2010 3:04, bearophile wrote:as compile-time arguments both floating point values and strings of 8,16,32 bit chars, but I don't know why arrays are not allowedActually, they are allowed via an additional alias: void main() { float[][] outmat = [[0.0]]; enum float[][] mask = [[0.0]]; convolve!mask([[1.0, 1.0]], outmat); }
Mar 31 2010
Max Samukha:Actually, they are allowed via an additional alias:<This doesn't compile: void convolve(float[N][M] mask, N, M)(float[][] a, float[][] b) { //... } void main() { float[][] outmat = [[0.0]]; enum float[1][2] mask = [[1.0],[1.0]]; convolve!mask([[1.0, 1.0]], outmat); } You have to use an alias plus static asserts: void convolve(alias mask)(float[][] a, float[][] b) { static assert(__traits(isStaticArray, typeof(mask))); static assert(__traits(isStaticArray, typeof(mask[0]))); //... } void main() { float[][] outmat = [[0.0]]; enum float[1][2] mask = [[1.0],[1.0]]; convolve!mask([[1.0, 1.0]], outmat); } While with an array of dchar (4 bytes each) compiles: void foo(immutable(dchar)[] s)() {} void main() { immutable(dchar)[] s1 = "Hello"d; foo!(s1)(); } So I'd like arrays too to be allowd as template parameters. (The other thing I've asked in that post (the enum argument type for functions) I've seen is similar to the "static" arguments in the "The future of D", that I think was tried and abandoned because too much hard to implement. So it's probably an useless request, sorry.) Bye, bearophile
Mar 31 2010
void convolve(float[N][M] mask, N, M)(float[][] a, float[][] b) {That's quite wrong anyway. This looks a bit better: void convolve(float[N][M] mask)(float[][] a, float[][] b) {You have to use an alias plus static asserts:Or better a template constraint: void convolve(alias mask)(float[][] a, float[][] b) if (__traits(isStaticArray, typeof(mask)) && __traits(isStaticArray, typeof(mask[0]))) { //... } Bye, bearophile
Mar 31 2010
well you can always use Varargs... void convolve(int n,mask...)(...) Fawzi On 31-mar-10, at 13:28, bearophile wrote:Max Samukha:Actually, they are allowed via an additional alias:<This doesn't compile: void convolve(float[N][M] mask, N, M)(float[][] a, float[][] b) { //... } void main() { float[][] outmat = [[0.0]]; enum float[1][2] mask = [[1.0],[1.0]]; convolve!mask([[1.0, 1.0]], outmat); } You have to use an alias plus static asserts: void convolve(alias mask)(float[][] a, float[][] b) { static assert(__traits(isStaticArray, typeof(mask))); static assert(__traits(isStaticArray, typeof(mask[0]))); //... } void main() { float[][] outmat = [[0.0]]; enum float[1][2] mask = [[1.0],[1.0]]; convolve!mask([[1.0, 1.0]], outmat); } While with an array of dchar (4 bytes each) compiles: void foo(immutable(dchar)[] s)() {} void main() { immutable(dchar)[] s1 = "Hello"d; foo!(s1)(); } So I'd like arrays too to be allowd as template parameters. (The other thing I've asked in that post (the enum argument type for functions) I've seen is similar to the "static" arguments in the "The future of D", that I think was tried and abandoned because too much hard to implement. So it's probably an useless request, sorry.) Bye, bearophile
Mar 31 2010
Sorry for pulling out this old thread again, I have one thing to add.void convolve(const float[][] mat, enum float[][] mask, float[][] outmat);A possible variant of "enum" arguments is "auto enum" arguments. If the given value is a compile-time constant then the function becomes a template as before. Otherwise if the given value is a run-time value, then the argument is a normal function argument. So this code: void foo(int a, auto enum int b) {} void main() { int x = 10; enum int y = 10; foo(x, y); int z = 10; foo(x, z); } is syntax sugar for: void foo_t(int b)(int a) {} void foo(int a, int b) {} void main() { int x = 10; enum int y = 10; foo_t!(y)(x); int z = 10; foo(x, z); } This allows for a cheap form of partial compilation :-) It's "cheap" for the compiler because it's the programmer that tells the compiler on what it can partially compile, so the compiler doesn't need to be smart to guess as in a true partial compilation implementation. In many situations I think this can be enough. Bye, bearophile
Apr 04 2010