Re: Supporting and signature-checking all foreach variations

2012-02-25 Thread Jesse Phillips

On Saturday, 25 February 2012 at 16:26:05 UTC, Ashish Myles wrote:

2. Secondly, TDPL on page 381 says that foreach iterates over 
C[], if

  C defines the opSlice() function without any arguments.
  However the code above doesn't seem to work and requires me to
  explicitly invoke the slice operator myself like
foreach(p; C[]) { ... }
  when my data structure clearly defines the following 
functions.

Point3[] opSlice() { return _cpts[]; }
const (Point3)[] opSlice() const { return _cpts[]; }
  Is this a misunderstanding on my part or an unimplemented 
feature?


Is not implemented, not seeing a bug report
http://d.puremagic.com/issues/

3. A more general question: Is there any by any chance a way to 
avoid the
  redundancy above of defining two opSlice() functions (or two 
opAssign()
  functions if I went that route -- one for const and another 
for ref)?

  I suspect that the answer is no, but I just wanted to verify.


Not sure look into information on 'auto ref' and 'inout' these
were built for removing duplications of const and ref functions.
These have had some work done to make them functional, but could
still have holes.


Re: struct init() method

2012-02-25 Thread Alex Rønne Petersen

On 26-02-2012 02:54, Jonathan M Davis wrote:

On Saturday, February 25, 2012 17:54:44 H. S. Teoh wrote:

On Sun, Feb 26, 2012 at 12:23:47AM +0100, Alex Rønne Petersen wrote:

On 26-02-2012 00:18, Jonathan M Davis wrote:

On Saturday, February 25, 2012 17:07:14 Timon Gehr wrote:

This is useful:

struct S{

  @disable enum init = 0;

}


I thought that the way that you were supposed to do that was

@disable this();

- Jonathan M Davis


Yeah, I'm not sure what purpose the other example serves.


[...]

It serves to prove that we need to disallow 'init' as a member name. :-)


No. I think that he meant that he doesn't know what purpose

@disable enum init = 0;

serves given that

@disable this();

already disables the init property. The fact that you're able to override init
is a separate, albeit related issue. But yes, it should be disallowed to
declare any symbol as a member of a struct or class with the name init.

- Jonathan M Davis


Yep, exactly.

--
- Alex


Re: std.socket with GDC

