-
Notifications
You must be signed in to change notification settings - Fork 17
Add a new Function object #61
base: master
Are you sure you want to change the base?
Conversation
It appears that compiler-polyfill will need some work to enable this. Specifically, it requires an implementation of |
Not certain if compiler-polyfil is place for library utilities, more like library-polyfill. @pan- already did already some for their ble testing framework. From his commit message |
@0xc0170 I think it might be too early to start doing a lib-polyfill repo. Let's start if off in compiler-polyfill, then break it out into its own repo when necessary. |
f(f), storage(t) | ||
{} | ||
|
||
virtual ReturnType operator () (ArgTypes&&... Args) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why this is virtual ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It probably doesn't need to be.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I didn't saw that CaptureFirst inherit from FunctionInterface, it makes sense if it is virtual.
4a1560c
to
5872886
Compare
Added a new set of APIs for C Function escalation. Suppose there is a C API that looks like this: typedef void (*foocb) (void*, int, double, char);
int foo(int, char, foocb callback, void * context); Then, suppose that this should be called in a C++ context, e.g. a lambda. In order to achieve this, the previous commit's static APIs can be used. Function<void(int,double,char)> foofunc = [](int i, double d, char c) {
printf("%i, %lf, %c\n", i,d,c);
};
foo(1,'a', &foofunc::call_from_void_dec, foofunc.get_ref());
// If the call is to be used multiple times, then:
foo(1,'a', &foofunc::call_from_void, foofunc.get_ref()); Note that |
cc @Patater |
I'm not exactly sure what this is supposed to solve, but the idea of doing manual ref counting like this looks quite a bit scary. |
This deals with a very common problem in the C/C++ boundary layer, without the use of |
@bogdanm Note that this doesn't have to live in |
The tuple instantiated above is not optimal. It doesn't perform a full sort, so it does not achieve optimal packing. |
+1 for having this syntax available Using similar to std::function, people might try to use it the same way. I did once and failed (use cv qualifier member function with our current fp, see later.) Therefore might be beneficial to share how this differs, or better said what it provides and its known limitations (for a function objects, it's captured nicely in tr1). A quick look at the this changeset a distinction is quite big. For instance, a member function with cv-qualifiers is not covered here. How are arguments binded? I assume using tuple, first argument plus tuple the rest of arguments? How many arguments can be binded? Is there limitation (FUNCTION_SIZE?)? Does it allow small object optimization? Looking at the code, seems like not, and we alloc for any member pointer in ctor for Function:
I am interested to see how call_from_void, and similar work. I'll have a look at this later. I am missing docs for the hierarchy of classes to build this Function type (where magic lies in), which might answer my questions above. |
@0xc0170 You're right, it needs more documentation and more helper methods. I think it would be a good idea to make sure that all of the The tuple is recursively defined and the only constraint is that it must fit in the available allocator. |
Functional is built using reference-counted, pool-allocated functors. Function is the reference type for functors.
This commit adds several updates to the Function implementation * bind_first and bind_last both work * APIs changed to snake_case * atomic_incr and atomic_decr are now used instead of Cortex-M3+ primitives * The first bits of documentation have been added
* Explicit call to ```ExtendablePoolAllocator()``` * Remove unnecessary virtuals * Add asserts for memory allocation failure
Supports ARMmbed/sockets#58 * Add an API to obtain the internal reference as a ```void *``` * Add an API to call a Function from a ```void *``` reference * Add an API to call a Function from a ```void *``` reference, then decrement the reference count
* create a polyfill namespace * move forward to polyfill * Add a sorted tuple
Function could replace FunctionPointer. This PR is not quite finished yet, since it requires more documentation. There is also some cleanup that could be done on
bind_first
/bind_last
, which currently take completely different approaches to how they create the newFunction
.Excerpt from the
Function
documentation:In order to maintain compatibility with existing code,
Function
is intended to be duck-type compatible with theFunctionPointer
family of classes, but it is intentionally not named the same way. A family of compatibility classes is provided to support conversion fromFunctionPointer
code toFunction
. These compatibility classes will be deprecated in an upcoming release.Superficially,
Function
is intented to appear similar tostd::function
. However,Function
has a number of key differences.Function
uses reference counting to limit the copying of large callable objects, such as lambdas with large capture lists orFunction
s with large or many arguments.Function
also uses pool allocation so that objects can be created in interrupt context without usingmalloc()
. These choices are to overcome two specific limitations ofstd::function