Get template parameter value

2015-09-29 Thread rumbu via Digitalmars-d-learn

Having a template:

struct SomeStruct(int size)
{

}

Is there any language trait returning the value of size template 
parameter for the template instantiation SomeStruct!10?


In fact, I'm interested in an eponymous template to test if some 
type is a template inttantation for SomeStruct(int size).


template isSomeStruct(T)
{
  enum isSomeStruct = ?
}

template getStructSize(T) if (isSomeStruct!T)
{
  enum getStructSize = ?
}


I know that I can do something like this:

struct SomeStruct(int size)
{
   enum internalSize = size;
}

template isSomeStruct(T)
{
  enum isSomeStruct = is (typeof(T.internalSize): int);
}

template getStructSize(T) if (isSomeStruct!T)
{
  enum getStructSize = T.internalSize;
}

but I wonder that if it's not another simple and safe way. This 
approach is not safe because there is a risk to have 
SomeOtherStruct(int size) defined with similar semantics.


Thanks.



Re: enum to flags

2015-09-29 Thread Nicholas Wilson via Digitalmars-d-learn

On Tuesday, 29 September 2015 at 06:08:03 UTC, Cauterite wrote:
On Tuesday, 29 September 2015 at 03:31:44 UTC, Nicholas Wilson 
wrote:
so I have a bunch of enums (0 .. n) that i also want to 
represent as flags ( 1 << n foreach n ). Is there anyway to do 
this other than a string mixin?


You could cheat with operator overloading:

enum blah {
foo,
bar,
baz,
};

struct EnumToFlags(alias E) {
template opDispatch(string Name) {
enum opDispatch = 1 << __traits(getMember, E, Name);
};
};

alias blahFlags = EnumToFlags!blah;

static assert(blahFlags.foo == (1 << blah.foo));
static assert(blahFlags.bar == (1 << blah.bar));
static assert(blahFlags.baz == (1 << blah.baz));


Cheating is always good. I'l probably add some template 
constraints.


Thanks
Nic


Re: enum to flags

2015-09-29 Thread Cauterite via Digitalmars-d-learn
On Tuesday, 29 September 2015 at 03:31:44 UTC, Nicholas Wilson 
wrote:
so I have a bunch of enums (0 .. n) that i also want to 
represent as flags ( 1 << n foreach n ). Is there anyway to do 
this other than a string mixin?


You could cheat with operator overloading:

enum blah {
foo,
bar,
baz,
};

struct EnumToFlags(alias E) {
template opDispatch(string Name) {
enum opDispatch = 1 << __traits(getMember, E, Name);
};
};

alias blahFlags = EnumToFlags!blah;

static assert(blahFlags.foo == (1 << blah.foo));
static assert(blahFlags.bar == (1 << blah.bar));
static assert(blahFlags.baz == (1 << blah.baz));


Re: enum to flags

2015-09-29 Thread Meta via Digitalmars-d-learn
On Tuesday, 29 September 2015 at 03:31:44 UTC, Nicholas Wilson 
wrote:
so I have a bunch of enums (0 .. n) that i also want to 
represent as flags ( 1 << n foreach n ). Is there anyway to do 
this other than a string mixin?


use like:

enum blah
{
foo,
bar,
baz,
}

alias blahFlags = EnumToFlags!blah;

static assert(blahFlags.baz == 1 << blah.baz)


Take a look at the BitFlags template as well. It won't create 
such an enum for you, but will provide a convenient wrapper for 
using it afterword:


http://dlang.org/phobos/std_typecons.html#.BitFlags


Re: enum to flags

2015-09-29 Thread Nicholas Wilson via Digitalmars-d-learn

On Tuesday, 29 September 2015 at 09:18:52 UTC, John Colvin wrote:
On Tuesday, 29 September 2015 at 03:31:44 UTC, Nicholas Wilson 
wrote:
so I have a bunch of enums (0 .. n) that i also want to 
represent as flags ( 1 << n foreach n ). Is there anyway to do 
this other than a string mixin?


use like:

enum blah
{
foo,
bar,
baz,
}

alias blahFlags = EnumToFlags!blah;

