Re: string vs. w/char*
Tyro[a.c.edwards] Wrote: class TopWinClass: WinClass { this(ushort resId, HINSTANCE hInst, WNDPROC wndProc) { super(resId, hInst, wndProc); SetResIcons(resId); wc.lpszMenuName = MAKEINTRESOURCEA(resId); // [PROBLEM] } } Every access to wc.lpszMenuName after this point fails. Who accesses it? MAKEINTRESOURCEA just casts int to char* so it's an invalid pointer while still valid resource indentifier, windows can differentiate them by zeroed high word.
Re: string vs. w/char*
Kagamin Wrote: Tyro[a.c.edwards] Wrote: class TopWinClass: WinClass { this(ushort resId, HINSTANCE hInst, WNDPROC wndProc) { super(resId, hInst, wndProc); SetResIcons(resId); wc.lpszMenuName = MAKEINTRESOURCEA(resId); // [PROBLEM] } } Every access to wc.lpszMenuName after this point fails. Who accesses it? MAKEINTRESOURCEA just casts int to char* so it's an invalid pointer while still valid resource indentifier, windows can differentiate them by zeroed high word. casts ushort to char*
Re: Two questions about %a
On 2011-03-04 03:16:50 +0100, Nick Sabalausky said: I'm no floating-point expert, but I would think that the only way to get an exact representation would be to output the raw data in hex (or binary, or octal, etc): writef(0x%X, cast(ulong)1.2); That's also an option, certainly. Then I could just write it as a decimal integer, I guess. But the point of hex-literals for floats is precicely that they can represent floats exactly (even though it may not *look* like it, as in this case, because lots of digits are required to approximate the decimal value 1.2). So using those shold be safe -- and perhaps more easily read on other platforms, for example (byte order), or into floats with other precisions or the like. Thanks for the suggestion, though :) -- Magnus Lie Hetland http://hetland.org
Re: Iterating a typle tuple of templates
Jacob Carlborg: Maybe you can try something like typeof(t2) in the foreach. If you mean code like this: import std.typetuple; int foo(T)(T x) { return x; } void main() { alias TypeTuple!(foo, foo) t2; foreach (i, t; typeof(t2)) { pragma(msg, t); assert(t2[i](i) == i); // OK //assert(t(i) == i); // Not OK } } It seems t is not useful... Is all this Bugzilla-worthy? Thank you, bye, bearophile
Re: Iterating a typle tuple of templates
bearophile Wrote: It seems t is not useful... Yep, foreach over tuples is kinda messed up. Same with reference tuple foreach: http://d.puremagic.com/issues/show_bug.cgi?id=2411 Direct access doesn't work but accessing via [i] does.
Overriding in operator
I'm writing a collection with functionality for membership checking. I thought it would be nice to use the in operator. In the docs for std.collections I surmise that this is the standard way to go. From the source code, I see there's no special opIn, but that it can be done with the more general... bool opBinary(string op)(T k) if (op == in) { ... } Here T is, of course, a compile-time argument of the surrounding struct or class. So ... this is used in the the Phobos source in the DMD 2.052 distro (if I'm not mistaken), but I can't get dmd 2.052 to accept it? I keep getting the error message Error: rvalue of in expression must be an associative array, not Foo!(uint). I guess either that this is a recent feature -- I didn't see it mentioned in Andrei's book -- and that my Phobos source is too recent for my dmd ... or that I'm doing something wrong elsewhere in my code, preventing the operator overloading to take force. Suggestions/solutions?-) -- Magnus Lie Hetland http://hetland.org
Re: Overriding in operator
Am 04.03.2011 17:01, schrieb Magnus Lie Hetland: I'm writing a collection with functionality for membership checking. I thought it would be nice to use the in operator. In the docs for std.collections I surmise that this is the standard way to go. From the source code, I see there's no special opIn, but that it can be done with the more general... bool opBinary(string op)(T k) if (op == in) { ... } Here T is, of course, a compile-time argument of the surrounding struct or class. So ... this is used in the the Phobos source in the DMD 2.052 distro (if I'm not mistaken), but I can't get dmd 2.052 to accept it? I keep getting the error message Error: rvalue of in expression must be an associative array, not Foo!(uint). I guess either that this is a recent feature -- I didn't see it mentioned in Andrei's book -- and that my Phobos source is too recent for my dmd ... or that I'm doing something wrong elsewhere in my code, preventing the operator overloading to take force. Suggestions/solutions?-) If you try to use it in the manner of `something in classWhichDefinesThisOpBinary` then it doesn't work because operator overloading normally overloads on the left operand (ie something). Use opBinaryRight(string op)(...) if(...) to get it working. Mafi
Overriding iteration
From what I understand, when you override iteration, you can either implement the basic range primitives, permitting foreach to destructively iterate over your object, or you can implement a custom method that's called, and that must perform the iteration. The destructiveness of the first option can, of course, be mitigated if you use a struct rather than a class, and make sure that anything that would be destroyed by popFront() is copied. What I'm wondering is whether there is a way to do what Python does -- to construct/return an iterator (or, in this case, a range) that is used during the iteration, rather than the object itself? I'm thinking about when you iterate directly over the object here. As far as I can see, the solution used in the std.container is to use opSlice() for this functionality. In other words, in order to iterate over container foo, you need to use foreach(e; foo[])? Is there no way to get this functionality directly (i.e., for foreach(e; foo))? -- Magnus Lie Hetland http://hetland.org
Re: Overriding in operator
On 2011-03-04 17:06:29 +0100, Mafi said: If you try to use it in the manner of `something in classWhichDefinesThisOpBinary` then it doesn't work because operator overloading normally overloads on the left operand (ie something). Use opBinaryRight(string op)(...) if(...) to get it working. Aaah. That makes sense. And works. *But*: I copied my code from Phobos :D If you search for in, with the quotes, in std/container.d, you'll find two occurrences. The actual live use (in RedBlackTree) is opBinaryRight (which makes sense), but in the dummy class, TotalContainer, which is described as an unimplemented container that illustrates a host of primitives that a container may define, uses just opBinary. The doc-comment says that $(D k in container) returns true if the given key is in the container. So ... a bug, I guess? (One that isn't really executed -- but still...) Worth reporting? Anwyay: Thanks for the clarification :) -- Magnus Lie Hetland http://hetland.org
Re: Overriding in operator
Magnus Lie Hetland mag...@hetland.org wrote: On 2011-03-04 17:06:29 +0100, Mafi said: If you try to use it in the manner of `something in classWhichDefinesThisOpBinary` then it doesn't work because operator overloading normally overloads on the left operand (ie something). Use opBinaryRight(string op)(...) if(...) to get it working. Aaah. That makes sense. And works. *But*: I copied my code from Phobos :D If you search for in, with the quotes, in std/container.d, you'll find two occurrences. The actual live use (in RedBlackTree) is opBinaryRight (which makes sense), but in the dummy class, TotalContainer, which is described as an unimplemented container that illustrates a host of primitives that a container may define, uses just opBinary. The doc-comment says that $(D k in container) returns true if the given key is in the container. So ... a bug, I guess? (One that isn't really executed -- but still...) Worth reporting? Anwyay: Thanks for the clarification :) Definitely report it. -- Simen
Re: Overriding iteration
Magnus Lie Hetland mag...@hetland.org wrote: From what I understand, when you override iteration, you can either implement the basic range primitives, permitting foreach to destructively iterate over your object, or you can implement a custom method that's called, and that must perform the iteration. The destructiveness of the first option can, of course, be mitigated if you use a struct rather than a class, and make sure that anything that would be destroyed by popFront() is copied. What I'm wondering is whether there is a way to do what Python does -- to construct/return an iterator (or, in this case, a range) that is used during the iteration, rather than the object itself? I'm thinking about when you iterate directly over the object here. As far as I can see, the solution used in the std.container is to use opSlice() for this functionality. In other words, in order to iterate over container foo, you need to use foreach(e; foo[])? Is there no way to get this functionality directly (i.e., for foreach(e; foo))? foreach ( e; foo ) {} Should work. I believe there is a bug already filed on it not working. -- Simen
Re: Iterating a typle tuple of templates
bearophile bearophileh...@lycos.com wrote: Jacob Carlborg: Maybe you can try something like typeof(t2) in the foreach. If you mean code like this: import std.typetuple; int foo(T)(T x) { return x; } void main() { alias TypeTuple!(foo, foo) t2; foreach (i, t; typeof(t2)) { pragma(msg, t); assert(t2[i](i) == i); // OK //assert(t(i) == i); // Not OK } } It seems t is not useful... Is all this Bugzilla-worthy? Yes. -- Simen
Re: Overriding iteration
On Fri, 04 Mar 2011 11:29:08 -0500, Magnus Lie Hetland mag...@hetland.org wrote: From what I understand, when you override iteration, you can either implement the basic range primitives, permitting foreach to destructively iterate over your object, or you can implement a custom method that's called, and that must perform the iteration. The destructiveness of the first option can, of course, be mitigated if you use a struct rather than a class, and make sure that anything that would be destroyed by popFront() is copied. What I'm wondering is whether there is a way to do what Python does -- to construct/return an iterator (or, in this case, a range) that is used during the iteration, rather than the object itself? That's exactly how to do it. I'm thinking about when you iterate directly over the object here. As far as I can see, the solution used in the std.container is to use opSlice() for this functionality. In other words, in order to iterate over container foo, you need to use foreach(e; foo[])? Is there no way to get this functionality directly (i.e., for foreach(e; foo))? I believe someone has filed a bug for this, because TDPL has said this should be possible. But with the current compiler, you can use opApply to achieve that behavior. -Steve
Re: Overriding iteration
Simen kjaeraas simen.kja...@gmail.com wrote: Magnus Lie Hetland mag...@hetland.org wrote: From what I understand, when you override iteration, you can either implement the basic range primitives, permitting foreach to destructively iterate over your object, or you can implement a custom method that's called, and that must perform the iteration. The destructiveness of the first option can, of course, be mitigated if you use a struct rather than a class, and make sure that anything that would be destroyed by popFront() is copied. What I'm wondering is whether there is a way to do what Python does -- to construct/return an iterator (or, in this case, a range) that is used during the iteration, rather than the object itself? I'm thinking about when you iterate directly over the object here. As far as I can see, the solution used in the std.container is to use opSlice() for this functionality. In other words, in order to iterate over container foo, you need to use foreach(e; foo[])? Is there no way to get this functionality directly (i.e., for foreach(e; foo))? foreach ( e; foo ) {} Should work. I believe there is a bug already filed on it not working. Found it: http://d.puremagic.com/issues/show_bug.cgi?id=5605 -- Simen
Re: Overriding in operator
On 03/04/2011 05:01 PM, Magnus Lie Hetland wrote: I'm writing a collection with functionality for membership checking. I thought it would be nice to use the in operator. In the docs for std.collections I surmise that this is the standard way to go. From the source code, I see there's no special opIn, but that it can be done with the more general... bool opBinary(string op)(T k) if (op == in) { ... } Here T is, of course, a compile-time argument of the surrounding struct or class. So ... this is used in the the Phobos source in the DMD 2.052 distro (if I'm not mistaken), but I can't get dmd 2.052 to accept it? I keep getting the error message Error: rvalue of in expression must be an associative array, not Foo!(uint). I guess either that this is a recent feature -- I didn't see it mentioned in Andrei's book -- and that my Phobos source is too recent for my dmd ... or that I'm doing something wrong elsewhere in my code, preventing the operator overloading to take force. Suggestions/solutions?-) Didn't even know 'in' can be defined with opBinary... I use opIn_r ('r' for right side, since the container stand on the right of the expression) everywhere, and it works fine. Denis -- _ vita es estrany spir.wikidot.com
Re: Overriding iteration
On 03/04/2011 05:43 PM, Steven Schveighoffer wrote: On Fri, 04 Mar 2011 11:29:08 -0500, Magnus Lie Hetland mag...@hetland.org wrote: From what I understand, when you override iteration, you can either implement the basic range primitives, permitting foreach to destructively iterate over your object, or you can implement a custom method that's called, and that must perform the iteration. The destructiveness of the first option can, of course, be mitigated if you use a struct rather than a class, and make sure that anything that would be destroyed by popFront() is copied. What I'm wondering is whether there is a way to do what Python does -- to construct/return an iterator (or, in this case, a range) that is used during the iteration, rather than the object itself? That's exactly how to do it. I'm thinking about when you iterate directly over the object here. As far as I can see, the solution used in the std.container is to use opSlice() for this functionality. In other words, in order to iterate over container foo, you need to use foreach(e; foo[])? Is there no way to get this functionality directly (i.e., for foreach(e; foo))? I believe someone has filed a bug for this, because TDPL has said this should be possible. But with the current compiler, you can use opApply to achieve that behavior. opApply should work but it is supposed to be slower. Defining range primitives directly on the object/container cannot work as of now, unfortunately, because of a pair of bugs (conflicts in formatValue template definitions between struct/class on one hand and ranges on the other). Denis -- _ vita es estrany spir.wikidot.com
Re: Overriding iteration
On Friday, March 04, 2011 09:13:34 spir wrote: On 03/04/2011 05:43 PM, Steven Schveighoffer wrote: On Fri, 04 Mar 2011 11:29:08 -0500, Magnus Lie Hetland mag...@hetland.org wrote: From what I understand, when you override iteration, you can either implement the basic range primitives, permitting foreach to destructively iterate over your object, or you can implement a custom method that's called, and that must perform the iteration. The destructiveness of the first option can, of course, be mitigated if you use a struct rather than a class, and make sure that anything that would be destroyed by popFront() is copied. What I'm wondering is whether there is a way to do what Python does -- to construct/return an iterator (or, in this case, a range) that is used during the iteration, rather than the object itself? That's exactly how to do it. I'm thinking about when you iterate directly over the object here. As far as I can see, the solution used in the std.container is to use opSlice() for this functionality. In other words, in order to iterate over container foo, you need to use foreach(e; foo[])? Is there no way to get this functionality directly (i.e., for foreach(e; foo))? I believe someone has filed a bug for this, because TDPL has said this should be possible. But with the current compiler, you can use opApply to achieve that behavior. opApply should work but it is supposed to be slower. Defining range primitives directly on the object/container cannot work as of now, unfortunately, because of a pair of bugs (conflicts in formatValue template definitions between struct/class on one hand and ranges on the other). You don't _want_ range primitives directly on the container. That would mean that everything in your container goes away when you process it. Every popFront() call would be removing an element from your container. So, for insteance, you try and call find() on your container and everything before what you were looking isn't in the container anymore - and if it isn't there at all, you have an empty container. You _want_ to have a separate type which is a slice of our container and has the range primitives. Now, it could very well be that foreach(v; container) should be calling opSlice on the container, allowing you to feed the container to foreach directly instead of having to slice it yourself foreach(v; container[]) but that's just syntactic sugar. You don't want to actually treat your container like a range. Ranges should be slices of containers, not containers themselves. - Jonathan M Davis
Re: Overriding iteration
On Fri, 04 Mar 2011 12:13:34 -0500, spir denis.s...@gmail.com wrote: On 03/04/2011 05:43 PM, Steven Schveighoffer wrote: But with the current compiler, you can use opApply to achieve that behavior. opApply should work but it is supposed to be slower. It depends on the application and aggregate you are trying to iterate. If inlining is possible, ranges can be extremely fast. However, there are certain applications that are better suited or only work with opApply: * iterating polymorphic types (i.e. classes or interfaces) * iterating non-linearly (e.g. iterating a tree) * iterating multiple items in foreach (i.e. foreach(i, v; arr) ) In addition, LDC is able to inline opApply delegates that are compiler-generated, making opApply pretty much as fast as a range iteration. I hope some day dmd can do this too. Defining range primitives directly on the object/container cannot work as of now, unfortunately, because of a pair of bugs (conflicts in formatValue template definitions between struct/class on one hand and ranges on the other). It is not a good idea to define range primitives on a container. This would mean that iterating the container destroys the data. What you want is a range on the container, and to iterate that range. Think of a range as a view of the data in the container. Think of the container as the owner of the data. A confusing aspect is that builtin arrays are often thought of as containers. They are not containers, they are ranges. The owner of the data is actually the GC. -Steve
Non-Virtual Interfaces
I'm trying to use NVI idiom but i keep getting errors from dmd. This is my setup: module test; import std.stdio; interface IBase { void foo(); void bar(); } interface IBar : IBase { final void bar() { writefln(IBar.bar()); } } class Foo : IBar { void foo() { writefln(Foo.foo()); } } void main() { Foo foo = new Foo(); foo.foo(); } When I try to compile it i get test.d(16): Error: class test.Foo interface function IBar.bar isn't implemented And if I try to define bar() in Foo i receive test.d(22): Error: function test.Foo.bar cannot override final function IBar.test.IBar.bar which is expected since IBar.bar() is final. So, am I missing some point about NVIs here or is it just not yet implemented in dmd?
Re: Overriding iteration
On 2011-03-04 17:46:39 +0100, Simen kjaeraas said: Simen kjaeraas simen.kja...@gmail.com wrote: [snip] Found it: http://d.puremagic.com/issues/show_bug.cgi?id=5605 Oo -- nice :) (That it should work, that is; not that it doesn't ;) -- Magnus Lie Hetland http://hetland.org
Re: Overriding in operator
On 2011-03-04 18:08:08 +0100, spir said: Didn't even know 'in' can be defined with opBinary... I use opIn_r ('r' for right side, since the container stand on the right of the expression) everywhere, and it works fine. Huh. Cool. Works like a charm. Seems cleaner like the opBinaryRight solution, really. I just didn't know of it :) -- Magnus Lie Hetland http://hetland.org
Re: Non-Virtual Interfaces
On Fri, 04 Mar 2011 05:17:00 -0500, Aleksandar Ružičić ruzicic.aleksan...@gmail.com wrote: I'm trying to use NVI idiom but i keep getting errors from dmd. This is my setup: module test; import std.stdio; interface IBase { void foo(); void bar(); } interface IBar : IBase { final void bar() { writefln(IBar.bar()); } } class Foo : IBar { void foo() { writefln(Foo.foo()); } } void main() { Foo foo = new Foo(); foo.foo(); } When I try to compile it i get test.d(16): Error: class test.Foo interface function IBar.bar isn't implemented And if I try to define bar() in Foo i receive test.d(22): Error: function test.Foo.bar cannot override final function IBar.test.IBar.bar which is expected since IBar.bar() is final. So, am I missing some point about NVIs here or is it just not yet implemented in dmd? The traditional explanation of NVI is that the final function is never virtual. In your case, bar must be virtual at the IBase level, so it must go in the vtable. I'm unsure whether this is intended to be a bug or a feature. What you may want to consider is an abstract class instead of NVI, as long as you don't need multiple inheritance, it should be fine. -Steve
Re: Overriding iteration
On 2011-03-04 19:06:34 +0100, Jonathan M Davis said: On Friday, March 04, 2011 09:13:34 spir wrote: On 03/04/2011 05:43 PM, Steven Schveighoffer wrote: [snip] opApply should work but it is supposed to be slower. Defining range primitives directly on the object/container cannot work as of now, unfortunately, because of a pair of bugs (conflicts in formatValue template definitions between struct/class on one hand and ranges on the other). You don't _want_ range primitives directly on the container. That would mean that everything in your container goes away when you process it. That was the point of my original question, yes :) In TDPL, where Andrei discusses overloading foreach, he has two main examples -- one using opApply, and one using such a self-destructive container. I think (as I said in my post) that what saves that list is that it's a struct, so it's copied by the initial assignment of the foreach statement. You _want_ to have a separate type which is a slice of our container and has the range primitives. Exactly. That was what I was asking for. Now, it could very well be that foreach(v; container) should be calling opSlice on the container, allowing you to feed the container to foreach directly instead of having to slice it yourself foreach(v; container[]) but that's just syntactic sugar. Sure. And judging from the other responses (and from TDPL), the fact that this doesn't currently work is just a bug. You don't want to actually treat your container like a range. Ranges should be slices of containers, not containers themselves. Well, it would still be nice to have things be consistent -- and in order for the opSlice approach to be consistent with the opApply approach (so a client needn't know how iteration is implemented for a given container), it seems reasonable to me to have foreach directly run on a slice of your container (i.e., implicitly calling []). But as this seems to be the way it is (save for the current bug), I guess it's sort of a moot point. I certainly agree with your point, though. In Python, too, iterators (i.e., ranges) and iterables (i.e., containers) are separate concepts. You can iterate over an iterable, and the loop then automatically extracts an iterator. As this is The Way to Go, it makes sense to me that it's automatic/implicit. -- Magnus Lie Hetland http://hetland.org
C const
I'm not quite sure how to wrap c's const. This page, http://www.digitalmars.com/d/2.0/htomodule.html, says: D has const as a type modifier. void foo(const int *p, char *const q); becomes: void foo(const int* p, const char* q); But D's const is transitive - there are no const pointers to mutable types in D. When encountering such in C code, simply drop the const. So const on basic types should be const in D too. It also says char const* q. Is const char* the same thing in C? But this page, http://www.digitalmars.com/d/2.0/interfaceToC.html, says: There are no const or volatile type modifiers in D. To declare a C function that uses those type modifiers, just drop those keywords from the declaration. So all const modifiers should be dropped everywhere..? And should the const be dropped here? struct somestruct { const struct otherstruct; }
Re: Non-Virtual Interfaces
On Friday, March 04, 2011 02:17:00 Aleksandar Ružičić wrote: I'm trying to use NVI idiom but i keep getting errors from dmd. This is my setup: module test; import std.stdio; interface IBase { void foo(); void bar(); } interface IBar : IBase { final void bar() { writefln(IBar.bar()); } } class Foo : IBar { void foo() { writefln(Foo.foo()); } } void main() { Foo foo = new Foo(); foo.foo(); } When I try to compile it i get test.d(16): Error: class test.Foo interface function IBar.bar isn't implemented And if I try to define bar() in Foo i receive test.d(22): Error: function test.Foo.bar cannot override final function IBar.test.IBar.bar which is expected since IBar.bar() is final. So, am I missing some point about NVIs here or is it just not yet implemented in dmd? In NVI, you have a public, non-virtual function which calls a private one which is then overridden by a derived class (or in this case, a class which implements the interface). So, the API is non-virtual, but the functionality is overridden. It gives you the ability to enforce that certain things happen when the function is called (such as checking something about the parameters or enforcing that a set of functions are always called in a particular order), but the actual functionality is still overridden. In D, the public function would have to be final to make it non-virtual/non- overridable, and the function it calls would have to be protected, since you can't override private functions ( http://d.puremagic.com/issues/show_bug.cgi?id=4542 ). In this case, you're trying to override final functions, which doens't work at all. However, if you're not trying to do anything other than call the implemented function (you're certainly not here), then there's no point to NVI. Just use a normal, public interface function or make the base class of your class abstract and put the function's declaration there. - Jonathan M Davis
Wrapping C that uses compiler extensions
This code confuses me... It's from the c mysql windows dll, libmysql.dll. size_t (*snprintf)(struct charset_info_st *, char *to, size_t n, const char *fmt, ...) ATTRIBUTE_FORMAT_FPTR(printf, 4, 5); #ifndef _my_attribute_h #define _my_attribute_h /* Disable __attribute__() on gcc 2.7, g++ 3.4, and non-gcc compilers. Some forms of __attribute__ are actually supported in earlier versions of g++, but we just disable them all because we only use them to generate compilation warnings. */ #ifndef __attribute__ # if !defined(__GNUC__) # define __attribute__(A) # elif GCC_VERSION 2008 # define __attribute__(A) # elif defined(__cplusplus) GCC_VERSION 3004 # define __attribute__(A) # endif #endif /* __attribute__((format(...))) is only supported in gcc = 2.8 and g++ = 3.4 But that's already covered by the __attribute__ tests above, so this is just a convenience macro. */ #ifndef ATTRIBUTE_FORMAT # define ATTRIBUTE_FORMAT(style, m, n) __attribute__((format(style, m, n))) #endif /* __attribute__((format(...))) on a function pointer is not supported until gcc 3.1 */ #ifndef ATTRIBUTE_FORMAT_FPTR # if (GCC_VERSION = 3001) # define ATTRIBUTE_FORMAT_FPTR(style, m, n) ATTRIBUTE_FORMAT(style, m, n) # else # define ATTRIBUTE_FORMAT_FPTR(style, m, n) # endif /* GNUC = 3.1 */ #endif #endif
Re: Overriding iteration
On 03/04/2011 07:06 PM, Jonathan M Davis wrote: On Friday, March 04, 2011 09:13:34 spir wrote: On 03/04/2011 05:43 PM, Steven Schveighoffer wrote: On Fri, 04 Mar 2011 11:29:08 -0500, Magnus Lie Hetlandmag...@hetland.org wrote: From what I understand, when you override iteration, you can either implement the basic range primitives, permitting foreach to destructively iterate over your object, or you can implement a custom method that's called, and that must perform the iteration. The destructiveness of the first option can, of course, be mitigated if you use a struct rather than a class, and make sure that anything that would be destroyed by popFront() is copied. What I'm wondering is whether there is a way to do what Python does -- to construct/return an iterator (or, in this case, a range) that is used during the iteration, rather than the object itself? That's exactly how to do it. I'm thinking about when you iterate directly over the object here. As far as I can see, the solution used in the std.container is to use opSlice() for this functionality. In other words, in order to iterate over container foo, you need to use foreach(e; foo[])? Is there no way to get this functionality directly (i.e., for foreach(e; foo))? I believe someone has filed a bug for this, because TDPL has said this should be possible. But with the current compiler, you can use opApply to achieve that behavior. opApply should work but it is supposed to be slower. Defining range primitives directly on the object/container cannot work as of now, unfortunately, because of a pair of bugs (conflicts in formatValue template definitions between struct/class on one hand and ranges on the other). You don't _want_ range primitives directly on the container. That would mean that everything in your container goes away when you process it. Every popFront() call would be removing an element from your container. So, for insteance, you try and call find() on your container and everything before what you were looking isn't in the container anymore - and if it isn't there at all, you have an empty container. You _want_ to have a separate type which is a slice of our container and has the range primitives. Certainly, as long as, on an array-like container, you implement popFront as this = this[1..$]; or this.elements = this.elements[1..$]; then, yes, iterating on it shrinks it. (Note this works only on array-like containers; how would you shrink a tree?) But I prefere using a private index an have popFront do: ++ this.index; This is a more general iteration mechanism solution, based on current state of the object beeing iterated on. For many kinds of sequences, you needs state anyway. How else iterate over the sequence of multiples of 3, or squares of natural numbers? Now, it could very well be that foreach(v; container) should be calling opSlice on the container, allowing you to feed the container to foreach directly instead of having to slice it yourself foreach(v; container[]) but that's just syntactic sugar. You don't want to actually treat your container like a range. Ranges should be slices of containers, not containers themselves. I agree slices should be an alternate iteration mechanism (as said in TDPL). But one cannot slice a tree that easily :-) (where's my chain saw?) Denis -- _ vita es estrany spir.wikidot.com
Re: Overriding in operator
On 03/04/2011 10:41 AM, Magnus Lie Hetland wrote: On 2011-03-04 18:08:08 +0100, spir said: Didn't even know 'in' can be defined with opBinary... I use opIn_r ('r' for right side, since the container stand on the right of the expression) everywhere, and it works fine. Huh. Cool. Works like a charm. Seems cleaner like the opBinaryRight solution, really. I just didn't know of it :) It can be seen on the D1 documentation: http://www.digitalmars.com/d/1.0/operatoroverloading.html That is (or will be) deprecated in D2. Ali
Re: Wrapping C that uses compiler extensions
simendsjo wrote: This code confuses me... It's from the c mysql windows dll, libmysql.dll. size_t (*snprintf)(struct charset_info_st *, char *to, size_t n, const char *fmt, ...) ATTRIBUTE_FORMAT_FPTR(printf, 4, 5); You can safely ignore the “ATTRIBUTE_FORMAT_FPTR(printf, 4, 5)”. All it does is that it enables the compiler to check the format string against the variable arguments and generate a warning if they do not match. Jerome -- mailto:jeber...@free.fr http://jeberger.free.fr Jabber: jeber...@jabber.fr signature.asc Description: OpenPGP digital signature
Dupping in a nothrow function?
It's now OK to create a new array in a nothrow function, but it seems dup is not allowed: nothrow void foo(int[] a) { a.dup; } void main() {} Errors with dmd 2.052, is this correct? test.d(2): Error: _adDupT is not nothrow test.d(1): Error: function test.foo 'foo' is nothrow yet may throw Bye, bearophile
Re: Dupping in a nothrow function?
Simen kjaeraas: It's probably correct that _adDupT is not nothrow. It is also wrong that it shouldn't be. I was about to write a bug report regarding allowing dupping in nothrow functions, because this is now allowed, and I think this is the same thing as doing a dup: nothrow void foo(int[] a) { auto b = new int[a.length]; b[] = a[]; } void main() {} Bye, bearophile
Re: Dupping in a nothrow function?
bearophile bearophileh...@lycos.com wrote: Simen kjaeraas: It's probably correct that _adDupT is not nothrow. It is also wrong that it shouldn't be. I was about to write a bug report regarding allowing dupping in nothrow functions, because this is now allowed, and I think this is the same thing as doing a dup: nothrow void foo(int[] a) { auto b = new int[a.length]; b[] = a[]; } void main() {} Not sure it's doing the exact same thing, but in essence, it is. It's a bug, for sure. -- Simen
Help learning how to interface with c(++)
I can't seem to get this to work right: gcc -m32 -shared -fPIC Test.cpp -o libTest.so g++ -m32 test_c.cpp -L. -lTest -o test_c wine htod.exe Test.h Test.d dmd test_d.d Test.d -L-L. -L-lTest -oftest_d test_d.o: In function `_Dmain': Test.d:(.text._Dmain+0x20): undefined reference to `increment' collect2: ld returned 1 exit status --- errorlevel 1 make: *** [test_d] Error 1 The resulting test_c binary from g++ works as intented (With either LD_LIBRARY_PATH=. or LD_RUN_PATH=.): $ ./test_c Count = 0 Count = 1 $ ldd test_c linux-gate.so.1 = (0x00ad1000) libTest.so (0x005b9000) libstdc++.so.6 = /usr/lib/libstdc++.so.6 (0x4970f000) libm.so.6 = /lib/libm.so.6 (0x4955b000) libgcc_s.so.1 = /lib/libgcc_s.so.1 (0x49587000) libc.so.6 = /lib/libc.so.6 (0x493ab000) /lib/ld-linux.so.2 (0x4938a000) Any ideas on what I'm doing wrong here? I've dropbox-ed the code if it's helpful. http://dl.dropbox.com/u/12135920/kai_test_c_interface.zip -Kai Meyer
Const struct assign error messages
This is a little wrong D2 program: void bar(const int data) { auto d = data; d = data; } void main() {} With the error message DMD gives it's easy to understand the error and fix it: test.d(3): Error: variable test.bar.d cannot modify const This is a similar program that uses a Tuple instead of an int: import std.typecons; alias Tuple!(int) Foo; void bar(const Foo data) { auto d = data; d = data; } void main() {} But now the errors given are not so easy to understand: test.d(5): Error: template std.typecons.Tuple!(int).Tuple.opAssign(R) if (isTuple!(R)) does not match any function template declaration test.d(5): Error: template std.typecons.Tuple!(int).Tuple.opAssign(R) if (isTuple!(R)) cannot deduce template function from argument types !()(const(Tuple!(int))) Being that d a const Foo struct, that you can never be assigned to, can't DMD give a nicer error message, like in the first program? Bye, bearophile
Re: Wrapping C that uses compiler extensions
On 04.03.2011 22:42, Jérôme M. Berger wrote: int main(string[] args) { auto s1 =(); // MH MH auto s2 =(); // OK s2.c =ull; // OK return 0; } Is part of your message gone? You can safely ignore the “ATTRIBUTE_FORMAT_FPTR(printf, 4, 5)”. That I understood :) Thanks!
Re: C const
On 04.03.2011 23:10, Jesse Phillips wrote: simendsjo Wrote: So all const modifiers should be dropped everywhere..? And should the const be dropped here? struct somestruct { const struct otherstruct; } All in all the real answer comes down to, is the data modified. Since C makes no guarantees you must only declare things const if you know the library will abide by it. In the case above I think you have to drop it. Remember that const/immutable, and other attributes/properties aren't going to change the ABI so dropping them will be safer then leaving them. Thanks. Does this apply to all uses of const, or just complex members?
Re: Const struct assign error messages
On Friday, March 04, 2011 15:19:22 bearophile wrote: This is a little wrong D2 program: void bar(const int data) { auto d = data; d = data; } void main() {} With the error message DMD gives it's easy to understand the error and fix it: test.d(3): Error: variable test.bar.d cannot modify const This is a similar program that uses a Tuple instead of an int: import std.typecons; alias Tuple!(int) Foo; void bar(const Foo data) { auto d = data; d = data; } void main() {} But now the errors given are not so easy to understand: test.d(5): Error: template std.typecons.Tuple!(int).Tuple.opAssign(R) if (isTuple!(R)) does not match any function template declaration test.d(5): Error: template std.typecons.Tuple!(int).Tuple.opAssign(R) if (isTuple!(R)) cannot deduce template function from argument types !()(const(Tuple!(int))) Being that d a const Foo struct, that you can never be assigned to, can't DMD give a nicer error message, like in the first program? Well, you just added a template into the mix. That complicates things considerably. It's going to have to actually instantiate the templated opAssign before it will have code to compare similar to the first situation. And since the template constraint is failing, the template doesn't get instantiated and so you don't get the nice error. I don't think that there's anything that the compiler can really do about that. If you adjusted the template constraint, you'd likely just get an error in compiling opAssign and that error would be in std.typecons, not your code, so it would make it lookng like std.typecons was broken rather than your code, and it would probably be much harder to track down, since I don't think that it would tell you which line of your code is causing the problem. So, while I can see while you'd want a better error message, I don't think that you can do it with templated function. The way templates work just doesn't lend itself to doing what you want. You'd have to be able to instantiate an invalid template, which you obviously can't do. - Jonathan M Davis
Re: Non-Virtual Interfaces
What you may want to consider is an abstract class instead of NVI, as long as you don't need multiple inheritance, it should be fine. -Steve Well, I've decided to give NVI a try just because multiple inheritance would be best way to do what I want (aldo I hate that feature of C++ and just don't use it) but it seems I can't do it with a NVI either... So back to the drawing board for me :) thanks for reply - Aleksandar
Re: Non-Virtual Interfaces
In D, the public function would have to be final to make it non-virtual/non- overridable, and the function it calls would have to be protected, since you can't override private functions ( http://d.puremagic.com/issues/show_bug.cgi?id=4542 ). In this case, you're trying to override final functions, which doens't work at all. Well I don't try to override final function, I know it cannot be done :) I've just tried to override bar() in Foo when compiler told me that I don't have that function implemented and I received message that it cannot be overriden, as I've expected.. However, if you're not trying to do anything other than call the implemented function (you're certainly not here), then there's no point to NVI. Just use a normal, public interface function or make the base class of your class abstract and put the function's declaration there. - Jonathan M Davis That was just an example, what was my goal was is to have setup like this: interface IEvent { EventType type(); } interface IEventListener { void handle(IEvent event); } class MyEvent : IEvent { this(bool flag) { this.flag = flag; } EventType type() { return EventType.MyEvent; } bool isFlag() { return flag; } private: bool flag; } interface IMyEventListener : IEventListener { void onFlag(MyEvent event); void onNotFlag(MyEvent event); final void handle(IEvent event) { MyEvent e = cast(MyEvent) event; if (e !is null) { if (e.isFlag()) { onFlag(e); } else { onNotFlag(e); } } } } which would allow me to have a class that can listen for different events at the same time, but it seems that to be able to do that I'd have to move handling routine into the event class..
Re: Const struct assign error messages
Jonathan M Davis: Well, you just added a template into the mix. Right. The opAssign of Tuple is: void opAssign(R)(R rhs) if (isTuple!R) And since the template constraint is failing, This little test program shows that the template constraint of opAssign isn't needed to produce the same two error messages: struct Foo { int x; void opAssign(R)(R other) { //x = other.x; } } void bar(const Foo data) { auto d = data; d = data; // line 9 } void main() {} test.d(9): Error: template test.Foo.opAssign(R) does not match any function template declaration test.d(9): Error: template test.Foo.opAssign(R) cannot deduce template function from argument types !()(const(Foo)) The semantics of opAssign() is to assign something to the struct, even if opAssign() is templated. So I think the compiler has enough information to give a nicer error message if a struct with opAssign is const. Thank you for your answers, bye, bearophile
Template type parameters with their own type parameters
I have a function that I think should look something like this: MyStruct!T myFunc(T)(MyStruct!T x, ...) { ... return MyStruct!T(...); } and the closest I can get to is: T myFunc(T)(T x, ...) { ... return T(...); } which works, but doesn't make clear the intended use and gets in the way of overloading. How can I express the intent of the first version.
in/out with -release
I have an 'enforce' function call in an 'in' block for a function. When I compile with -release -O -inline, the in/out blocks appear to be skipped. It's a simple verification for a dynamic array to not have a length of 0. In debug mode, the test condition hits the enforce in the 'in' block, but in release mode it does not. In both release and debug mode, the same exact enforce function works properly. So am I to understand that -release will skip in/out blocks entirely?
Re: in/out with -release
On Friday 04 March 2011 20:14:32 Kai Meyer wrote: I have an 'enforce' function call in an 'in' block for a function. When I compile with -release -O -inline, the in/out blocks appear to be skipped. It's a simple verification for a dynamic array to not have a length of 0. In debug mode, the test condition hits the enforce in the 'in' block, but in release mode it does not. In both release and debug mode, the same exact enforce function works properly. So am I to understand that -release will skip in/out blocks entirely? Of course. It uses asserts. asserts are disabled in -release. Asserts are for debugging, testing, and verifying code when developing, not for code which is released. So, you get the benefit of the test when you don't have -release and the benefit of speed when you do have -release. If an assertion fails, your code logic is invalid. It's for validating your code, not user input or whatnot. enforce, on the other hand, is not a language primitive. It's not intended for testing or debugging. It's intended to be used in production code to throw an exception when its condition fails. If an enforce fails, that generally means that you had bad input somewhere or that an operation failed or whatnot. It's not intended for testing the logic of your code like assert is intended to do. It's simply a shorthand way to throw an exception when your program runs into a problem. - Jonathan M Davis
Re: C const
simendsjo Wrote: On 04.03.2011 23:10, Jesse Phillips wrote: Remember that const/immutable, and other attributes/properties aren't going to change the ABI so dropping them will be safer then leaving them. Thanks. Does this apply to all uses of const, or just complex members? Hopefully I'm not wrong on this, but you should even be able to change the type as long as the size is the same. So instead of int you could use uint or byte[8]... granted the library will still interpret it as int. And of course that is assuming you are on a machine with a 32 bit int.