Re: alias to a property as an argument to a mixin template
On Sunday, 23 September 2012 at 21:44:20 UTC, comco wrote: [SNIP] Now we can implement our rotate in terms of reassign: void rotate(node* u) { auto v = u.right; reassign(u.right, v.left, u); } This works and is general enough, but notice the duplication of u.right. I don't like it - this may become an arbitrary large expression. [SNIP] void rotate(node* u) { node* v; mixin ReassignMixin!(v, u.right, v.left, u); reassign(); } See how the client code looks nicer when the template arguments are not wrapped as strings. I just don't see neither the problem, nor how the proposed solution is any better. All I see is a clean, closed and finished rotate at first, and then... something else... Relate: BR 8718 I just filed: Template mixin + string mixin name collision http://d.puremagic.com/issues/show_bug.cgi?id=8718
Re: Testing for template argument being result of takeExactly
On Monday, September 24, 2012 08:21:46 monarch_dodra wrote: > template Hello(R) > if ( is(typeof(takeExactly(R.init, 1))) && > is(R == typeof(takeExactly(R.init, 1))) > ) > { > alias R Hello; > } > What is wrong with my proposed solution? It may work, but again, it's relying on how takeExactly works. It's testing that you can call takeExactly on R.init and then that R is the same type as that result, which means that it's relies on the fact that takeExactly returns itself if you call takeExactly on it. It also relies on init, which can be risky, given the fact that it can be disabled. So, between your prosposal and the other that Philippe and Timon gave, theirs seems better. But unfortunately, none of the proposals work generically. Ideally, there would be a way to generically test that a type is the type returned by particular function, and I would _think_ that that's possible, but the way that I would expect to work doesn't. Regardless, thanks for your help. - Jonathan M Davis
Re: Stupid scope destruction question
20.09.2012 15:35, monarch_dodra пишет: On Thursday, 20 September 2012 at 09:31:45 UTC, Denis Shelomovskij wrote: 20.09.2012 13:27, Denis Shelomovskij пишет: Is there any guaranties that `ScopeTemp` will not be destroyed before `f` call because it isn't used? --- ... f(ScopeTemp(...).value); } --- According to http://dlang.org/struct.html#StructDestructor "Destructors are called when an object goes out of scope." So I understand it as "it will not be destroyed before scope exit even if not used". Is it correct? So the question is if `ScopeTemp`'s scope is `main` scope, not some possibly generated "temp scope" (don't now what documentation statements prohibit compiler from doing so). AFAIK, if the rules are the same in C++ (which they probably are), then: "Any object constructed during argument passing will remain valid for the duration of the call. It will go out of scope once the function has finished returning, and after the return value has itself gone out of scope and been destroyed." Thanks, looks like D does have C++ behaviour here. But your last statement about return value is incorrect. More than that function call doesn't change anything. Correct answers are here: * `12.2 Temporary objects [class.temporary]` section of C++ standard * http://stackoverflow.com/questions/2506793/c-life-span-of-temporary-arguments * http://stackoverflow.com/questions/5459759/full-expression-boundaries-and-lifetime-of-temporaries -- Денис В. Шеломовский Denis V. Shelomovskij
Re: Testing for template argument being result of takeExactly
On Monday, 24 September 2012 at 07:07:16 UTC, Jonathan M Davis wrote: On Monday, September 24, 2012 08:21:46 monarch_dodra wrote: template Hello(R) if ( is(typeof(takeExactly(R.init, 1))) && is(R == typeof(takeExactly(R.init, 1))) ) { alias R Hello; } What is wrong with my proposed solution? It may work, but again, it's relying on how takeExactly works. It's testing that you can call takeExactly on R.init and then that R is the same type as that result, which means that it's relies on the fact that takeExactly returns itself if you call takeExactly on it. It also relies on init, which can be risky, given the fact that it can be disabled. So, between your prosposal and the other that Philippe and Timon gave, theirs seems better. But unfortunately, none of the proposals work generically. Ideally, there would be a way to generically test that a type is the type returned by particular function, and I would _think_ that that's possible, but the way that I would expect to work doesn't. Regardless, thanks for your help. - Jonathan M Davis Good points. Regarding the ".init" issue, I hadn't thought of that, but it can be worked around pretty easily with an is(R r): template Hello(R) if ( is(R r) && is(typeof(takeExactly(r, 1))) && is(R == typeof(takeExactly(r, 1))) ) { alias R Hello; } After that, I guess it is indeed one implementation detail vs the other. IMO, it really depends on whether or not you'd want "int[]" to be considered the return type of a takeExactly :/ Maybe it is, maybe it ain't.
Re: Stupid scope destruction question
On Monday, 24 September 2012 at 07:25:28 UTC, Denis Shelomovskij wrote: 20.09.2012 15:35, monarch_dodra пишет: AFAIK, if the rules are the same in C++ (which they probably are), then: "Any object constructed during argument passing will remain valid for the duration of the call. It will go out of scope once the function has finished returning, and after the return value has itself gone out of scope and been destroyed." Thanks, looks like D does have C++ behaviour here. But your last statement about return value is incorrect. More than that function call doesn't change anything. Correct answers are here: * `12.2 Temporary objects [class.temporary]` section of C++ standard * http://stackoverflow.com/questions/2506793/c-life-span-of-temporary-arguments * http://stackoverflow.com/questions/5459759/full-expression-boundaries-and-lifetime-of-temporaries How is my statement incorrect? The "function call" itself doesn't change anything sure, since it is more generally a "full expression": The return value itself is created *during* that full expression, but after the creation of the arguments. Last in, first out, it is destroyed before the passed in arguments. Unless you were playing on the words "gone out of scope" (which is indeed not the 100% correct), I don't see how my statement is incorrect.
Re: Testing for template argument being result of takeExactly
On Monday, September 24, 2012 09:41:26 monarch_dodra wrote: > Regarding the ".init" issue, I hadn't thought of that, but it can > be worked around pretty easily with an is(R r): > > > template Hello(R) > if ( is(R r) && >is(typeof(takeExactly(r, 1))) && >is(R == typeof(takeExactly(r, 1))) > ) > { > alias R Hello; > } > That was one trick that I was not aware of. I didn't think that one is expression could have an effect on a later one in the surrounding expression. Cool. Though I would point out that that probably doesn't avoid the init problem, because R r uses R.init (unless is expressions treat it differently, which they may). The normal way to avoid that is to do R r = void; but I don't think that that would work in that is expression. Sometimes disabling init is useful, but it can definitely be problematic. It may ultimately have been a mistake to allow it. I don't know. - Jonathan M Davis
Re: Testing for template argument being result of takeExactly
On Monday, 24 September 2012 at 07:51:23 UTC, Jonathan M Davis wrote: On Monday, September 24, 2012 09:41:26 monarch_dodra wrote: Regarding the ".init" issue, I hadn't thought of that, but it can be worked around pretty easily with an is(R r): template Hello(R) if ( is(R r) && is(typeof(takeExactly(r, 1))) && is(R == typeof(takeExactly(r, 1))) ) { alias R Hello; } That was one trick that I was not aware of. I didn't think that one is expression could have an effect on a later one in the surrounding expression. Cool. Though I would point out that that probably doesn't avoid the init problem, because R r uses R.init (unless is expressions treat it differently, which they may). The normal way to avoid that is to do R r = void; but I don't think that that would work in that is expression. Sometimes disabling init is useful, but it can definitely be problematic. It may ultimately have been a mistake to allow it. I don't know. - Jonathan M Davis Well, it does work... struct S { @disable this(); } void foo(T)(T i) if ( is(T t)) {} void main() { //S s; //Fail S s = void; foo(s); //Works } I think it makes sense that it works, because "is" doesn't actually validate a compile time syntax, rather it is just declaring that "t can be used as an instance of T", but it is not actually declaring *the variable* "t" itself... Not sure I'm explaining myself. Or I think that's how it works. I've been on a wrong streak lately :/
Re: Testing for template argument being result of takeExactly
On Monday, September 24, 2012 10:02:54 monarch_dodra wrote: > Well, it does work... > > struct S > { > @disable this(); > } > > void foo(T)(T i) > if ( is(T t)) > {} > > void main() > { > //S s; //Fail > S s = void; > foo(s); //Works > } > > I think it makes sense that it works, because "is" doesn't > actually validate a compile time syntax, rather it is just > declaring that "t can be used as an instance of T", but it is not > actually declaring *the variable* "t" itself... Not sure I'm > explaining myself. > > Or I think that's how it works. I've been on a wrong streak > lately :/ @disable this; is pretty broken, so I wouldn't really trust it at this point. http://d.puremagic.com/issues/show_bug.cgi?id=7021 But it wouldn't surprise if is expressions are supposed to act differently. is expressions are arguably too fancy for their own good (well, our good anyway). - Jonathan M Davis
Re: alias to a property as an argument to a mixin template
On Monday, 24 September 2012 at 07:00:37 UTC, monarch_dodra wrote: On Sunday, 23 September 2012 at 21:44:20 UTC, comco wrote: [SNIP] Now we can implement our rotate in terms of reassign: void rotate(node* u) { auto v = u.right; reassign(u.right, v.left, u); } This works and is general enough, but notice the duplication of u.right. I don't like it - this may become an arbitrary large expression. [SNIP] void rotate(node* u) { node* v; mixin ReassignMixin!(v, u.right, v.left, u); reassign(); } See how the client code looks nicer when the template arguments are not wrapped as strings. I just don't see neither the problem, nor how the proposed solution is any better. All I see is a clean, closed and finished rotate at first, and then... something else... Relate: BR 8718 I just filed: Template mixin + string mixin name collision http://d.puremagic.com/issues/show_bug.cgi?id=8718 Yes, I don't claim that - the last thing is just nasty. It's just playing with constructs seeing how far can we go. By the way, now I use the reassign function all over the place! I'm also very glad this discussion ends with a (remotely connected) bug report!
Re: alias to a property as an argument to a mixin template
On Monday, 24 September 2012 at 10:53:47 UTC, comco wrote: Yes, I don't claim that - the last thing is just nasty. It's just playing with constructs seeing how far can we go. By the way, now I use the reassign function all over the place! I'm also very glad this discussion ends with a (remotely connected) bug report! Oh. I think I just got what your "reassign" was meant to do. I think I see it now. I guess it does work nice actually. I'd say that unfortunately, your *new* reassign is making the assumption that it is possible to grab a reference of the passed in objects. It will fail with "write properties", that need to evaluate different functions depending on read context and write context: import std.stdio; void reassign(A...)(ref A a) { //L3 static if (A.length > 1) { a[0] = a[1]; reassign(a[1 .. $]); } } struct S { private int i; @property int x(){return i;} @property int x(int v){return i = v;} } void main() { S a = S(1); S b = S(2); S c = S(3); a.x = b.x; b.x = c.x; c.x = 4; writefln("%s %s %s", a.x, b.x, c.x); reassign(a.x, b.x, c.x, 5); //L27 writefln("%s %s %s", a.x, b.x, c.x); } main.d(3): Error: template main.reassign(A...) cannot deduce template function from argument types !()(int,int,int,int) You could get away with it with some sort of template string mixin: mixin ReassignMixin!("a.x", "b.x", "c.x", 5"); reassign(); The problem with this approach though, is that it only works once per scope... and really, it is not much more than a glorified macro.
Re: alias to a property as an argument to a mixin template
On Monday, 24 September 2012 at 11:39:08 UTC, monarch_dodra wrote: Oh. I think I just got what your "reassign" was meant to do. I think I see it now. I guess it does work nice actually. I'd say that unfortunately, your *new* reassign is making the assumption that it is possible to grab a reference of the passed in objects. It will fail with "write properties", that need to evaluate different functions depending on read context and write context: ... The problem with this approach though, is that it only works once per scope... and really, it is not much more than a glorified macro. That's exactly the point :) - the `unfortunate` assumption about the references keeps this functionality nice and usable, and anything beyond that would just be too bit of a clumsy glorified macro, not worth the effort using it.
Re: static init cycle detection problem
On Wed, 19 Sep 2012 16:25:46 -0400, Øivind wrote: I am struggeling to get around the cycle detection kicking in when I have static init in modules that depend on eachother. I have seen some threads on 'fixes' for this, e.g. adding a @standalone property to the module or similar. Has there been any progress on this? No. If two initializations truly don't depend on each other, you can initialize in their own module. The issue is that you have to move *all* the initializations into their own module. The compiler doesn't keep track of complex dependencies, it's all on a module-level. I redesigned the static cycle detection code a while back (it was broken (allowed certain cycles) and much less informative), and I can say it was a very difficult problem to solve. If not would it be possible in e.g. main() to get a list of all compiled-in modules, and then iterate over them and call an init function where it exists? As long as there is a way to list the name of the modules at compile-time, this should be pretty easy..? No, you have no idea at compile-time what other modules will be linked in. You need to do the cycle detection at link-time or run-time, and as long as we use standard C linkers, we cannot add that feature. -Steve
FormattedRead hex string
I imagine there's a slick way to do this, but I'm not seeing it. I have a string of hex digits which I'd like to convert to an array of 8 ubytes: 0123456789abcdef --> [0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF] I'm looking at std.format.formattedRead, but the documentation is...lightish. First of all, it seems there's no format specifier except %s on reads and type information is gleaned from the args' types. I was able to experiment and show that %x works, but no documentation on exactly how. Second, array syntax seems to work only if there's some delimiter. With: void main(string[] args) { ubyte[8] b; formattedRead(args[1], "%(%s%)", &b); } I get std.conv.ConvOverflowException@C:\Tools\D\dmd2\windows\bin\..\..\src\phobos\std\ conv.d(2006): Overflow in integral conversion at least once. :) But that makes sense--hard to tell how many input chars to assign to one byte versus another (although it seems to me a hungry algorithm would work--saturate one type's max and move to the next.) There doesn't seem to be any support for field sizes or counts in formatted read, similar to old C "%16x". This barks at me right away--"%1 not supported." I know I could read (in this case) as two longs or a uint16, but I don't want to deal with endianess--just data. Is there some trick to use the fact that b is fixed size 8 bytes and know that requires 16 hex digits and converts automatically? Is there some other suggestion for how to do this eloquently? I can play around with split and join, but it seemed like there is probably some way to do this directly that I'm not seeing. Thanks! Jason
Re: FormattedRead hex string
On Monday, 24 September 2012 at 15:05:54 UTC, Jason Spencer wrote: I imagine there's a slick way to do this, but I'm not seeing it. I have a string of hex digits which I'd like to convert to an array of 8 ubytes: 0123456789abcdef --> [0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF] I'm looking at std.format.formattedRead, but the documentation is...lightish. First of all, it seems there's no format specifier except %s on reads and type information is gleaned from the args' types. I was able to experiment and show that %x works, but no documentation on exactly how. Second, array syntax seems to work only if there's some delimiter. With: void main(string[] args) { ubyte[8] b; formattedRead(args[1], "%(%s%)", &b); } I get std.conv.ConvOverflowException@C:\Tools\D\dmd2\windows\bin\..\..\src\phobos\std\ conv.d(2006): Overflow in integral conversion at least once. :) But that makes sense--hard to tell how many input chars to assign to one byte versus another (although it seems to me a hungry algorithm would work--saturate one type's max and move to the next.) There doesn't seem to be any support for field sizes or counts in formatted read, similar to old C "%16x". This barks at me right away--"%1 not supported." I know I could read (in this case) as two longs or a uint16, but I don't want to deal with endianess--just data. Is there some trick to use the fact that b is fixed size 8 bytes and know that requires 16 hex digits and converts automatically? Is there some other suggestion for how to do this eloquently? I can play around with split and join, but it seemed like there is probably some way to do this directly that I'm not seeing. Thanks! Jason I think that you are not supposed to use a static array: If there are not EXACTLY as many array elements as there are parse-able elements, then the formatted read will consider the parse to have failed. Try this, it's what you want, right? void main() { string s = " fff ff f"; ushort[] vals; formattedRead(s, "%(%x %)", &vals); writefln("%(%s - %)", vals); } 65535 - 4095 - 255 - 15 Regarding the %1x, well, I guess it just isn't supported (yet?)
Re: memory de-allocation?
On Monday, 24 September 2012 at 00:16:33 UTC, freeman wrote: Given: void main () { system("rdmd prog_one.d"); //... output from prog_one system("rdmd prog_two.d"); //... output again from prog_one and new output from prog_two. } Any suggestions for getting rid of the ghost of prog_one? After more testing, I think this problem relates to processing over nfs, so network latency might be the issue. Maybe a buffer is not getting cleared quick enough.
Re: Stupid scope destruction question
On 09/24/2012 12:49 AM, monarch_dodra wrote: > On Monday, 24 September 2012 at 07:25:28 UTC, Denis Shelomovskij wrote: >> 20.09.2012 15:35, monarch_dodra пишет: >>> >>> AFAIK, if the rules are the same in C++ (which they probably are), then: >>> "Any object constructed during argument passing will remain valid for >>> the duration of the call. It will go out of scope once the function has >>> finished returning, and after the return value has itself gone out of >>> scope and been destroyed." That sounds like you are saying that the temporary S() is destroyed after 'r' below: // C++ code R r = foo(S()); > How is my statement incorrect? The "function call" itself doesn't change > anything sure, since it is more generally a "full expression": The > return value itself is created *during* that full expression, but after > the creation of the arguments. Last in, first out, it is destroyed > before the passed in arguments. That is not correct. The temporary S() is destroyed at the end of the assignment expression (at the semicolon), while 'r' will live until the end of the current scope. Ali
Re: Stupid scope destruction question
On Monday, 24 September 2012 at 17:49:22 UTC, Ali Çehreli wrote: On 09/24/2012 12:49 AM, monarch_dodra wrote: > On Monday, 24 September 2012 at 07:25:28 UTC, Denis Shelomovskij wrote: >> 20.09.2012 15:35, monarch_dodra пишет: >>> >>> AFAIK, if the rules are the same in C++ (which they probably are), then: >>> "Any object constructed during argument passing will remain valid for >>> the duration of the call. It will go out of scope once the function has >>> finished returning, and after the return value has itself gone out of >>> scope and been destroyed." That sounds like you are saying that the temporary S() is destroyed after 'r' below: // C++ code R r = foo(S()); > How is my statement incorrect? The "function call" itself doesn't change > anything sure, since it is more generally a "full expression": The > return value itself is created *during* that full expression, but after > the creation of the arguments. Last in, first out, it is destroyed > before the passed in arguments. That is not correct. The temporary S() is destroyed at the end of the assignment expression (at the semicolon), while 'r' will live until the end of the current scope. Ali Ah... but see, "s" is *not* the temporary returned value. It is a normal stack variable to which the the return value is copied. Also, as I said, in this situation, the compiler will elide the return completely by constructing the returned value directly into s, so you won't see the destroyer. Try this though: void main() { S s; foo(S(1)); } D:C++ C0C:0 C1C:1 foo(S)foo(S) C2C:2 D~1 D~:2 D~2 D~:1 D~0 D~:0 As you can see, three destructors. It would appear that D, contrary to C++, actually destroys the return value before the passed in arguments. Interesting. A valid behavior like any other I guess, but doesn't change much. I'll admit I was wrong regarding that (regarding D), but it stays right for C++ :p Not your example you ask? HERE is the *money* example: void main() { S s; s = foo(S(1)); } D:C++ C0C:0 C1C:1 foo(S)foo(S) C2C:2 D~1 D~:2 D~0 D~:1 D~2 D~:2 Again 3 destroyers. Again, C++, again works as I said. Regarding D, WTF is D~0 ? That is D's "return value move" into action! First time I observe it myself! Exciting! * First, the passed in argument is destroyed: D~1. * Then it gets interesting: * D first calls a destroyer on s (but doesn't actually remove it from the stack): D~0. * Then D does a memcpy from the returned value, onto s (the move). * Finally, the actual return value is then removed from the stack, but no destructor ever called on it. * Finally, at the end of the program, s is destroyed (D~2). Neat-o!
How do I use std.zlib to write a struct of data to a binary file with compression?
Hello, I am trying to save some data to compressed binary files. I have my data in a struct, which I can write to a binary file just fine: align(1) struct TradesBin { int ttim; int prc; int siz; short g127; short corr; char[2] cond; char ex; } auto fout = new BufferedFile(outfile, FileMode.Out); fout.writeExact(&bin, TradesBin.sizeof); Where bin is of type TradesBin, filled with data. The question is how do I now do this with zlib to get compression? Suggestions and help are mightily appreciated! TJB
Re: How do I use std.zlib to write a struct of data to a binary file with compression?
On Mon, 24 Sep 2012 22:10:04 +0200, TJB wrote: > Hello, > > I am trying to save some data to compressed binary files. I have my > data in a struct, which I can write to a binary file just fine: > > align(1) struct TradesBin { >int ttim; int prc; >int siz; short g127; short corr; char[2] cond; >char ex; > } > > auto fout = new BufferedFile(outfile, FileMode.Out); > fout.writeExact(&bin, TradesBin.sizeof); > > Where bin is of type TradesBin, filled with data. The question is how > do I now do this with zlib to get compression? > Suggestions and help are mightily appreciated! > > TJB Since you're already set up with the Stream interface, try creating a MemoryStream instead of a BufferedFile. Write to the stream just as you are now, then use the .data() property (on MemoryStream's superclass, TArrayStream) to get an array of raw bytes. You can feed this array into the compress function in std.zlib to produce a new (hopefully shorter) array of bytes that contains the compressed data. Simply write this compressed data to a file with `fout.writeExact(compressed.ptr, compressed.length)` and you're done. Since uncompress works better if you know the exact size of the uncompressed data, you might also consider writing the uncompressed size of the data to your output file before the compressed data. Justin
Re: Testing for template argument being result of takeExactly
On 09/24/2012 09:41 AM, monarch_dodra wrote: ... Regarding the ".init" issue, I hadn't thought of that, but it can be worked around pretty easily with an is(R r): template Hello(R) if ( is(R r) && is(typeof(takeExactly(r, 1))) && is(R == typeof(takeExactly(r, 1))) ) { alias R Hello; } After that, I guess it is indeed one implementation detail vs the other. I don't think this does what you think it does. The 'is(R r)' declares r to be an alias for R. So 'r' is a type in that code snippet. Also, is(typeof(takeExactly(R, 1))) && is(R == typeof(takeExactly(R, 1))) can be written in a more compact way as is(typeof(takeExactly(R, 1)) == R) IMO, it really depends on whether or not you'd want "int[]" to be considered the return type of a takeExactly :/ Maybe it is, maybe it ain't.
Re: FormattedRead hex string
On Monday, 24 September 2012 at 16:32:45 UTC, monarch_dodra wrote: On Monday, 24 September 2012 at 15:05:54 UTC, Jason Spencer wrote: I imagine there's a slick way to do this, but I'm not seeing it. I have a string of hex digits which I'd like to convert to an array of 8 ubytes: 0123456789abcdef --> [0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF] void main(string[] args) { ubyte[8] b; formattedRead(args[1], "%(%s%)", &b); } I think that you are not supposed to use a static array: If there are not EXACTLY as many array elements as there are parse-able elements, then the formatted read will consider the parse to have failed. The sample code was just for testing convenience. In practice the string will be conditioned and known to have 16 characters in {0-9, a-f}. Try this, it's what you want, right? void main() { string s = " fff ff f"; ushort[] vals; formattedRead(s, "%(%x %)", &vals); writefln("%(%s - %)", vals); } Not quite. You've taken the liberty of using a delimiter--spaces. I have to take 16 contiguous, NON-delimited hex digits and produce 8 bytes. So I could read it as a uint64 (not uint16, as I mistakenly posted before), but then I'd have to byte-reverse it. I could use slicing and do a byte at a time. I just wondered if there were a slick way to get in-place data from a contiguous hex string. Thanks, Jason
Re: Passing associative array to another thread
On Sep 22, 2012, at 2:24 AM, Martin Drasar wrote: > On 21.9.2012 19:01, Jacob Carlborg wrote: >> Perhaps declaring the associative array as "shared". An alternative >> would be to serialize the aa, pass it to another thread, and deserialize >> it. That would though create a copy. > > Hi Jacob, > > thanks for the hint. Making it shared sounds a bit fishy to me. My > intention is to pass some read only data, that are in fact thread local > and there is no real need to make them shared. If you're passing via std.concurrency then you'll currently have to cast to shared. I'd been considering allowing Unique!T to be sent as well, but haven't done so yet.
Re: How do I use std.zlib to write a struct of data to a binary file with compression?
Since you're already set up with the Stream interface, try creating a MemoryStream instead of a BufferedFile. Write to the stream just as you are now, then use the .data() property (on MemoryStream's superclass, TArrayStream) to get an array of raw bytes. You can feed this array into the compress function in std.zlib to produce a new (hopefully shorter) array of bytes that contains the compressed data. Simply write this compressed data to a file with `fout.writeExact(compressed.ptr, compressed.length)` and you're done. Since uncompress works better if you know the exact size of the uncompressed data, you might also consider writing the uncompressed size of the data to your output file before the compressed data. Justin Ok, I think I get it. Can you help me set up the first part, writing to the MemoryStream? TJB
Zipped sorting
This line of code sorts two arrays in "lock step", according to the items of the first array: zip(first, second).sort!q{a[0] < b[0]}(); This code is handy, nice looking, short and sufficiently easy to recognize once you have seen it before. It's one case where D code is better than a Python version (and this returns two tuples instead of two lists): first, second = zip(*sorted(izip(first, second), key=itemgetter(0))) But with DMD on shortish arrays of about 20-30 items (each one 24 bytes long) I've seen that D code 3-5 times slower (to be sure of such timings I have to write down a proper benchmark) than sorting the items with simple manually written sorting D code, like a bubble sort or something similar (where inside swaps items of both arrays). So if this sorting is done in inner loops or critical parts of code, you can't use that zip+sort :-( Bye, bearophile
Re: Zipped sorting
On Tuesday, 25 September 2012 at 02:17:53 UTC, bearophile wrote: This line of code sorts two arrays in "lock step", according to the items of the first array: zip(first, second).sort!q{a[0] < b[0]}(); Tangential to your point, but I hadn't seen the q{} syntax used before. Are there reasons to favor this over other string literals?
Re: Passing associative array to another thread
On 2012-09-25 00:47, Sean Kelly wrote: If you're passing via std.concurrency then you'll currently have to cast to shared. I'd been considering allowing Unique!T to be sent as well, but haven't done so yet. Hey, if it's immutable why use std.concurrency at all? Just import the module and use the variable willy nilly. I mean, isn't that the whole point of immutable anyway, you can share it freely among threads without any risks? -- /Jacob Carlborg
Re: How do I use std.zlib to write a struct of data to a binary file with compression?
On 25-Sep-12 00:10, TJB wrote: Hello, I am trying to save some data to compressed binary files. I have my data in a struct, which I can write to a binary file just fine: align(1) struct TradesBin { Just a note: recently compiler changed so this align(1) have no effect on the fields alignment only on a struct as a whole. So instead align(1): inside of struct should probably work. int ttim; int prc; int siz; short g127; short corr; char[2] cond; char ex; } auto fout = new BufferedFile(outfile, FileMode.Out); fout.writeExact(&bin, TradesBin.sizeof); Where bin is of type TradesBin, filled with data. The question is how do I now do this with zlib to get compression? Suggestions and help are mightily appreciated! TJB -- Dmitry Olshansky
Re: Testing for template argument being result of takeExactly
On Monday, 24 September 2012 at 22:13:51 UTC, Timon Gehr wrote: On 09/24/2012 09:41 AM, monarch_dodra wrote: > [SNIP] I don't think this does what you think it does. The 'is(R r)' declares r to be an alias for R. So 'r' is a type in that code snippet. Darn :( Also, is(typeof(takeExactly(R, 1))) && is(R == typeof(takeExactly(R, 1))) can be written in a more compact way as is(typeof(takeExactly(R, 1)) == R) Technically, no: That was my first try, and as mentioned in the first reply, this returns true when the types of takeExactly and R are equal comparable, but does not make sure they are the actually the same types. "is(R == typeof(takeExactly(R, 1)))" Makes sure they are the exact same type, and "is(typeof(takeExactly(R, 1)))" is a short-circuit, to prevent the second test from error'ing if takeExactly!R is not legal.
Re: Zipped sorting
On 25-Sep-12 06:18, bearophile wrote: This line of code sorts two arrays in "lock step", according to the items of the first array: zip(first, second).sort!q{a[0] < b[0]}(); This code is handy, nice looking, short and sufficiently easy to recognize once you have seen it before. Analyzing asm dump should help. But either way zip-sort heavily relies on proper inlining and I suspect it's not fully "unrolled". Did you try DMD or other compilers? It's one case where D code is better than a Python version (and this returns two tuples instead of two lists): first, second = zip(*sorted(izip(first, second), key=itemgetter(0))) But with DMD on shortish arrays of about 20-30 items (each one 24 bytes long) I've seen that D code 3-5 times slower (to be sure of such timings I have to write down a proper benchmark) than sorting the items with simple manually written sorting D code, like a bubble sort or something similar (where inside swaps items of both arrays). So if this sorting is done in inner loops or critical parts of code, you can't use that zip+sort :-( Bye, bearophile -- Dmitry Olshansky