static assert(blahFlags.baz == 1 << blah.baz)


Answering a slightly different question, I just wanted to be 
sure you're aware of this old idiom:


enum blah
{
foo = 0b1;
bar = 0b10;
baz = 0b100;
//and so on...
}

auto fdsa = blah.foo | blah.baz;
assert(fdsa & blah.foo);
assert(fdsa & blah.baz);
assert(!(fdsa & blah.bar));


I am. The reason I wanted was so i could easily reorder them 
(logical groupings etc. ) .


Nic


Re: Do users need to install VS runtime redistributable if linking with Microsoft linker?

2015-09-29 Thread Sebastiaan Koppe via Digitalmars-d-learn

On Tuesday, 29 September 2015 at 09:15:29 UTC, ponce wrote:
On Monday, 28 September 2015 at 16:01:54 UTC, Sebastiaan Koppe 
wrote:
I could not find out which redistributable I had to install 
(what version of VS did you have installed / on what version 
of windows are you?). I decided to install them all, but 
couldn't install the one for 2015 (due to 
Windows6.1-KB2999226-x64.msu). After trying some workarounds I 
gave up.




You need the VC++ 2015 64-bit redistributable.


Can you either link statically or try an older version of VC, one 
that is more likely to be found in the wild? (or does ldc require 
2015?)


I really want to try your game :)


Re: Get template parameter value

2015-09-29 Thread John Colvin via Digitalmars-d-learn

On Tuesday, 29 September 2015 at 09:53:39 UTC, Kagamin wrote:
On Tuesday, 29 September 2015 at 09:11:15 UTC, John Colvin 
wrote:
Welcome to the weird and wonderful work of  
http://dlang.org/expression.html#IsExpression


No, use template pattern matching instead:

struct A(int s){}
template B(T:A!s, int s){ enum B=s; }
static assert(B!(A!4)==4);


For some reason I never think of template pattern matching. Not 
my favourite feature, although it's probably just the ':' that 
bothers me, I always think of implicit convertibility like in 
is(T : Q). Anyway, you're right, it makes for shorter, neater 
code in simple cases (the static if version is equivalent if you 
just add a template constraint to it).


Re: Get template parameter value

2015-09-29 Thread Andrea Fontana via Digitalmars-d-learn

On Tuesday, 29 September 2015 at 07:50:42 UTC, rumbu wrote:

Having a template:

struct SomeStruct(int size)
{

}

Is there any language trait returning the value of size 
template parameter for the template instantiation SomeStruct!10?


Something like this is ok?

struct SomeStruct(int size)
{
enum structSize = size;
}

template isSomeStruct(alias S)
{
void check(alias T)(SomeStruct!T val) { }
enum isSomeStruct = __traits(compiles, check(S));
}

template getStructSize(alias S) if (isSomeStruct!S)
{
enum getStructSize = S.structSize;
}

void main()
{
import std.stdio;
SomeStruct!10 test;
writeln(isSomeStruct!test);
writeln(getStructSize!test);
}




Re: enum to flags

2015-09-29 Thread John Colvin via Digitalmars-d-learn
On Tuesday, 29 September 2015 at 03:31:44 UTC, Nicholas Wilson 
wrote:
so I have a bunch of enums (0 .. n) that i also want to 
represent as flags ( 1 << n foreach n ). Is there anyway to do 
this other than a string mixin?


use like:

enum blah
{
foo,
bar,
baz,
}

alias blahFlags = EnumToFlags!blah;

static assert(blahFlags.baz == 1 << blah.baz)


Answering a slightly different question, I just wanted to be sure 
you're aware of this old idiom:


enum blah
{
foo = 0b1;
bar = 0b10;
baz = 0b100;
//and so on...
}

auto fdsa = blah.foo | blah.baz;
assert(fdsa & blah.foo);
assert(fdsa & blah.baz);
assert(!(fdsa & blah.bar));


Re: Do users need to install VS runtime redistributable if linking with Microsoft linker?

2015-09-29 Thread ponce via Digitalmars-d-learn
On Monday, 28 September 2015 at 16:01:54 UTC, Sebastiaan Koppe 
wrote:
I could not find out which redistributable I had to install 
(what version of VS did you have installed / on what version of 
windows are you?). I decided to install them all, but couldn't 
install the one for 2015 (due to Windows6.1-KB2999226-x64.msu). 
After trying some workarounds I gave up.




You need the VC++ 2015 64-bit redistributable.


Re: Do users need to install VS runtime redistributable if linking with Microsoft linker?

2015-09-29 Thread Kagamin via Digitalmars-d-learn

On Monday, 28 September 2015 at 16:36:47 UTC, ponce wrote:
OK, but why does that need to happen? I don't get why does 
linking with MS linker implies a runtime dependency.


I thought we would be left out of these sort of problems when 
using D :(


About universal CRT: 
http://blogs.msdn.com/b/vcblog/archive/2015/03/03/introducing-the-universal-crt.aspx

https://support.microsoft.com/en-us/kb/2999226


Re: Get template parameter value

2015-09-29 Thread Andrea Fontana via Digitalmars-d-learn
On Tuesday, 29 September 2015 at 08:44:03 UTC, Andrea Fontana 
wrote:

On Tuesday, 29 September 2015 at 07:50:42 UTC, rumbu wrote:

Having a template:

struct SomeStruct(int size)
{

}

Is there any language trait returning the value of size 
template parameter for the template instantiation 
SomeStruct!10?


Something like this is ok?

struct SomeStruct(int size)
{
enum structSize = size;
}

template isSomeStruct(alias S)
{
void check(alias T)(SomeStruct!T val) { }
enum isSomeStruct = __traits(compiles, check(S));
}

template getStructSize(alias S) if (isSomeStruct!S)
{
enum getStructSize = S.structSize;
}

void main()
{
import std.stdio;
SomeStruct!10 test;
writeln(isSomeStruct!test);
writeln(getStructSize!test);
}


You can also write void check(alias T) as void check(int T), of 
course.


Re: Get template parameter value

2015-09-29 Thread rumbu via Digitalmars-d-learn

On Tuesday, 29 September 2015 at 09:53:39 UTC, Kagamin wrote:
On Tuesday, 29 September 2015 at 09:11:15 UTC, John Colvin 
wrote:
Welcome to the weird and wonderful work of  
http://dlang.org/expression.html#IsExpression


No, use template pattern matching instead:

struct A(int s){}
template B(T:A!s, int s){ enum B=s; }
static assert(B!(A!4)==4);


Thank you, this is perfect.


Re: Get template parameter value

2015-09-29 Thread John Colvin via Digitalmars-d-learn

On Tuesday, 29 September 2015 at 07:50:42 UTC, rumbu wrote:

Having a template:

struct SomeStruct(int size)
{

}

Is there any language trait returning the value of size 
template parameter for the template instantiation SomeStruct!10?


This should do it (untested):

template SomeStructSize(T)
{
static if(is(T == SomeStruct!n, n))
enum SomeStructSize = n;
else static assert(false, T.stringof ~ " is not an instance 
of SomeStruct");

}

Welcome to the weird and wonderful work of  
http://dlang.org/expression.html#IsExpression


Re: Threading Questions

2015-09-29 Thread Russel Winder via Digitalmars-d-learn
On Tue, 2015-09-29 at 03:05 +, bitwise via Digitalmars-d-learn
wrote:
> On Monday, 28 September 2015 at 11:47:38 UTC, Russel Winder wrote:
> > I hadn't answered as I do not have answers to the questions you 
> > ask. My reason: people should not be doing their codes using 
> > these low-level shared memory techniques. Data parallel things 
> > should be using the std.parallelism module. Dataflow-style 
> > things should be using spawn and channels – akin to the way you 
> > do things in Go.
> > 
> > So to give you an answer I would go back a stage, forget 
> > threads, mutexes, synchronized, etc. and ask what do you want 
> > you workers to do? If they are to do something and return a 
> > result then spawn and channel is exactly the right abstraction 
> > to use. Think "farmer–worker", the farmer spawns the workers 
> > and then collects their results. No shared memory anywyere – at 
> > least not mutable.
> 
> https://www.youtube.com/watch?v=S7pGs7JU7eM
> 
>  Bit

What's the tl;dr as text, I very, very rarely watch videos.

-- 
Russel.
=
Dr Russel Winder  t: +44 20 7585 2200   voip: sip:russel.win...@ekiga.net
41 Buckmaster Roadm: +44 7770 465 077   xmpp: rus...@winder.org.uk
London SW11 1EN, UK   w: www.russel.org.uk  skype: russel_winder



signature.asc
Description: This is a digitally signed message part


Re: Do users need to install VS runtime redistributable if linking with Microsoft linker?

2015-09-29 Thread ponce via Digitalmars-d-learn
On Tuesday, 29 September 2015 at 09:44:58 UTC, Sebastiaan Koppe 
wrote:

On Tuesday, 29 September 2015 at 09:15:29 UTC, ponce wrote:
On Monday, 28 September 2015 at 16:01:54 UTC, Sebastiaan Koppe 
wrote:
I could not find out which redistributable I had to install 
(what version of VS did you have installed / on what version 
of windows are you?). I decided to install them all, but 
couldn't install the one for 2015 (due to 
Windows6.1-KB2999226-x64.msu). After trying some workarounds 
I gave up.




You need the VC++ 2015 64-bit redistributable.


Can you either link statically or try an older version of VC, 
one that is more likely to be found in the wild? (or does ldc 
require 2015?)


No, not without rebuilding Phobos/druntime as it stands.
https://github.com/ldc-developers/ldc/issues/1133



I really want to try your game :)


Version 1.7 is still available and is compiled with DMD for 
32-bit Windows.


You can also clone the repo and type "dub": 
https://github.com/p0nce/Vibrant


Given the general speed up with LDC, it would need more 
profiling/optimizing to get back to DMD. Maybe next release.





Re: Why getting private member fails using getMember trait in a template?

2015-09-29 Thread Alexandru Ermicioi via Digitalmars-d-learn
On Saturday, 26 September 2015 at 10:10:39 UTC, Alexandru 
Ermicioi wrote:

Suppose we have, two modules:

module testOne;

[...]


So, is this behavior correct?
If yes, then why?


Re: Get template parameter value

2015-09-29 Thread Kagamin via Digitalmars-d-learn

On Tuesday, 29 September 2015 at 09:11:15 UTC, John Colvin wrote:
Welcome to the weird and wonderful work of  
http://dlang.org/expression.html#IsExpression


No, use template pattern matching instead:

struct A(int s){}
template B(T:A!s, int s){ enum B=s; }
static assert(B!(A!4)==4);


Move Semantics

2015-09-29 Thread Alex via Digitalmars-d-learn

Another question on move semantics from the cheap seats...

See my code here: http://dpaste.dzfl.pl/995c5af59dd6
There are indeed three questions, all marked in the code, so the 
rest of the text here is maybe redundant... but just in case and 
for summary:


I try to model a inner class of some outer one. Then, as I 
learned from the docu, there is a implicit pointer to the outer 
class from the inner one by ".outer" key word. So far so good.

My outer class has an associative array of the inner objects.
Now, I try to apply a move action to the inner objects between 
two outer objects.


The first (minor) question is:
I have to initialize some dummy inner objects, before I can apply 
the move action. Is this really necessary? It won't be that 
problem I think, if it is so, but it would be nicer, if I could 
just perform the move operation.


The second question is:
Following my code, the inner object I moved does not disappear 
from the array in the source outer object. Why? I tried it 
without, with an empty and with a non empty destructor, the 
result was the same.


And the third, main, question is:
After I moved the inner object to the new outer object, the 
pointer to the outer object remains in the old state, to the 
source outer object. This is not what I expected! Well, yes this 
is some subjective expectation, but shouldn't an implicit pointer 
update itself to not break the logic of what it points to?


The third question has some more meaning in my case: I would like 
to compose some immutable classes, which are inner classes. The 
only mutable value therein should be the pointer to the outer 
class.
I know, I could manage this by some map (+ an array, optionally) 
construct, and I'm on my way to implement this approach. But 
then, I noticed the nested class section and the implicit 
pointers, which are not present in C++, for example, and I wanted 
to try this solution.

