Re: A question about DbC

2010-10-08 Thread Jonathan M Davis
On Friday 08 October 2010 20:16:10 bearophile wrote:
> This is a simple D2 class that uses Contracts:
> 
> 
> import std.c.stdio: printf;
> 
> class Car {
> int speed = 0;
> 
> invariant() {
> printf("Car invariant: %d\n", speed);
> assert(speed >= 0);
> }
> 
> this() {
> printf("Car constructor: %d\n", speed);
> speed = 0;
> }
> 
> void setSpeed(int kmph)
> in {
> printf("Car.setSpeed precondition: %d\n", kmph);
> assert(kmph >= 0);
> } out {
> printf("Car.setSpeed postcondition: %d\n", speed);
> assert(speed == kmph);
> } body {
> printf("Car.setSpeed body\n");
> speed = kmph;
> }
> }
> 
> void main() {
> auto c = new Car();
> c.setSpeed(10);
> }
> 
> 
> This is the output of the program, dmd 2.049:
> 
> Car constructor: 0
> Car invariant: 0
> Car.setSpeed precondition: 10
> Car invariant: 0
> Car.setSpeed body
> Car invariant: 10
> Car.setSpeed postcondition: 10
> 
> Is it correct? I think the invariant needs to run before the precondition
> and after the postcondition.

Why? The invariant only really needs to be run after each public function runs. 
It could be before or after the postcondition. Both the postcondition and 
invariant need to be true and they're completely independent, so they could be 
run in either order. What's odder is that the invariant is run after the 
precondition. That shouldn't be necessary, since any changes to the object 
would 
have been verifed after the last time that a public member function was called. 
Maybe it's because of the possibility of member variables being altered because 
they were returned by reference or because of public member variables having 
possibly been altered. Regardless, since the postcondition and invariant are 
indepedent, it shouldn't matter which order they run in - particularly since 
they are essentially pure, even if purity is not enforced for them (that is, 
unless you're doing something stupid, neither of them will alter the state of 
the object, so they could be run in either order).

- Jonathan M Davis


A question about DbC

2010-10-08 Thread bearophile
This is a simple D2 class that uses Contracts:


import std.c.stdio: printf;

class Car {
int speed = 0;

invariant() {
printf("Car invariant: %d\n", speed);
assert(speed >= 0);
}

this() {
printf("Car constructor: %d\n", speed);
speed = 0;
}

void setSpeed(int kmph)
in {
printf("Car.setSpeed precondition: %d\n", kmph);
assert(kmph >= 0);
} out {
printf("Car.setSpeed postcondition: %d\n", speed);
assert(speed == kmph);
} body {
printf("Car.setSpeed body\n");
speed = kmph;
}
}

void main() {
auto c = new Car();
c.setSpeed(10);
}


This is the output of the program, dmd 2.049:

Car constructor: 0
Car invariant: 0
Car.setSpeed precondition: 10
Car invariant: 0
Car.setSpeed body
Car invariant: 10
Car.setSpeed postcondition: 10

Is it correct? I think the invariant needs to run before the precondition and 
after the postcondition.

Bye,
bearophile


Re: ditto in DDoc

2010-10-08 Thread Jonathan M Davis
On Friday, October 08, 2010 15:17:13 bearophile wrote:
> Jonathan M Davis:
> > It's the past participle of the Italian word dire (to say)
> 
> It was, a long time ago. Today it's "detto".
> 
> Bye,
> bearophile

Good to know. I was just going by what Merriam Webster had to say on that one. 
I 
know French but not Italian.

- Jonathan M Davis


Re: ditto in DDoc

2010-10-08 Thread Denis Koroskin

On Sat, 09 Oct 2010 01:22:33 +0400, Tomek Sowiński  wrote:


More of an English question...
dunno <- don't know
ditto <- ?



Ditto is used to indicate that something already said is applicable a  
second time.
In documentation, "ditto" means that previous comment also applies here.  
Here is an example:


/// helper function
void doStuff();

/// ditto (i.e. helper function)
void doOtherStuff();


Re: ditto in DDoc

2010-10-08 Thread bearophile
Jonathan M Davis:

> It's the past participle of the Italian word dire (to say)

It was, a long time ago. Today it's "detto".

Bye,
bearophile


Re: ditto in DDoc

