Re: Scale advocacy

2011-07-04 Thread Daniel Murphy
"Ali Çehreli"  wrote in message 
news:iuqja8$7nl$2...@digitalmars.com...
> { bool result = ElementType!Range.init is null; } ))

is(typeof(ElementType!Range.init is null))
__traits(compiles, cast(void)ElementType!Range.init is null)
__traits(compiles, { return ElementType!Range.init is null; })
should all work. 




Using a C function with command line parameters

2011-07-04 Thread Jonathan Sternberg
glut has the function:

void glutInit( int* pargc, char** argv );

In order to use it. Since D has an ABI compatible with C, I should be able to
write a D file with extern (C) on the glut functions. How would I wrap this
function to be used with D arrays? Such as:

int main(string[] args)
{
glutInit( /* I don't know what to do here */ );
return 0;
}

Thanks.


Re: Using a C function with command line parameters

2011-07-04 Thread Steven Schveighoffer
On Mon, 04 Jul 2011 10:31:58 -0400, Jonathan Sternberg  
 wrote:



glut has the function:

void glutInit( int* pargc, char** argv );

In order to use it. Since D has an ABI compatible with C, I should be  
able to
write a D file with extern (C) on the glut functions. How would I wrap  
this

function to be used with D arrays? Such as:

int main(string[] args)
{
glutInit( /* I don't know what to do here */ );
return 0;
}

Thanks.


Convert all the args to zero-terminated strings.  One thing to look at,  
does glutInit actually modify any of the strings or does it just remove  
them from the argv array?  Because I would expect the argv argument to be  
const(char)** if it doesn't modify.  That would allow you to pass in the  
strings without having to duplicate them.


Some untested code:

auto argarr = new immutable(char)*[args.length];
foreach(i, a; args)
   argarr[i] = (a.dup ~ '\0').ptr;

int argc = argarr.length;
glutInit(&argc, argarr.ptr);

// now, need to refix args to ignore arguments already consumed by glutInit
...

-Steve


Re: Using a C function with command line parameters

2011-07-04 Thread Steven Schveighoffer
On Mon, 04 Jul 2011 10:39:07 -0400, Steven Schveighoffer  
 wrote:


On Mon, 04 Jul 2011 10:31:58 -0400, Jonathan Sternberg  
 wrote:



glut has the function:

void glutInit( int* pargc, char** argv );

In order to use it. Since D has an ABI compatible with C, I should be  
able to
write a D file with extern (C) on the glut functions. How would I wrap  
this

function to be used with D arrays? Such as:

int main(string[] args)
{
glutInit( /* I don't know what to do here */ );
return 0;
}

Thanks.


Convert all the args to zero-terminated strings.  One thing to look at,  
does glutInit actually modify any of the strings or does it just remove  
them from the argv array?  Because I would expect the argv argument to  
be const(char)** if it doesn't modify.  That would allow you to pass in  
the strings without having to duplicate them.


Some untested code:

auto argarr = new immutable(char)*[args.length];


bleh, this should have been new char*[args.length];

Sorry.

-Steve


swap doesn't work in CTFE?

2011-07-04 Thread Johann MacDonagh
Although CTFE supports ref parameters, swap doesn't appear to work. This 
casues dmd to segfault in 2.053 and the current dmd master.


import std.algorithm;
import std.stdio;

string ctfeRef(ref string a, ref string b)
{
return a;
}

string ctfeSort()
{
auto x = [ "a", "c", "b" ];
swap(x[1], x[0]);   // This is the problem here
return ctfeRef(x[1], x[0]);
}

void main()
{
enum xx = ctfeSort();
writeln(xx);
}

This means things like sort won't work in CTFE. Does anyone know if this 
is a known bug? My searching didn't bring anything up.


Re: Using a C function with command line parameters

2011-07-04 Thread Jacob Carlborg

On 2011-07-04 16:31, Jonathan Sternberg wrote:

glut has the function:

 void glutInit( int* pargc, char** argv );

In order to use it. Since D has an ABI compatible with C, I should be able to
write a D file with extern (C) on the glut functions. How would I wrap this
function to be used with D arrays? Such as:

int main(string[] args)
{
 glutInit( /* I don't know what to do here */ );
 return 0;
}

Thanks.


It depends on what your needs are. If your not actually using the 
arguments then you can pass in 0 and null, or 1 and the name of the 
application.