2012-02-25 Thread Andrew Wiley
On Sat, Feb 25, 2012 at 4:45 PM, DNewbie  wrote:
>
>
> On Sat, Feb 25, 2012, at 10:38 PM, Mars wrote:
>> On Saturday, 25 February 2012 at 18:27:29 UTC, Vladimir Panteleev
>> wrote:
>> > On Friday, 24 February 2012 at 19:15:26 UTC, Mars wrote:
>> >> Hello everybody.
>> >>
>> >> When trying to compile a program using GDC (Windows), which
>> >> includes an import std.socket, I get a lot "undefined
>> >> reference"s, like
>> >>>undefined reference to `WSAGetLastError@0'
>> >
>> > Try linking with libws2_32.a.
>>
>> Still the same. Does that work for you?
>>
>
> std.socket works for me,
> gdc64 (windows)


I recall having some issues because Winsock needs to be on the linker
commandline *after* phobos. Try running with `gdc -v` to see what the
linker commandline looks like.


Re: struct init() method

2012-02-25 Thread Jonathan M Davis
On Saturday, February 25, 2012 17:54:44 H. S. Teoh wrote:
> On Sun, Feb 26, 2012 at 12:23:47AM +0100, Alex Rønne Petersen wrote:
> > On 26-02-2012 00:18, Jonathan M Davis wrote:
> > >On Saturday, February 25, 2012 17:07:14 Timon Gehr wrote:
> > >>This is useful:
> > >>
> > >>struct S{
> > >>
> > >>  @disable enum init = 0;
> > >>
> > >>}
> > >
> > >I thought that the way that you were supposed to do that was
> > >
> > >@disable this();
> > >
> > >- Jonathan M Davis
> > 
> > Yeah, I'm not sure what purpose the other example serves.
> 
> [...]
> 
> It serves to prove that we need to disallow 'init' as a member name. :-)

No. I think that he meant that he doesn't know what purpose

@disable enum init = 0;

serves given that

@disable this();

already disables the init property. The fact that you're able to override init 
is a separate, albeit related issue. But yes, it should be disallowed to 
declare any symbol as a member of a struct or class with the name init.

- Jonathan M Davis


Re: struct init() method

2012-02-25 Thread H. S. Teoh
On Sun, Feb 26, 2012 at 12:23:47AM +0100, Alex Rønne Petersen wrote:
> On 26-02-2012 00:18, Jonathan M Davis wrote:
> >On Saturday, February 25, 2012 17:07:14 Timon Gehr wrote:
> >>This is useful:
> >>
> >>struct S{
> >>  @disable enum init = 0;
> >>}
> >
> >I thought that the way that you were supposed to do that was
> >
> >@disable this();
> >
> >- Jonathan M Davis
> 
> Yeah, I'm not sure what purpose the other example serves.
[...]

It serves to prove that we need to disallow 'init' as a member name. :-)


T

-- 
Skill without imagination is craftsmanship and gives us many useful
objects such as wickerwork picnic baskets.  Imagination without skill
gives us modern art. -- Tom Stoppard


Re: Make alias parameter optional?

2012-02-25 Thread Andrej Mitrovic
On 2/25/12, Ali Çehreli  wrote:
> Apparently template parameters
> with default values need not be at the end of the template parameter list

Well it would make variadic templates rather hard to use if this was illegal:

void print(bool pretty = false, T...)(T args) { }
void main() { print(1, "two", 3.0); }


Re: Make alias parameter optional?

2012-02-25 Thread Robert Rouse

On Saturday, 25 February 2012 at 23:10:51 UTC, Ary Manzana wrote:

On 2/25/12 7:31 PM, Robert Rouse wrote:



On Saturday, 25 February 2012 at 22:12:55 UTC, Ali Çehreli 
wrote:

On 02/25/2012 01:55 PM, Robert Rouse wrote:

On Saturday, 25 February 2012 at 18:54:35 UTC, Trass3r wrote:

void foo(T, T2, alias thing = (){})(T a, T2 b)
{
thing();
}

void bar(){}

void main()
{
foo!(int,int,bar)(1,2);
foo(1,2);
}


Cool. Didn't know you can do that, but I guess it makes 
sense that it

would work that way.

The only thing I wish for is if I didn't have to explicitly 
define what

T and T2 were and I could just do

foo!(bar)(1,2);


The following works and is news to me. Apparently template 
parameters
with default values need not be at the end of the template 
parameter

list:

void foo(alias thing = (){}, T, T2)(T a, T2 b)
{
thing();
}

void bar(){}

void main()
{
foo!(bar)(1,2);
}

Ali


This means that D can simulate Ruby blocks more than I 
thought. That's

pretty awesome. I'm loving D more every day.


How's that like a Ruby block?


The D code simulates the following Ruby if you were to make bar 
print "something" with writeln.


def foo(a, b, &block)
  puts "a is #{a}")
  b.call
  yield
end

f = lambda { puts "good bye" }

foo(1, f) { puts "something" }


That's what I'm talking about.



Re: Write struct to file

2012-02-25 Thread Ali Çehreli

On 02/25/2012 03:00 PM, Andrej Mitrovic wrote:

On 2/25/12, Ali Çehreli  wrote:

But there is no way for fwrite to follow name.ptr to also write the
characters that are in the string, right?


Oh my I just got a big fat zero on the finals. You're absolutely
right, what gets copied is the length and the pointer. The only reason
my last sample worked is because the memory for the strings was
allocated on the stack, which had the same address between runs.


Ha ha! :) Sorry, I wasn't clear before. That was exactly what I meant. 
Whenever I see objects written by &object, I hear warning bells. :)


Ali


Re: struct init() method

2012-02-25 Thread Alex Rønne Petersen

On 26-02-2012 00:18, Jonathan M Davis wrote:

On Saturday, February 25, 2012 17:07:14 Timon Gehr wrote:

This is useful:

struct S{
  @disable enum init = 0;
}


I thought that the way that you were supposed to do that was

@disable this();

- Jonathan M Davis


Yeah, I'm not sure what purpose the other example serves.

--
- Alex


Re: struct init() method

2012-02-25 Thread Jonathan M Davis
On Saturday, February 25, 2012 17:07:14 Timon Gehr wrote:
> This is useful:
> 
> struct S{
>  @disable enum init = 0;
> }

I thought that the way that you were supposed to do that was

@disable this();

- Jonathan M Davis


Re: Make alias parameter optional?

2012-02-25 Thread Ary Manzana

On 2/25/12 7:31 PM, Robert Rouse wrote:



On Saturday, 25 February 2012 at 22:12:55 UTC, Ali Çehreli wrote:

On 02/25/2012 01:55 PM, Robert Rouse wrote:

On Saturday, 25 February 2012 at 18:54:35 UTC, Trass3r wrote:

void foo(T, T2, alias thing = (){})(T a, T2 b)
{
thing();
}

void bar(){}

void main()
{
foo!(int,int,bar)(1,2);
foo(1,2);
}


Cool. Didn't know you can do that, but I guess it makes sense that it
would work that way.

The only thing I wish for is if I didn't have to explicitly define what
T and T2 were and I could just do

foo!(bar)(1,2);


The following works and is news to me. Apparently template parameters
with default values need not be at the end of the template parameter
list:

void foo(alias thing = (){}, T, T2)(T a, T2 b)
{
thing();
}

void bar(){}

void main()
{
foo!(bar)(1,2);
}

Ali


This means that D can simulate Ruby blocks more than I thought. That's
pretty awesome. I'm loving D more every day.


How's that like a Ruby block?


Re: Write struct to file

2012-02-25 Thread Andrej Mitrovic
On 2/25/12, Andrej Mitrovic  wrote:
> I'm not sure where you're getting that from:

Let that be a classic lesson on what never to do. Here's a
demonstration on how wrong I was:

import std.stdio;

struct Foo
{
char[] name;
}

void main(string[] args)
{
   if (args[1] == "write")
   {
   Foo foo;
   foo.name = new char[](16);
   foo.name[] = 'a';
   writeln(foo);

   auto file   = File("test.bin", "w");
   auto writeBytes = fwrite(&foo, byte.sizeof, foo.sizeof, file.getFP());
   }
   else
   if (args[1] == "read")
   {
   Foo foo;
   auto file = File("test.bin", "r");
   auto readBytes = fread(&foo, byte.sizeof, foo.sizeof, file.getFP());
   writeln(foo);
   }
}

$ D:\dev\code\d_code>test write
Foo("")

$ D:\dev\code\d_code>test read
Foo(x"D8 6E 43 00 01 00 00 00 08 00 00 00 90 A0 42 00"c)

:)

To OP: If you want to serialize I recommend ae's json module
(ae.util.json) from https://github.com/CyberShadow/ae . There's also
Orange but it's based on xml and seems to be buggy the last time I've
tried it.


Re: Write struct to file

2012-02-25 Thread Andrej Mitrovic
On 2/26/12, Andrej Mitrovic  wrote:
> allocated on the stack

Sorry, I meant the data segment not the stack. That's -1 score for me.


Re: Write struct to file

2012-02-25 Thread Andrej Mitrovic
On 2/25/12, Ali Çehreli  wrote:
> But there is no way for fwrite to follow name.ptr to also write the
> characters that are in the string, right?

Oh my I just got a big fat zero on the finals. You're absolutely
right, what gets copied is the length and the pointer. The only reason
my last sample worked is because the memory for the strings was
allocated on the stack, which had the same address between runs.


Re: std.socket with GDC

2012-02-25 Thread DNewbie


On Sat, Feb 25, 2012, at 10:38 PM, Mars wrote:
> On Saturday, 25 February 2012 at 18:27:29 UTC, Vladimir Panteleev 
> wrote:
> > On Friday, 24 February 2012 at 19:15:26 UTC, Mars wrote:
> >> Hello everybody.
> >>
> >> When trying to compile a program using GDC (Windows), which 
> >> includes an import std.socket, I get a lot "undefined 
> >> reference"s, like
> >>>undefined reference to `WSAGetLastError@0'
> >
> > Try linking with libws2_32.a.
> 
> Still the same. Does that work for you?
> 

std.socket works for me,
gdc64 (windows)


Re: Write struct to file

2012-02-25 Thread Andrej Mitrovic
To be honest the C fread and fwrite aren't even necessary since you
can do a rawRead and rawWrite instead.


Re: Write struct to file

2012-02-25 Thread Andrej Mitrovic
On 2/25/12, Ali Çehreli  wrote:
> That passes because lal.name.ptr and dup.name.ptr have the same value.
> Maybe that wasn't the intention but the data is not really in the file.

I'm not sure where you're getting that from:

import std.stdio;

struct nagger
{
string name;
int age;
double weight;
string msg;
}

void main(string[] args)
{
if (args[1] == "write")
{
nagger lal;
lal.name   = "name";
lal.age= 23;
lal.weight = 108.5;
lal.msg= "msg";

auto file   = File("test.bin", "w");
auto writeBytes = fwrite(&lal, byte.sizeof, lal.sizeof, file.getFP());
}
else
if (args[1] == "read")
{
nagger dup;
auto file = File("test.bin", "r");
auto readBytes = fread(&dup, byte.sizeof, dup.sizeof, file.getFP());
writeln(dup);
}
}

$ rdmd test.d write
$ rdmd test.d read
nagger("name", 23, 108.5, "msg")


Re: Make alias parameter optional?

2012-02-25 Thread Robert Rouse



On Saturday, 25 February 2012 at 22:12:55 UTC, Ali Çehreli wrote:

On 02/25/2012 01:55 PM, Robert Rouse wrote:

On Saturday, 25 February 2012 at 18:54:35 UTC, Trass3r wrote:

void foo(T, T2, alias thing = (){})(T a, T2 b)
{
thing();
}

void bar(){}

void main()
{
foo!(int,int,bar)(1,2);
foo(1,2);
}


Cool. Didn't know you can do that, but I guess it makes sense 
that it

would work that way.

The only thing I wish for is if I didn't have to explicitly 
define what

T and T2 were and I could just do

foo!(bar)(1,2);


The following works and is news to me. Apparently template 
parameters with default values need not be at the end of the 
template parameter list:


void foo(alias thing = (){}, T, T2)(T a, T2 b)
{
thing();
}

void bar(){}

void main()
{
foo!(bar)(1,2);
}

Ali


This means that D can simulate Ruby blocks more than I thought. 
That's pretty awesome. I'm loving D more every day.


Re: Make alias parameter optional?

2012-02-25 Thread Ali Çehreli

On 02/25/2012 01:55 PM, Robert Rouse wrote:

On Saturday, 25 February 2012 at 18:54:35 UTC, Trass3r wrote:

void foo(T, T2, alias thing = (){})(T a, T2 b)
{
thing();
}

void bar(){}

void main()
{
foo!(int,int,bar)(1,2);
foo(1,2);
}


Cool. Didn't know you can do that, but I guess it makes sense that it
would work that way.

