| |
| Posted by Stanislav Blinov in reply to Timon Gehr | PermalinkReply |
|
Stanislav Blinov
Posted in reply to Timon Gehr
| On Tuesday, 9 November 2021 at 15:07:58 UTC, Timon Gehr wrote:
> On 09.11.21 15:11, Stanislav Blinov wrote:
>> On Tuesday, 9 November 2021 at 09:24:29 UTC, Timon Gehr wrote:
>>> ...
>>>
>>> There is never really a need to instantiate a value of any type just to check what it supports.
>>
>> Yes, there is. isInputRange tries, and fails for some nested structs (keyword - some).
>
> Fair, sometimes you want to check whether you can declare a value of the given type, though that _should_ fail in case it's not actually possible for the algorithm to do that and get an actually working instance. It's plausible that that check does not actually work correctly for some Phobos functions though, as local instantiation of templates is a bit messy.
The point is it must be possible to test that, and it's not, because of some arbitrary artificial limitation. I mean, we can freely instantiate null delegates, but we can't instantiate nested structs? There's, to me, zero logic in that.
> I see, I guess you actually want this, but it does not work:
>
> enum bool isNothrowCopyable(To, From) = __traits(compiles, (From from)nothrow{ To to=from; });
No, that also tests destruction, of both `from`, because it's D, where functions destruct their arguments, and `to`, because it's a local :) What I want is this:
```d
template isNothrowCopyable(To, From)
if (is(immutable To == immutable From))
{
enum bool isNothrowCopyable = is(typeof((ref scope From from) nothrow { union U { To to; } U u = U(from); }));
}
```
...but it indeed doesn't work for nested structs. And a thing that does "work" has to reimplement compiler's copy semantics, including field-by-field blitting, calling constructors and postblits, etc.
> What's the use case for checking only this kind of initialization, if you don't need to create new instances of `to`?
? You *do* need to create new instances of `to`. By copying existing instances. Any container that wants to support copying has to do that, and beyond. I want a test that would also tell me if my container needs special handling of exception guarantees, or if it can freely do an easy thing and not worry about it: can I just copy existing things on element insertion one element over, or do I have to do a three step algorithm because copying might throw?..
I also want other tests, that would tell me if copying is safe to do, if it needs GC, if it's pure... (I *do* have them already, but like I said, they're ludicrous, for no other reason than this handwaving error message). And as for isInputRange - I haven't got a clue if it's even possible to make it work for all nested structs unless the compiler stops issuing this error message.
|