As an alternative, most platforms have an API for getting the arguments 
passed to an application.


Mac OS X: extern (C) char*** _NSGetEnviron();
Posix: extern (C) extern char** environ;

Don't know about Windows.

--
/Jacob Carlborg


Re: Using a C function with command line parameters

2011-07-04 Thread Steven Schveighoffer

On Mon, 04 Jul 2011 12:51:48 -0400, Jacob Carlborg  wrote:


On 2011-07-04 16:31, Jonathan Sternberg wrote:

glut has the function:

 void glutInit( int* pargc, char** argv );

In order to use it. Since D has an ABI compatible with C, I should be  
able to
write a D file with extern (C) on the glut functions. How would I wrap  
this

function to be used with D arrays? Such as:

int main(string[] args)
{
 glutInit( /* I don't know what to do here */ );
 return 0;
}

Thanks.


It depends on what your needs are. If your not actually using the  
arguments then you can pass in 0 and null, or 1 and the name of the  
application.


A typical library that uses standardized arguments (i.e. parameters that  
always mean the same thing across applications that use that library) has  
a parameter pre-processing function such as this which "consume" their  
specific arguments from the command line.  The idea is, you pass the  
command line to those functions, the library processes its specific  
arguments, removing them from the command line array, and then all  
applications using that library have a way to control the library from the  
command line.  I think the first one I remember having this is X and Xt.   
For example, most X-based applications you can pass --display=mysystem:0  
and it uses that display.  The applications simply use a libX function  
that processes those args from the command line and never have to deal  
with it.


As an alternative, most platforms have an API for getting the arguments  
passed to an application.


Mac OS X: extern (C) char*** _NSGetEnviron();
Posix: extern (C) extern char** environ;


Those get the environment variables, not the command line arguments.


Don't know about Windows.


Windows actually does have a command line fetching function.  Can't  
remember what it is, but if I had to guess I'd say it was GetCommandLine :)


-Steve


Pre and Post contracts and signature constraints

2011-07-04 Thread Zardoz
How is the correct way of mix  Pre and Post contracts and signature constraints 
?

I try this that looks logic way and not compile : 

T foo (T) (T a) 
if ( is(T : real)) {
 in {
assert (a > 0); 
 }
 body {
return a*2;
 }
}

I get this errors : 
Declaration expected, not 'if'
unrecognized declaration

And this with same result :

T foo (T) (T a) 
in {
assert (a > 0); 
}
if ( is(T : real)) {
 body {
return a*2;
 }
}

I'm using dmd 2.053.

-- 
Yep, I'm afraid that I have a blog : zardoz.es


Re: swap doesn't work in CTFE?

2011-07-04 Thread Daniel Murphy
"Johann MacDonagh"  wrote in message 
news:iusp80$vnr$1...@digitalmars.com...
> Although CTFE supports ref parameters, swap doesn't appear to work. This 
> casues dmd to segfault in 2.053 and the current dmd master.
>
> import std.algorithm;
> import std.stdio;
>
> string ctfeRef(ref string a, ref string b)
> {
> return a;
> }
>
> string ctfeSort()
> {
> auto x = [ "a", "c", "b" ];
> swap(x[1], x[0]);   // This is the problem here
> return ctfeRef(x[1], x[0]);
> }
>
> void main()
> {
> enum xx = ctfeSort();
> writeln(xx);
> }
>
> This means things like sort won't work in CTFE. Does anyone know if this 
> is a known bug? My searching didn't bring anything up.

Same thing happens with pointers.  Reduced:

void swap(int[]* lhs, int[]* rhs)
{
*lhs = *rhs;
*rhs = *lhs;
}

int ctfeSort()
{
 int[][2] x;
 swap(&x[0], &x[1]);
 return 0;
}

void main()
{
enum x = ctfeSort();
}




Re: Pre and Post contracts and signature constraints

2011-07-04 Thread simendsjo

On 04.07.2011 19:20, Zardoz wrote:

How is the correct way of mix  Pre and Post contracts and signature constraints 
?

I try this that looks logic way and not compile :

T foo (T) (T a)
if ( is(T : real)) {
  in {
assert (a>  0);
  }
  body {
return a*2;
  }
}

I get this errors :
Declaration expected, not 'if'
unrecognized declaration

And this with same result :

T foo (T) (T a)
in {
assert (a>  0);
}
if ( is(T : real)) {
  body {
return a*2;
  }
}

I'm using dmd 2.053.



The "in" should be in a block of it's own:

T foo(T)(T a)
if(...) // notice no { here
in {
} body {
}


Re: Pre and Post contracts and signature constraints

2011-07-04 Thread simendsjo

On 04.07.2011 19:42, simendsjo wrote:


The "in" should be in a block of it's own:

T foo(T)(T a)
if(...) // notice no { here
in {
} body {
}


I of course mean that if should not create a new block.


Bits in reverse order in BitArray

2011-07-04 Thread Christian Manning
Hi, when I populate a BitArray using .init, the bits are in reverse 
order, although the bytes are in the correct order.

eg:

import std.stdio,std.bitmanip;

void main() {
ubyte[] arr = [130,56,43,2];

BitArray ba;
ba.init(cast(void[])arr,32);
foreach(b; ba)
   write(cast(ubyte) b); //bits in each byte reversed
 //010100011100110101000100
writeln();

ba.init(cast(void[])arr.reverse,32);
foreach(b; ba.reverse)
   write(cast(ubyte) b); //bits printed in intended order
 //10100011101010110010
writeln();
}

Why does this happen?

Thanks


Re: Pre and Post contracts and signature constraints

2011-07-04 Thread Zardoz
On Mon, 04 Jul 2011 19:52:10 +0200, simendsjo wrote:

> On 04.07.2011 19:42, simendsjo wrote:
>>
>> The "in" should be in a block of it's own:
>>
>> T foo(T)(T a)
>> if(...) // notice no { here
>> in {
>> } body {
>> }
> 
> I of course mean that if should not create a new block.
Thanks !
I thought that the if () needs to make a block. :P




-- 
Yep, I'm afraid that I have a blog : zardoz.es


Re: swap doesn't work in CTFE?

2011-07-04 Thread bearophile
Daniel Murphy:

> Same thing happens with pointers.  Reduced:

Pointers to structs in CTFE will work in DMD 2.054 :-)

Bye,
bearophile


Re: Bits in reverse order in BitArray

2011-07-04 Thread Steven Schveighoffer
On Mon, 04 Jul 2011 14:03:35 -0400, Christian Manning  
 wrote:


Hi, when I populate a BitArray using .init, the bits are in reverse  
order, although the bytes are in the correct order.

eg:

import std.stdio,std.bitmanip;

void main() {
 ubyte[] arr = [130,56,43,2];

 BitArray ba;
 ba.init(cast(void[])arr,32);
 foreach(b; ba)
write(cast(ubyte) b); //bits in each byte reversed
  //010100011100110101000100
 writeln();

 ba.init(cast(void[])arr.reverse,32);
 foreach(b; ba.reverse)
write(cast(ubyte) b); //bits printed in intended order
  //10100011101010110010
 writeln();
}

Why does this happen?


What exactly are you expecting?  In other words, when using the void[]  
version of init, you are specifying the exact memory to use, which implies  
you know how BitArray's internals work.  If you create a BitArray by  
adding bits to the BitArray, then it's internal storage doesn't matter to  
you, it can store however it wants.


I'd guess the most logical reason to store the bits in reverse order would  
be for performance.  Not sure what the merits are, but typically, it's  
faster to access and manipulate the 0 bit than some arbitrary bit.


-Steve


Re: Pre and Post contracts and signature constraints

2011-07-04 Thread simendsjo

On 04.07.2011 20:12, Zardoz wrote:

On Mon, 04 Jul 2011 19:52:10 +0200, simendsjo wrote:


On 04.07.2011 19:42, simendsjo wrote:


The "in" should be in a block of it's own:

T foo(T)(T a)
if(...) // notice no { here
in {
} body {
}


I of course mean that if should not create a new block.

Thanks !
I thought that the if () needs to make a block. :P


The if is called a template constrain: 
http://www.d-programming-language.org/template.html#Constraint


T foo(T)(T a) is a shorthand (I think) for

template foo(T) {
  T foo(T a) {
  }
}

The constraint refers to the template part:

template foo(T) if(is(T:real)) {
  T foo(T a) {
  }
}

Because the template only contain a single member, and it's named the 
same as the template, you can instantiate it directly as foo(1.2);
If the function was named bar, you'd have to instantiate it yourself: 
foo!real.bar(1.2);


Re: Bits in reverse order in BitArray

