Re: Specialize mixin templates
On 08/11/2012 11:42 PM, Henning Pohl wrote: A struct takes a mixin template as argument: struct S(alias Mixin) { mixin Mixin; } How to specialize a mixin template like this one to pass to S? mixin template MixinTemplate(T) { } S(MixinTemplate!float); // Something like this This is a way to do it: struct S(alias Mixin){ mixin Mixin; } mixin template MixinTemplate(T){ } mixin template MixinTemplateFloat(){ mixin MixinTemplate!float; } S!MixinTemplateFloat s;
Re: vector Cross/Dot using core.simd?
On 8/11/2012 8:23 PM, F i L wrote: I'm trying to write a Cross and Dot function using core.simd.float4 and DMD Does anyone know anything about SIMD operations that may be able to help me translate these functions into a D equivalent? I would very much appreciate your help. Some reference: C++ simd intrinsic for dot product (requires SSE 4.1, very modern) _mm_dp_ps C++ simd instrinsic for horizontal add (requires SSE3, also reasonably modern) _mm_hadd_ps If you are on SSE2 (which is the base spec for x64) and also the minimum CPU target we use at work for commercial game development, you are stuck doing shuffles and adds for dot product, which effectively process these operations as scalar). Ideally one of the sides of the dot product is an array and you can vectorize the dot product itself (1 vector vs 4 others, or 4 v 4). This is common when setting up shapes like view frustum culling (point tested against 6-8 extruded planes in an array)
Re: vector Cross/Dot using core.simd?
On a side note, if I run the simple code: void16 a = 0, b = 0; void16 r = __simd(XMM.PSHUFB, a, b); writeln(r.array); I get the following error: Internal error: e2ir.c 3817
vector Cross/Dot using core.simd?
I'm trying to write a Cross and Dot function using core.simd.float4 and DMD The C++ code looks like: from: http://fastcpp.blogspot.com/2011/04/vector-cross-product-using-sse-code.html inline __m128 CrossProduct(__m128 a, __m128 b) { return _mm_sub_ps ( _mm_mul_ps ( _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 0, 2, 1)), _mm_shuffle_ps(b, b, _MM_SHUFFLE(3, 1, 0, 2)) ), _mm_mul_ps ( _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 1, 0, 2)), _mm_shuffle_ps(b, b, _MM_SHUFFLE(3, 0, 2, 1)) ) ); } I can see that core.simd.XMM supports a XMM.PSHUFB command I can use with __simd(), but I'm not sure how to go about translate the _MM_SHUFFLE() macro above. For Dot product, I have a C# Mono.Simd function: public static Vector4f Dot(Vector4f a, Vector4f b) { var result = a * b; result = HorizontalAdd(result, result); result = HorizontalAdd(result, result); return result.X; } And I have no idea what XMM command HorizontalAdd would translate to. But the Mono.Simd documentation says it performs: Vector4f HorizontalAdd(Vector4f a, Vector4f b) { return new Vector4f ( (a.X + a.Y), (a.Z + a.W), (b.X + b.Y), (b.Z + b.W) ); } Does anyone know anything about SIMD operations that may be able to help me translate these functions into a D equivalent? I would very much appreciate your help.
Re: Optional extra return value? Multiple return values with auto?
There is no compiler bug. You cannot pass immutable/rvalue by reference to mutable.
Re: Optional extra return value? Multiple return values with auto?
On 08/11/2012 03:48 PM, ReneSac wrote: > On Tuesday, 24 July 2012 at 05:30:49 UTC, Ali Çehreli wrote: >> - Use an out parameter, which can have a default lvalue: >> >> int g_default_param; >> >> void foo(ref int i = g_default_param) >> { >> if (&i == &g_param) { >> // The caller is not interested in 'i' >> >> } else { >> // The caller wants 'i' >> i = 42; >> } >> } >> >> void main() >> { >> foo(); >> >> int i; >> foo(i); >> assert(i == 42); >> } > > This is not working inside a class. I'm not sure what default value I > should put when I don't know the type entered: > > class a (T) { > T dummy = T.init; > bool foo(int a, out T optional = dummy) > { > return true; > } > } > > void main () { > auto c = new a!uint(); > c.foo(5); > } > > I get the following error: > > Error: need 'this' to access member dummy > I am not a fan of this solution either. To make the code to compile, define dummy as static: static T dummy = T.init; // <-- this works That way there will be just one copy for the entire type, instead of one copy per object. I also tried to define it as immutable but the following line fails to compile: static immutable T dummy = T.init; // <-- compilation error I thought that a solution would be to define 'static this()': class a (T){ static immutable T dummy; static this() { dummy = T.init; } bool foo(int a, out T optional = dummy) { // <-- compilation error on this line return true; } } Still fails to compile: Error: cast(uint)dummy is not an lvalue The error is on the line that I have pointed in the code. I think this is a compiler bug. T is not a reference type and 'cast(uint)dummy' not being an lvalue should not matter. I tried an enum too but a different error on the same line: static enum T dummy = T.init; Error: constant 0u is not an lvalue Ali
Re: Optional extra return value? Multiple return values with auto?
On Tuesday, 24 July 2012 at 05:30:49 UTC, Ali Çehreli wrote: The options that I can think of: - Return a struct (or a class) where one of the members is not filled-in - Similarly, return a tuple This is awkward, and doesn't look good for performance. - Use an out parameter, which can have a default lvalue: int g_default_param; void foo(ref int i = g_default_param) { if (&i == &g_param) { // The caller is not interested in 'i' } else { // The caller wants 'i' i = 42; } } void main() { foo(); int i; foo(i); assert(i == 42); } This is not working inside a class. I'm not sure what default value I should put when I don't know the type entered: class a (T) { T dummy = T.init; bool foo(int a, out T optional = dummy) { return true; } } void main () { auto c = new a!uint(); c.foo(5); } I get the following error: Error: need 'this' to access member dummy
Re: Null Object works still fine
Am Sun, 12 Aug 2012 00:23:10 +0200 schrieb "Namespace" : > This code works fine but it shouldn't, or? > > http://dpaste.dzfl.pl/b9027fff That's fine. There is no check for null at every possible occasion, like I think in Java. The operating system will catch any actual null dereference though, by notifying you of an invalid memory access. So in other words, D uses the fast approach. Cases where your print will not work is, when print() is a virtual method of that class (one that can be overridden). That would need to actually dereference the object to take a look into the virtual method table. 'private' and 'final' methods (or methods of a 'final class') are not virtual. -- Marco
Re: Null Object works still fine
On Saturday, 11 August 2012 at 22:23:12 UTC, Namespace wrote: This code works fine but it shouldn't, or? http://dpaste.dzfl.pl/b9027fff You don't actually dereference ›this‹ in print(), so the null value in the implicit this parameter doesn't matter. David
Re: Null Object works still fine
On Saturday, 11 August 2012 at 22:23:12 UTC, Namespace wrote: This code works fine but it shouldn't, or? The reason is the print method is private, which means it is also automatically final and doesn't access any member variables. Since it doesn't access members, it doesn't actually try to use the object and thus works ok. (You can access private methods as long as you are still in the same module, so this is by design too.) It being final is important because it means it is just a regular function - it doesn't need to access the object's virtual function table either. If it was a public final method, it would say "AssertEerror: null this", but since it is private I think that check is intentionally left out. But what you have here is everything working right, but the rule might seem weird... it's just because you aren't actually accessing the object, so the fact that it is null never comes into play.
Specialize mixin templates
A struct takes a mixin template as argument: struct S(alias Mixin) { mixin Mixin; } How to specialize a mixin template like this one to pass to S? mixin template MixinTemplate(T) { } S(MixinTemplate!float); // Something like this
Re: "For" infinite loop
bioinfornatics: n this case why not using a while loop ? It uses less lines of code, and with the for loop you have a single place where to put the loop variable initialization, test and increment. This makes the code simpler to read. In this case the test is moved inside the loop, but it's better still than a regular while loop. Bye, bearophile
Re: "For" infinite loop
On Saturday, 11 August 2012 at 20:00:40 UTC, bioinfornatics wrote: n this case why not using a while loop ? You mean like this? void main() { ubyte i = 0; do { write(i, " "); } while(i++ != 255); } or void main() { ubyte i = 0; while(true) { write(i, " "); if(i++ == 255) break; } } ? It's kind of a personal preference on how you want to handle this case, IMO. I think using a for loop how bearophile showed is more typical. Most would argue going with the "standard" approach is the most correct way ... but I almost like using a do-while in this case.
Re: "For" infinite loop
Le samedi 11 août 2012 à 20:48 +0200, bearophile a écrit : > RivenTheMage: > > > This is infinite loop: > > > > for (ubyte i=0; i<=255; i++) > > { > > ... > > } > > > > I guess it's a bug? > > One way to scan all the ubytes with a for loop: > > import std.stdio; > void main() { > for (ubyte i = 0; ; i++) { > write(i, " "); > if (i == 255) > break; > } > } > > Bye, > bearophile n this case why not using a while loop ?
Re: "For" infinite loop
Okay, thanks for helping!
Re: Check whether a type is a instantiated by a template struct
On Saturday, 11 August 2012 at 19:06:22 UTC, Chris Cain wrote: Same idea, but doing it with just one template and using static ifs... struct S(T) {} template isS(T) { static if(is(T _ : S!U, U)) enum isS = true; else enum isS = false; } static assert(isS!(S!float)); static assert(!isS!float); I usually prefer overloading for this particular kind of template because of the restriction that is() expressions may only introduce symbols when used in static-if statements. I think the if(blah) a = true; else a = false; pattern is worth avoiding as it leaves a bad taste in the mouth of many programmers.
Re: Check whether a type is a instantiated by a template struct
On Saturday, 11 August 2012 at 19:06:22 UTC, Chris Cain wrote: Same idea, but doing it with just one template and using static ifs... struct S(T) {} template isS(T) { static if(is(T _ : S!U, U)) enum isS = true; else enum isS = false; } static assert(isS!(S!float)); static assert(!isS!float); Thank you two. Did not know about the great abilities of is.
Re: "For" infinite loop
On Saturday, 11 August 2012 at 19:20:36 UTC, RivenTheMage wrote: Isn't both "i" and "255" should be propagated to int before comparison? Implicitly propagated, I mean. Regardless, a ubyte 0 converted to an int is still 0. a ubyte can only hold a maximum of 255 and will roll over to 0 when incremented at that point. So, i = 0 i <= 255 (0 <= 255 is true) // do stuff ++i (i = 1) i <= 255 (1 <= 255 is true) // do stuff ... ++i (i = 255) i <= 255 (255 <= 255 is true) // do stuff ++i (i = 0) i <= 255 (0 <= 255 is true) ... go on infinitely.
Re: "For" infinite loop
On Saturday, 11 August 2012 at 19:18:14 UTC, RivenTheMage wrote: On Saturday, 11 August 2012 at 18:37:18 UTC, Adam D. Ruppe wrote: A ubyte is ALWAYS <=255, since ubyte 255 + 1 == 0. Isn't both "i" and "255" should be propagated to int before comparison? Implicitly propagated, I mean.
Re: "For" infinite loop
On Saturday, 11 August 2012 at 18:37:18 UTC, Adam D. Ruppe wrote: A ubyte is ALWAYS <=255, since ubyte 255 + 1 == 0. Isn't both "i" and "255" should be propagated to int before comparison?
Re: Check whether a type is a instantiated by a template struct
On Saturday, 11 August 2012 at 18:56:30 UTC, Jakob Ovrum wrote: struct S(T) {} template isS(T : S!U, U) { enum isS = true; } template isS(T) { enum isS = false; } static assert(isS!(S!float)); static assert(!isS!float); Same idea, but doing it with just one template and using static ifs... struct S(T) {} template isS(T) { static if(is(T _ : S!U, U)) enum isS = true; else enum isS = false; } static assert(isS!(S!float)); static assert(!isS!float);
Re: Convert little imperative code to functional coding style
Le vendredi 10 août 2012 à 20:26 +0200, Timon Gehr a écrit : > Is this what you are looking for? > > import std.stdio; > import std.range: iota; > import std.algorithm: map, filter, joiner; > import std.typecons : tuple; > import std.math : sqrt, floor; > > void main(){ > immutable limit = cast(size_t)floor(sqrt(1_000.0)); > > auto r = iota(2,limit).map!(m=>iota(1,m-1).map!(n=>tuple(m,n))).joiner > .filter!(t=>2*t[0]*(t[0]+t[1])==1_000) > .map!(t=>(t[0]^^4-t[1]^^4)*(2*t[0]*t[1])); > > writeln(r.front); > } > oh yes beautiful thanks
Re: Check whether a type is a instantiated by a template struct
On Saturday, 11 August 2012 at 18:51:36 UTC, Henning Pohl wrote: So the struct is defined as: struct S(T) { } template isS(T) { // ... } static assert(isS(S!float)); static assert(!isS(float)); There may be some nasty ways using fullQualifiedName!T and so on but I guess there is a better way, isn't it? struct S(T) {} template isS(T : S!U, U) { enum isS = true; } template isS(T) { enum isS = false; } static assert(isS!(S!float)); static assert(!isS!float);
Check whether a type is a instantiated by a template struct
So the struct is defined as: struct S(T) { } template isS(T) { // ... } static assert(isS(S!float)); static assert(!isS(float)); There may be some nasty ways using fullQualifiedName!T and so on but I guess there is a better way, isn't it?
Re: "For" infinite loop
RivenTheMage: This is infinite loop: for (ubyte i=0; i<=255; i++) { ... } I guess it's a bug? One way to scan all the ubytes with a for loop: import std.stdio; void main() { for (ubyte i = 0; ; i++) { write(i, " "); if (i == 255) break; } } Bye, bearophile
Re: "For" infinite loop
A ubyte is ALWAYS <=255, since ubyte 255 + 1 == 0.
"For" infinite loop
This is infinite loop: for (ubyte i=0; i<=255; i++) { ... } I guess it's a bug?
Re: Reading a csv file
On Fri, 10 Aug 2012 03:44:11 +0200, Jesse Phillips wrote: > On Friday, 10 August 2012 at 01:39:32 UTC, Andrew wrote: >> I'm trying to read in a csv file. The examples in the docs for std.csv >> all assume you're reading from a string rather than a file. > > It requires a range of dchar. I believe there is an undocumented > function to get a dchar range out of a File, but as it is > undocumented... > > std.file.readText() will be your friend. This works perfectly, and thank you. I've since run into something peculiar. Here's my csv loader. It stuffs a csv file into an associative array containing structs of an arbitrary type, so long as the struct defines csvid(), which is needed to tell it what to use as the array key: T[string] loadcsvtable(T)(string filename) { string input = readText(filename); auto records = csvReader!T(input, null); T[string] table; foreach(record; records) table[record.csvid] = record; <---NOTE record.csvid return table; } Only I forgot the parenthesis on csvid()...and it still works. And I can't figure out why. I know you can do this sort of thing with @property, but the method definition doesn't have @property set. I'm not precisely complaining, but something's going on here I don't understand. -- Andrew