[phobos] What does this code do?

David Simcha dsimcha at gmail.com
Tue Aug 17 18:31:45 PDT 2010


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
>> phobos at puremagic.com
>> http://lists.puremagic.com/mailman/listinfo/phobos
>



More information about the phobos mailing list