2010-10-08 Thread Jonathan M Davis
On Friday, October 08, 2010 14:22:33 Tomek Sowiński wrote:
> More of an English question...
> dunno <- don't know
> ditto <- ?

It's a word in and of itself, not the shortening or butchering of another word. 
According to merriam-webster.com ( http://www.merriam-
webster.com/dictionary/ditto ), it comes from Italian. It's the past participle 
of the Italian word dire (to say) - which also happens to be the French word 
for 
to say, but French has a different past participle.

- Jonathan M Davis


Re: ditto in DDoc

2010-10-08 Thread Yao G.

On Fri, 08 Oct 2010 16:22:33 -0500, Tomek Sowiński  wrote:


More of an English question...
dunno <- don't know
ditto <- ?


http://en.wiktionary.org/wiki/ditto

ditto (plural dittos)
1. That which was stated before, the aforesaid, the above, the same.
2. (informal) A duplicate or copy of a document.

--
Yao G.


Re: std.regex character consumption

2010-10-08 Thread Jonathan M Davis
On Friday, October 08, 2010 14:13:36 petevi...@yahoo.com.au wrote:
> I've been running into a few problems with regular expressions in D. One
> of the issues I've had recently is matching strings with non ascii
> characters. As an example:
> 
> auto re = regex( `(.*)\.txt`, "i" );
> re.printProgram();
> auto m = match( "bà.txt", re );
> writefln( "'%s'", m.captures[1] );
> 
> When I run this I get the following error:
> 
> dchar decode(in char[], ref size_t): Invalid UTF-8 sequence [160 46 116
> 120] around index 0
> printProgram()
>   0:  REparen len=1 n=0, pc=>10
>   9:  REanystar
>  10:  REistring x4, '.txt'
>  19:  REend
> 
> While investigating the cause, I noticed that during execution of many
> of the regex instructions (e.g. REanystar), the source is advanced with:
> 
> src++;
> 
> However in other cases (REanychar), it is advanced with:
> 
> src += std.utf.stride(input, src);
> 
> I found that by replacing the code REanystar with stride, the code
> worked as expected. Although I can't claim to have a solid understanding
> of the code, it seems to me that most of the cases of src++ should be
> using stride instead.
> 
> Is this correct, or have I made some silly mistake and got completely
> the wrong end of the stick?

Well, without looking at the code, I can't say for certain what's going on, but 
using ++ with chars or wchars is definitely wrong in virtually all cases. 
stride() will actually go to the next code point, while ++ will just go to the 
next code unit, which could be in the middle of a code point.

- Jonathan M Davis


ditto in DDoc

2010-10-08 Thread Tomek Sowiński
More of an English question...
dunno <- don't know
ditto <- ?

-- 
Tomek


std.regex character consumption

2010-10-08 Thread petevik38
I've been running into a few problems with regular expressions in D. One
of the issues I've had recently is matching strings with non ascii
characters. As an example:

auto re = regex( `(.*)\.txt`, "i" );
re.printProgram();
auto m = match( "bà.txt", re );
writefln( "'%s'", m.captures[1] );

When I run this I get the following error:

dchar decode(in char[], ref size_t): Invalid UTF-8 sequence [160 46 116
120] around index 0
printProgram()
  0:REparen len=1 n=0, pc=>10
  9:REanystar
 10:REistring x4, '.txt'
 19:REend

While investigating the cause, I noticed that during execution of many
of the regex instructions (e.g. REanystar), the source is advanced with:

src++;

However in other cases (REanychar), it is advanced with:

src += std.utf.stride(input, src);

I found that by replacing the code REanystar with stride, the code
worked as expected. Although I can't claim to have a solid understanding
of the code, it seems to me that most of the cases of src++ should be
using stride instead.

Is this correct, or have I made some silly mistake and got completely
the wrong end of the stick?


Re: [D1][expressions] Order Of Evaluation

2010-10-08 Thread %u
== Quote from Denis Koroskin (2kor...@gmail.com)'s article
> On Fri, 08 Oct 2010 18:49:36 +0400, %u  wrote:
> > /The following binary expressions are evaluated in an
> > implementation-defined
> > order:
> > AssignExpression/../AddExpression/
> >
> > /It is an error to depend on order of evaluation when it is not
> > specified./
> >
> > That makes this an error!?
> >
> > y = x + 1;
> >
> > Am I being paranoid or should I be adding more brackets?
> Assignment has higher precedence that addition so your code has no errors.
You probably mean that the other way around ;)

