Sorry for the double mail, Andrei. I meant to send this to the whole list but my mail client screwed up.

I ran into a few issues w/ emplace while trying to improve array() that I don't know how to fix:

1. Bug 4671 (http://d.puremagic.com/issues/show_bug.cgi?id=4671). Basically, emplace() doesn't work if args is arguments for a struct literal, not a struct c'tor. I assume that this is supposed to work. I'm not sure how to fix it because:

a. Something like the following won't work if the struct contains const/immutable elements that are supposed to be initialized in the c'tor:

foreach(ti, arg; args) {
    (*result).tupleof[ti] = arg;
}

b. Creating a new struct using args and then using memcpy to copy it to the buffer will do weird things if the struct has a destructor.

c. Creating a new struct using args, initializing the buffer and then assigning it to *result using opAssign might do weird things if the semantics of opAssign and the semantics of the c'tor aren't the consistent, though this is poor enough design that anyone who does it probably deserves what they get.

2.  I don't understand this code:

    else static if (Args.length == 1)
    {
        // T doesn't define a constructor, must be a primitive type
        static if (is(typeof(result.opAssign(args))))
        {
            static init = T.init;
            memcpy(p, &init, T.sizeof);
        }
        *result = args[0];
    }

How can something be a primitive if it has an opAssign?

3. In the memcpy() line in the code above, I assume you meant memcpy(result, &init, T.sizeof)? There is no variable p in that scope.



On 8/17/2010 2:07 PM, Andrei Alexandrescu wrote:
The idea is to create a typed object in uninitialized memory. Generally using the assignment operator for that is suicide because that guy assumes the object was previously initialized.

Instead of placement new, a better way is to use emplace(). Grep for it to see documentation and examples. Please let us know if you hit another hitch.


Andrei

On 08/16/2010 07:01 PM, David Simcha wrote:
I'm trying to revamp array() to follow Bearophile's very good suggestion
of letting any foreachable object be convertible to an array even if
it's opApply-based, not a range. My efforts have been blocked by this
cryptic piece of code:

foreach (ref e; result)
{
// hacky
static if (is(typeof(&e.opAssign)))
{
// this should be in-place construction
new(&e) E(r.front);
}
else
{
e = r.front;
}
r.popFront;
}

It took me awhile to even wrap my head around what the point of that
code is. First of all, why are we bypassing opAssign? Secondly, what if
the E doesn't have a constructor that takes only another E as an argument?
_______________________________________________
phobos mailing list
[email protected]
http://lists.puremagic.com/mailman/listinfo/phobos


_______________________________________________
phobos mailing list
[email protected]
http://lists.puremagic.com/mailman/listinfo/phobos

Reply via email to