The only thing I wish for is if I didn't have to explicitly define what
T and T2 were and I could just do

foo!(bar)(1,2);


The following works and is news to me. Apparently template parameters 
with default values need not be at the end of the template parameter list:


void foo(alias thing = (){}, T, T2)(T a, T2 b)
{
thing();
}

void bar(){}

void main()
{
foo!(bar)(1,2);
}

Ali


Re: Write struct to file

2012-02-25 Thread Ali Çehreli

On 02/25/2012 10:33 AM, Andrej Mitrovic wrote:

Well first I'd recommend not allocating the struct on the heap. Then you can do:

import std.stdio;

struct nagger
{
 string name;
 int age;
 double weight;
 string msg;
}

void main()
{
 nagger lal;
 lal.name   = "name";
 lal.age= 23;
 lal.weight = 108.5;
 lal.msg= "msg";

 auto file = File("test.bin", "w");
 auto writeBytes = fwrite(&lal, byte.sizeof, lal.sizeof, file.getFP());


But there is no way for fwrite to follow name.ptr to also write the 
characters that are in the string, right?



 file.close();

 nagger dup;
 file = File("test.bin", "r");
 auto readBytes = fread(&dup, byte.sizeof, dup.sizeof, file.getFP());

 assert(lal == dup);


That passes because lal.name.ptr and dup.name.ptr have the same value. 
Maybe that wasn't the intention but the data is not really in the file.



}

This doesn't work for heap-allocated structs.


Ali


Re: Make alias parameter optional?

2012-02-25 Thread Robert Rouse

On Saturday, 25 February 2012 at 18:54:35 UTC, Trass3r wrote:

void foo(T, T2, alias thing = (){})(T a, T2 b)
{
thing();
}

void bar(){}

void main()
{
foo!(int,int,bar)(1,2);
foo(1,2);
}


Cool. Didn't know you can do that, but I guess it makes sense 
that it would work that way.


The only thing I wish for is if I didn't have to explicitly 
define what T and T2 were and I could just do


foo!(bar)(1,2);


Re: std.socket with GDC

2012-02-25 Thread Mars
On Saturday, 25 February 2012 at 18:27:29 UTC, Vladimir Panteleev 
wrote:

On Friday, 24 February 2012 at 19:15:26 UTC, Mars wrote:

Hello everybody.

When trying to compile a program using GDC (Windows), which 
includes an import std.socket, I get a lot "undefined 
reference"s, like