Is there maybe an error somewhere in my code?


Re: Get template parameter value

2015-09-29 Thread Artur Skawina via Digitalmars-d-learn
On 09/29/15 12:13, rumbu via Digitalmars-d-learn wrote:
> On Tuesday, 29 September 2015 at 09:53:39 UTC, Kagamin wrote:
>> On Tuesday, 29 September 2015 at 09:11:15 UTC, John Colvin wrote:
>>> Welcome to the weird and wonderful work of  
>>> http://dlang.org/expression.html#IsExpression
>>
>> No, use template pattern matching instead:
>>
>> struct A(int s){}
>> template B(T:A!s, int s){ enum B=s; }
>> static assert(B!(A!4)==4);
> 
> Thank you, this is perfect.

There's always room for improvement... ;)

   enum B(T:A!s, int s) = s;

artur



Re: Interval Arithmetic

2015-09-29 Thread anonymous via Digitalmars-d-learn

On Tuesday, 29 September 2015 at 21:04:06 UTC, Wulfrick wrote:
Is there an interval arithmetic library in D? I couldn’t find 
one.

None I am aware of.


In case I had to write my own, I understand that the IEEE 
standard floating point arithmetic provides operations for 
rounding up or down certain operations like summing, 
subtracting, etc. (thus overriding the default behavior of 
rounding to nearest representable).


How do I access this functionality in D? At first I thought 
that std.math.nextDown and nextUp is what I needed, but not so. 
Apparently these functions return the previous or next 
representable *after* the calculation has been done.


For example, I would like the value of x+y rounded in the 
arithmetic towards -\infty, which may or may not be 
nextDown(x+y).


Any luck?
Thanks for reading!


fencv.h  [1] + a few extern(C) declarations could work - changes 
the rounding mode.

Maybe there is an inline ASM solution, too.

I have never tried to use that from D. The FENV_ACCESS pragma 
could cause problems - don't know how to pass that info to a D 
compiler (never tried to figure it out).


It may be easier to generate an binding for an existing C/C++ 
lib, e.g. [2] (page is in German, but the downloadable tar.gz 
("komprimierte (gzipped) tar-Datei") contains an English readme. 
Boost also contains an interval arithmetic lib [3], but the use 
of C++ templates will most likely force you to write some glue 
code in C++...



[1] http://www.cplusplus.com/reference/cfenv/
[2] http://www.ti3.tuhh.de/keil/profil/ (GPL)
[3] 
http://www.boost.org/doc/libs/1_58_0/libs/numeric/interval/doc/interval.htm




Re: Threading Questions

2015-09-29 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/29/15 4:38 PM, Johannes Pfau wrote:

Am Tue, 29 Sep 2015 15:10:58 -0400
schrieb Steven Schveighoffer :




3) Why do I have to pass a "Mutex" to "Condition"? Why can't I just
pass an "Object"?


An object that implements the Monitor interface may not actually be a
mutex. For example, a pthread_cond_t requires a pthread_mutex_t to
operate properly. If you passed it anything that can act like a lock,
it won't work. So the Condition needs to know that it has an actual
Mutex, not just any lock-like object.

I think I advocated in the past to Sean that Condition should provide
a default ctor that just constructs a mutex, but it doesn't look like
that was done.



But you'll need access to the Mutex in user code as well.


synchronized(condition.mutex)


And often you
use multiple Conditions with one Mutex so a Condition doesn't really
own the Mutex.


It's just a different option. Often times, you have a condition 
variable, and a mutex variable.


It's not super-important, you can always do:

new Condition(new Mutex);





4) Will D's Condition ever experience spurious wakeups?


What do you mean by "spurious"? If you notify a condition, anything
that is waiting on it can be woken up. Since the condition itself is
user defined, there is no way for the actual Condition to verify you
will only be woken up when it is satisfied.

In terms of whether a condition could be woken when notify *isn't*
called, I suppose it's possible (perhaps interrupted by a signal?).
But I don't know why it would matter -- per above you should already
be checking the condition while within the lock.


