Open the-moisrex opened 2 years ago
A couple of links to consider:
I'm intentionally excluding Small Objection Optimization from it in order to let the user of the istl::function
choose the amount of SOO with the help of stack_allocator
(#153).
Oh man, I'm really stuck at copying/moving istl::function<..., AllocA>
to istl::function<..., AllocB>
.
run_action
function pointer, operator=(...)
(and thus in the copy_from/copy_to/move_from/move_to)alloc_traits::construct(..., Callable)
witch requires both the allocator and the Callable type at the same time.I have tried many possible solutions so far, I've been working on this for days man!
Okay, in order to fix this, I'm gonna write the journey as I go here, let's see if I can fix this or not.
run_action
to an objectStoring a random type, is only possible through function pointers. When the user calls operator=
for a lambda, the caller
and action_runner
methods (which they technically can be combined into one, but it's not recommended because the CPU has to do more work in order to call the function) will be changed to pointing to the new function pointers that have been created with the template, but a function pointer doesn't care about whether or not the function was a templated function or not so this way we're storing the Callable and FunctionType (which is istl::function<..., ...>
) types. The same thing happens in vtables.
I've already tried several ways of rebind method. I can't get them to work because the copy_from/move_from functions don't know the type of the run_action.
FunctionType
from run_action
See, the thing is, we need FunctionType
or at least allocator_type
that is inside the function type, in order to deallocate, and destroy the allocated Callable
which can have any size it wants. We do the construct
and allocate
outside of the run_action
, but the copy/move construct, deallocate, and destroy need to be called inside the run_action
because they need to have access to the Callable
type.
Of course, deallocate
doesn't exactly needs Callable type because we already have a get_size
action which means we can deallocate that amount of size.
My idea here is this: alloc_traits::destroy
calls the Callable's destructor. We can do that without the help of the allocator ourselves. The standard allocators do this anyway. But the problem is that when the user provides a custom allocator, this means that we're skipping the user provided allocator which if we wanted to do that we would be better off with std::function
witch essentially doesn't have allocators nowadays.
run_action
The good thing about run_action
is that it takes a void*
as input. So we can pass a function pointer to it so it can call it and somehow pass the callable type back to the move_to/clone_to functions.
This way, we would be copying/moving the whole istl::function
as a Callable which add another level of indirection for when you want to actually call the object. This has a performance hit so I'm not comfortable with this one.
I think we do need a
std::function
alternative with allocator/traits support. We had such thing, but it's been deprecated.Example usage in:
mustache_view/basic_renderer
Example usage in:
query_builder
Todo: