Re: Scale advocacy
"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
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
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
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?
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
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
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
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?
"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
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
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
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
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?
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
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
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
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
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
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?
"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
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
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
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
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