2011-07-04 Thread Christian Manning

On 04/07/2011 19:34, Steven Schveighoffer wrote:

On Mon, 04 Jul 2011 14:03:35 -0400, Christian Manning
 wrote:


Hi, when I populate a BitArray using .init, the bits are in reverse
order, although the bytes are in the correct order.
eg:

import std.stdio,std.bitmanip;

void main() {
ubyte[] arr = [130,56,43,2];

BitArray ba;
ba.init(cast(void[])arr,32);
foreach(b; ba)
write(cast(ubyte) b); //bits in each byte reversed
//010100011100110101000100
writeln();

ba.init(cast(void[])arr.reverse,32);
foreach(b; ba.reverse)
write(cast(ubyte) b); //bits printed in intended order
//10100011101010110010
writeln();
}

Why does this happen?


What exactly are you expecting? In other words, when using the void[]
version of init, you are specifying the exact memory to use, which
implies you know how BitArray's internals work. If you create a BitArray
by adding bits to the BitArray, then it's internal storage doesn't
matter to you, it can store however it wants.

I'd guess the most logical reason to store the bits in reverse order
would be for performance. Not sure what the merits are, but typically,
it's faster to access and manipulate the 0 bit than some arbitrary bit.

-Steve


Sorry, I assumed it was BitArray causing this, but that's just what made 
me aware of it.


It seems dmd does this when accessing pointers directly, so your 
reasoning is probably right!


Thanks!


Re: Operator Overloading and boilerplate code

2011-07-04 Thread Loopback

I've researched a bit though I still haven't come up with a solution.
Since the problem lies within (the most simple) constructor, I tried to
modify it for another outcome. If I supplied a generic parameter to the
pre-constructor the "Cannot evaluate at compile time" message
disappeared but two new errors appeared instead.

This is what I modified:

this()(float x, float y, float z) => this(T)(float x, float y, float z)

If I use this code instead, I get two other errors appearing:

Error: template test.DVECTOR2.__ctor(T) does not match any function 
template declaration


This error and another one (individual to each statement) appears in the
following code statements:


Error: template test.DVECTOR2.__ctor(T) cannot deduce template function 
from argument types !()(float,float)

DVECTOR2 m_zoom = DVECTOR2(2f, 2f);

Error: template test.DVECTOR2.__ctor(T) cannot deduce template function 
from argument types !()(immutable(float),const(float))

immutable DVECTOR2 m_UP_DIR = DVECTOR2(0f, 1f, 0f);


Re: Operator Overloading and boilerplate code

2011-07-04 Thread Ali Çehreli
On Tue, 05 Jul 2011 02:44:03 +0200, Loopback wrote:

> I've researched a bit though I still haven't come up with a solution.
> Since the problem lies within (the most simple) constructor, I tried to
> modify it for another outcome. If I supplied a generic parameter to the
> pre-constructor the "Cannot evaluate at compile time" message
> disappeared but two new errors appeared instead.
> 
> This is what I modified:
> 
> this()(float x, float y, float z) => this(T)(float x, float y, float z)
> 
> If I use this code instead, I get two other errors appearing:
> 
> Error: template test.DVECTOR2.__ctor(T) does not match any function
> template declaration
> 
> This error and another one (individual to each statement) appears in the
> following code statements:
> 
> 
> Error: template test.DVECTOR2.__ctor(T) cannot deduce template function
> from argument types !()(float,float)
> DVECTOR2 m_zoom = DVECTOR2(2f, 2f);
> 
> Error: template test.DVECTOR2.__ctor(T) cannot deduce template function
> from argument types !()(immutable(float),const(float)) immutable
> DVECTOR2 m_UP_DIR = DVECTOR2(0f, 1f, 0f);

Here is a simple form of the same problem:

struct S
{
this(T)(double d)
{}
}

void main()
{
auto o = S(1.5);
}

Error: template deneme.S.__ctor(T) does not match any function template 
declaration
Error: template deneme.S.__ctor(T) cannot deduce template function from 
argument types !()(double)

The compiler is right: What should T be there? int? string? MyClass?

I've realized again that I don't know how to specify the template 
parameter for the constructor. The following attempt fails as the 
compiler thinks S itself is a template:

auto o = S!string(1.5);

Error: template instance S is not a template declaration, it is a struct

And if I try to be smart after the error message, this seg faults the 
compiler:

auto o = S.__ctor!string(1.5);