undefined reference to `WSAGetLastError@0'


Try linking with libws2_32.a.


Still the same. Does that work for you?


Re: struct init() method

2012-02-25 Thread Dmitry Olshansky

On 25.02.2012 8:05, bearophile wrote:

This program comes from a reduction of a bug I've found:


struct Foo {
 void init() {}
}
void main() {
 Foo*[] foos;
 //(*foos[0]).init(); // OK
 foos[0].init(); // Error: function expected before (), not null of type 
Foo*
}


What do you think about the idea of not allowing methods named init() in 
structs? (Especially if they are a @property). Or maybe there is a better 
solution, opinions welcome.

Bye,
bearophile


FWIW I've encountered this thingy while messing with phobos std.file 
around a year ago. Still allowed and mishandled it seems.


--
Dmitry Olshansky


Re: Supporting and signature-checking all foreach variations

2012-02-25 Thread Dmitry Olshansky

On 25.02.2012 20:25, Ashish Myles wrote:

I want to define a general-purpose centroid computer for point containers
and ran into a couple of challenges. Firstly, here is the basic code

 Point3 computeCentroid(PointContainer)(const ref PointContainer C)
 if (...)// want a signature constraint for usability of foreach
 {
 Point3 c = Point3(0.0, 0.0, 0.0);
 size_t total = 0;
 foreach(Point3 p; C) {   // enforce that the container supports this
 c += p; ++total;
 }
 if (total>  0)
 c /= cast(double)(total);
 return c;
 }

I want to have the most generally-applicable version of this functionality
(for const/immutable/etc containers supporting foreach in various ways),
ideally without needing to write multiple versions of this function.

1. Since support for foreach can be added in many ways (with
   ref/non-ref/const variants), I wanted to check if there was any
   signature constraint that could check if the container supports foreach
   as above. I looked into the "compiles" traits, but that doesn't work for
   statements.

   For an opAssign version, I had tried
 if (is(typeof(C.opApply(delegate(const ref Point3) { return 1;}
   but this is unelegant because the container's opApply could have instead
   supplied delegate(Point3) or delegate(ref Point3) (although the latter
   would require me to not use a "const" on the parameter declaration).

2. Secondly, TDPL on page 381 says that foreach iterates over C[], if
   C defines the opSlice() function without any arguments.
   However the code above doesn't seem to work and requires me to
   explicitly invoke the slice operator myself like
 foreach(p; C[]) { ... }
   when my data structure clearly defines the following functions.
 Point3[] opSlice() { return _cpts[]; }
 const (Point3)[] opSlice() const { return _cpts[]; }
   Is this a misunderstanding on my part or an unimplemented feature?


It's supposed to work.
I think it's just not implemented yet.



3. A more general question: Is there any by any chance a way to avoid the
   redundancy above of defining two opSlice() functions (or two opAssign()
   functions if I went that route -- one for const and another for ref)?
   I suspect that the answer is no, but I just wanted to verify.



--
Dmitry Olshansky


Re: Supporting and signature-checking all foreach variations

2012-02-25 Thread Ashish Myles
On Sat, Feb 25, 2012 at 11:37 AM, Alex Rønne Petersen
 wrote:
> On 25-02-2012 17:25, Ashish Myles wrote:
>>
>> 1. Since support for foreach can be added in many ways (with
>>   ref/non-ref/const variants), I wanted to check if there was any
>>   signature constraint that could check if the container supports foreach
>>   as above. I looked into the "compiles" traits, but that doesn't work for
>>   statements.
>
> I think std.traits.isIterable(T) is what you want.
>

Great! Now that I know the answer to the first question, it is so easy
to find the answer on google :P .   Technically, I want something like
isIterable(T,Point3); given the definition of isIterable, I can easily
get this functionality.

I am still looking for answers to the second question (which might
indicate a bug in the frontend) and third question whose answer would
be really enlightening if what I requested is possible.


Re: Make alias parameter optional?

2012-02-25 Thread Trass3r

void foo(T, T2, alias thing = (){})(T a, T2 b)
{
thing();
}

void bar(){}

void main()
{
foo!(int,int,bar)(1,2);
foo(1,2);
}


Make alias parameter optional?

2012-02-25 Thread Robert Rouse

Is it possible to do something like this?

void foo(T, T2, alias thing)(T a, T2 b) {
  // do stuff with a
  // call b (since b would be a delegate)
  // call thing if thing is given
}

I come from the Ruby world and I'm just playing around to see how 
much I can replicate of the "block" functionality that Ruby has.


Re: Using delegates in callbacks for extern(C) functions

2012-02-25 Thread simendsjo

On Sat, 25 Feb 2012 17:12:50 +0100, Timon Gehr  wrote:


On 02/24/2012 07:22 PM, simendsjo wrote:

I have a C function taking a callback function as a parameter. My
thought was to wrap this up using a template, but I cannot get it to  
work:


extern(C) alias void function() Callback;

template Wrap(alias dg)
{
extern(C) void Wrap()
{
dg();
}
}

void main()
{
Callback cb = &Wrap!( () {} );
}

Error: cannot implicitly convert expression (&Wrap) of type void
delegate() pure nothrow @safe to extern (C) void function()


This is a bug. '() {}' should be inferred as void function()pure nothrow  
@safe. Workaround: The code compiles if you use function() {} instead. I  
don't know if a bug report exists already.


Thanks. http://d.puremagic.com/issues/show_bug.cgi?id=7585


Re: Write struct to file

2012-02-25 Thread Andrej Mitrovic
On 2/25/12, Andrej Mitrovic  wrote:
> This doesn't work for heap-allocated structs.
>

Sorry my bad. .sizeof should always be set on Types and not variable
names, because a struct pointer will have sizeof == size_t, whereas a
simple struct variable will have sizeof equal to the struct size. So
it can work just fine with heap-allocated structs:

void main()
{
auto lal = new nagger();
lal.name   = "name";
lal.age= 23;
lal.weight = 108.5;
lal.msg= "msg";

auto file = File("test.bin", "w");
auto writeBytes = fwrite(cast(void*)lal, byte.sizeof,
nagger.sizeof, file.getFP());
file.close();

nagger dup;
file = File("test.bin", "r");
auto readBytes = fread(&dup, byte.sizeof, nagger.sizeof, file.getFP());

assert(dup == *lal);
}


Re: Write struct to file

2012-02-25 Thread Andrej Mitrovic
Well first I'd recommend not allocating the struct on the heap. Then you can do:

import std.stdio;

struct nagger
{
string name;
int age;
double weight;
string msg;
}

void main()
{
nagger lal;
lal.name   = "name";
lal.age= 23;
lal.weight = 108.5;
lal.msg= "msg";

auto file = File("test.bin", "w");
auto writeBytes = fwrite(&lal, byte.sizeof, lal.sizeof, file.getFP());
file.close();

nagger dup;
file = File("test.bin", "r");
auto readBytes = fread(&dup, byte.sizeof, dup.sizeof, file.getFP());

assert(lal == dup);
}

This doesn't work for heap-allocated structs.


Re: std.socket with GDC

2012-02-25 Thread Vladimir Panteleev

On Friday, 24 February 2012 at 19:15:26 UTC, Mars wrote:

Hello everybody.

When trying to compile a program using GDC (Windows), which 
includes an import std.socket, I get a lot "undefined 
reference"s, like

undefined reference to `WSAGetLastError@0'


Try linking with libws2_32.a.


Re: delegate as memeber

2012-02-25 Thread Timon Gehr

On 02/25/2012 07:23 PM, Artur Skawina wrote:

On 02/25/12 15:37, Timon Gehr wrote:

On 02/25/2012 03:32 PM, Stewart Gordon wrote:

On 21/02/2012 17:46, Jacob Carlborg wrote:

On 2012-02-21 16:55, deadalnix wrote:



