Generic Property Implementation
Alex
sascha.orlov at gmail.com
Mon Mar 12 10:37:00 UTC 2018
On Monday, 12 March 2018 at 09:54:20 UTC, Simen Kjærås wrote:
>
> But I don't have a hook to update the pointer when the struct
> is moved. The GC may move my struct without informing me in any
> way. In fact, even just a copy construction will break this:
>
> struct S {
> S* ptr;
> this(int dummy) {
> ptr = &this;
> }
> ~this() {
> // This assert will fail.
> assert(ptr == &this);
> }
> }
>
> unittest {
> S s1 = S(0);
> S s2 = S(0);
>
> assert(&s1 == s1.ptr);
> assert(&s2 == s2.ptr);
>
> s1 = s2;
> }
>
> The reason is copy construction makes a copy[1] of the lhs,
> then performs the copy construction[2]. If the copy
> construction[2] succeeds, the copy[1] is destroyed. If not, the
> copy[1] is blitted back over the original, to give the
> impression that nothing ever happened.
>
> When the destructor is called on the copy[1], &this returns a
> different address from what it did before, since it's a copy
> and logically resides at a different address.
>
Sure, you have.
https://dlang.org/spec/struct.html#assign-overload
Point #4.
In this case,
ref S opAssign(ref S rhs)
{
return this;
}
Another point is, that I hope, that pointers don't move anywhere,
as in C, by definition.
>
>> struct SomeType(alias fn) {}
>>
>> is (or has to be) lowered to something like
>>
>> struct SomeType
>> {
>> typeof(fn)* fn;
>> }
>>
>> Even if fn contains a frame pointer to S it is perfectly legal
>> to have such a type. SomeType would contain a delegate then.
>
> Indeed. But stack frames aren't copied or moved the way structs
> are.
>
Yes. This is how the structs are meant to be, I thought :)
>
>> However, I think, the syntax
>>
>>>> struct S {
>>>> int n, m;
>>>> SomeType!(() => n + m) a;
>>>> }
>>
>> is still invalid and
>>
>>>> struct S {
>>>> int n, m;
>>>> auto a() { return SomeType!(() => n + m)(); }
>>>> }
>>
>> has another semantics.
>>
>> The latter closures above the current values inside of S.
>> The former has to be constructible without the context, as it
>> is perfectly legal to write
>>
>> struct Outer
>> {
>> struct Inner{}
>> }
>>
>> void main()
>> {
>> auto i = Outer.Inner();
>> }
>>
>> but would be impossible with this syntax.
>
> I'm not using any inner structs in my examples. SomeType is
> assumed to be a separate type that knows nothing about S. If
> you're saying this should work:
>
Ah... I was unclear, I think...
> unittest {
> auto tmp = typeof(S.a)();
> }
I thought, this shouldn't be possible (at least in my mind)
>
> It wouldn't, and such code is not possible in D today:
>
> struct S {
> int n;
> auto a() { return SomeType!(() => n)(); }
> }
>
> struct SomeType(alias fn) {
> int get() { return fn(); }
> }
>
But this is clearly valid.
> unittest {
> // cannot access frame pointer of foo.S.a.SomeType!(delegate
> () => this.n).SomeType
> auto tmp = typeof(S.a())();
> }
>
For sure, tmp cannot be defined without an instance of S. So the
correct unittest in my eyes would be:
unittest {
S s;
auto res = s.a;
assert(res.get == S.init.n);
}
> --
> Simen
More information about the Digitalmars-d-learn
mailing list