But you are right, I am confusing precedence and associativity.
The expressions page reads like there are only two levels of precedence, but it
only says anyting about the associativity.
A quick search on precedence shows that the C precedence rules apply.

> However, the following one does:
> int x = 1;
> int y = (x = 2) + x;
> because "x" and "x = 2" has same precedence and thus may be evaluated in
> any order.
> Stay away from such code and you should be fine.

I never assign within assignments :)


Re: [D1][expressions] Order Of Evaluation

2010-10-08 Thread Denis Koroskin

On Fri, 08 Oct 2010 18:49:36 +0400, %u  wrote:

/The following binary expressions are evaluated in an  
implementation-defined

order:
AssignExpression/../AddExpression/

/It is an error to depend on order of evaluation when it is not  
specified./


That makes this an error!?

y = x + 1;

Am I being paranoid or should I be adding more brackets?


Assignment has higher precedence that addition so your code has no errors.

However, the following one does:

int x = 1;
int y = (x = 2) + x;

because "x" and "x = 2" has same precedence and thus may be evaluated in  
any order.


Stay away from such code and you should be fine.


Re: [D1][expressions] Order Of Evaluation

2010-10-08 Thread bearophile
%u:

> That makes this an error!?
> 
> y = x + 1;
> 
> Am I being paranoid or should I be adding more brackets?

I presume this doesn't need other brackets.
And Walter has two or three times stated that he wants to eventually define the 
order of evaluation in D (as C#/Java), I hope this will happen.

Bye,
bearophile


Re: Destruction Sequence: module and classes defined within

2010-10-08 Thread Lutger
Lars T. Kyllingstad wrote:

> On Tue, 05 Oct 2010 23:25:36 +0200, vano wrote:
> 
>> The code below:
>>  module used;
>> 
>>  import std.stdio;
>> 
>>  class ClassA {
>>  this()  { writeln("A ctor"); }
>>  ~this() { writeln("A dtor"); }
>>  }
>> 
>>  static this()  { writeln("used.sctor"); } static ~this() {
>>  writeln("used.sdtor"); }
>> 
>>  void main() {
>>  auto a = new ClassA();
>>  }
>> produces the following output (DMD v2.049):
>>  used.sctor
>>  A ctor
>>  used.sdtor
>>  A dtor
>> 
>> The question is: should the module be allowed to be unloaded before all
>> module-level objects/structures are destructed/unloaded?
> 
> 
> I'm no expert on this, but I think it has to be that way.  Consider this:
> 
>   class Foo { ... }
>   Foo foo;
> 
>   static this()
>   {
>   foo = new Foo;
>   }
> 
>   static ~this()
>   {
>   foo.doStuff();
>   }
> 
> So you see, if foo had already been destroyed and garbage collected, my
> program would have crashed when the module static destructor was run.
> Thus, I guess, running the garbage collector for the final time has to be
> one of the last things done on program shutdown, after running all module
> destructors.
> 
> -Lars

In this case however, foo is still referenced whereas in the original example 
'a' is unreferenced after main exits.

I could only find this in the spec: "The garbage collector is not guaranteed to 
run the destructor for all unreferenced objects." *

>From reading the spec, I think that all one can conclude is that after main 
unreferenced objects may be finalized any time, or not at all.

* http://www.digitalmars.com/d/2.0/class.html#Destructor


[D1][expressions] Order Of Evaluation

2010-10-08 Thread %u
/The following binary expressions are evaluated in an implementation-defined
order:
AssignExpression/../AddExpression/

/It is an error to depend on order of evaluation when it is not specified./

That makes this an error!?

y = x + 1;

Am I being paranoid or should I be adding more brackets?


Re: lvalue method

2010-10-08 Thread Steven Schveighoffer
On Fri, 08 Oct 2010 09:51:59 -0400, Simen kjaeraas  
 wrote:



Steven Schveighoffer  wrote:


The correct way is to use auto ref as the parameter:

struct vec4
{
...
vec4 Normalize(auto ref const(vec4) param) {...}
}

But AFAIK, this doesn't really work.


It doesn't, no. I'm not even sure it's scheduled for inclusion.


Andrei, I thought this was planned?


Also, with bugzilla #4843, overloading ref/non-ref for structs don't
work, so the only current solution is to not use ref.


Bummer.  At least rvalues will be as fast as possible, and it will work as  
a temporary solution.


FWIW, I don't consider duplicating a function to be a good solution, we  
can do better.


But don't try doing opEquals without ref const, because the compiler won't  
allow it :)


-Steve


Re: lvalue method

2010-10-08 Thread Simen kjaeraas

Steven Schveighoffer  wrote:


The correct way is to use auto ref as the parameter:

struct vec4
{
...
vec4 Normalize(auto ref const(vec4) param) {...}
}

But AFAIK, this doesn't really work.


It doesn't, no. I'm not even sure it's scheduled for inclusion.
Also, with bugzilla #4843, overloading ref/non-ref for structs don't
work, so the only current solution is to not use ref.

--
Simen


Re: lvalue method

2010-10-08 Thread Steven Schveighoffer
On Fri, 08 Oct 2010 09:26:19 -0400, Benjamin Thaut  
 wrote:



Am 08.10.2010 11:13, schrieb Lars T. Kyllingstad:

On Fri, 08 Oct 2010 09:33:22 +0200, Benjamin Thaut wrote:


Hi, I'm writing a vec4 math struct and I have a method of which the
return value has to be a lvalue so I wonder which is the correct way to
do this:

vec4 Normalize() const { ... } //won't work, not a lvalue

ref vec4 Normalize() const {
vec4 temp;
...
return temp;
} //will this lead to a segfault or not?


The compiler shouldn't even accept this.  When I try a similar thing,  
DMD

says "Error: escaping reference to local variable temp".



ref vec4 Normalize() const {
vec4* temp = new vec4;
...
return *temp;
} //ugly, don't want to allocate anything on the heap


This would work, since the variable is no longer on the stack and thus
survives the return of the function.



auto ref vec4 Normalize() const {
vec4 temp;
...
return temp;
} //will this lead to a segfault?


Well, that should compile, but it doesn't work the way you want.  'auto
ref' means that the function returns by ref if the return expression is
an lvalue *and it would not be a reference to a local or a parameter*.
So for this example, your function would return by value, not by ref.



Or do I need to do it totaly in some other way?


