Re: How to strip struct/class invariants?

2015-07-06 Thread Steven Schveighoffer via Digitalmars-d-learn

On 7/5/15 8:15 AM, Artem Tarasov wrote:

OK, so there was an old bug fixed in 2.067
(https://issues.dlang.org/show_bug.cgi?id=4421) so that now unions
apparently can't contain a struct that has invariants. It kinda makes
sense, although I don't see why the invariants can be simply ignored, as
they don't have as much importance as destructors/postblits.


More importantly, invariants are only called when you call members of a 
struct (or assert it). It requires actual usage of the particular union 
member. So already the programmer has indicated that member is valid by 
using it.


It is NOT valid to arbitrarily pick one member of the union and call its 
invariant (or call all of them).


I think this is an incorrect position D has taken -- Invariants should 
be called when calling members of a struct in a union. If an implicit 
choice must be made, then it should be an error. But it's easy to make 
the invariant call explicit.


-Steve


Re: How to strip struct/class invariants?

2015-07-06 Thread John Colvin via Digitalmars-d-learn

On Sunday, 5 July 2015 at 15:39:50 UTC, Artem Tarasov wrote:

On Sunday, 5 July 2015 at 14:44:30 UTC, John Colvin wrote:


struct A
{
ubyte[B.sizeof] mem;
@property ref B b()
{
return *cast(B*)(mem.ptr);
}
mixin std.typecons.Proxy!b;
}



Thanks, I followed your suggestion and effectively rolled out 
my own union implementation. Ugly but it works.


struct A
{
ubyte[maxSizeof] _data;
@property ref T _as(T)() inout { return 
*cast(T*)(_data.ptr); }

alias b = _as!uint;
alias c = _as!size_t;
alias d = _as!double;
}


That works, but what I meant was, using my definition of struct 
A, you can put it in a union without the compiler complaining, 
and the invariants still get called. No need to write your own 
union implementation.


Re: How to strip struct/class invariants?

2015-07-05 Thread Artem Tarasov via Digitalmars-d-learn

On Sunday, 5 July 2015 at 14:44:30 UTC, John Colvin wrote:


struct A
{
ubyte[B.sizeof] mem;
@property ref B b()
{
return *cast(B*)(mem.ptr);
}
mixin std.typecons.Proxy!b;
}



Thanks, I followed your suggestion and effectively rolled out my 
own union implementation. Ugly but it works.


struct A
{
ubyte[maxSizeof] _data;
@property ref T _as(T)() inout { return *cast(T*)(_data.ptr); 
}

alias b = _as!uint;
alias c = _as!size_t;
alias d = _as!double;
}



Re: How to strip struct/class invariants?

2015-07-05 Thread John Colvin via Digitalmars-d-learn

On Sunday, 5 July 2015 at 12:15:32 UTC, Artem Tarasov wrote:
OK, so there was an old bug fixed in 2.067 
(https://issues.dlang.org/show_bug.cgi?id=4421) so that now 
unions apparently can't contain a struct that has invariants. 
It kinda makes sense, although I don't see why the invariants 
can be simply ignored, as they don't have as much importance as 
destructors/postblits.


But more to the point. I have a struct that has an invariant, 
and I wish to use it as a member of an union. With the latest 
compiler, I have to somehow remove the invariant. Is there some 
compile-time magic that I can use for this?


Not perfect, but I think you can do:

struct A
{
ubyte[B.sizeof] mem;
@property ref B b()
{
return *cast(B*)(mem.ptr);
}
mixin std.typecons.Proxy!b;
}

where B has an invariant. Even better, the invariant should still 
get called.


How to strip struct/class invariants?

2015-07-05 Thread Artem Tarasov via Digitalmars-d-learn
OK, so there was an old bug fixed in 2.067 
(https://issues.dlang.org/show_bug.cgi?id=4421) so that now 
unions apparently can't contain a struct that has invariants. It 
kinda makes sense, although I don't see why the invariants can be 
simply ignored, as they don't have as much importance as 
destructors/postblits.


But more to the point. I have a struct that has an invariant, and 
I wish to use it as a member of an union. With the latest 
compiler, I have to somehow remove the invariant. Is there some 
compile-time magic that I can use for this?