Googles appar
Huvudmeny

Post a Comment On: cbloom rants

"02-01-09 - Swap and Templates Part 2"

6 Comments -

1 – 6 of 6
Blogger Arseny Kapoulkine said...

Back then when I had my own resizable vector (now I don't use one, except for tools where it's std::vector), I moved objects via simple memcpy (and did not call destructor on old chunk of memory). Sure, it's kind of UB, but I've never seen a real-world class that does not work with this approach on platforms I care about.

February 2, 2009 at 11:12 AM

Blogger cbloom said...

Hmm.. interesting. At first I was like "wat" but you're right, just moving the bytes like that is going to work for 99% of data.

The only time it doesn't work is if somebody is keeping pointers into himself (weird and rare) or if someone has a pointer registered with someone else that points back at you. In those cases you usually have a RefCounted or some kind of Handle system, and the vector actually holds a shared pointer (which is copyable) not the actual object (whose address matters).

You could easily make that clean by using type traits. You could make the default option be "bit copy" in the type traits, and require people who want to be "assignment copied" to set up the traits for their type to indicate that.

February 2, 2009 at 12:25 PM

Blogger MH said...

Yep, I just suggested this same solution to someone for their .erase(). Just memcopy or regular slow copy the item into a temp var, then memmove item + 1 through end into item + 0. Then destruct the temp var.

(The order of the vector mattered, but constructs, destructs were touching many random places in memory)

February 2, 2009 at 2:35 PM

Blogger cbloom said...

Word.

I've been thinking about this; I used to have a type traits in galaxy to indicate that a type was "memcopyable" in which case I would use memcpy instead of operator =.

This is not quite the same thing, this is a question of whether the object is "relocatable". You can have lots of objects that are relocatable but not memcopyable. (for example auto_ptr,shared_ptr, etc. are relocatable but not memcopyable).

In fact I think if you are doing a custom game-STL type of thing it probably is reasonable to constrain your containers to only be able to hold relocatable objects.

Almost any time you actually have something that's not relocatable, you don't jam it in a container, you hold it with some kind of pointer.

February 2, 2009 at 2:49 PM

Blogger MH said...

The code in .erase in a vector|T| is relocating each element above iterator it down by sizeof( T ), unless Im missing something.

February 2, 2009 at 7:16 PM

Blogger cbloom said...

No, it's not just relocating down. According to the standard, it calls the destructor of the element being erased and then operator= to slide the others down.

STLport for example uses __type_traits::has_trivial_assignment_operator to switch to memmove in many cases.

February 2, 2009 at 9:45 PM

You can use some HTML tags, such as <b>, <i>, <a>

This blog does not allow anonymous comments.

Comment moderation has been enabled. All comments must be approved by the blog author.

You will be asked to sign in after submitting your comment.