Spurious wakeup is a common term when talking about posix conditions
and it does indeed mean a wait() call can return without ever calling
notify():
https://en.wikipedia.org/wiki/Spurious_wakeup
http://stackoverflow.com/questions/8594591/why-does-pthread-cond-wait-have-spurious-wakeups


OK thanks.


5) Why doesn't D's Condition.wait take a predicate? I assume this is
because the answer to (4) is no.


The actual "condition" that you are waiting on is up to you to
check/define.



He probably means that you could pass an expression to wait and wait
would do the looping / check internally. That's probably a nicer API
but not implemented.


yeah, that could probably be done. One thing to note is that these 
classes are from ages ago (probably close to 10 years). New API 
suggestions may be allowed.


I just wanted to stress that there isn't some sort of built-in condition 
predicate (like a boolean).


-Steve


Re: Move Semantics

2015-09-29 Thread Alex via Digitalmars-d-learn

Thank you very much for the comments.
It is much clearer now. The .outer link is just a shortcut, which 
does not mean I don't have to reset it, where I have to.
So... essentially, my expectation WAS to subjective and I have to 
separate better, what is the part of the model in my head and 
what is expected from the language/compiler.


Re: Threading Questions

2015-09-29 Thread Johannes Pfau via Digitalmars-d-learn
Am Tue, 29 Sep 2015 15:10:58 -0400
schrieb Steven Schveighoffer :

> 
> > 3) Why do I have to pass a "Mutex" to "Condition"? Why can't I just
> > pass an "Object"?
> 
> An object that implements the Monitor interface may not actually be a 
> mutex. For example, a pthread_cond_t requires a pthread_mutex_t to 
> operate properly. If you passed it anything that can act like a lock,
> it won't work. So the Condition needs to know that it has an actual
> Mutex, not just any lock-like object.
> 
> I think I advocated in the past to Sean that Condition should provide
> a default ctor that just constructs a mutex, but it doesn't look like
> that was done.
> 

But you'll need access to the Mutex in user code as well. And often you
use multiple Conditions with one Mutex so a Condition doesn't really
own the Mutex.

> >
> > 4) Will D's Condition ever experience spurious wakeups?
> 
> What do you mean by "spurious"? If you notify a condition, anything
> that is waiting on it can be woken up. Since the condition itself is
> user defined, there is no way for the actual Condition to verify you
> will only be woken up when it is satisfied.
> 
> In terms of whether a condition could be woken when notify *isn't* 
> called, I suppose it's possible (perhaps interrupted by a signal?).
> But I don't know why it would matter -- per above you should already
> be checking the condition while within the lock.

Spurious wakeup is a common term when talking about posix conditions
and it does indeed mean a wait() call can return without ever calling
notify():
https://en.wikipedia.org/wiki/Spurious_wakeup
http://stackoverflow.com/questions/8594591/why-does-pthread-cond-wait-have-spurious-wakeups

And yes, this does happen for core.sync.condition as well. As a result
you'll always have to check in a loop:

synchronized(mutex)
{
while(some_flag_or_expression)
{
cond.wait();
}
}

-
synchronized(mutex)
{
some_flag_or_expression = true;
cond.notify();
}

> 
> I think there are cases with multiple threads where you can
> potentially wake up the thread waiting on a condition AFTER the
> condition was already reset by another.
> 
> > 5) Why doesn't D's Condition.wait take a predicate? I assume this is
> > because the answer to (4) is no.
> 
> The actual "condition" that you are waiting on is up to you to
> check/define.
> 

He probably means that you could pass an expression to wait and wait
would do the looping / check internally. That's probably a nicer API
but not implemented.

> > 6) Does 'shared' actually have any effect on non-global variables
> > beside the syntactic regulations?
> 
> I believe shared doesn't alter code generation at all. It only
> prevents certain things and affects the type.
> 

It shouldn't. I think in GDC it does generate different code, but that's
an implementation detail that needs to be fixed.






Interval Arithmetic

2015-09-29 Thread Wulfrick via Digitalmars-d-learn

Is there an interval arithmetic library in D? I couldn’t find one.

In case I had to write my own, I understand that the IEEE 
standard floating point arithmetic provides operations for 
rounding up or down certain operations like summing, subtracting, 
etc. (thus overriding the default behavior of rounding to nearest 
representable).


