June 02, 2019
On Sunday, June 2, 2019 1:29:22 PM MDT Jonathan M Davis via Digitalmars-d- learn wrote:
> On Sunday, June 2, 2019 8:32:16 AM MDT Paul Backus via Digitalmars-d-learn wrote:
> > On Sunday, 2 June 2019 at 06:59:02 UTC, Jonathan M Davis wrote:
> > > Almost certainly, hasElaborateCopyConstructor should be updated to test for both postblit constructors and copy constructors, since its purpose is to test for whether the type has a user-defined copying function [...] Whether hasElaborateCopyConstructor was the best name is debatable, but it _does_ involve "elaborate" copying, and copy constructors weren't actually in the language at the time. The documentation is wonderfully confusing though in that it talks about copy constructors and then says that a copy constructor is introduced by defining this(this) for a struct. So, it basically calls a postblit constructor a copy constructor.
> >
> > I've made the mistake in the past of trying to use hasElaborateCopyConstructor to test for the presence of __xpostblit, and I'm sure I'm not the only one. The name is quite misleading--even more so now that D has real copy constructors.
> >
> > If std.v2 ever materializes, we'll have an opportunity to fix papercuts like this. Until then, my preferred workaround is to use a renaming import:
> >
> > import std.traits: hasNontrivialCopy = hasElaborateCopyConstructor;
>
> Why is it a mistake to use hasElaborateCopyConstructor to test for __xpostblit? Because you're trying to test for __xpostblit for some purpose other than determining whether the type is blittable? I'm not sure what other reason there would be to test for __xpostblit though. Either way, hasElaborateCopyConstructor currently checks for exactly that (with the addition that it checks whether a static array has elements with __xpostblit):
>
> template hasElaborateCopyConstructor(S)
> {
>     static if (__traits(isStaticArray, S) && S.length)
>     {
>         enum bool hasElaborateCopyConstructor =
> hasElaborateCopyConstructor! (typeof(S.init[0]));
>     }
>     else static if (is(S == struct))
>     {
>         enum hasElaborateCopyConstructor = __traits(hasMember, S,
> "__xpostblit");
>     }
>     else
>     {
>         enum bool hasElaborateCopyConstructor = false;
>     }
> }
>
> My point was that given the purpose of hasElaborateCopyConstructor, updating it to test for both a postblit constructor and copy constructor would be appropriate. In fact, the fact that it hasn't been means that the introduction of copy constructors has broken existing code (or at least that such code won't interact correctly with structs that have copy constructors). There should be no need to rename the trait, just update it, and whether it uses the name "elaborate" or "non-trivial" is pretty much irrelevant. Personally, I probably would have chosen hasNonTrivial over hasElaborate, but they mean the same thing, and we have hasElaborateDestructor for the corresponding test for destructors and hasElaborateAssign for the corresponding test for assignment. It really doesn't make sense to change the name at this point.

It looks like Manu already reported a bug on this:

https://issues.dlang.org/show_bug.cgi?id=19902

- Jonathan M Davis



1 2
Next ›   Last »