You can implement a static opCall and use that instead of the
constructor.


But you don't have to call a static opCall. You can just declare a
struct instance without any initialisation. Presumably half the point is
to ensure that exceptionBuilder is still initialised in such cases.

Stewart.


struct exceptionBuilder{
 @disable this();
 @disable enum init=0;
 static exceptionBuilder opCall(...){...}
}


Too bad this doesn't work when opCall takes args.

IOW, "S(2)" results in

  Error: constructor m.S.this () is not callable using argument types (int)
  Error: constructor m.S.this is not callable because it is annotated with 
@disable
  Error: expected 0 arguments, not 1 for non-variadic function type ref S()

Removing the disabled 'this()' makes the error go away and the right
opCall() gets called.

artur


Well, that is a bug.

http://d.puremagic.com/issues/show_bug.cgi?id=6036


Re: delegate as memeber

2012-02-25 Thread Artur Skawina
On 02/25/12 15:37, Timon Gehr wrote:
> On 02/25/2012 03:32 PM, Stewart Gordon wrote:
>> On 21/02/2012 17:46, Jacob Carlborg wrote:
>>> On 2012-02-21 16:55, deadalnix wrote:
>> 
>>> You can implement a static opCall and use that instead of the
>>> constructor.
>>
>> But you don't have to call a static opCall. You can just declare a
>> struct instance without any initialisation. Presumably half the point is
>> to ensure that exceptionBuilder is still initialised in such cases.
>>
>> Stewart.
> 
> struct exceptionBuilder{
> @disable this();
> @disable enum init=0;
> static exceptionBuilder opCall(...){...}
> }

Too bad this doesn't work when opCall takes args.

IOW, "S(2)" results in 

 Error: constructor m.S.this () is not callable using argument types (int)
 Error: constructor m.S.this is not callable because it is annotated with 
@disable
 Error: expected 0 arguments, not 1 for non-variadic function type ref S()

Removing the disabled 'this()' makes the error go away and the right
opCall() gets called.

artur


Re: Write struct to file

2012-02-25 Thread Timon Gehr

On 02/25/2012 07:15 PM, Timon Gehr wrote:

On 02/25/2012 07:03 PM, Chopin wrote:

Hello!

import std.stdio;

struct nagger
{
string name;
int age;
double weight;
string msg;
}

void main()
{
auto lal = new nagger();
lal.name = "AHAHAHAHHA";
lal.age = 23;
lal.weight = 108.5;
lal.msg = "fgfdgfdgfdgfdgfdgfdg";
writeln(cast(ubyte[])(lal));
}

Gives error: Error: e2ir: cannot cast lal of type nagger* to type ubyte[]
I have bad knowledge about this and don't understand why I cant do
this :(
What I really want is an array of naggers and save them binary to a
file :)
This was like my step 1, and it failed miserably...

Thanks for help.



Structs are not castable to arrays directly. You can achieve what you
want like this (untested, but should work).

(cast(void*)&lal)[0..nagger.sizeof];



You also have to change the first line of main to:

auto lol = nagger();

This will allocate the struct on the stack.

If you want to keep auto lal = new nagger(); for some reason, then do 
the cast like this:


(cast(void*)lal)[0..nagger.sizeof]


Re: Write struct to file

2012-02-25 Thread Timon Gehr

On 02/25/2012 07:03 PM, Chopin wrote:

Hello!

import std.stdio;

struct nagger
{
string name;
int age;
double weight;
string msg;
}

void main()
{
auto lal = new nagger();
lal.name = "AHAHAHAHHA";
lal.age = 23;
lal.weight = 108.5;
lal.msg = "fgfdgfdgfdgfdgfdgfdg";
writeln(cast(ubyte[])(lal));
}

Gives error: Error: e2ir: cannot cast lal of type nagger* to type ubyte[]
I have bad knowledge about this and don't understand why I cant do this :(
What I really want is an array of naggers and save them binary to a file :)
This was like my step 1, and it failed miserably...

Thanks for help.



Structs are not castable to arrays directly. You can achieve what you 
want like this (untested, but should work).


(cast(void*)&lal)[0..nagger.sizeof];



Write struct to file

2012-02-25 Thread Chopin

Hello!

import std.stdio;

struct nagger
{
string name;
int age;
double weight;
string msg;
}

void main()
{
auto lal = new nagger();
lal.name = "AHAHAHAHHA";
lal.age = 23;
lal.weight = 108.5;
lal.msg = "fgfdgfdgfdgfdgfdgfdg";
writeln(cast(ubyte[])(lal));
}

Gives error: Error: e2ir: cannot cast lal of type nagger* to type 
ubyte[]
I have bad knowledge about this and don't understand why I cant 
do this :(
What I really want is an array of naggers and save them binary to 
a file :)

This was like my step 1, and it failed miserably...

Thanks for help.



Re: Supporting and signature-checking all foreach variations

2012-02-25 Thread Alex Rønne Petersen

On 25-02-2012 17:25, Ashish Myles wrote:

