Open AlexGuteniev opened 4 years ago
I'd add from myself here:
While implementing this, you may simulate vtable with static struct that contains pointer. This may make the technique easier to understand, as vptr
re-assignment will happen as plain vptr re-assignment, not as placement new. This may also reduce RTTI overhead.
This will also make std::function not self-referencing ( #964 will be presumably fixed by compiler, but it might come handy if uses decides to move std::function objects with memcpy ).
It will make it non-self-referencing, but I don't think the transformation allows to use memcpy, as it will still have to go through a virtual copy/move operation unless you encode this information (trivially copyable/trivially movable/trivially relocatable) separately.
A lot of non-trivial objects can be memcpy
'd if you forget to destroy the original.
Sure it is UB for nontrivial objects, but it still happens to work.
Some MFC and ATL containers use memcpy
this way for optimization.
A lot of non-trivial objects can be memcpy'd if you forget to destroy the original.
a.k.a trivially relocatable (hope that gest into c++23).
Sure, if you are happy with UB and you know that all the callables in your std::functions are trivially relocatable then that change would help (I'd probably not use a std::function int he first place then though).
a.k.a trivially relocatable (hope that gest into c++23).
Oh, so this has chance to become standard conforming.
Then there is even more sense to make std::finction
such, to prepare for trivial relocation future.
Then there is even more sense to make std::finction such, to prepare for trivial relocation future.
If we decide to make function
and move_only_function
trivially relocatable, we also need to reject non-trivially-relocatable target types for small object optimization. It seems unimplementable without the proposed is_trivially_relocatable
though.
If we decide to make
function
andmove_only_function
trivially relocatable, we also need to reject non-trivially-relocatable target types for small object optimization
Hm, right. Not sure if function
worth making trivially-relocatable then.
Also maybe copying small part of the SFO buffer is better thhan trivially relocating always entire SFO buffer
@MikeGitb mentioned in https://github.com/microsoft/STL/issues/964#issuecomment-652925503
Are you sure? I thought Sean Parent had shown in his lightning talk "Polymorphic Task Template in Ten" (Meeting C++ 2017) how this works without the extra pointer: https://www.youtube.com/watch?v=2KGkcGtGVM4. I don't remember if there were any problems with his implementation that would prevent the same implementation strategy in std::function.
Will try to explain very briefly:
Currently
std::function
uses pointer to small implementation in its buffer and large implementation on heap.It could instead both place small and large implementation in its buffer. In this case, large implementation data has to be on heap, but
vptr
of large implementation is still in the buffer. But both implementations are on a known location, so no pointer to it is needed.This would result in avoiding extra indirection (both pointer size and run-time pointer chasing).
This will also make
std::function
not self-referencing ( #964 will be presumably fixed by compiler, but it might come handy if uses decides to movestd::function
objects withmemcpy
).