www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Enum arguments?

reply bearophile <bearophileHUGS lycos.com> writes:
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
next sibling parent reply Max Samukha <spambox d-coding.com> writes:
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 allowed
Actually, 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
parent reply bearophile <bearophileHUGS lycos.com> writes:
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
next sibling parent bearophile <bearophileHUGS lycos.com> writes:
 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
prev sibling parent Fawzi Mohamed <fawzi gmx.ch> writes:
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
prev sibling parent bearophile <bearophileHUGS lycos.com> writes:
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