I want to define a general-purpose centroid computer for point containers
and ran into a couple of challenges. Firstly, here is the basic code

 Point3 computeCentroid(PointContainer)(const ref PointContainer C)
 if (...)// want a signature constraint for usability of foreach
 {
 Point3 c = Point3(0.0, 0.0, 0.0);
 size_t total = 0;
 foreach(Point3 p; C) {   // enforce that the container supports this
 c += p; ++total;
 }
 if (total>  0)
 c /= cast(double)(total);
 return c;
 }

I want to have the most generally-applicable version of this functionality
(for const/immutable/etc containers supporting foreach in various ways),
ideally without needing to write multiple versions of this function.

1. Since support for foreach can be added in many ways (with
   ref/non-ref/const variants), I wanted to check if there was any
   signature constraint that could check if the container supports foreach
   as above. I looked into the "compiles" traits, but that doesn't work for
   statements.

   For an opAssign version, I had tried
 if (is(typeof(C.opApply(delegate(const ref Point3) { return 1;}
   but this is unelegant because the container's opApply could have instead
   supplied delegate(Point3) or delegate(ref Point3) (although the latter
   would require me to not use a "const" on the parameter declaration).

2. Secondly, TDPL on page 381 says that foreach iterates over C[], if
   C defines the opSlice() function without any arguments.
   However the code above doesn't seem to work and requires me to
   explicitly invoke the slice operator myself like
 foreach(p; C[]) { ... }
   when my data structure clearly defines the following functions.
 Point3[] opSlice() { return _cpts[]; }
 const (Point3)[] opSlice() const { return _cpts[]; }
   Is this a misunderstanding on my part or an unimplemented feature?

3. A more general question: Is there any by any chance a way to avoid the
   redundancy above of defining two opSlice() functions (or two opAssign()
   functions if I went that route -- one for const and another for ref)?
   I suspect that the answer is no, but I just wanted to verify.


I think std.traits.isIterable(T) is what you want.

--
- Alex


Supporting and signature-checking all foreach variations

2012-02-25 Thread Ashish Myles
I want to define a general-purpose centroid computer for point containers
and ran into a couple of challenges. Firstly, here is the basic code

Point3 computeCentroid(PointContainer)(const ref PointContainer C)
if (...)// want a signature constraint for usability of foreach
{
Point3 c = Point3(0.0, 0.0, 0.0);
size_t total = 0;
foreach(Point3 p; C) {   // enforce that the container supports this
c += p; ++total;
}
if (total > 0)
c /= cast(double)(total);
return c;
}

I want to have the most generally-applicable version of this functionality
(for const/immutable/etc containers supporting foreach in various ways),
ideally without needing to write multiple versions of this function.

1. Since support for foreach can be added in many ways (with
  ref/non-ref/const variants), I wanted to check if there was any
  signature constraint that could check if the container supports foreach
  as above. I looked into the "compiles" traits, but that doesn't work for
  statements.

  For an opAssign version, I had tried
if (is(typeof(C.opApply(delegate(const ref Point3) { return 1;}
  but this is unelegant because the container's opApply could have instead
  supplied delegate(Point3) or delegate(ref Point3) (although the latter
  would require me to not use a "const" on the parameter declaration).

2. Secondly, TDPL on page 381 says that foreach iterates over C[], if
  C defines the opSlice() function without any arguments.
  However the code above doesn't seem to work and requires me to
  explicitly invoke the slice operator myself like
foreach(p; C[]) { ... }
  when my data structure clearly defines the following functions.
Point3[] opSlice() { return _cpts[]; }
const (Point3)[] opSlice() const { return _cpts[]; }
  Is this a misunderstanding on my part or an unimplemented feature?

3. A more general question: Is there any by any chance a way to avoid the
  redundancy above of defining two opSlice() functions (or two opAssign()
  functions if I went that route -- one for const and another for ref)?
  I suspect that the answer is no, but I just wanted to verify.


Re: Using delegates in callbacks for extern(C) functions

2012-02-25 Thread Timon Gehr

On 02/24/2012 07:22 PM, simendsjo wrote:

I have a C function taking a callback function as a parameter. My
thought was to wrap this up using a template, but I cannot get it to work:

extern(C) alias void function() Callback;

template Wrap(alias dg)
{
extern(C) void Wrap()
{
dg();
}
}

void main()
{
Callback cb = &Wrap!( () {} );
}

Error: cannot implicitly convert expression (&Wrap) of type void
delegate() pure nothrow @safe to extern (C) void function()


This is a bug. '() {}' should be inferred as void function()pure nothrow 
@safe. Workaround: The code compiles if you use function() {} instead. I 
don't know if a bug report exists already.


Re: struct init() method

2012-02-25 Thread Timon Gehr

On 02/25/2012 04:52 PM, H. S. Teoh wrote:

On Sat, Feb 25, 2012 at 01:23:21PM +0100, Alex Rønne Petersen wrote:

On 25-02-2012 05:05, bearophile wrote:

This program comes from a reduction of a bug I've found:


struct Foo {
 void init() {}
}
void main() {
 Foo*[] foos;
 //(*foos[0]).init(); // OK
 foos[0].init(); // Error: function expected before (), not null of type 
Foo*
}


What do you think about the idea of not allowing methods named init() in 
structs? (Especially if they are a @property). Or maybe there is a better 
solution, opinions welcome.

Bye,
bearophile


IMHO we shouldn't allow having *any* members that use the same name
as any of the compiler-provided properties/functions.

[...]

Agreed.


T



This is useful:

struct S{
@disable enum init = 0;
}


Re: struct init() method

2012-02-25 Thread H. S. Teoh
On Sat, Feb 25, 2012 at 01:23:21PM +0100, Alex Rønne Petersen wrote:
> On 25-02-2012 05:05, bearophile wrote:
> >This program comes from a reduction of a bug I've found:
> >
> >
> >struct Foo {
> > void init() {}
> >}
> >void main() {
> > Foo*[] foos;
> > //(*foos[0]).init(); // OK
> > foos[0].init(); // Error: function expected before (), not null of type 
> > Foo*
> >}
> >
> >
> >What do you think about the idea of not allowing methods named init() in 
> >structs? (Especially if they are a @property). Or maybe there is a better 
> >solution, opinions welcome.
> >
> >Bye,
> >bearophile
> 
> IMHO we shouldn't allow having *any* members that use the same name
> as any of the compiler-provided properties/functions.
[...]

Agreed.


T

-- 
Marketing: the art of convincing people to pay for what they didn't need
before which you can't deliver after.


Re: deh_end

2012-02-25 Thread Jacob Carlborg

On 2012-02-24 23:37, Ellery Newcomer wrote:

So I'm all trying out this hot new shared switch, and it works just
dandy for -m32 when d has the main function. But now I want to be able
to call my shared lib from C.

my little shared lib, tup.d:


import std.stdio;
extern(C) void xyz(int i){
writeln(i);
}


compiled like so:

dmd -shared -m32 tup.d -oflibtup.so

my little C program, tok.c:

extern void xyz(int);

int main(int argc, char **argv){
xyz(1);
}


compiled like so:

gcc -m32 tok.c -L. -ltup

Oh no!

./libtup.so: undefined reference to `_deh_beg'
./libtup.so: undefined reference to `_tlsend'
./libtup.so: undefined reference to `_tlsstart'
./libtup.so: undefined reference to `_deh_end'
collect2: ld returned 1 exit status


It seems like I've run into this before with static libs, but I'll ask
again anyways. What the heck are these symbols for?


_deh_beg and _deh_end is the start and end of the exception handling 
tables. _tlsstart and _tlsend would be the start and end of the TLS 
data. As far as I know druntime has not yet been adapted to handle 
dynamic libraries.


I think there's a pull request that fixes this.

--
/Jacob Carlborg


Re: Template Inheritance

2012-02-25 Thread Timon Gehr

On 02/22/2012 01:13 AM, BLM wrote:

That last one looks a lot better than my solution. It's certainly a lot clearer.

One problem I discovered with using templates was that I ended up needing 
virtual
functions, which means that I had to convert the template functions to mixins 
and
just instantiate them for each type (at least there were only two types to
handle!) in the base class. The problem I've got now is that if I create 
versions
of get() that take different types in subclasses, I lose access to the
superclass's overload set. If I try to use "alias Base.get get", DMD complains
that the alias and the functions conflict. It looks like I can override existing
overloads but not create new ones. I guess I might have to put a hold on the
project until the language gets modified (assuming that actually happens). How
would I go about filing an enhancement request?


You can post it in the bug tracker and choose severity as 'enhancement':
http://d.puremagic.com/issues/


Re: delegate as memeber

2012-02-25 Thread Timon Gehr

On 02/25/2012 03:32 PM, Stewart Gordon wrote:

On 21/02/2012 17:46, Jacob Carlborg wrote:

On 2012-02-21 16:55, deadalnix wrote:



You can implement a static opCall and use that instead of the
constructor.


But you don't have to call a static opCall. You can just declare a
struct instance without any initialisation. Presumably half the point is
to ensure that exceptionBuilder is still initialised in such cases.

Stewart.


struct exceptionBuilder{
@disable this();
@disable enum init=0;
static exceptionBuilder opCall(...){...}
}


Re: delegate as memeber

2012-02-25 Thread Stewart Gordon

On 21/02/2012 17:46, Jacob Carlborg wrote:

On 2012-02-21 16:55, deadalnix wrote:



You can implement a static opCall and use that instead of the constructor.


But you don't have to call a static opCall.  You can just declare a struct instance 
without any initialisation.  Presumably half the point is to ensure that exceptionBuilder 
is still initialised in such cases.


Stewart.


Re: struct init() method

2012-02-25 Thread Alex Rønne Petersen

On 25-02-2012 05:05, bearophile wrote:

This program comes from a reduction of a bug I've found:


struct Foo {
 void init() {}
}
void main() {
 Foo*[] foos;
 //(*foos[0]).init(); // OK
 foos[0].init(); // Error: function expected before (), not null of type 
Foo*
}


What do you think about the idea of not allowing methods named init() in 
structs? (Especially if they are a @property). Or maybe there is a better 
solution, opinions welcome.

Bye,
bearophile


IMHO we shouldn't allow having *any* members that use the same name as 
any of the compiler-provided properties/functions.


--
- Alex