Yes, you do. :)  You are trying to create a variable on the stack, and
return it by reference.  The problem is that when the function returns,
its stack frame (the memory occupied by the function's local variables)
is "released".  At that point the variable doesn't exist anymore, and  
any

reference to it would be invalid.

-Lars


All this was only to get it to return a lvalue. I need a lvalue to be  
able to do stuff like this.


vec4 v1 = vec4(...);
vec4 v2 = vec4(...);
vec4 v3 = v1.Cross(v2.Normalize()).Normalize();

Here it complained that v2.Normalize is not a lvalue, for whatever  
reason.


I'm trying to make my matrix class work even if it is const to prevent  
it from coyping 16 floats everytime I pass it to a function.


mat4 opMul(ref const(mat4) m1, ref const(mat4) m2) const {
   ...
}

I tried many things, but it turned out that basically I have to get rid  
of all the consts and let it copy the matrixes everytime.


Because either it would tell me can not call  
opMul((mat4)const,(mat4)const) const with (mat4)const, (mat4)const <- I  
think this is because of the ref.


Or it would tell me opMul(...) is not a lvalue if I try it to use it  
like this


vec4 v1,v2;
mat4 m;

vec4 res = (v1 - m * v2);

I'm coming form C++ so is it the correct way to overload such operators  
without const at all? Because obviously I don't want it to copy  
unneccessarily.


The correct way is to use auto ref as the parameter:

struct vec4
{
   ...
   vec4 Normalize(auto ref const(vec4) param) {...}
}

But AFAIK, this doesn't really work.

What it *should* do is generate two versions of Normalize, one which  
passes param by reference for lvalues, and one that passes by value for  
rvalues.  Passing rvalues by value is more efficient and less problematic  
than passing by reference, since the value is already located on the  
stack, and there is no need to make a copy.


-Steve


Re: lvalue method

2010-10-08 Thread Benjamin Thaut

Am 08.10.2010 11:13, schrieb Lars T. Kyllingstad:

On Fri, 08 Oct 2010 09:33:22 +0200, Benjamin Thaut wrote:


Hi, I'm writing a vec4 math struct and I have a method of which the
return value has to be a lvalue so I wonder which is the correct way to
do this:

vec4 Normalize() const { ... } //won't work, not a lvalue

ref vec4 Normalize() const {
vec4 temp;
...
return temp;
} //will this lead to a segfault or not?


The compiler shouldn't even accept this.  When I try a similar thing, DMD
says "Error: escaping reference to local variable temp".



ref vec4 Normalize() const {
vec4* temp = new vec4;
...
return *temp;
} //ugly, don't want to allocate anything on the heap


This would work, since the variable is no longer on the stack and thus
survives the return of the function.



auto ref vec4 Normalize() const {
vec4 temp;
...
return temp;
} //will this lead to a segfault?


Well, that should compile, but it doesn't work the way you want.  'auto
ref' means that the function returns by ref if the return expression is
an lvalue *and it would not be a reference to a local or a parameter*.
So for this example, your function would return by value, not by ref.



Or do I need to do it totaly in some other way?


Yes, you do. :)  You are trying to create a variable on the stack, and
return it by reference.  The problem is that when the function returns,
its stack frame (the memory occupied by the function's local variables)
is "released".  At that point the variable doesn't exist anymore, and any
reference to it would be invalid.

-Lars


All this was only to get it to return a lvalue. I need a lvalue to be 
able to do stuff like this.


vec4 v1 = vec4(...);
vec4 v2 = vec4(...);
vec4 v3 = v1.Cross(v2.Normalize()).Normalize();

Here it complained that v2.Normalize is not a lvalue, for whatever reason.

I'm trying to make my matrix class work even if it is const to prevent 
it from coyping 16 floats everytime I pass it to a function.


mat4 opMul(ref const(mat4) m1, ref const(mat4) m2) const {
  ...
}

I tried many things, but it turned out that basically I have to get rid 
of all the consts and let it copy the matrixes everytime.


Because either it would tell me can not call 
opMul((mat4)const,(mat4)const) const with (mat4)const, (mat4)const <- I 
think this is because of the ref.


Or it would tell me opMul(...) is not a lvalue if I try it to use it 
like this


vec4 v1,v2;
mat4 m;

vec4 res = (v1 - m * v2);

I'm coming form C++ so is it the correct way to overload such operators 
without const at all? Because obviously I don't want it to copy 
unneccessarily.


--
Kind Regards
Benjamin Thaut


Re: question about property for built-in type

2010-10-08 Thread %u
Thanks for the reply.

I wonder are there any alternatives to achieve similar things for built-in 
types?
I think this is very helpful for template function for built-in types.


Re: question about property for built-in type

2010-10-08 Thread Stanislav Blinov

 08.10.2010 16:19, %u wrote:

Hi,
I'm learning D right now and got a question about property.
I tried to add a property for built-in type like the following

@property bool equalZero(double a) { return a == 0.0; }

void main()
{
   ...
   double x = 4.4;
   bool isXZero = x.equalZero;
   ...
}

but got an error message
main.d(75): Error: no property 'equalZero' for type 'double'

I tried similar thing with int[] and it works.
Is that I did something wrong or property does not support built-in type like
double, int, real, ...?

Appreciate for your time and answer.



What you're trying to do is utilize uniform function call syntax (foo(T) 
=== T.foo()), but that is currently supported *only* for arrays. AFAIK 
it's going to be implemented at some point, but right now you will have 
to use equalZero(a) instead of a.equalZero.


Re: question about property for built-in type

2010-10-08 Thread Denis Koroskin

On Fri, 08 Oct 2010 16:19:43 +0400, %u  wrote:


Hi,
I'm learning D right now and got a question about property.
I tried to add a property for built-in type like the following

@property bool equalZero(double a) { return a == 0.0; }

void main()
{
  ...
  double x = 4.4;
  bool isXZero = x.equalZero;
  ...
}

but got an error message
main.d(75): Error: no property 'equalZero' for type 'double'

I tried similar thing with int[] and it works.
Is that I did something wrong or property does not support built-in type  
like

double, int, real, ...?

Appreciate for your time and answer.



Uniform Function Call syntax (i.e. a.b(c) -> b(a, c)) only works for  
arrays atm. This may or may not be changed in future.


