Re: string vs. w/char*

2011-03-04 Thread Kagamin
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*

2011-03-04 Thread Kagamin
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

2011-03-04 Thread Magnus Lie Hetland

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

2011-03-04 Thread bearophile
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

2011-03-04 Thread Trass3r
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

2011-03-04 Thread 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?-)


--
Magnus Lie Hetland
http://hetland.org



Re: Overriding in operator

2011-03-04 Thread Mafi

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

2011-03-04 Thread Magnus Lie Hetland
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

2011-03-04 Thread Magnus Lie Hetland

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

2011-03-04 Thread Simen kjaeraas

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

2011-03-04 Thread Simen kjaeraas

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

2011-03-04 Thread Simen kjaeraas

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

2011-03-04 Thread Steven Schveighoffer
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

2011-03-04 Thread Simen kjaeraas

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

2011-03-04 Thread spir

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

2011-03-04 Thread spir

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

2011-03-04 Thread Jonathan M Davis
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

2011-03-04 Thread Steven Schveighoffer

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

2011-03-04 Thread Aleksandar Ružičić
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

2011-03-04 Thread Magnus Lie Hetland

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

2011-03-04 Thread Magnus Lie Hetland

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

2011-03-04 Thread Steven Schveighoffer
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

2011-03-04 Thread Magnus Lie Hetland

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

2011-03-04 Thread simendsjo
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

2011-03-04 Thread Jonathan M Davis
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

2011-03-04 Thread simendsjo


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

2011-03-04 Thread spir

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

2011-03-04 Thread Ali Çehreli

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

2011-03-04 Thread Jérôme M. Berger
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?

2011-03-04 Thread bearophile
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?

2011-03-04 Thread bearophile
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?

2011-03-04 Thread Simen kjaeraas

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(++)

2011-03-04 Thread Kai Meyer

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

2011-03-04 Thread bearophile
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

2011-03-04 Thread simendsjo

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

2011-03-04 Thread simendsjo

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

2011-03-04 Thread Jonathan M Davis
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

2011-03-04 Thread Aleksandar Ružičić

 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

2011-03-04 Thread Aleksandar Ružičić

 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

2011-03-04 Thread bearophile
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

2011-03-04 Thread Peter Lundgren
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

2011-03-04 Thread Kai Meyer
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

2011-03-04 Thread Jonathan M Davis
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

2011-03-04 Thread Jesse Phillips
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.