Stanislav Blinov
Posted in reply to Timon Gehr
| On Tuesday, 9 November 2021 at 21:08:08 UTC, Timon Gehr wrote:
> On 09.11.21 19:41, Stanislav Blinov wrote:
>> On Tuesday, 9 November 2021 at 17:18:31 UTC, Timon Gehr wrote:
>>> On 09.11.21 17:51, Stanislav Blinov wrote:
>>>> On Tuesday, 9 November 2021 at 16:34:26 UTC, Timon Gehr wrote:
>>>>
>>>>> Sure, which is what I said (do it = copy things). But why would you want the check to behave differently from actual code that copies things?
>>>>
>>>> ? Because the check only needs to tell me if copying throws or not.
>>>
>>> For the specific issue we have been discussing, it seems to me that copying does not work at all, independent of whether it's throwing or not. It should just work.
>>
>> It does work just fine. Can copy NestedThatFails within its context. Can copy it to outside of its context too if need be, with copyEmplace. Before you ask "why not just use copyEmplace for the test then?" the answers are 2:
>>
>> 1) it's '@system', so I won't be able to devise an isSafe... test out of it, and
>
> Also, you won't be able to use it in `@safe` code. That's not the same as "just work". The compiler should just do this correctly, just like copyEmplace.
You can use it in @safe code. If you can determine that the copy is actually safe, and you're not corrupting anyone's memory. Just like the ctor from my example in the previous post.
> You said: "should be _that same_ union test [...] it is not". My question was what is not the same.
I meant that currently it can't be "that same union test only without the attributes" because it will also fail, i.e. it will evaluate to false for copyable structs, for the same reasons. So, alas, it has to be a workaround monstrosity.
>> You've seen the test. It's a lambda outside of unittest. How do you propose to write a trait that DOES have access to context? Same goes for std.range.isInputRange...
>> ...
> The constraint should have as much access to context as the function itself does. E.g., templates are sometimes instantiated locally in the caller's context.
That won't help. Look at the example from my previous post. Container is nowhere near that context, and can't be. But it needs to be able to get *useful* introspection out of T. It won't if the compiler bails artificially.
>> Just to reiterate - I *have* a working implementation of a test that works around this problem for testing copy initialization specifically.
For reference:
```d
enum bool isCopyable(T, From=T) = is(typeof(inferCopyAttributesIfCopyable!(T,From)));
enum bool isSafeCopyable(T, From=T) = is(typeof(() @safe => inferCopyAttributesIfCopyable!(T,From)));
enum bool isNogcCopyable(T, From=T) = is(typeof(() @nogc => inferCopyAttributesIfCopyable!(T,From)));
version (D_BetterC) {
enum bool isNothrowCopyable(T, From=T) = .isCopyable!(T, From);
} else {
enum bool isNothrowCopyable(T, From=T) = is(typeof(() nothrow => inferCopyAttributesIfCopyable!(T,From)));
}
void inferIfBlittable(To, From)(scope To* to = null, scope From* from = null)
if (is(immutable To == immutable From))
{
static if (__traits(isStaticArray, To))
inferIfBlittable(&(*to)[0], &(*from)[0]);
else static if (is(To == struct)) {
foreach (i, ref it; to.tupleof[0 .. $-__traits(isNested, To)]) {
inferIfBlittable(&it, &from.tupleof[i]);
}
} else {
To copied = *from;
}
}
void inferCopyAttributesIfCopyable(To, From)(scope To* to = null, scope From* from = null)
if (is(immutable To == immutable From))
{
static if (__traits(isStaticArray, To))
inferCopyAttributesIfCopyable(&(*to)[0], &(*from)[0]);
else static if (is(To == struct)) {
// This all SOOOO does not need to exist...
// Unfortunately, if the struct is nested, doing a simple test
// would result in "cannot access frame pointer" blah blah,
// and if a nested struct is a field in some other struct, well,
// that's even more "pleasant"...
static if (__traits(hasPostblit, To)) {
inferIfBlittable(to, from);
to.__xpostblit;
} else static if (__traits(hasCopyConstructor, To)) {
to.__ctor(*from);
} else {
inferIfBlittable(to, from);
}
} else {
To copied = *from;
}
}
```
I mean, seriously, what the what! :D
|