How do I access this functionality in D? At first I thought that 
std.math.nextDown and nextUp is what I needed, but not so. 
Apparently these functions return the previous or next 
representable *after* the calculation has been done.


For example, I would like the value of x+y rounded in the 
arithmetic towards -\infty, which may or may not be nextDown(x+y).


Any luck?
Thanks for reading!



Re: Move Semantics

2015-09-29 Thread anonymous via Digitalmars-d-learn
On Tuesday 29 September 2015 16:38, Alex wrote:

> Another question on move semantics from the cheap seats...
> 
> See my code here: http://dpaste.dzfl.pl/995c5af59dd6
[...]
> The first (minor) question is:
> I have to initialize some dummy inner objects, before I can apply 
> the move action. Is this really necessary? It won't be that 
> problem I think, if it is so, but it would be nicer, if I could 
> just perform the move operation.

Accessing an non-existing element of an associative array doesn't initialize 
it. You have to assign to it. I've been slightly annoyed by this, too. I'm 
not sure what the reasons for the current behavior are. I guess it would 
slow down accesses (a bit? a lot?).

> The second question is:
> Following my code, the inner object I moved does not disappear 
> from the array in the source outer object. Why? I tried it 
> without, with an empty and with a non empty destructor, the 
> result was the same.

`move` doesn't know what greater structure you're moving from. It just takes 
two locations. There's no way for it to figure out that the source location 
is an element of an associative array or whatever.

> And the third, main, question is:
> After I moved the inner object to the new outer object, the 
> pointer to the outer object remains in the old state, to the 
> source outer object. This is not what I expected! Well, yes this 
> is some subjective expectation, but shouldn't an implicit pointer 
> update itself to not break the logic of what it points to?

Your view on the relations of the objects is that the Inner objects in an 
Outer's _innerarr field are owned by that Outer object. The compiler and 
`move` have no such notion. Objects of nested classes are not restricted to 
exist in fields of their .outer objects.

All in all, I think you expected more from nested classes and `move` than 
they provide.

An object of a (non-static) nested class just has a pointer to an object of 
the outer class. All this allows is some shorter syntax. The bond between 
the two objects isn't any tighter than other pointers.

`move` does little more than copying. It avoids postblits and destroys the 
source if necessary (i.e. reset to .init). It doesn't have any notion of 
ownership transfer.


Re: Move Semantics

2015-09-29 Thread Ali Çehreli via Digitalmars-d-learn

On 09/29/2015 07:38 AM, Alex wrote:

> See my code here: http://dpaste.dzfl.pl/995c5af59dd6

> Following my code, the inner object I moved does not disappear from the
> array in the source outer object. Why?

> After I moved the inner object to the new outer object, the pointer to
> the outer object remains in the old state, to the source outer object.

The output of the program is too complicated for me to understand what 
the expected behavior should be. Going with the text... :)


Some notes:

- Unlike C++, as classes have reference semantics, normally there should 
be no need to move class objects around.


* Even so, your expectation of the 'outer' pointer being updated is not 
something move() can decide on its own. Moving an object's parts 
elsewhere not necessarily require changing the context it operates in. 
move() cannot know that being a part of a member associative array (AA) 
constitues changing the 'outer' pointer. move() doesn't even know that 
the destination location is a part of a memory that is being used by an AA.


- When it is needed to transfer an object from one Outer object to 
another, setting the .outer property seems to work:


import std.stdio;

class Outer {
int i;

this (int i) {
writefln("Constructing an Outer at %s.", cast(void*)this);
this.i = i;
}

class Inner {
void workWith(Outer newOuter) {
this.outer = newOuter;
}

void report() {
writefln("I am working with %s. Its i is %s.",
 cast(void*)this.outer, this.outer.i);
}
}
}

void main() {
auto o1 = new Outer(1);
auto o2 = new Outer(2);

auto inner = o1.new Outer.Inner();

inner.report();
inner.workWith(o2);
inner.report();
}

(Casting a class variable to void* provides the location of the class 
object.)


Prints:

Constructing an Outer at 7F136FB81060.
Constructing an Outer at 7F136FB81080.
I am working with 7F136FB81060. Its i is 1.
I am working with 7F136FB81080. Its i is 2.

- Unrelated note: Unless there is a convincing reason, I recommend that 
constructors simply construct objects. Side-effects like objects' 
registering themselves should not take place in a constructor. I have 
been bitten by that myself and I have heard the same suggestion from 
others several times before.


Ali



Re: Threading Questions

2015-09-29 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/25/15 11:19 AM, bitwise wrote:

Hey, I've got a few questions if anybody's got a minute.

I'm trying to wrap my head around the threading situation in D. So far,
things seem to be working as expected, but I want to verify my solutions.

1) Are the following two snippets exactly equivalent(not just in
observable behaviour)?
a)

Mutex mut;
mut.lock();
scope(exit) mut.unlock();

b)
Mutex mut;
synchronized(mut) { }

Will 'synchronized' call 'lock' on the Mutex, or do something
else(possibly related to the interface Object.Monitor)?


Yes. A mutex object has it's internal lock as its monitor.


2) Phobos has 'Condition' which takes a Mutex in the constructor. The
documentation doesn't exactly specify this, but should I assume it works
the same as std::condition_variable in C++?


I am not sure about std::condition_variable. core.sync.condition works 
like a standard condition 
(https://en.wikipedia.org/wiki/Monitor_%28synchronization%29)



For example, is this correct?

Mutex mut;
Condition cond = new Condition(mut);

// mut must be locked before calling Condition.wait
synchronized(mut)  // depends on answer to (1)
{
 // wait() unlocks the mutex and enters wait state
 // wait() must re-acquire the mutex before returning when cond is
signalled
 cond.wait();
}


Yes, I believe it is.


3) Why do I have to pass a "Mutex" to "Condition"? Why can't I just pass
an "Object"?


An object that implements the Monitor interface may not actually be a 
mutex. For example, a pthread_cond_t requires a pthread_mutex_t to 
operate properly. If you passed it anything that can act like a lock, it 
won't work. So the Condition needs to know that it has an actual Mutex, 
not just any lock-like object.


I think I advocated in the past to Sean that Condition should provide a 
default ctor that just constructs a mutex, but it doesn't look like that 
was done.




4) Will D's Condition ever experience spurious wakeups?


What do you mean by "spurious"? If you notify a condition, anything that 
is waiting on it can be woken up. Since the condition itself is user 
defined, there is no way for the actual Condition to verify you will 
only be woken up when it is satisfied.


In terms of whether a condition could be woken when notify *isn't* 
called, I suppose it's possible (perhaps interrupted by a signal?). But 
I don't know why it would matter -- per above you should already be 
checking the condition while within the lock.


I think there are cases with multiple threads where you can potentially 
wake up the thread waiting on a condition AFTER the condition was 
already reset by another.



5) Why doesn't D's Condition.wait take a predicate? I assume this is
because the answer to (4) is no.


The actual "condition" that you are waiting on is up to you to check/define.


6) Does 'shared' actually have any effect on non-global variables beside
the syntactic regulations?


I believe shared doesn't alter code generation at all. It only prevents 
certain things and affects the type.



I know that all global variables are TLS unless explicitly marked as
'shared', but someone once told me something about 'shared' affecting
member variables in that accessing them from a separate thread would
return T.init instead of the actual value... or something like that.
This seems to be wrong(thankfully).


No, this isn't true.


For example, I have created this simple Worker class which seems to work
fine without a 'shared' keyword in sight(thankfully). I'm wondering
though, if there would be any unexpected consequences of doing things
this way.

http://dpaste.com/2ZG2QZV


Some errors:

1. When calling notifyAll, you should ALWAYS have the mutex locked.
2. Since the mutex is protecting _run, it should only be 
checked/modified with the lock held.
3. After you have been woken up, you should check that the condition is 
satisfied.
4. Technically, you shouldn't access member variables that are GC 
allocated from a dtor. I know it's a struct, but structs can be GC 
allocated as well.


I would replace your if(tasks.empty) with while(tasks.empty && _run) to 
fix issue 3.


-Steve