question about property for built-in type

2010-10-08 Thread %u
Hi,
I'm learning D right now and got a question about property.
I tried to add a property for built-in type like the following

@property bool equalZero(double a) { return a == 0.0; }

void main()
{
  ...
  double x = 4.4;
  bool isXZero = x.equalZero;
  ...
}

but got an error message
main.d(75): Error: no property 'equalZero' for type 'double'

I tried similar thing with int[] and it works.
Is that I did something wrong or property does not support built-in type like
double, int, real, ...?

Appreciate for your time and answer.



Re: lvalue method

2010-10-08 Thread Lars T. Kyllingstad
On Fri, 08 Oct 2010 09:33:22 +0200, Benjamin Thaut wrote:

> Hi, I'm writing a vec4 math struct and I have a method of which the
> return value has to be a lvalue so I wonder which is the correct way to
> do this:
>
> vec4 Normalize() const { ... } //won't work, not a lvalue
> 
> ref vec4 Normalize() const {
>vec4 temp;
>...
>return temp;
> } //will this lead to a segfault or not?

The compiler shouldn't even accept this.  When I try a similar thing, DMD 
says "Error: escaping reference to local variable temp".


> ref vec4 Normalize() const {
>vec4* temp = new vec4;
>...
>return *temp;
> } //ugly, don't want to allocate anything on the heap

This would work, since the variable is no longer on the stack and thus 
survives the return of the function.


> auto ref vec4 Normalize() const {
>vec4 temp;
>...
>return temp;
> } //will this lead to a segfault?

Well, that should compile, but it doesn't work the way you want.  'auto 
ref' means that the function returns by ref if the return expression is 
an lvalue *and it would not be a reference to a local or a parameter*.  
So for this example, your function would return by value, not by ref.

 
> Or do I need to do it totaly in some other way?

Yes, you do. :)  You are trying to create a variable on the stack, and 
return it by reference.  The problem is that when the function returns, 
its stack frame (the memory occupied by the function's local variables) 
is "released".  At that point the variable doesn't exist anymore, and any 
reference to it would be invalid.

-Lars


Re: lvalue method

2010-10-08 Thread Simen kjaeraas

Benjamin Thaut  wrote:

Hi, I'm writing a vec4 math struct and I have a method of which the  
return value has to be a lvalue so I wonder which is the correct way to  
do this:


vec4 Normalize() const { ... } //won't work, not a lvalue

ref vec4 Normalize() const {
   vec4 temp;
   ...
   return temp;
} //will this lead to a segfault or not?


Will simply not compile.
(Error: escaping reference to local variable temp)



ref vec4 Normalize() const {
   vec4* temp = new vec4;
   ...
   return *temp;
} //ugly, don't want to allocate anything on the heap


This will work.



auto ref vec4 Normalize() const {
   vec4 temp;
   ...
   return temp;
} //will this lead to a segfault?


The compiler will conclude that temp cannot be returned as ref, and
thus do a value return.



Or do I need to do it totaly in some other way?


Don't know. Why does it have to be an lvalue?

--
Simen


Re: lvalue method

2010-10-08 Thread Stanislav Blinov

Benjamin Thaut wrote:
Hi, I'm writing a vec4 math struct and I have a method of which the 
return value has to be a lvalue so I wonder which is the correct way to 
do this:


vec4 Normalize() const { ... } //won't work, not a lvalue

ref vec4 Normalize() const {
  vec4 temp;
  ...
  return temp;
} //will this lead to a segfault or not?

ref vec4 Normalize() const {
  vec4* temp = new vec4;
  ...
  return *temp;
} //ugly, don't want to allocate anything on the heap

auto ref vec4 Normalize() const {
  vec4 temp;
  ...
  return temp;
} //will this lead to a segfault?

Or do I need to do it totaly in some other way?



If you need to normalize vector inplace, then your Normalize() shouldn't 
be const:


ref vec4 Normalize() {
// code
return this;
}

If you want to return a normalized copy of vector, the you don't need ref:

vec4 Normalize() const {
vec4 temp;
//...
return temp;
}


Re: Static problem

2010-10-08 Thread Stanislav Blinov

Bob Cowdery wrote:

 On 07/10/2010 21:32, Stanislav Blinov wrote:

Steven Schveighoffer wrote:


What I'd propose is either:
1) Create your own lock-free associative array (yup, reinvent the
wheel to introduce AA to the world of 'shared')
2) In this small case it may seem best (though mind that often such
cases do grow up to the point when you still need to rethink design):
Make your associative array __gshared and perform synchronization by
hand, i.e. create a static Mutex (from core.sync.mutex) variable and
initialize it in your CRegistry's static ctor, and then enclose all
access to associative array in synchronized(mutex) {} blocks.

