Re: this compare not using opCmp?
On Monday, April 30, 2012 07:28:16 Era Scarecrow wrote: > On Monday, 30 April 2012 at 05:22:56 UTC, Jonathan M Davis wrote: > > == uses opEquals, not opCmp. It's using Object's opEquals, > > which does a > > comparison of the references, so it's true when comparing the > > exact same > > object and false otherwise. > > Ahhh of course. Personally I think opCmp includes opEquals... At > least I only have to deal with 2 compare functions and not more. I believe that there are two major reasons why opEquals is separate: 1. Many types of objects can have equality but less than and greater than comparisons would make no sense for them. 2. It's more efficient to check for equality with opEquals than it would be with opCmp. - Jonathan M Davis
Re: this compare not using opCmp?
On Monday, 30 April 2012 at 05:22:56 UTC, Jonathan M Davis wrote: == uses opEquals, not opCmp. It's using Object's opEquals, which does a comparison of the references, so it's true when comparing the exact same object and false otherwise. Ahhh of course. Personally I think opCmp includes opEquals... At least I only have to deal with 2 compare functions and not more.
Re: struct to/from void, object to/from void
On Monday, 30 April 2012 at 05:07:04 UTC, Ali Çehreli wrote: You mean "object"? A class variable is just a handle to the class object. Class variables are implemented as pointers, so yes, they will be the size of a pointer. Since I suspect that the pointers are 4 bytes on the OP's 32-bit system, I don't see any fatness there. It is just a plain pointer. I was thinking the 'string' which was a fat pointer, but likely I misread it and assumed the size was referring to the object's contents. 4bytes would be a single pointer, so my mistake on that part. The object itself has some data that makes it behave like its actual type but I wouldn't be surprised if it contained a virtual function table pointer just like in C++. But note that the object, not the variable is fat in that sense. But unlike in C++, it only incorporates it if you add 'virtual', so the up and down casting can revert to it's previous version. I've read about it more than used it so.. //c++ - not tested.. class Base { void func() { stdout << "base!";} } bass Derived : Base { virtual void func() {stdout << "derived (virtual)";} } void main(){ //use pointers? I can't remember... Derived d = new Derived; base b = (Base) d; b.func(); //Logically should call the derived one, but since there's no virtual table, we get the base's one instead!! } Inside the derived class it's a virtual call, change it back to it's base and it loses that extra information. You may be able to up/down cast, but it's a problem in C++. One more reason I don't use C++ if I don't have to. Correction: It is actually an upcast, which does not require the explicit cast anyway. I am getting up and down backwards. My bad.. I find the following message more descriptive: assert(ba !is null, "a is not actually a BA?"); To be more pedantic, 'a' is neither an A nor a BA. It is a variable that provides access to an object through the A interface.
Re: this compare not using opCmp?
On Monday, April 30, 2012 07:09:46 Era Scarecrow wrote: > In some code I'm working on, my asserted when I've confirmed it > was correct. With the opCmp() overridden. 'this' refers to the > current object, so why doesn't the first one succeed? > > class X { >int z; > >this(int xx) { > z = xx; >} > >override int opCmp(Object y){ > X x = cast(X) y; > return z - x.z; >} > >void something(X rhs) { > assert(this.opCmp(rhs) == 0); //works fine. > assert(this == rhs); //fails? >} > } > > int main(){ > X a = new X(10); > X b = new X(10); //different objects, same compare value > a.something(b); > return 0; > } == uses opEquals, not opCmp. It's using Object's opEquals, which does a comparison of the references, so it's true when comparing the exact same object and false otherwise. - Jonathan M Davis
this compare not using opCmp?
In some code I'm working on, my asserted when I've confirmed it was correct. With the opCmp() overridden. 'this' refers to the current object, so why doesn't the first one succeed? class X { int z; this(int xx) { z = xx; } override int opCmp(Object y){ X x = cast(X) y; return z - x.z; } void something(X rhs) { assert(this.opCmp(rhs) == 0); //works fine. assert(this == rhs); //fails? } } int main(){ X a = new X(10); X b = new X(10); //different objects, same compare value a.something(b); return 0; }
Re: struct to/from void, object to/from void
On 04/29/2012 06:01 PM, Era Scarecrow wrote: > On Monday, 30 April 2012 at 00:28:15 UTC, Jason King wrote: >> myobject.sizeof returns 4 (in 32 bit DMD) for every object I've >> tested, so I'm inclined to suspect its a bog-standard pointer, >> just what I'm looking to save and retrieve. >> Anybody else want to chime in? > > I'd say that's right and wrong. Someone correct me if I'm wrong. > > The 4(bytes) is likely the fat pointer of the string. You mean "object"? A class variable is just a handle to the class object. Class variables are implemented as pointers, so yes, they will be the size of a pointer. Since I suspect that the pointers are 4 bytes on the OP's 32-bit system, I don't see any fatness there. It is just a plain pointer. > It still has to > contain information saying it's this type of object, and inheritance if > it was of another type. I believe it will be something like you have a > 16 byte header specifying the object(s) information, and then the object > data (4 bytes in this case). This is where it differs from C++ and acts > more like java. The object itself has some data that makes it behave like its actual type but I wouldn't be surprised if it contained a virtual function table pointer just like in C++. But note that the object, not the variable is fat in that sense. > A heavy part of why this is the case is not only for casting up and > down, but management of virtual functions (overloaded). Otherwise you > get into C++'s old mess of needing to explicitly saying virtual for > every function that 'MIGHT' be overloaded in the future. > > I haven't tested this, but you should get the idea. > class A {} > class BA : A{} > > //returns a BA object from it's A superclass > A test() { > return cast(A) new BA(); //cast down Correction: It is actually an upcast, which does not require the explicit cast anyway. > } > > void test2() { > A a = test(); > BA ba = cast(BA) a; //fails if we have no information, we only see class A. And that's a down cast. > assert(ba !is null, "Failed! ba not inherited from A?"); > } I find the following message more descriptive: assert(ba !is null, "a is not actually a BA?"); To be more pedantic, 'a' is neither an A nor a BA. It is a variable that provides access to an object through the A interface. Ali
Re: -lib question(s)
On Monday, 30 April 2012 at 02:49:21 UTC, Jesse Phillips wrote: However you also will need to specify the library you want to load: -L-lworld More detail. [snip] Hi Jesse, Thanks for the help, that was informative! I didn't realize I needed the load command (-L-lworld) and so I was trying to use the libworld.a file directly, thinking that dmd's -L-L search paths would handle it. Josh
Re: -lib question(s)
On Saturday, 28 April 2012 at 05:37:20 UTC, Joshua Niehus wrote: Q1) The template version of hello seems to work, but the simpleton version doesn't. What am i missing? Q2) Shouldn't I be compiling world.d with -lib and then put world.a in some linker directory? I did that but got nowhere fast. Basically I have my .a file and a bunch of lame scripts that need to use functions from it, its in a -L dir listed in my dmd.conf, but nothing compiles. Sounds like linux, you are correct that you'll want libworld.a in a path specified by -L-L However you also will need to specify the library you want to load: -L-lworld More detail. The compiler needs to know the signatures of functions it is calling. It does this by reading "header" files. In D's case source files will do. These files are searched for from your include paths which are specified with -I Once compilation is complete the compiler make a call to the linker. Linker commands are passed through with -L. The linker needs to know two things, where to find library files (defaults with /usr/lib and /usr/local/lib), and also what libraries to load. Libraries have a special naming convention which starts with 'lib' the name of the library, and an extension of .a or .so. This way you can request the library by name, -lworld, and it can be found. When using dmd you give command to be passed to the linker -L-lworld. Alternatively you could just pass the library to the compiler, libworld.a.
Re: type conversions
On Monday, April 30, 2012 01:42:38 WhatMeWorry wrote: > I'm trying to get my head around D's type conversion. What is the > best way to convert a string to a char array? Or I should say is > this the best way? > > string s = "Hello There"; > char[] c; > > c = string.dup; dup will return a mutable copy of an array. idup will return an immutable copy of an array. They will both always copy. If you want to convert without having to make a copy if the array is of the constancy that you want already (e.g. if a templated function is templated on string type, and it could be any constancy of char[]), then use std.conv.to. auto c = to!(char[])(str); If str was already char[], then it will just be returned, whereas if it's immutable(char)[], then it would dup it and return that. > Also, what is the best way to explicitly convert a string to an > int? I've been looking at Library Reference (Phobos) but I'm > stuck. Use std.conv.to: auto i = to!string("1234"); std.conv.to is what you use for pretty much any conversion. - Jonathan M Davis
Re: struct to/from void, object to/from void
On Monday, 30 April 2012 at 00:28:15 UTC, Jason King wrote: myobject.sizeof returns 4 (in 32 bit DMD) for every object I've tested, so I'm inclined to suspect its a bog-standard pointer, just what I'm looking to save and retrieve. Anybody else want to chime in? I'd say that's right and wrong. Someone correct me if I'm wrong. The 4(bytes) is likely the fat pointer of the string. It still has to contain information saying it's this type of object, and inheritance if it was of another type. I believe it will be something like you have a 16 byte header specifying the object(s) information, and then the object data (4 bytes in this case). This is where it differs from C++ and acts more like java. A heavy part of why this is the case is not only for casting up and down, but management of virtual functions (overloaded). Otherwise you get into C++'s old mess of needing to explicitly saying virtual for every function that 'MIGHT' be overloaded in the future. I haven't tested this, but you should get the idea. class A {} class BA : A{} //returns a BA object from it's A superclass A test() { return cast(A) new BA(); //cast down } void test2() { A a = test(); BA ba = cast(BA) a; //fails if we have no information, we only see class A. assert(ba !is null, "Failed! ba not inherited from A?"); }
Re: struct to/from void, object to/from void
Thanks for the rapid reply. void* opCast() { return &this; } Honestly, in my opinion, drop this. Don't make it more 'pointer-like'. Unless there's a good reason, or it makes sense (Mathematical), then don't. You keep having half the tests using regular &(address) operator; what's wrong with that? Since &thing works, I'm fine with it instead of opCast. The opCast was in the code I borrowed so I wanted to show both approaches for someone to say "this way is better" (which you did). I'm not sure how safe casting an object to void* would be, or back. If you can't avoid it, I would say make overloaded methods that do the intermediate work and make it transparent for you afterwards. myobject.sizeof returns 4 (in 32 bit DMD) for every object I've tested, so I'm inclined to suspect its a bog-standard pointer, just what I'm looking to save and retrieve. Anybody else want to chime in?
Re: type conversions
On Sunday, 29 April 2012 at 23:42:39 UTC, WhatMeWorry wrote: I'm trying to get my head around D's type conversion. What is the best way to convert a string to a char array? Or I should say is this the best way? string s = "Hello There"; char[] c; c = string.dup; Also, what is the best way to explicitly convert a string to an int? I've been looking at Library Reference (Phobos) but I'm stuck. I think this is right... import std.stdio; import std.conv; int main(string args[]){ string str = "Hello world!"; char[] c = to!(char[])(str); string num = "1234"; int i = to!int(num); writefln("%s\t- %s", typeid(str), str); writefln("%s\t- %s", typeid(num), num); writefln("%s\t- %s", typeid(c), c); writefln("%s\t- %s", typeid(i), i); return 0; }
Re: type conversions
On 4/30/12, WhatMeWorry wrote: > I'm trying to get my head around D's type conversion. What is the > best way to convert a string to a char array? Or I should say is > this the best way? > > string s = "Hello There"; > char[] c; > > c = string.dup; > Well it depends . Why do you need a char[]? If you're interfacing with C you most likely need a 0-terminated string and not a char[]. > Also, what is the best way to explicitly convert a string to an > int? import std.conv; int i = to!int("12345");
type conversions
I'm trying to get my head around D's type conversion. What is the best way to convert a string to a char array? Or I should say is this the best way? string s = "Hello There"; char[] c; c = string.dup; Also, what is the best way to explicitly convert a string to an int? I've been looking at Library Reference (Phobos) but I'm stuck.
Re: struct to/from void, object to/from void
On Sunday, 29 April 2012 at 22:35:19 UTC, Jason King wrote: I'm another of what seem to be legions of people trying to interface with OS stores that keep void * in c/c++. My particular one is Windows TLSData, but for my example I don't need any Windows code, just D. void* opCast() { return &this; } Honestly, in my opinion, drop this. Don't make it more 'pointer-like'. Unless there's a good reason, or it makes sense (Mathematical), then don't. You keep having half the tests using regular &(address) operator; what's wrong with that? Structs having no inheritance or virtual functions hold no extra information, which is one reason you can void cast them from one type or from void to their type without any issues. Casting to an object though I am not sure, but I think it won't let you unless it is able to. Besides once you have the pointer you don't really need to deference unless you want to copy the struct. I'm not sure how safe casting an object to void* would be, or back. If you can't avoid it, I would say make overloaded methods that do the intermediate work and make it transparent for you afterwards.
struct to/from void, object to/from void
I'm another of what seem to be legions of people trying to interface with OS stores that keep void * in c/c++. My particular one is Windows TLSData, but for my example I don't need any Windows code, just D. // this based on code I snagged from this group // DMD 2.059 Win 7 Home Premium 64 bit. import std.stdio: writeln; struct MyStruct { string structName; public string toString() { return structName; } void* opCast() { return &this; } } class MyObject { string oname; this(string who) { oname = who; } public string toString() { return oname; } void* opCast() { return &this; } } void main() { MyStruct test = MyStruct("Example struct"); MyStruct test2; void* temp1 = cast(void*)test; void* temp2 = &test; assert(temp1 == temp2); writeln(*cast(MyStruct*)temp1); test2 = *cast(MyStruct*)temp1; writeln(test2); auto o1 = new MyObject("Ok"); MyObject o2; temp1 = cast(void*)o1; temp2 = &o1; //assert(temp1 == temp2); // this is true for struct, // why not object? writeln(*cast(MyObject*)temp1); o2 = *cast(MyObject*)temp1; writeln(o2); } Structs seem to go both directions just fine, although something prettier than *cast(MyStruct*) would be nice for the return trip. Objects seem to require a dedicated opCast and from my ng spelunking it appears opCast is frowned upon. How would I do the to void* w/o opCast and is there a prettier way than *cast(MyThing*) to get back the original "thing" from a void *? If I get prettier code I'll post it to the FAQ on the Wiki so that you gurus can quit dealing with the question so often.
Re: restrict alias this?
On Sunday, 29 April 2012 at 17:29:03 UTC, Simen Kjaeraas wrote: On Sun, 29 Apr 2012 14:28:05 +0200, Namespace wrote: On Sunday, 29 April 2012 at 11:24:00 UTC, Simen Kjaeraas wrote: On Sun, 29 Apr 2012 10:14:09 +0200, Namespace wrote: Based on my previous thread (http://forum.dlang.org/thread/rpcqefmyqigftxsgs...@forum.dlang.org), I got the question whether it is possible to restrict "alias this"? Similar to templates function, e.g. "void foo(T)(T value) if (isNumeric!(T) ...", but it should be limited here so that it does not interact with the cast or something other. As far as I know, "alias this" is an implicit cast. And just like an explicit cast (opCast) it should be possible to restrict it. Otherwise, I have unfortunately run out of ideas how I can allow an implicit conversion. What do you mean restrict it? I mean that you can limit it similar as you can with templates. In my code i'm using "alias this" to enable an implicit conversion from any class, e.g. Foo, to Ref!Foo. Ref is an struct which checks if the value of Foo is null. If it's null a error message will let you know, that you have a problem with one of your objects (i hate the access violation message, that's the original reason for that). But if i cast with a class, that implements the implicit conversion, as in the following: [code] class A { mixin TRef!(A); } class B : A { } A a1 = new B(); B b1 = cast(B) a1.access; // <- problem [/code] the cast will implicit convert with "alias this" to Ref!B. And that isn't what i want and neither what should happen. In this case a limit to "alias this" would be great. A limitation, that "alias this" must not convert the cast to Ref!B. But that's not what happens. a1's compile-time type is A, so the compiler looks up 'access' in A, but finds nothing. So it tries the alias this, gets a Ref!A, and calls access on that. At this point, T is A, so access returns an A. Then, the compiler tries to convert that A to a B, and gets confused. This is absolutely a bug. In fact, it is the bug Jesse Phillips reported[1]. [1]: http://d.puremagic.com/issues/show_bug.cgi?id=8001 Yes, I've just noticed that. Are there already workarounds for that problem?
Re: restrict alias this?
On Sun, 29 Apr 2012 14:28:05 +0200, Namespace wrote: On Sunday, 29 April 2012 at 11:24:00 UTC, Simen Kjaeraas wrote: On Sun, 29 Apr 2012 10:14:09 +0200, Namespace wrote: Based on my previous thread (http://forum.dlang.org/thread/rpcqefmyqigftxsgs...@forum.dlang.org), I got the question whether it is possible to restrict "alias this"? Similar to templates function, e.g. "void foo(T)(T value) if (isNumeric!(T) ...", but it should be limited here so that it does not interact with the cast or something other. As far as I know, "alias this" is an implicit cast. And just like an explicit cast (opCast) it should be possible to restrict it. Otherwise, I have unfortunately run out of ideas how I can allow an implicit conversion. What do you mean restrict it? I mean that you can limit it similar as you can with templates. In my code i'm using "alias this" to enable an implicit conversion from any class, e.g. Foo, to Ref!Foo. Ref is an struct which checks if the value of Foo is null. If it's null a error message will let you know, that you have a problem with one of your objects (i hate the access violation message, that's the original reason for that). But if i cast with a class, that implements the implicit conversion, as in the following: [code] class A { mixin TRef!(A); } class B : A { } A a1 = new B(); B b1 = cast(B) a1.access; // <- problem [/code] the cast will implicit convert with "alias this" to Ref!B. And that isn't what i want and neither what should happen. In this case a limit to "alias this" would be great. A limitation, that "alias this" must not convert the cast to Ref!B. But that's not what happens. a1's compile-time type is A, so the compiler looks up 'access' in A, but finds nothing. So it tries the alias this, gets a Ref!A, and calls access on that. At this point, T is A, so access returns an A. Then, the compiler tries to convert that A to a B, and gets confused. This is absolutely a bug. In fact, it is the bug Jesse Phillips reported[1]. [1]: http://d.puremagic.com/issues/show_bug.cgi?id=8001
Re: mysql binding/wrapper?
On Saturday, 28 April 2012 at 15:30:13 UTC, simendsjo wrote: stuff/blob/master/mysql.d http://my.opera.com/run3/blog/2012/03/13/d-mysql I use it in a bank account application. It works.
Re: cannot cast
On Sunday, 29 April 2012 at 14:40:55 UTC, Jesse Phillips wrote: On Saturday, 28 April 2012 at 14:21:32 UTC, Namespace wrote: I finished my Ref/NotNull struct, but i've got a problem: If i try to cast the class, which should implicit convert to Ref!(Type) with alias this, i get the following error message: "cannot cast a1.getRef("Ref.d",72u) of type Ref!(A) to type RefTest.Ref.__unittest1.B" I would consider this a bug: http://d.puremagic.com/issues/show_bug.cgi?id=8001 Oh, that could explain a lot. Some workaround until now?
Re: cannot cast
On Saturday, 28 April 2012 at 14:21:32 UTC, Namespace wrote: I finished my Ref/NotNull struct, but i've got a problem: If i try to cast the class, which should implicit convert to Ref!(Type) with alias this, i get the following error message: "cannot cast a1.getRef("Ref.d",72u) of type Ref!(A) to type RefTest.Ref.__unittest1.B" I would consider this a bug: http://d.puremagic.com/issues/show_bug.cgi?id=8001
Re: restrict alias this?
On Sunday, 29 April 2012 at 11:24:00 UTC, Simen Kjaeraas wrote: On Sun, 29 Apr 2012 10:14:09 +0200, Namespace wrote: Based on my previous thread (http://forum.dlang.org/thread/rpcqefmyqigftxsgs...@forum.dlang.org), I got the question whether it is possible to restrict "alias this"? Similar to templates function, e.g. "void foo(T)(T value) if (isNumeric!(T) ...", but it should be limited here so that it does not interact with the cast or something other. As far as I know, "alias this" is an implicit cast. And just like an explicit cast (opCast) it should be possible to restrict it. Otherwise, I have unfortunately run out of ideas how I can allow an implicit conversion. What do you mean restrict it? I mean that you can limit it similar as you can with templates. In my code i'm using "alias this" to enable an implicit conversion from any class, e.g. Foo, to Ref!Foo. Ref is an struct which checks if the value of Foo is null. If it's null a error message will let you know, that you have a problem with one of your objects (i hate the access violation message, that's the original reason for that). But if i cast with a class, that implements the implicit conversion, as in the following: [code] class A { mixin TRef!(A); } class B : A { } A a1 = new B(); B b1 = cast(B) a1.access; // <- problem [/code] the cast will implicit convert with "alias this" to Ref!B. And that isn't what i want and neither what should happen. In this case a limit to "alias this" would be great. A limitation, that "alias this" must not convert the cast to Ref!B.
Re: restrict alias this?
On Sun, 29 Apr 2012 10:14:09 +0200, Namespace wrote: Based on my previous thread (http://forum.dlang.org/thread/rpcqefmyqigftxsgs...@forum.dlang.org), I got the question whether it is possible to restrict "alias this"? Similar to templates function, e.g. "void foo(T)(T value) if (isNumeric!(T) ...", but it should be limited here so that it does not interact with the cast or something other. As far as I know, "alias this" is an implicit cast. And just like an explicit cast (opCast) it should be possible to restrict it. Otherwise, I have unfortunately run out of ideas how I can allow an implicit conversion. What do you mean restrict it?
restrict alias this?
Based on my previous thread (http://forum.dlang.org/thread/rpcqefmyqigftxsgs...@forum.dlang.org), I got the question whether it is possible to restrict "alias this"? Similar to templates function, e.g. "void foo(T)(T value) if (isNumeric!(T) ...", but it should be limited here so that it does not interact with the cast or something other. As far as I know, "alias this" is an implicit cast. And just like an explicit cast (opCast) it should be possible to restrict it. Otherwise, I have unfortunately run out of ideas how I can allow an implicit conversion.