Ali


Re: swap doesn't work in CTFE?

2011-07-04 Thread Daniel Murphy
"bearophile"  wrote in message 
news:iut093$1bjg$1...@digitalmars.com...
> Daniel Murphy:
>
>> Same thing happens with pointers.  Reduced:
>
> Pointers to structs in CTFE will work in DMD 2.054 :-)

When they don't crash the compiler, that is.
http://d.puremagic.com/issues/show_bug.cgi?id=6250 




Re: Using a C function with command line parameters

2011-07-04 Thread Jonathan Sternberg
It's one of the applications that consumes command line arguments. So if I 
wanted
to implement this, a copy of the D strings (and null terminated) would have to 
be
made. I would also likely need to add another slot to the command line arguments
as usually the command line is null terminated for C programs.

Generally, command line arguments don't modify the parameters. But C isn't
particularly good at using const correctness.

A wrapper around glutInit would require copying the array to a C-style array,
calling the extern (C)'d function, then copying back the changes to the D side
back to a D style array. Right?


Dynamic multidimensional arrays

2011-07-04 Thread Bellum
Can anyone point me in the right direction for doing something like this 
in D:


char[][] anArray;
int rows, cols;

...

anArray = new char[rows][cols];

It isn't possible in this way because "rows cannot be read at compile 
time", which seems to me to be the point of dynamic arrays. :P


Re: Using a C function with command line parameters

2011-07-04 Thread Jacob Carlborg

On 2011-07-04 18:59, Steven Schveighoffer wrote:

On Mon, 04 Jul 2011 12:51:48 -0400, Jacob Carlborg  wrote:


On 2011-07-04 16:31, Jonathan Sternberg wrote:

glut has the function:

void glutInit( int* pargc, char** argv );

In order to use it. Since D has an ABI compatible with C, I should be
able to
write a D file with extern (C) on the glut functions. How would I
wrap this
function to be used with D arrays? Such as:

int main(string[] args)
{
glutInit( /* I don't know what to do here */ );
return 0;
}

Thanks.


It depends on what your needs are. If your not actually using the
arguments then you can pass in 0 and null, or 1 and the name of the
application.


A typical library that uses standardized arguments (i.e. parameters that
always mean the same thing across applications that use that library)
has a parameter pre-processing function such as this which "consume"
their specific arguments from the command line. The idea is, you pass
the command line to those functions, the library processes its specific
arguments, removing them from the command line array, and then all
applications using that library have a way to control the library from
the command line. I think the first one I remember having this is X and
Xt. For example, most X-based applications you can pass
--display=mysystem:0 and it uses that display. The applications simply
use a libX function that processes those args from the command line and
never have to deal with it.


As an alternative, most platforms have an API for getting the
arguments passed to an application.

Mac OS X: extern (C) char*** _NSGetEnviron();
Posix: extern (C) extern char** environ;


Those get the environment variables, not the command line arguments.


Hehe. Wonder what I was thinking. Anyway, the platforms usually do have 
an API for that, second try:


Mac OS X:
extern(C) char*** _NSGetArgv();
extern(C) int* _NSGetArgc();

Linux:
I read somewhere you could read from /proc//cmdline
Where  is the process id.


Don't know about Windows.


Windows actually does have a command line fetching function. Can't
remember what it is, but if I had to guess I'd say it was GetCommandLine :)

-Steve


Seems to be that one.

--
/Jacob Carlborg


Re: Dynamic multidimensional arrays

2011-07-04 Thread Jonathan M Davis
On 2011-07-04 23:42, Bellum wrote:
> Can anyone point me in the right direction for doing something like this
> in D:
> 
>  char[][] anArray;
>  int rows, cols;
> 
>  ...
> 
>  anArray = new char[rows][cols];
> 
> It isn't possible in this way because "rows cannot be read at compile
> time", which seems to me to be the point of dynamic arrays. :P

auto anArray = new char[][](rows, cols);

Putting the numbers directly in the brackets tries to create a static array 
once you get beyond the first dimension. So,

auto anArary = new char[4][5];

would create a dynamic array of length for with elements which are static 
arrays of length 5. If you want it to by dynamic all the way, you need to put 
the dimensions in the parens like above. Personally, I _never_ put them in the 
brackets, even when the dynamic array has just one dimension. It's just 
simpler to always put them in the parens and not worry about it.

- Jonathan M Davis