Maybe concurrent-programming-in-D guru may propose simpler solution,
but I don't see another.

FWIW, the classinfo of a class is an object, and as such can be used
as sort of a global lock without having to use a static constructor:

synchronized(this.classinfo)
{
   
}

-Steve

Thanks. To my shame, I repeatedly keep forgetting about this.

Thanks for the suggestions. I'm keen to avoid locks as everything so far
is message parsing and the system is real-time. Having lots of threads
that all talk to each other I needed a place to keep the Tid's which is
accessible to everyone. There is no conflict because the main thread
creates all others and registers the Tid's. Once the threads go the
registry is read only. Just setting __gshared makes the app work. This
may not be good practice I know and I will come back to it when I have
more time.

I'm not sure how to use synchronized(this.classinfo). Is this in
combination with __gshared to synchronise access at the method level. Is
it like a wrapper that goes inside the method?

bob


Yeah, it's like this:

static void register(E_PROC name, Tid tid)
{
synchronized(this.classinfo)
{
theRegistry[name] = tid;
}
}

static Tid getTid(E_PROC name)
{
Tid* result;
synchronized(this.classinfo)
{
result = name in TidRegistry;
}
//...
}

All Objects contain a 'monitor' which is a synchronization primitive.

synchronized(some_object)
{
foo();
}

is similar to

{
some_mutex.lock();
scope(exit) some_mutex.unlock();
// some code
}


Re: Static problem

2010-10-08 Thread Bob Cowdery
 On 07/10/2010 21:32, Stanislav Blinov wrote:
> Steven Schveighoffer wrote:
>
>>> What I'd propose is either:
>>> 1) Create your own lock-free associative array (yup, reinvent the
>>> wheel to introduce AA to the world of 'shared')
>>> 2) In this small case it may seem best (though mind that often such
>>> cases do grow up to the point when you still need to rethink design):
>>> Make your associative array __gshared and perform synchronization by
>>> hand, i.e. create a static Mutex (from core.sync.mutex) variable and
>>> initialize it in your CRegistry's static ctor, and then enclose all
>>> access to associative array in synchronized(mutex) {} blocks.
>>>
>>> Maybe concurrent-programming-in-D guru may propose simpler solution,
>>> but I don't see another.
>>
>> FWIW, the classinfo of a class is an object, and as such can be used
>> as sort of a global lock without having to use a static constructor:
>>
>> synchronized(this.classinfo)
>> {
>>
>> }
>>
>> -Steve
>
> Thanks. To my shame, I repeatedly keep forgetting about this.
Thanks for the suggestions. I'm keen to avoid locks as everything so far
is message parsing and the system is real-time. Having lots of threads
that all talk to each other I needed a place to keep the Tid's which is
accessible to everyone. There is no conflict because the main thread
creates all others and registers the Tid's. Once the threads go the
registry is read only. Just setting __gshared makes the app work. This
may not be good practice I know and I will come back to it when I have
more time.

I'm not sure how to use synchronized(this.classinfo). Is this in
combination with __gshared to synchronise access at the method level. Is
it like a wrapper that goes inside the method?

bob


lvalue method

2010-10-08 Thread Benjamin Thaut
Hi, I'm writing a vec4 math struct and I have a method of which the 
return value has to be a lvalue so I wonder which is the correct way to 
do this:


vec4 Normalize() const { ... } //won't work, not a lvalue

ref vec4 Normalize() const {
  vec4 temp;
  ...
  return temp;
} //will this lead to a segfault or not?

ref vec4 Normalize() const {
  vec4* temp = new vec4;
  ...
  return *temp;
} //ugly, don't want to allocate anything on the heap

auto ref vec4 Normalize() const {
  vec4 temp;
  ...
  return temp;
} //will this lead to a segfault?

Or do I need to do it totaly in some other way?

--
Kind Regards
Benjamin Thaut