Re: Iterating over an enum associative array
== Quote from Nebster (evil.nebs...@gmail.com)'s article Hey, I'm having some problems iterating over an enumerated associative array. It comes up with this error at compile time: Internal error: e2ir.c 4835 I cut the code down to this: import std.stdio; enum int[string] assoc = [;: 0, =: 1, +: 2, -: 2, *: 3, /: 3]; void main() { foreach(op; assoc.byKey()) writefln(op: %s, op); } What does this mean/how can I get this to work? Thanks, Nebster That's a rather cryptic error message. Hopefully someone smarter than I can trace down why this doesn't have better error reporting. I suspect the problem has something to do with CTFE. Because you're using an enum, D assumes you want its value to be computed at compile time. However, currently, associative arrays can not be evaluated at compile time. Using a static this to initialize the value at runtime, as already suggested, should solve your issue.
Static Associative Array
Can you define an associative array in a way that can be evaluated at compile time like you can with non-associative arrays?
Re: Static Associative Array
== Quote from Jonathan M Davis (jmdavisp...@gmx.com)'s article On Sunday 06 March 2011 14:05:04 Peter Lundgren wrote: Can you define an associative array in a way that can be evaluated at compile time like you can with non-associative arrays? I'm pretty sure not. I think that it's currently suffering the same fate as stuff like classes and is not yet able to be CTFEed. Some day... - Jonathan M Davis If not, then what is the D way to initialize a static field of a struct or class a la Java's static initializer blocks? I don't mind constructing the associative array at run-time if I have to, but I can't afford to do it more than the once needed.
Benchmarking with -profile
How do you guys benchmark your D code? I tried using the -profile option, but was surprised to see wildly varying results (greater than an order of magnitude difference in Func Time) from one run to the next.
Re: Template type parameters with their own type parameters
== Quote from spir (denis.s...@gmail.com)'s article On 03/05/2011 04:02 AM, Peter Lundgren wrote: I have a function that I think should look something like this: MyStruct!T myFunc(T)(MyStruct!T x, ...) { ... return MyStruct!T(...); } and the closest I can get to is: T myFunc(T)(T x, ...) { ... return T(...); } which works, but doesn't make clear the intended use and gets in the way of overloading. How can I express the intent of the first version. Maybe I do not exactly understand your problem; anyway, the following runs fine by me: struct S (T) { T v; } S!T inc (T) (S!T s) { return S!T(s.v + 1); } unittest { auto s1 = S!int(1); auto s2 = inc(s1); assert ( s2.v == 2 ); } Could you provide (1) context (2) example (3) errors? Denis Thanks for the help. I'd convinced myself that it didn't work and missed the actual problem. I was mixing template type and template value parameters. What I really wanted was this: MyStruct!v myFunc(string v)(MyStruct!v x, ...) { ... return MyStruct!v(...); }
Template type parameters with their own type parameters
I have a function that I think should look something like this: MyStruct!T myFunc(T)(MyStruct!T x, ...) { ... return MyStruct!T(...); } and the closest I can get to is: T myFunc(T)(T x, ...) { ... return T(...); } which works, but doesn't make clear the intended use and gets in the way of overloading. How can I express the intent of the first version.
Re: Parameterized Structs
== Quote from Ali Çehreli (acehr...@yahoo.com)'s article On 03/02/2011 11:11 PM, Peter Lundgren wrote: == Quote from Ali Çehreli (acehr...@yahoo.com)'s article On 03/02/2011 08:56 PM, Peter Lundgren wrote: Where can I go to learn about parameterized structs? I can't seem to find any literature on the subject. In particular, what are you allowed to use as a parameter? I would like to define a struct like so: struct MyStruct(T, T[] a) { ... } but I receive the following error: Error: arithmetic/string type expected for value-parameter, not T[] Are arrays not allowed? Are you trying to parametrize by the type of the container or just trying to use an array of a specified type? (As opposed to say, a linked list of the specified type?) If the former, it's simple. And the simplest thing is to just use an array in the implementation: struct S(T) { T[] a; void foo(T element) { /* Just use like an array */ a ~= element; a[0] = element; } } void main() { auto s = S!double(); s.foo(1.5); } If you want to use a different container of the specified T, then a second template parameter can be used. This one uses an array as the default one: class SomeContainer {} struct S(T, Cont = T[]) { Cont a; void foo(T element) { /* This time the use must match the allowed container types */ } } void main() { auto s = S!(double, SomeContainer)(); s.foo(1.5); } I would recommend pulling information out ;) of this page: http://digitalmars.com/d/2.0/template.html Template Alias Parameters is very different after C++ and can be very powerful: http://digitalmars.com/d/2.0/template.html#TemplateAliasParameter Ali I'm using this for an alternative implementation of a string, if you will. Where T is the type of a single character and a would be the alphabet (an array of allowed characters). The rest of the implementation of the struct would, of course, depend upon the provided alphabet. I guess value parameters can't be arbitrary types. I can probably get by with using a string for my alphabet just fine, it just seemed an arbitrary limitation. Why accept only arrays of characters when the code will be the same for any type? I think the SomeContainer example above should work then: it is not arrays of characters. T[] was just the default implementation. If SomeContainer is templatized, then I think this is what you want: /* A templatized container */ class SomeContainer(T) { /* having container functions */ void add(T element) {} T access(size_t index) { return T.init; } } /* This is your alternative implementation of a string. Can use any * container type, the default is array of Ts */ struct S(T, Cont = T[]) { Cont a; void foo(T element) { /* here the use must match the allowed container types */ } } void main() { /* We are instantiating it with * * double as the element type * SomeContainer!double as the container type */ auto s = S!(double, SomeContainer!double)(); s.foo(1.5); } But we can make it better, because 'double' and 'SomeContainer!double' repeat double. Here the alias template parameters are handy: struct S(T, alias ContType) // -- alias { ContType!T a;// -- ContType!T instead of just Cont void foo(T element) { /* here the use must match the allowed container types */ } } The second parameter is an alias template parameter. (I had to drop the default value; I think we can use Array!T there, but I haven't bothered to test.) Now the use is easier and less error prone, because 'double' need not be repeated: auto s = S!(double, SomeContainer)(); Ali That's closer, except I want to pass a value parameter (specifically, some compile time instance of SomeContainer) instead of a type parameter, but that doesn't look like it's supported.
Parameterized Structs
Where can I go to learn about parameterized structs? I can't seem to find any literature on the subject. In particular, what are you allowed to use as a parameter? I would like to define a struct like so: struct MyStruct(T, T[] a) { ... } but I receive the following error: Error: arithmetic/string type expected for value-parameter, not T[] Are arrays not allowed?
Re: Parameterized Structs
== Quote from Ali Çehreli (acehr...@yahoo.com)'s article On 03/02/2011 08:56 PM, Peter Lundgren wrote: Where can I go to learn about parameterized structs? I can't seem to find any literature on the subject. In particular, what are you allowed to use as a parameter? I would like to define a struct like so: struct MyStruct(T, T[] a) { ... } but I receive the following error: Error: arithmetic/string type expected for value-parameter, not T[] Are arrays not allowed? Are you trying to parametrize by the type of the container or just trying to use an array of a specified type? (As opposed to say, a linked list of the specified type?) If the former, it's simple. And the simplest thing is to just use an array in the implementation: struct S(T) { T[] a; void foo(T element) { /* Just use like an array */ a ~= element; a[0] = element; } } void main() { auto s = S!double(); s.foo(1.5); } If you want to use a different container of the specified T, then a second template parameter can be used. This one uses an array as the default one: class SomeContainer {} struct S(T, Cont = T[]) { Cont a; void foo(T element) { /* This time the use must match the allowed container types */ } } void main() { auto s = S!(double, SomeContainer)(); s.foo(1.5); } I would recommend pulling information out ;) of this page: http://digitalmars.com/d/2.0/template.html Template Alias Parameters is very different after C++ and can be very powerful: http://digitalmars.com/d/2.0/template.html#TemplateAliasParameter Ali I'm using this for an alternative implementation of a string, if you will. Where T is the type of a single character and a would be the alphabet (an array of allowed characters). The rest of the implementation of the struct would, of course, depend upon the provided alphabet. I guess value parameters can't be arbitrary types. I can probably get by with using a string for my alphabet just fine, it just seemed an arbitrary limitation. Why accept only arrays of characters when the code will be the same for any type?
Re: Mixins: to!string cannot be interpreted at compile time
That worked, thanks. This is interesting because the example used in The D Programming Language on page 83 gets away with it just fine. I had no problem running this: result ~= to!string(bitsSet(b)) ~ , ;
Mixins: to!string cannot be interpreted at compile time
I'm trying to use mixins to generate an array of numbers that are coprime to a statically known value. I've tried the following, but I receive the error: Error: to(i) ~ , cannot be interpreted at compile time string makePossibleAValues(string name, byte m) { string result = immutable byte[] ~name~ = [; foreach (i; 0 .. m) { if (coprime(i, m)) { result ~= to!string(i) ~ , ; } } return result ~ ];; } bool coprime(ulong a, ulong b) { return gcd(a, b) == 1; } ulong gcd(ulong a, ulong b) { while (b) { auto t = b; b = a % b; a = t; } return a; } mixin(makePossibleAValues(aValues, 26)); makePossibleAValues(aValues, 26) produces the correct result, immutable byte[] aValues = [1, 3, 5, 7, 9, 11, 15, 17, 19, 21, 23, 25, ];, at runtime and I know to!string can be used in mixins. Any idea as to why this particular code is having trouble with to!string?
Defining type coercion
I'd like to define a type Ordinal which behaves like an int (using a struct or alias) that represents the 26 letters, A-Z, with the numbers 1-26. Then, I would like to be able to coerce between chars and Ordinals appropriately. chars and ints already have the ability to coerce between each other using the appropriate ASCII values. So, really, I'd just like to define a type that overrides this behavior. As far as I can tell, the place to define such rules is with opCast!, but I'm at a loss for how to add additional rules to built in types.