Re: alias to a property as an argument to a mixin template

2012-09-24 Thread monarch_dodra

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

2012-09-24 Thread Jonathan M Davis
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

2012-09-24 Thread Denis Shelomovskij

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

2012-09-24 Thread monarch_dodra

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

2012-09-24 Thread monarch_dodra
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

2012-09-24 Thread Jonathan M Davis
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

2012-09-24 Thread monarch_dodra
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

2012-09-24 Thread Jonathan M Davis
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

2012-09-24 Thread comco

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

2012-09-24 Thread monarch_dodra

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

2012-09-24 Thread comco

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

2012-09-24 Thread Steven Schveighoffer

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

2012-09-24 Thread Jason Spencer

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

2012-09-24 Thread monarch_dodra

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?

2012-09-24 Thread freeman

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

2012-09-24 Thread Ali Çehreli

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

2012-09-24 Thread monarch_dodra

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?

2012-09-24 Thread TJB

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?

2012-09-24 Thread Justin Whear
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

2012-09-24 Thread Timon Gehr

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

2012-09-24 Thread Jason Spencer

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

2012-09-24 Thread Sean Kelly
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?

2012-09-24 Thread 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


Ok, I think I get it.  Can you help me set up the first part, 
writing to the MemoryStream?


TJB


Zipped sorting

2012-09-24 Thread bearophile
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

2012-09-24 Thread cal

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

2012-09-24 Thread Jacob Carlborg

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?

2012-09-24 Thread Dmitry Olshansky

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

2012-09-24 Thread monarch_dodra

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

2012-09-24 Thread Dmitry Olshansky

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